├── demoapp ├── __init__.py ├── manage.py ├── urls.py └── settings.py ├── configdir ├── management │ ├── __init__.py │ └── commands │ │ ├── __init__.py │ │ └── confignginx.py ├── template.py ├── __init__.py └── django_confighelper.py ├── AUTHORS ├── MANIFEST.in ├── .hgtags ├── LICENSE ├── .veh.conf ├── setup.py └── README /demoapp/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /configdir/management/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /configdir/management/commands/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | seb@woome.com 2 | nferrier@ferrier.me.uk 3 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include AUTHORS 2 | include LICENSE 3 | include README 4 | -------------------------------------------------------------------------------- /.hgtags: -------------------------------------------------------------------------------- 1 | 0a489f78248ad96620e9d101e877e7870b41a5c0 release_0_1_7 2 | 92dd1f479e2a42520ba9c83e95ff0e8bf490f3cb release_0_1_8 3 | 3d08da625efbbab34d88ebc7992d470143342704 release_0_1_9 4 | 5eec4be9b03caf827cdb6b8470110e7c45a72fc6 release_0_1_10 5 | -------------------------------------------------------------------------------- /demoapp/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from django.core.management import execute_manager 3 | import imp 4 | try: 5 | imp.find_module('settings') # Assumed to be in the same directory. 6 | except ImportError: 7 | import sys 8 | sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n" % __file__) 9 | sys.exit(1) 10 | 11 | import settings 12 | 13 | if __name__ == "__main__": 14 | execute_manager(settings) 15 | -------------------------------------------------------------------------------- /configdir/template.py: -------------------------------------------------------------------------------- 1 | SETTINGS_TEMPLATE = """ 2 | 3 | try: 4 | import configdir 5 | conf = configdir.get() 6 | cmod = __import__("configs.%s" % conf, {}, {}, ['']) 7 | cmod_dict = dict([ 8 | (k,v) for k,v in cmod.__dict__.iteritems() if not k.startswith('_') 9 | ]) 10 | gd = globals() 11 | gd.update(cmod_dict) 12 | del gd 13 | except Exception, e: 14 | print "FAILED: Cannot import configdir settings:\\n %s" % (e,) 15 | import sys 16 | sys.exit(1) 17 | finally: 18 | if 'REQUIRED_VARS' in globals().keys(): 19 | configdir.failOnMissing(globals(), REQUIRED_VARS) 20 | 21 | """ 22 | -------------------------------------------------------------------------------- /demoapp/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls.defaults import patterns, include, url 2 | 3 | # Uncomment the next two lines to enable the admin: 4 | # from django.contrib import admin 5 | # admin.autodiscover() 6 | 7 | urlpatterns = patterns('', 8 | # Examples: 9 | # url(r'^$', 'demoapp.views.home', name='home'), 10 | # url(r'^demoapp/', include('demoapp.foo.urls')), 11 | 12 | # Uncomment the admin/doc line below to enable admin documentation: 13 | # url(r'^admin/doc/', include('django.contrib.admindocs.urls')), 14 | 15 | # Uncomment the next line to enable the admin: 16 | # url(r'^admin/', include(admin.site.urls)), 17 | ) 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) WooMedia Inc. 2 | All rights reserved. 3 | 4 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 5 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 6 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 7 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 8 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 9 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 10 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 11 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 12 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 13 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 14 | -------------------------------------------------------------------------------- /configdir/__init__.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import os 3 | import logging 4 | import pwd 5 | 6 | def get(): 7 | logger = logging.getLogger("configdir.get") 8 | h = socket.gethostname() 9 | # Pick the username from either an env var or from unix 10 | l = os.environ.get("CONFIG_USER", pwd.getpwuid(os.getuid())[0]) 11 | wd = os.path.basename(os.getcwd()) 12 | parts = (h, l, wd) 13 | conf = [confitem.replace('-', '_').replace('.', '_') \ 14 | for confitem in parts] 15 | name = "%s.%s__%s" % tuple(conf) 16 | return name 17 | 18 | 19 | # Test required variables and fail if they aren't there 20 | def failOnMissing(globalvars, REQUIRED_VARS): 21 | import sys 22 | do_fail = False 23 | for varname in REQUIRED_VARS: 24 | if varname not in globalvars: 25 | print >>sys.stderr, """ERROR: refusing to start django: %s was not present""" % varname 26 | do_fail = True 27 | if do_fail: 28 | # Not sure if this should raise an error 29 | print >>sys.stderr, """try: django_confighelper edit 30 | and set the correct value. Please check all settings values that are required.""" 31 | sys.exit(1) 32 | 33 | # End 34 | -------------------------------------------------------------------------------- /.veh.conf: -------------------------------------------------------------------------------- 1 | [packages] 2 | # enter package names here like 3 | # packagelabel = packagename 4 | # 5 | # The package name on the right are passed directly to pip. 6 | # The package label is not used right now. 7 | # 8 | # This makes it easy to use either a pypi name: 9 | # packagelabel = packagename 10 | # or if the package name is the same as the option label: 11 | # packagelabel = 12 | # 13 | # or a url: 14 | # packagelabel = http://pypi.python.org/packages/source/v/virtualenv/virtualenv-1.4.9.tar.gz#md5=c49067cab242b5ff8c7b681a5a99533a 15 | # 16 | # or a vc reference: 17 | # packagelabel = hg+http://domain/repo 18 | django = django==1.3 19 | django-configdir = . 20 | 21 | [veh] 22 | # supported options for veh: 23 | # rebuilding creates a brand new virtualenv leaving the old in place. 24 | # the following options controls whether the previously active virtualenv 25 | # is deleted during rebuild or not: 26 | # delete-on-rebuild = true 27 | 28 | 29 | [pip] 30 | # supported options for pip: 31 | # always-upgrade = true 32 | # supply the --upgrade option to pip when building the virtualenv 33 | # download-cache = DIRECTORY 34 | # specifies a directory to use for pip's download cache 35 | 36 | # End 37 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import os 2 | from setuptools import setup 3 | 4 | # Utility function to read the README file. 5 | # Used for the long_description. It's nice, because now 1) we have a top level 6 | # README file and 2) it's easier to type in the README file than to put a raw 7 | # string in below ... 8 | def read(fname): 9 | return open(os.path.join(os.path.dirname(__file__), fname)).read() 10 | 11 | setup( 12 | name = "django_configdir", 13 | version = "0.1.10", 14 | author = "Seb Potter", 15 | author_email = "seb@woome.com", 16 | description = ("A utility to create per-user, per-host configuration " 17 | "files for Django."), 18 | license = "GPLv2", 19 | keywords = "django configuration instance utility user", 20 | url = "http://github.com/woome/django_configdir", 21 | packages=['configdir', 'configdir.management', 'configdir.management.commands'], 22 | requires=['django'], 23 | entry_points = { 24 | 'console_scripts': [ 25 | 'django_confighelper = configdir.django_confighelper:main', 26 | 'django-confighelper = configdir.django_confighelper:main', 27 | ] 28 | }, 29 | long_description=read('README'), 30 | classifiers=[ 31 | "Development Status :: 4 - Beta", 32 | "Topic :: Utilities", 33 | "License :: OSI Approved :: GNU General Public License (GPL)", 34 | "Framework :: Django", 35 | ], 36 | ) 37 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | A tool for helping with override Django configs. 2 | 3 | django_confighelper on its own creates a config for the current django 4 | instance based on the current hostname, the current name of the 5 | effective uid and the current directory in which the django instance 6 | is sitting: 7 | 8 | config/hostname/euidname__dirname.py 9 | 10 | If the config already exists django_confighelper exits with a warning. 11 | 12 | The 'edit' subcommand attempts to start a system editor on the 13 | config. It first tries the environment variable $EDITOR and then 14 | switches to "editor" from the execution path. 15 | 16 | The 'print' subcommand prints the filename of the config file. This is 17 | so you can script further interactions, for example: 18 | 19 | echo "CONFIG_SPECIAL=True" >> $(django_confighelper print) 20 | 21 | The 'default' subcommand looks for a default config file in 22 | config/defaults/$user.py and if it exists, it creates a config using 23 | the values contained there in. It opens the newly created file just 24 | in case you need to change some values - like FRONTEND_PORT e.t.c 25 | 26 | The 'printval' subcommand prints the value of a DJANGO config setting 27 | after the config has been applied. For example: 28 | 29 | django_confighelper printval DATABASE_HOST 30 | 31 | prints out the setting of the database host. 32 | 33 | The 'updatesettings' subcommand appends the contents of configdir/templates.py 34 | to the end of the settings.py in the current directory. This is required to be 35 | run once (and once only), and simply adds some import statements to handle 36 | the additional import of per-instance settings files. 37 | 38 | The 'cat' subcommands outputs the contents of the instance specific config file 39 | (i.e. config/hostname/euidname__dirname.py) 40 | 41 | The 'dir' subcommand outputs the evaluated values of all settings managed by 42 | django_confighelper. 43 | 44 | 45 | confignginx is also included. This is a management command you can use 46 | to generate Nginx configs from your Django app. 47 | 48 | ./manage.py confignginx --port=8100 --domain=www.example.com 49 | 50 | will generare an nginx config that will proxy requests to the port but 51 | send all static data to the STATIC_ROOT via the STATIC_URL. 52 | -------------------------------------------------------------------------------- /configdir/management/commands/confignginx.py: -------------------------------------------------------------------------------- 1 | from django.core.management.base import BaseCommand 2 | from django.core.management.base import CommandError 3 | from django.conf import settings 4 | from os.path import abspath 5 | from optparse import make_option 6 | import socket 7 | import re 8 | 9 | class Command(BaseCommand): 10 | args = ' []' 11 | option_list = BaseCommand.option_list + ( 12 | make_option( 13 | '--port', 14 | action='store', 15 | dest='tcp_port', 16 | default=8099, 17 | help='The tcp port to use for Nginx to talk to Django.' 18 | ), 19 | make_option( 20 | "--host-address", 21 | action="store", 22 | default="_", 23 | dest="host_address", 24 | help="The ip address for nginx to listen on, use _ to try to resolve the domain name (the default)" 25 | ) 26 | ) 27 | 28 | help = 'Generates an Nginx config to map the current Django app to Nginx.' 29 | 30 | def handle(self, *args, **options): 31 | domain = args[0] 32 | domains = "" 33 | if len(args) > 1: 34 | domains = args[1:] 35 | 36 | host_addr = options["host_address"] 37 | if host_addr == "_": 38 | host_addr = socket.gethostbyname(domain) 39 | elif not re.match("^([0-9]+\\.){3}[0-9]+$", host_addr): 40 | host_addr = socket.gethostbyname(host_addr) 41 | 42 | variables = { 43 | "HOST_ADDRESS": host_addr, 44 | "PORT": options["tcp_port"], 45 | "DOMAIN": domain, 46 | "DOMAINS": " ".join(domains), 47 | "UPSTREAM_NAME": "django__" + domain.replace(".", "__"), 48 | "STATIC_URL": settings.STATIC_URL, 49 | "DOCROOT": abspath(settings.STATIC_ROOT), 50 | } 51 | config = """# Nginx config generated by django-config 52 | 53 | upstream %(UPSTREAM_NAME)s { 54 | server localhost:%(PORT)s; 55 | } 56 | 57 | server { 58 | listen %(HOST_ADDRESS)s:80; 59 | server_name %(DOMAIN)s %(DOMAINS)s; 60 | root %(DOCROOT)s; 61 | 62 | location %(STATIC_URL)s { 63 | rewrite ^%(STATIC_URL)s(.*)$ /$1 break; 64 | } 65 | 66 | location / { 67 | proxy_pass http://%(UPSTREAM_NAME)s; 68 | proxy_redirect off; 69 | proxy_set_header Host "%(DOMAIN)s"; 70 | proxy_next_upstream error timeout; 71 | proxy_connect_timeout 120; 72 | proxy_send_timeout 120; 73 | proxy_read_timeout 120; 74 | } 75 | 76 | } 77 | """ % variables 78 | print config 79 | 80 | # End 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /demoapp/settings.py: -------------------------------------------------------------------------------- 1 | # Django settings for demoapp project. 2 | 3 | DEBUG = True 4 | TEMPLATE_DEBUG = DEBUG 5 | 6 | ADMINS = ( 7 | # ('Your Name', 'your_email@example.com'), 8 | ) 9 | 10 | MANAGERS = ADMINS 11 | 12 | DATABASES = { 13 | 'default': { 14 | 'ENGINE': 'django.db.backends.', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. 15 | 'NAME': '', # Or path to database file if using sqlite3. 16 | 'USER': '', # Not used with sqlite3. 17 | 'PASSWORD': '', # Not used with sqlite3. 18 | 'HOST': '', # Set to empty string for localhost. Not used with sqlite3. 19 | 'PORT': '', # Set to empty string for default. Not used with sqlite3. 20 | } 21 | } 22 | 23 | # Local time zone for this installation. Choices can be found here: 24 | # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name 25 | # although not all choices may be available on all operating systems. 26 | # On Unix systems, a value of None will cause Django to use the same 27 | # timezone as the operating system. 28 | # If running in a Windows environment this must be set to the same as your 29 | # system time zone. 30 | TIME_ZONE = 'America/Chicago' 31 | 32 | # Language code for this installation. All choices can be found here: 33 | # http://www.i18nguy.com/unicode/language-identifiers.html 34 | LANGUAGE_CODE = 'en-us' 35 | 36 | SITE_ID = 1 37 | 38 | # If you set this to False, Django will make some optimizations so as not 39 | # to load the internationalization machinery. 40 | USE_I18N = True 41 | 42 | # If you set this to False, Django will not format dates, numbers and 43 | # calendars according to the current locale 44 | USE_L10N = True 45 | 46 | # Absolute filesystem path to the directory that will hold user-uploaded files. 47 | # Example: "/home/media/media.lawrence.com/media/" 48 | MEDIA_ROOT = '' 49 | 50 | # URL that handles the media served from MEDIA_ROOT. Make sure to use a 51 | # trailing slash. 52 | # Examples: "http://media.lawrence.com/media/", "http://example.com/media/" 53 | MEDIA_URL = '' 54 | 55 | # Absolute path to the directory static files should be collected to. 56 | # Don't put anything in this directory yourself; store your static files 57 | # in apps' "static/" subdirectories and in STATICFILES_DIRS. 58 | # Example: "/home/media/media.lawrence.com/static/" 59 | STATIC_ROOT = '' 60 | 61 | # URL prefix for static files. 62 | # Example: "http://media.lawrence.com/static/" 63 | STATIC_URL = '/static/' 64 | 65 | # URL prefix for admin static files -- CSS, JavaScript and images. 66 | # Make sure to use a trailing slash. 67 | # Examples: "http://foo.com/static/admin/", "/static/admin/". 68 | ADMIN_MEDIA_PREFIX = '/static/admin/' 69 | 70 | # Additional locations of static files 71 | STATICFILES_DIRS = ( 72 | # Put strings here, like "/home/html/static" or "C:/www/django/static". 73 | # Always use forward slashes, even on Windows. 74 | # Don't forget to use absolute paths, not relative paths. 75 | ) 76 | 77 | # List of finder classes that know how to find static files in 78 | # various locations. 79 | STATICFILES_FINDERS = ( 80 | 'django.contrib.staticfiles.finders.FileSystemFinder', 81 | 'django.contrib.staticfiles.finders.AppDirectoriesFinder', 82 | # 'django.contrib.staticfiles.finders.DefaultStorageFinder', 83 | ) 84 | 85 | # Make this unique, and don't share it with anybody. 86 | SECRET_KEY = '^d)q+)2(2e(5q30+k29uc8bmu5)_0oy@h_787pxhg_iw@ey$k^' 87 | 88 | # List of callables that know how to import templates from various sources. 89 | TEMPLATE_LOADERS = ( 90 | 'django.template.loaders.filesystem.Loader', 91 | 'django.template.loaders.app_directories.Loader', 92 | # 'django.template.loaders.eggs.Loader', 93 | ) 94 | 95 | MIDDLEWARE_CLASSES = ( 96 | 'django.middleware.common.CommonMiddleware', 97 | 'django.contrib.sessions.middleware.SessionMiddleware', 98 | 'django.middleware.csrf.CsrfViewMiddleware', 99 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 100 | 'django.contrib.messages.middleware.MessageMiddleware', 101 | ) 102 | 103 | ROOT_URLCONF = 'demoapp.urls' 104 | 105 | TEMPLATE_DIRS = ( 106 | # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". 107 | # Always use forward slashes, even on Windows. 108 | # Don't forget to use absolute paths, not relative paths. 109 | ) 110 | 111 | INSTALLED_APPS = ( 112 | 'django.contrib.auth', 113 | 'django.contrib.contenttypes', 114 | 'django.contrib.sessions', 115 | 'django.contrib.sites', 116 | 'django.contrib.messages', 117 | 'django.contrib.staticfiles', 118 | # Uncomment the next line to enable the admin: 119 | # 'django.contrib.admin', 120 | # Uncomment the next line to enable admin documentation: 121 | # 'django.contrib.admindocs', 122 | ) 123 | 124 | # A sample logging configuration. The only tangible logging 125 | # performed by this configuration is to send an email to 126 | # the site admins on every HTTP 500 error. 127 | # See http://docs.djangoproject.com/en/dev/topics/logging for 128 | # more details on how to customize your logging configuration. 129 | LOGGING = { 130 | 'version': 1, 131 | 'disable_existing_loggers': False, 132 | 'handlers': { 133 | 'mail_admins': { 134 | 'level': 'ERROR', 135 | 'class': 'django.utils.log.AdminEmailHandler' 136 | } 137 | }, 138 | 'loggers': { 139 | 'django.request': { 140 | 'handlers': ['mail_admins'], 141 | 'level': 'ERROR', 142 | 'propagate': True, 143 | }, 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /configdir/django_confighelper.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """A module that auto creates django override configs""" 4 | 5 | from __future__ import with_statement 6 | 7 | import re 8 | import os 9 | import os.path 10 | import sys 11 | import types 12 | 13 | import configdir 14 | 15 | 16 | def print_value(v): 17 | if isinstance(v, types.ListType) or isinstance(v, types.TupleType): 18 | for val in v: 19 | print_value(val) 20 | else: 21 | print v 22 | 23 | 24 | def setup_environment(filepath, depth): 25 | """setup our django 'app' environment""" 26 | from django.core.management import setup_environ 27 | import settings 28 | setup_environ(settings) 29 | 30 | 31 | def config_module_to_path(): 32 | module_name = configdir.get() 33 | pathname = "%s/configs/%s.py" % (os.getcwd(), module_name.replace(".", "/")) 34 | return pathname 35 | 36 | 37 | def update_settings_file(): 38 | from template import SETTINGS_TEMPLATE 39 | with open('settings.py', 'a') as fd: 40 | print >> fd, SETTINGS_TEMPLATE 41 | 42 | 43 | def config_dir(): 44 | try: 45 | from django.conf import settings 46 | os.environ["DJANGO_SETTINGS_MODULE"] = settings.__file__ 47 | except ImportError: 48 | import os 49 | sys.path += [os.getcwd()] 50 | import settings 51 | os.environ["DJANGO_SETTINGS_MODULE"] = settings.__file__ 52 | for s in dir(settings): 53 | if not s.startswith("_"): 54 | print "%s = %r" % (s, settings.__dict__[s]) 55 | else: 56 | for s in dir(settings): 57 | if not s.startswith("_"): 58 | print "%s = %r" % (s, settings.__dict__[s]) 59 | 60 | 61 | def config_printval(): 62 | import settings 63 | for val in sys.argv[2:]: 64 | try: 65 | print_value(settings.__dict__[val]) 66 | except KeyError: 67 | print >>sys.stderr, "WARNING: %s does not exist in settings" % val 68 | sys.exit(1) 69 | 70 | def make_default(path, fname=None, post_edit=True): 71 | path_values = re.search(r'(?P.*)\.(?P.*)__(?P.*)', configdir.get()).groupdict() 72 | default_config_path = "configs/defaults/%(userid)s.py" % path_values 73 | 74 | # check if it exists 75 | if os.path.exists(default_config_path): 76 | print "\nwriting default values from %s to current config file\n" % (default_config_path,) 77 | # check if one exists and delete it 78 | if os.path.exists(path): 79 | response = raw_input("you already have a config file - %s \nthis command will override it, do you wish to continue [y/n]: " % path) 80 | while response not in ('y', 'n'): 81 | response = raw_input('choose only one of [y/n]: ') 82 | if response == 'n': sys.exit(1) 83 | os.remove(path) 84 | make_file(path) 85 | with open(path, 'w') as fd: 86 | fd.write(open(default_config_path, 'r').read()) 87 | if post_edit: 88 | run_editor(path) 89 | else: 90 | print >>sys.stderr, "\ndefault config - %s does not exist. \nadd one or manually edit your local config.\n" % default_config_path 91 | 92 | 93 | def make_file(pathname): 94 | try: 95 | try: 96 | os.makedirs(os.path.dirname(pathname)) 97 | except Exception, e: 98 | print >>sys.stdout, "%s" % (e,) 99 | 100 | if os.path.exists(pathname): 101 | print >>sys.stderr, "%s already exists, try the 'edit' command" % pathname 102 | sys.exit(1) 103 | 104 | # Otherwise, setup default 105 | with open(pathname, "w") as fd: 106 | print >> fd, "# local config settings go here\n\nDEBUG=True\n" 107 | # Make a default module if none exists 108 | while pathname != os.getcwd(): 109 | pathname = os.path.dirname(pathname) 110 | ipath = "%s/__init__.py" % pathname 111 | if not os.path.exists(ipath): 112 | with open(ipath, 'w') as fid: 113 | print >> fid, """# module init file """ 114 | 115 | except Exception, e: 116 | print str(e) 117 | 118 | def run_editor(path): 119 | """Run whatever system editor you have""" 120 | 121 | def guardedexec(variable, cmd): 122 | if variable in os.environ.keys(): 123 | r = os.system(cmd) 124 | if r == 0: 125 | return 126 | raise Exception() 127 | 128 | try: 129 | guardedexec("EDITOR", "$EDITOR %s" % path) 130 | except Exception, e: 131 | try: 132 | guardedexec("VISUAL", "$VISUAL %s" % path) 133 | except Exception: 134 | os.system("editor %s" % path) 135 | 136 | def main(): 137 | import sys 138 | path = config_module_to_path() 139 | if "edit" in sys.argv: 140 | run_editor(path) 141 | elif "updatesettings" in sys.argv: 142 | update_settings_file() 143 | elif "default" in sys.argv: 144 | make_default(path, post_edit=('-n' not in sys.argv)) 145 | elif "print" in sys.argv: 146 | print path 147 | elif "cat" in sys.argv: 148 | with open(path, 'r') as fd: 149 | print "".join(fd.readlines()) 150 | elif "printval" in sys.argv or "pv" in sys.argv: 151 | config_printval() 152 | elif "dir" in sys.argv: 153 | print config_dir() 154 | elif "help" in sys.argv: 155 | print """django_confighelper 156 | 157 | django_confighelper updatesettings 158 | django_confighelper edit 159 | django_confighelper print 160 | django_confighelper default {default_config_file} 161 | django_confighelper pv {DJANGO_SETTING_NAME} 162 | django_confighelper printval {DJANGO_SETTING_NAME} 163 | django_confighelper setval {DJANGO_SETTING_NAME VALUE} 164 | 165 | A tool for helping with override Django configs. 166 | 167 | django_confighelper on it's own creates a config for the current django 168 | instance based on the current hostname, the current name of the 169 | effective uid and the current directory in which the django instance 170 | is sitting: 171 | 172 | config/hostname/euidname__dirname.py 173 | 174 | If the config already exists django_confighelper exits with a warning. 175 | 176 | The 'edit' subcommand attempts to start a system editor on the 177 | config. It first tries the environment variable $EDITOR and then 178 | switches to "editor" from the execution path. 179 | 180 | The 'print' subcommand prints the filename of the config file. This is 181 | so you can script further interactions, for example: 182 | 183 | echo "CONFIG_SPECIAL=True" >> $(django_confighelper print) 184 | 185 | The 'default' subcommand looks for a default config file in 186 | config/defaults/$user.py and if it exists, it creates a config using 187 | the values contained there in. It opens the newly created file just 188 | in case you need to change some values - like FRONTEND_PORT e.t.c 189 | 190 | The 'printval' subcommand prints the value of a DJANGO config setting 191 | after the config has been applied. For example: 192 | 193 | django_confighelper printval DATABASE_HOST 194 | 195 | prints out the setting of the database host. 196 | 197 | In addition to these behaviours django_confighelper tries to help find 198 | the initial DJANGO_PATH_DIR by looking for the envrionment variable: 199 | 200 | DJANGO_PATH_DIR 201 | 202 | and if that isn't found checking for the existance of the path: 203 | 204 | $HOME/django-hg-1.1 205 | 206 | and using that if found. 207 | 208 | It also writes commented out values for: 209 | 210 | FRONTEND_PORT 211 | BACKEND_PORT 212 | """ 213 | 214 | #The 'setval' subcommand sets the value of the specified DJANGO config 215 | #variable, directly in the config override file. 216 | 217 | else: 218 | make_file(path) 219 | 220 | 221 | if __name__ == '__main__': 222 | main() 223 | 224 | # End 225 | --------------------------------------------------------------------------------