be72082c5897 — Peter Sanchez 13 years ago
Initial commit..
5 files changed, 266 insertions(+), 0 deletions(-)

A => .hgignore
A => LICENSE
A => README.txt
A => easyconfig/__init__.py
A => setup.py
A => .hgignore +5 -0
@@ 0,0 1,5 @@ 
+syntax:glob
+.svn
+.hgsvn
+.*.swp
+**.pyc

          
A => LICENSE +32 -0
@@ 0,0 1,32 @@ 
+Copyright (c) 2010, Peter Sanchez <petersanchez@gmail.com>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or 
+without modification, are permitted provided that the 
+following conditions are met:
+
+ * Redistributions of source code must retain the above 
+   copyright notice, this list of conditions and the 
+   following disclaimer.
+
+ * Redistributions in binary form must reproduce the above 
+   copyright notice, this list of conditions and the following 
+   disclaimer in the documentation and/or other materials 
+   provided with the distribution.
+
+ * Neither the name of Peter Sanchez nor the names of its 
+   contributors may be used to endorse or promote products 
+   derived from this software without specific prior written 
+   permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

          
A => README.txt +126 -0
@@ 0,0 1,126 @@ 
+django-easyconfig
+------------------
+
+This app will make it easy to customize external Django apps 
+that use it.
+
+It takes an approach very similar to the django.contrib.comments 
+framework. It makes it easy to use custom forms, values, etc.
+
+Quick example...
+
+Say you have an open source Django app that lets you upload a 
+Photo and some metadata to that photo. To be able to customize 
+that form, the project owners would have to hack the app's 
+source to fit their needs (class names, etc.) or you have to 
+make your app customizable. That's where django-easyconfig 
+comes in...
+
+
+Install
+-------
+
+Basic Install:
+
+  $ python setup.py build
+  $ sudo python setup.py install
+
+Alternative Install (Manually):
+
+Place webutils directory in your Python path. Either in your Python 
+installs site-packages directory or set your $PYTHONPATH environment 
+variable to include a directory where the webutils directory lives.
+
+
+Use
+---
+
+* XXX * These are not great docs. I'll work on updating this soon!
+
+You must create a "Config" object in your app and use that to fetch 
+any object or value you want to be able to have customized.
+
+Here is a basic example.
+
+### yourapp/__init__.py
+
+from django.contrib.auth.forms import AuthenticationForm
+from yourapp.forms import PasswordChangeForm
+from easyconfig import EasyConfig
+
+
+class Config(object):
+    ''' Base config class to easily pass forms, etc. to 
+        yourapp views.
+    '''
+    # Use the dotted Python path to this class
+    config = EasyConfig('yourapp.Config', 'YOURAPP_CONFIG')
+	
+    def get_login_form(self):
+        return self.config.get_object('get_login_form', AuthenticationForm)
+
+    def get_password_change_form(self):
+        return self.config.get_object('get_password_change_form', PasswordChangeForm)
+
+
+Now, you just need to use your yourapp.Config class any time you need 
+to fetch one of these objects for use.
+
+Here's how it could be used in a urls.py file
+
+### urls.py
+
+from yourapp import Config
+from django.conf.urls.defaults import *
+
+
+config = Config()
+
+urlpatterns = patterns('yourapp.views',
+    url(r'^login/$',
+        'login', {
+            'template_name': 'yourapp/login.html',
+            'authentication_form': config.get_login_form(),
+        }, name='yourapp-login'),
+    url(r'^passwd_change/$',
+        'passwd_change', {
+            'template_name': 'yourapp/passwd_change.html',
+            'passwd_change_form': config.get_password_change_form(),
+        }, name='yourapp-passwd-change'),
+)
+
+Now, anybody using your app in their own project can easily change the 
+login and password change forms to whatever form they want. Here is how
+they would do so in their own project.
+
+
+### settings.py
+
+# Dotted python path to their own CustomConfig class
+YOURAPP_CONFIG = 'myproject.myapp.CustomConfig'
+
+
+### myproject/myapp/__init__.py
+
+from myproject.myapp.forms import AuthForm, ChangeForm
+
+
+class CustomConfig(object):    
+    ''' Customize the forms!
+    '''
+    def get_login_form(self):
+        return AuthForm
+    
+    def get_password_change_form(self):
+        return ChangeForm
+
+
+That's it. Easy right? :)
+
+
+Copyright & Warranty
+--------------------
+All documentation, libraries, and sample code are 
+Copyright 2010 Peter Sanchez <petersanchez@gmail.com>. The library and 
+sample code are made available to you under the terms of the BSD license 
+which is contained in the included file, BSD-LICENSE.

          
A => easyconfig/__init__.py +52 -0
@@ 0,0 1,52 @@ 
+from django.conf import settings
+from django.core.exceptions import ImproperlyConfigured
+from django.utils.importlib import import_module
+
+
+__version__ = '0.1'
+
+
+class EasyConfig(object):
+    def __init__(self, default_module, setting_name):
+        self.default_module = default_module
+        self.setting_name = setting_name
+
+    def _get_config(self):
+        ''' Get the config as defined in the settings
+        '''
+        config = self._get_config_name()
+        try:
+            package = import_module(config)
+        except ImportError:
+            path = '.'.join(config.split('.')[:-1])
+            pkg = config.split('.')[-1]
+            try:
+                tmp_package = import_module(path, package=pkg)
+                package = getattr(tmp_package, pkg)
+            except (ImportError, AttributeError):
+                raise ImproperlyConfigured(
+                    'The %s setting refers to a non-existing package.' % \
+                                                            self.setting_name
+                )
+        
+        if callable(package):
+            package = package()
+        return package
+
+    def _get_config_name(self):
+        ''' Returns the name of the support config (either the setting value, 
+            if it exists, or the default).
+        '''
+        return getattr(settings, self.setting_name, self.default_module)
+
+
+    def get_object(self, method, default_obj):
+        ''' Check that the support config is custom, and if so, that the 
+            right methods exist. If not, return the default_obj
+        '''
+        if self._get_config_name() != self.default_module:
+            config = self._get_config()
+            if hasattr(config, method):
+                return getattr(config, method)()
+
+        return default_obj

          
A => setup.py +51 -0
@@ 0,0 1,51 @@ 
+import os
+from distutils.core import setup
+
+
+project_name = 'easyconfig'
+long_description = open('README.txt').read()
+
+# Idea from django-registration setup.py
+packages, data_files = [], []
+root_dir = os.path.dirname(__file__)
+if root_dir:
+    os.chdir(root_dir)
+
+for dirpath, dirnames, filenames in os.walk(project_name):
+    # Ignore dirnames that start with '.'
+    for i, dirname in enumerate(dirnames):
+        if dirname.startswith('.'):
+            del dirnames[i]
+    if '__init__.py' in filenames:
+        pkg = dirpath.replace(os.path.sep, '.')
+        if os.path.altsep:
+            pkg = pkg.replace(os.path.altsep, '.')
+        packages.append(pkg)
+    elif filenames:
+        prefix = dirpath[(len(project_name) + 1):]
+        for f in filenames:
+            data_files.append(os.path.join(prefix, f))
+
+setup(
+    name='django-easyconfig',
+    version=__import__(project_name).__version__,
+    package_dir={project_name: project_name},
+    packages=packages,
+    package_data={project_name: data_files},
+    description='Module to make it easy to configure external Django apps.',
+    author='Peter Sanchez',
+    author_email='petersanchez@gmail.com',
+    license='BSD License',
+    url='http://bitbucket.org/petersanchez/django-easyconfig/',
+    long_description=long_description,
+    platforms=['any'],
+    classifiers=[
+        'Development Status :: 4 - Beta',
+        'Intended Audience :: Developers',
+        'License :: OSI Approved :: BSD License',
+        'Natural Language :: English',
+        'Operating System :: OS Independent',
+        'Programming Language :: Python',
+        'Environment :: Web Environment',
+    ],
+)