├── .gitignore ├── AUTHORS ├── LICENSE ├── MANIFEST.in ├── README.rst ├── confy ├── __init__.py ├── apps.py ├── cache.py ├── database.py ├── email.py └── search.py ├── docs ├── Makefile ├── conf.py ├── index.rst ├── installation.rst └── usage.rst └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | public/uploads/ 2 | public/assets/ 3 | 4 | *~ 5 | .DS_Store 6 | .AppleDouble 7 | .LSOverride 8 | .idea 9 | atlassian-ide-plugin.xml 10 | # Icon must ends with two \r. 11 | #Icon 12 | 13 | 14 | # Thumbnails 15 | ._* 16 | 17 | # Files that might appear on external disk 18 | .Spotlight-V100 19 | .Trashes 20 | 21 | *.sublime-workspace 22 | *.sublime-project 23 | 24 | # Virtualenv 25 | # http://iamzed.com/2009/05/07/a-primer-on-virtualenv/ 26 | .Python 27 | [Bb]in 28 | [Ii]nclude 29 | [Ll]ib 30 | [Ss]cripts 31 | 32 | 33 | 34 | local_settings.py 35 | .idea 36 | 37 | # Byte-compiled / optimized / DLL files 38 | __pycache__/ 39 | *.py[cod] 40 | 41 | # C extensions 42 | *.so 43 | 44 | # Distribution / packaging 45 | .Python 46 | env/ 47 | #bin/ 48 | build/ 49 | develop-eggs/ 50 | dist/ 51 | eggs/ 52 | lib/ 53 | lib64/ 54 | parts/ 55 | sdist/ 56 | var/ 57 | *.egg-info/ 58 | .installed.cfg 59 | *.egg 60 | 61 | # Installer logs 62 | pip-log.txt 63 | pip-delete-this-directory.txt 64 | 65 | # Unit test / coverage reports 66 | .tox/ 67 | .coverage 68 | .cache 69 | nosetests.xml 70 | coverage.xml 71 | 72 | # Translations 73 | *.mo 74 | 75 | # Mr Developer 76 | .mr.developer.cfg 77 | .project 78 | .pydevproject 79 | 80 | # Rope 81 | .ropeproject 82 | 83 | # Django stuff: 84 | *.log 85 | *.pot 86 | 87 | # Sphinx documentation 88 | docs/_build/ 89 | 90 | .env 91 | *.db 92 | *.sqlite 93 | *.sqlite3 -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Eugene MechanisM -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Eugene MechanisM 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include AUTHORS 2 | include LICENSE 3 | include README.rst -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | Django-Confy 2 | ~~~~~~~~~~~~ 3 | 4 | Comfy config for Django 5 | 6 | Actually this code is just a few apps combined together. 7 | 8 | 9 | Installation 10 | ------------ 11 | 12 | .. code-block:: sh 13 | 14 | pip install django-confy 15 | 16 | 17 | Example for settings.py 18 | ----------------------- 19 | 20 | .. code-block:: py 21 | 22 | from confy import env, database, cache 23 | 24 | DEBUG = env('DEV') 25 | SECRET_KEY = env('SECRET_KEY') 26 | 27 | DATABASES = {'default': database.config()} 28 | 29 | CACHES = {'default': cache.config()} 30 | 31 | 32 | Example for .env file 33 | --------------------- 34 | 35 | .. code-block:: sh 36 | 37 | DJANGO_SETTINGS_MODULE=project_name.settings 38 | DEV=True 39 | DATABASE_URL=sqlite:////server/apps/project_name/project_name.sqlite3 40 | CACHE_URL=uwsgi:// 41 | 42 | 43 | Example manage.py 44 | ----------------- 45 | 46 | .. code-block:: py 47 | 48 | #!/usr/bin/env python 49 | import sys 50 | import confy 51 | confy.read_environment_file() 52 | if __name__ == "__main__": 53 | from django.core.management import execute_from_command_line 54 | execute_from_command_line(sys.argv) 55 | 56 | 57 | Example for wsgi.py 58 | ------------------- 59 | 60 | .. code-block:: py 61 | 62 | from django.core.wsgi import get_wsgi_application 63 | application = get_wsgi_application() 64 | 65 | License 66 | ~~~~~~~ 67 | 68 | `MIT `_ 69 | 70 | Documentation 71 | ~~~~~~~~~~~~~ 72 | 73 | `Documentation `_ 74 | 75 | Credits 76 | ------- 77 | 78 | * Code borrowed by `Eugene MechanisM `_ 79 | * Released under `MIT License `_ 80 | * `django-dotenv `_ 81 | * `django-getenv `_ 82 | * `dj-database-url `_ 83 | * `dj-email-url `_ 84 | * `dj-search-url `_ 85 | * `django-cache-url `_ 86 | -------------------------------------------------------------------------------- /confy/__init__.py: -------------------------------------------------------------------------------- 1 | __version__ = '1.0.4' 2 | import os 3 | import sys 4 | import warnings 5 | import ast 6 | 7 | try: 8 | import urlparse 9 | except ImportError: 10 | import urllib.parse as urlparse 11 | 12 | 13 | 14 | def parse_environment_file(envfile): 15 | for line in open(envfile): 16 | line = line.strip() 17 | if not line or line.startswith('#') or '=' not in line: 18 | continue 19 | k, v = line.split('=', 1) 20 | v = v.strip("'").strip('"') 21 | yield k, v 22 | 23 | 24 | 25 | def read_environment_file(envfile=None): 26 | """ 27 | Read a .env file into os.environ. 28 | 29 | If not given a path to a envfile path, does filthy magic stack backtracking 30 | to find manage.py and then find the envfile. 31 | """ 32 | if envfile is None: 33 | frame = sys._getframe() 34 | envfile = os.path.join(os.path.dirname(frame.f_back.f_code.co_filename), '.env') 35 | if not os.path.exists(envfile): 36 | warnings.warn("not reading %s - it doesn't exist." % envfile) 37 | return 38 | for k, v in parse_environment_file(envfile): 39 | os.environ.setdefault(k, v) 40 | 41 | 42 | def env(key, default=None, required=False): 43 | """ 44 | Retrieves environment variables and returns Python natives. The (optional) 45 | default will be returned if the environment variable does not exist. 46 | """ 47 | try: 48 | value = os.environ[key] 49 | return ast.literal_eval(value) 50 | except (SyntaxError, ValueError): 51 | return value 52 | except KeyError: 53 | if default or not required: 54 | return default 55 | raise Exception("Missing required environment variable '%s'" % key) 56 | 57 | 58 | default_app_config = 'confy.apps.ConfyConfig' 59 | -------------------------------------------------------------------------------- /confy/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ConfyConfig(AppConfig): 5 | name = 'confy' 6 | verbose_name = "Confy" 7 | -------------------------------------------------------------------------------- /confy/cache.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from confy import env, urlparse 3 | 4 | 5 | CACHE_SCHEMES = { 6 | 'db': 'django.core.cache.backends.db.DatabaseCache', 7 | 'dummy': 'django.core.cache.backends.dummy.DummyCache', 8 | 'file': 'django.core.cache.backends.filebased.FileBasedCache', 9 | 'locmem': 'django.core.cache.backends.locmem.LocMemCache', 10 | 'memcached': 'django.core.cache.backends.memcached.PyLibMCCache', 11 | 'djangopylibmc': 'django_pylibmc.memcached.PyLibMCCache', 12 | 'pymemcached': 'django.core.cache.backends.memcached.MemcachedCache', 13 | 'redis': 'django_redis.cache.RedisCache', 14 | 'hiredis': 'django_redis.cache.RedisCache', 15 | 'uwsgi': 'django_uwsgi.cache.UwsgiCache' 16 | } 17 | 18 | 19 | # Register cache schemes in URLs. 20 | for c in CACHE_SCHEMES.items(): 21 | urlparse.uses_netloc.append(c[0]) 22 | 23 | 24 | def parse_cache_url(url): 25 | """Parses a cache URL.""" 26 | config = {} 27 | 28 | url = urlparse.urlparse(url) 29 | # Update with environment configuration. 30 | config['BACKEND'] = CACHE_SCHEMES[url.scheme] 31 | if url.scheme in ('file', 'uwsgi'): 32 | config['LOCATION'] = url.path 33 | return config 34 | elif url.scheme in ('redis', 'hiredis'): 35 | if url.netloc == 'unix': 36 | location_index = None 37 | bits = list(filter(None, url.path.split('/'))) 38 | # find the end of the socket path 39 | for index, bit in enumerate(bits, 1): 40 | if bit.endswith(('.sock', '.socket')): 41 | location_index = index 42 | break 43 | 44 | if location_index is None: 45 | # no socket file extension found, using the whole location 46 | location = bits 47 | else: 48 | # splitting socket path from database and prefix 49 | location = bits[:location_index] 50 | rest = bits[location_index:] 51 | if len(rest) > 0: 52 | try: 53 | # check if first item of the rest is a database 54 | database = int(rest[0]) 55 | prefix = rest[1:] 56 | except ValueError: 57 | # or assume the rest is the prefix 58 | database = 0 59 | prefix = rest 60 | else: 61 | database = prefix = None 62 | 63 | full_location = (url.netloc, '/' + '/'.join(location)) 64 | if database is not None: 65 | full_location += (str(database),) 66 | config['LOCATION'] = ':'.join(full_location) 67 | config['KEY_PREFIX'] = '/'.join(prefix) 68 | 69 | else: 70 | try: 71 | userpass, hostport = url.netloc.split('@') 72 | except ValueError: 73 | userpass, hostport = '', url.netloc 74 | 75 | try: 76 | username, password = userpass.split(':') 77 | except ValueError: 78 | pass 79 | 80 | path = list(filter(None, url.path.split('/'))) 81 | config['LOCATION'] = ':'.join((hostport, path[0])) 82 | config['KEY_PREFIX'] = '/'.join(path[1:]) 83 | 84 | redis_options = {} 85 | 86 | if url.scheme == 'hiredis': 87 | redis_options['PARSER_CLASS'] = 'redis.connection.HiredisParser' 88 | 89 | try: 90 | if password: 91 | redis_options['PASSWORD'] = password 92 | except NameError: # No password defined 93 | pass 94 | 95 | if redis_options: 96 | config['OPTIONS'] = redis_options 97 | 98 | else: 99 | netloc_list = url.netloc.split(',') 100 | if len(netloc_list) > 1: 101 | config['LOCATION'] = netloc_list 102 | else: 103 | config['LOCATION'] = url.netloc 104 | config['KEY_PREFIX'] = url.path[1:] 105 | 106 | return config 107 | 108 | 109 | def config(name='CACHE_URL', default='locmem://'): 110 | """Returns configured CACHES dictionary from CACHE_URL""" 111 | config = {} 112 | 113 | s = env(name, default) 114 | 115 | if s: 116 | config = parse_cache_url(s) 117 | 118 | return config 119 | -------------------------------------------------------------------------------- /confy/database.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from confy import env, urlparse 3 | 4 | 5 | DATABASE_SCHEMES = { 6 | 'postgres': 'django.db.backends.postgresql_psycopg2', 7 | 'postgresql': 'django.db.backends.postgresql', 8 | 'pgsql': 'django.db.backends.postgresql_psycopg2', 9 | 'postgis': 'django.contrib.gis.db.backends.postgis', 10 | 'mysql': 'django.db.backends.mysql', 11 | 'mysql2': 'django.db.backends.mysql', 12 | 'mysqlgis': 'django.contrib.gis.db.backends.mysql', 13 | 'spatialite': 'django.contrib.gis.db.backends.spatialite', 14 | 'sqlite': 'django.db.backends.sqlite3' 15 | } 16 | 17 | # Register database schemes in URLs. 18 | for i in DATABASE_SCHEMES.items(): 19 | urlparse.uses_netloc.append(i[0]) 20 | 21 | 22 | def parse_database_url(url): 23 | """Parses a database URL.""" 24 | 25 | if url == 'sqlite://:memory:': 26 | # this is a special case, because if we pass this URL into 27 | # urlparse, urlparse will choke trying to interpret "memory" 28 | # as a port number 29 | return { 30 | 'ENGINE': DATABASE_SCHEMES['sqlite'], 31 | 'NAME': ':memory:' 32 | } 33 | # note: no other settings are required for sqlite 34 | 35 | # otherwise parse the url as normal 36 | config = {} 37 | 38 | url = urlparse.urlparse(url) 39 | 40 | # Remove query strings. 41 | path = url.path[1:] 42 | path = path.split('?', 2)[0] 43 | 44 | # if we are using sqlite and we have no path, then assume we 45 | # want an in-memory database (this is the behaviour of sqlalchemy) 46 | if url.scheme == 'sqlite' and path == '': 47 | path = ':memory:' 48 | 49 | # Update with environment configuration. 50 | config.update({ 51 | 'NAME': path or '', 52 | 'USER': url.username or '', 53 | 'PASSWORD': url.password or '', 54 | 'HOST': url.hostname or '', 55 | 'PORT': url.port or '', 56 | }) 57 | 58 | if url.scheme in DATABASE_SCHEMES: 59 | config['ENGINE'] = DATABASE_SCHEMES[url.scheme] 60 | 61 | return config 62 | 63 | 64 | def config(name='DATABASE_URL', default='sqlite://:memory:'): 65 | """Returns configured DATABASE dictionary from DATABASE_URL.""" 66 | config = {} 67 | s = env(name, default) 68 | if s: 69 | config = parse_database_url(s) 70 | return config 71 | -------------------------------------------------------------------------------- /confy/email.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from confy import env, urlparse 3 | 4 | 5 | EMAIL_SCHEMES = { 6 | 'smtp': 'django.core.mail.backends.smtp.EmailBackend', 7 | 'smtps': 'django.core.mail.backends.smtp.EmailBackend', 8 | 'console': 'django.core.mail.backends.console.EmailBackend', 9 | 'file': 'django.core.mail.backends.filebased.EmailBackend', 10 | 'memory': 'django.core.mail.backends.locmem.EmailBackend', 11 | 'dummy': 'django.core.mail.backends.dummy.EmailBackend', 12 | 'uwsgi': 'django_uwsgi.mail.EmailBackend' 13 | } 14 | 15 | # Register email schemes in URLs. 16 | for e in EMAIL_SCHEMES.items(): 17 | urlparse.uses_netloc.append(e[0]) 18 | 19 | 20 | def parse_email_url(url): 21 | """Parses an email URL.""" 22 | 23 | conf = {} 24 | 25 | url = urlparse.urlparse(url) 26 | 27 | # Remove query strings 28 | path = url.path[1:] 29 | path = path.split('?', 2)[0] 30 | 31 | # Update with environment configuration 32 | conf.update({ 33 | 'EMAIL_FILE_PATH': path, 34 | 'EMAIL_HOST_USER': url.username, 35 | 'EMAIL_HOST_PASSWORD': url.password, 36 | 'EMAIL_HOST': url.hostname, 37 | 'EMAIL_PORT': url.port, 38 | }) 39 | 40 | if url.scheme in EMAIL_SCHEMES: 41 | conf['EMAIL_BACKEND'] = EMAIL_SCHEMES[url.scheme] 42 | 43 | if url.scheme == 'smtps': 44 | conf['EMAIL_USE_TLS'] = True 45 | else: 46 | conf['EMAIL_USE_TLS'] = False 47 | 48 | return conf 49 | 50 | 51 | def config(name='EMAIL_URL', default='console://'): 52 | """Returns a dictionary with EMAIL_* settings from EMAIL_URL.""" 53 | conf = {} 54 | s = env(name, default) 55 | if s: 56 | conf = parse_email_url(s) 57 | return conf 58 | -------------------------------------------------------------------------------- /confy/search.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from confy import env, urlparse 3 | 4 | 5 | SEARCH_SCHEMES = { 6 | 'elasticsearch': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine', 7 | 'solr': 'haystack.backends.solr_backend.SolrEngine', 8 | 'whoosh': 'haystack.backends.whoosh_backend.WhooshEngine', 9 | 'simple': 'haystack.backends.simple_backend.SimpleEngine', 10 | 'xapian': 'xapian_backend.XapianEngine' 11 | } 12 | 13 | # Register database schemes in URLs. 14 | for s in SEARCH_SCHEMES.items(): 15 | urlparse.uses_netloc.append(s[0]) 16 | 17 | 18 | USES_URL = ["solr"] 19 | USES_INDEX = ["elasticsearch"] 20 | USES_PATH = ["whoosh", "xapian"] 21 | 22 | 23 | def parse_search_url(url): 24 | """Parses a search URL.""" 25 | 26 | config = {} 27 | 28 | url = urlparse.urlparse(url) 29 | 30 | # Remove query strings. 31 | path = url.path[1:] 32 | path = path.split('?', 2)[0] 33 | 34 | if url.scheme in SEARCH_SCHEMES: 35 | config["ENGINE"] = SEARCH_SCHEMES[url.scheme] 36 | 37 | if url.scheme in USES_URL: 38 | config["URL"] = urlparse.urlunparse(("http",) + url[1:]) 39 | 40 | if url.scheme in USES_INDEX: 41 | if path.endswith("/"): 42 | path = path[:-1] 43 | 44 | split = path.rsplit("/", 1) 45 | 46 | if len(split) > 1: 47 | path = split[:-1] 48 | index = split[-1] 49 | else: 50 | path = "" 51 | index = split[0] 52 | 53 | config.update({ 54 | "URL": urlparse.urlunparse(("http",) + url[1:2] + (path,) + url[3:]), 55 | "INDEX_NAME": index, 56 | }) 57 | 58 | if url.scheme in USES_PATH: 59 | config.update({ 60 | "PATH": path, 61 | }) 62 | 63 | return config 64 | 65 | 66 | def config(name='SEARCH_URL', default='simple://'): 67 | """Returns configured SEARCH dictionary from SEARCH_URL""" 68 | config = {} 69 | 70 | s = env(name, default) 71 | 72 | if s: 73 | config = parse_search_url(s) 74 | 75 | return config 76 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = _build 9 | 10 | # User-friendly check for sphinx-build 11 | ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) 12 | $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) 13 | endif 14 | 15 | # Internal variables. 16 | PAPEROPT_a4 = -D latex_paper_size=a4 17 | PAPEROPT_letter = -D latex_paper_size=letter 18 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 19 | # the i18n builder cannot share the environment and doctrees with the others 20 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 21 | 22 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext 23 | 24 | help: 25 | @echo "Please use \`make ' where is one of" 26 | @echo " html to make standalone HTML files" 27 | @echo " dirhtml to make HTML files named index.html in directories" 28 | @echo " singlehtml to make a single large HTML file" 29 | @echo " pickle to make pickle files" 30 | @echo " json to make JSON files" 31 | @echo " htmlhelp to make HTML files and a HTML help project" 32 | @echo " qthelp to make HTML files and a qthelp project" 33 | @echo " devhelp to make HTML files and a Devhelp project" 34 | @echo " epub to make an epub" 35 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 36 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 37 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" 38 | @echo " text to make text files" 39 | @echo " man to make manual pages" 40 | @echo " texinfo to make Texinfo files" 41 | @echo " info to make Texinfo files and run them through makeinfo" 42 | @echo " gettext to make PO message catalogs" 43 | @echo " changes to make an overview of all changed/added/deprecated items" 44 | @echo " xml to make Docutils-native XML files" 45 | @echo " pseudoxml to make pseudoxml-XML files for display purposes" 46 | @echo " linkcheck to check all external links for integrity" 47 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 48 | 49 | clean: 50 | rm -rf $(BUILDDIR)/* 51 | 52 | html: 53 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 54 | @echo 55 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 56 | 57 | dirhtml: 58 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 59 | @echo 60 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 61 | 62 | singlehtml: 63 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 64 | @echo 65 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 66 | 67 | pickle: 68 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 69 | @echo 70 | @echo "Build finished; now you can process the pickle files." 71 | 72 | json: 73 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 74 | @echo 75 | @echo "Build finished; now you can process the JSON files." 76 | 77 | htmlhelp: 78 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 79 | @echo 80 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 81 | ".hhp project file in $(BUILDDIR)/htmlhelp." 82 | 83 | qthelp: 84 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 85 | @echo 86 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 87 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 88 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/django-confy.qhcp" 89 | @echo "To view the help file:" 90 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/django-confy.qhc" 91 | 92 | devhelp: 93 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 94 | @echo 95 | @echo "Build finished." 96 | @echo "To view the help file:" 97 | @echo "# mkdir -p $$HOME/.local/share/devhelp/django-confy" 98 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/django-confy" 99 | @echo "# devhelp" 100 | 101 | epub: 102 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 103 | @echo 104 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 105 | 106 | latex: 107 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 108 | @echo 109 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 110 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 111 | "(use \`make latexpdf' here to do that automatically)." 112 | 113 | latexpdf: 114 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 115 | @echo "Running LaTeX files through pdflatex..." 116 | $(MAKE) -C $(BUILDDIR)/latex all-pdf 117 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 118 | 119 | latexpdfja: 120 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 121 | @echo "Running LaTeX files through platex and dvipdfmx..." 122 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja 123 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 124 | 125 | text: 126 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 127 | @echo 128 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 129 | 130 | man: 131 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 132 | @echo 133 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 134 | 135 | texinfo: 136 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 137 | @echo 138 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." 139 | @echo "Run \`make' in that directory to run these through makeinfo" \ 140 | "(use \`make info' here to do that automatically)." 141 | 142 | info: 143 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 144 | @echo "Running Texinfo files through makeinfo..." 145 | make -C $(BUILDDIR)/texinfo info 146 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." 147 | 148 | gettext: 149 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale 150 | @echo 151 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." 152 | 153 | changes: 154 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 155 | @echo 156 | @echo "The overview file is in $(BUILDDIR)/changes." 157 | 158 | linkcheck: 159 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 160 | @echo 161 | @echo "Link check complete; look for any errors in the above output " \ 162 | "or in $(BUILDDIR)/linkcheck/output.txt." 163 | 164 | doctest: 165 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 166 | @echo "Testing of doctests in the sources finished, look at the " \ 167 | "results in $(BUILDDIR)/doctest/output.txt." 168 | 169 | xml: 170 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml 171 | @echo 172 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml." 173 | 174 | pseudoxml: 175 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml 176 | @echo 177 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." 178 | -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # django-confy documentation build configuration file, created by 4 | # sphinx-quickstart on Sun Apr 6 09:12:54 2014. 5 | # 6 | # This file is execfile()d with the current directory set to its 7 | # containing dir. 8 | # 9 | # Note that not all possible configuration values are present in this 10 | # autogenerated file. 11 | # 12 | # All configuration values have a default; values that are commented out 13 | # serve to show the default. 14 | 15 | import sys 16 | import os 17 | import sphinx_rtd_theme 18 | # If extensions (or modules to document with autodoc) are in another directory, 19 | # add these directories to sys.path here. If the directory is relative to the 20 | # documentation root, use os.path.abspath to make it absolute, like shown here. 21 | #sys.path.insert(0, os.path.abspath('.')) 22 | 23 | # -- General configuration ------------------------------------------------ 24 | 25 | # If your documentation needs a minimal Sphinx version, state it here. 26 | #needs_sphinx = '1.0' 27 | 28 | # Add any Sphinx extension module names here, as strings. They can be 29 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 30 | # ones. 31 | extensions = [ 32 | 'sphinx.ext.autodoc', 33 | 'sphinx.ext.doctest', 34 | 'sphinx.ext.intersphinx', 35 | 'sphinx.ext.todo', 36 | 'sphinx.ext.coverage', 37 | 'sphinx.ext.mathjax', 38 | 'sphinx.ext.ifconfig', 39 | 'sphinx.ext.viewcode', 40 | ] 41 | 42 | # Add any paths that contain templates here, relative to this directory. 43 | templates_path = ['_templates'] 44 | 45 | # The suffix of source filenames. 46 | source_suffix = '.rst' 47 | 48 | # The encoding of source files. 49 | #source_encoding = 'utf-8-sig' 50 | 51 | # The master toctree document. 52 | master_doc = 'index' 53 | 54 | # General information about the project. 55 | project = u'django-confy' 56 | copyright = u'2015, Eugene MechanisM' 57 | 58 | # The version info for the project you're documenting, acts as replacement for 59 | # |version| and |release|, also used in various other places throughout the 60 | # built documents. 61 | # 62 | # The short X.Y version. 63 | version = '1.0.4' 64 | # The full version, including alpha/beta/rc tags. 65 | release = '1.0.4' 66 | 67 | # The language for content autogenerated by Sphinx. Refer to documentation 68 | # for a list of supported languages. 69 | #language = None 70 | 71 | # There are two options for replacing |today|: either, you set today to some 72 | # non-false value, then it is used: 73 | #today = '' 74 | # Else, today_fmt is used as the format for a strftime call. 75 | #today_fmt = '%B %d, %Y' 76 | 77 | # List of patterns, relative to source directory, that match files and 78 | # directories to ignore when looking for source files. 79 | exclude_patterns = ['_build'] 80 | 81 | # The reST default role (used for this markup: `text`) to use for all 82 | # documents. 83 | #default_role = None 84 | 85 | # If true, '()' will be appended to :func: etc. cross-reference text. 86 | #add_function_parentheses = True 87 | 88 | # If true, the current module name will be prepended to all description 89 | # unit titles (such as .. function::). 90 | #add_module_names = True 91 | 92 | # If true, sectionauthor and moduleauthor directives will be shown in the 93 | # output. They are ignored by default. 94 | #show_authors = False 95 | 96 | # The name of the Pygments (syntax highlighting) style to use. 97 | pygments_style = 'sphinx' 98 | 99 | # A list of ignored prefixes for module index sorting. 100 | #modindex_common_prefix = [] 101 | 102 | # If true, keep warnings as "system message" paragraphs in the built documents. 103 | #keep_warnings = False 104 | 105 | 106 | # -- Options for HTML output ---------------------------------------------- 107 | 108 | # The theme to use for HTML and HTML Help pages. See the documentation for 109 | # a list of builtin themes. 110 | # html_theme = 'default' 111 | html_theme = "sphinx_rtd_theme" 112 | 113 | html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] 114 | # Theme options are theme-specific and customize the look and feel of a theme 115 | # further. For a list of options available for each theme, see the 116 | # documentation. 117 | #html_theme_options = {} 118 | 119 | # Add any paths that contain custom themes here, relative to this directory. 120 | #html_theme_path = [] 121 | 122 | # The name for this set of Sphinx documents. If None, it defaults to 123 | # " v documentation". 124 | #html_title = None 125 | 126 | # A shorter title for the navigation bar. Default is the same as html_title. 127 | #html_short_title = None 128 | 129 | # The name of an image file (relative to this directory) to place at the top 130 | # of the sidebar. 131 | #html_logo = None 132 | 133 | # The name of an image file (within the static path) to use as favicon of the 134 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 135 | # pixels large. 136 | #html_favicon = None 137 | 138 | # Add any paths that contain custom static files (such as style sheets) here, 139 | # relative to this directory. They are copied after the builtin static files, 140 | # so a file named "default.css" will overwrite the builtin "default.css". 141 | html_static_path = ['_static'] 142 | 143 | # Add any extra paths that contain custom files (such as robots.txt or 144 | # .htaccess) here, relative to this directory. These files are copied 145 | # directly to the root of the documentation. 146 | #html_extra_path = [] 147 | 148 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, 149 | # using the given strftime format. 150 | #html_last_updated_fmt = '%b %d, %Y' 151 | 152 | # If true, SmartyPants will be used to convert quotes and dashes to 153 | # typographically correct entities. 154 | #html_use_smartypants = True 155 | 156 | # Custom sidebar templates, maps document names to template names. 157 | #html_sidebars = {} 158 | 159 | # Additional templates that should be rendered to pages, maps page names to 160 | # template names. 161 | #html_additional_pages = {} 162 | 163 | # If false, no module index is generated. 164 | #html_domain_indices = True 165 | 166 | # If false, no index is generated. 167 | #html_use_index = True 168 | 169 | # If true, the index is split into individual pages for each letter. 170 | #html_split_index = False 171 | 172 | # If true, links to the reST sources are added to the pages. 173 | #html_show_sourcelink = True 174 | 175 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 176 | #html_show_sphinx = True 177 | 178 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 179 | #html_show_copyright = True 180 | 181 | # If true, an OpenSearch description file will be output, and all pages will 182 | # contain a tag referring to it. The value of this option must be the 183 | # base URL from which the finished HTML is served. 184 | #html_use_opensearch = '' 185 | 186 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 187 | #html_file_suffix = None 188 | 189 | # Output file base name for HTML help builder. 190 | htmlhelp_basename = 'django-confydoc' 191 | 192 | 193 | # -- Options for LaTeX output --------------------------------------------- 194 | 195 | latex_elements = { 196 | # The paper size ('letterpaper' or 'a4paper'). 197 | #'papersize': 'letterpaper', 198 | 199 | # The font size ('10pt', '11pt' or '12pt'). 200 | #'pointsize': '10pt', 201 | 202 | # Additional stuff for the LaTeX preamble. 203 | #'preamble': '', 204 | } 205 | 206 | # Grouping the document tree into LaTeX files. List of tuples 207 | # (source start file, target name, title, 208 | # author, documentclass [howto, manual, or own class]). 209 | latex_documents = [ 210 | ('index', 'django-confy.tex', u'django-confy Documentation', 211 | u'Eugene MechanisM', 'manual'), 212 | ] 213 | 214 | # The name of an image file (relative to this directory) to place at the top of 215 | # the title page. 216 | #latex_logo = None 217 | 218 | # For "manual" documents, if this is true, then toplevel headings are parts, 219 | # not chapters. 220 | #latex_use_parts = False 221 | 222 | # If true, show page references after internal links. 223 | #latex_show_pagerefs = False 224 | 225 | # If true, show URL addresses after external links. 226 | #latex_show_urls = False 227 | 228 | # Documents to append as an appendix to all manuals. 229 | #latex_appendices = [] 230 | 231 | # If false, no module index is generated. 232 | #latex_domain_indices = True 233 | 234 | 235 | # -- Options for manual page output --------------------------------------- 236 | 237 | # One entry per manual page. List of tuples 238 | # (source start file, name, description, authors, manual section). 239 | man_pages = [ 240 | ('index', 'django-confy', u'django-confy Documentation', 241 | [u'Eugene MechanisM'], 1) 242 | ] 243 | 244 | # If true, show URL addresses after external links. 245 | #man_show_urls = False 246 | 247 | 248 | # -- Options for Texinfo output ------------------------------------------- 249 | 250 | # Grouping the document tree into Texinfo files. List of tuples 251 | # (source start file, target name, title, author, 252 | # dir menu entry, description, category) 253 | texinfo_documents = [ 254 | ('index', 'django-confy', u'django-confy Documentation', 255 | u'Eugene MechanisM', 'django-confy', 'One line description of project.', 256 | 'Miscellaneous'), 257 | ] 258 | 259 | # Documents to append as an appendix to all manuals. 260 | #texinfo_appendices = [] 261 | 262 | # If false, no module index is generated. 263 | #texinfo_domain_indices = True 264 | 265 | # How to display URL addresses: 'footnote', 'no', or 'inline'. 266 | #texinfo_show_urls = 'footnote' 267 | 268 | # If true, do not generate a @detailmenu in the "Top" node's menu. 269 | #texinfo_no_detailmenu = False 270 | 271 | 272 | # -- Options for Epub output ---------------------------------------------- 273 | 274 | # Bibliographic Dublin Core info. 275 | epub_title = u'django-confy' 276 | epub_author = u'Eugene MechanisM' 277 | epub_publisher = u'Eugene MechanisM' 278 | epub_copyright = u'2014, Eugene MechanisM' 279 | 280 | # The basename for the epub file. It defaults to the project name. 281 | #epub_basename = u'django-confy' 282 | 283 | # The HTML theme for the epub output. Since the default themes are not optimized 284 | # for small screen space, using the same theme for HTML and epub output is 285 | # usually not wise. This defaults to 'epub', a theme designed to save visual 286 | # space. 287 | #epub_theme = 'epub' 288 | 289 | # The language of the text. It defaults to the language option 290 | # or en if the language is not set. 291 | #epub_language = '' 292 | 293 | # The scheme of the identifier. Typical schemes are ISBN or URL. 294 | #epub_scheme = '' 295 | 296 | # The unique identifier of the text. This can be a ISBN number 297 | # or the project homepage. 298 | #epub_identifier = '' 299 | 300 | # A unique identification for the text. 301 | #epub_uid = '' 302 | 303 | # A tuple containing the cover image and cover page html template filenames. 304 | #epub_cover = () 305 | 306 | # A sequence of (type, uri, title) tuples for the guide element of content.opf. 307 | #epub_guide = () 308 | 309 | # HTML files that should be inserted before the pages created by sphinx. 310 | # The format is a list of tuples containing the path and title. 311 | #epub_pre_files = [] 312 | 313 | # HTML files shat should be inserted after the pages created by sphinx. 314 | # The format is a list of tuples containing the path and title. 315 | #epub_post_files = [] 316 | 317 | # A list of files that should not be packed into the epub file. 318 | epub_exclude_files = ['search.html'] 319 | 320 | # The depth of the table of contents in toc.ncx. 321 | #epub_tocdepth = 3 322 | 323 | # Allow duplicate toc entries. 324 | #epub_tocdup = True 325 | 326 | # Choose between 'default' and 'includehidden'. 327 | #epub_tocscope = 'default' 328 | 329 | # Fix unsupported image types using the PIL. 330 | #epub_fix_images = False 331 | 332 | # Scale large images. 333 | #epub_max_image_width = 0 334 | 335 | # How to display URL addresses: 'footnote', 'no', or 'inline'. 336 | #epub_show_urls = 'inline' 337 | 338 | # If false, no index is generated. 339 | #epub_use_index = True 340 | 341 | 342 | # Example configuration for intersphinx: refer to the Python standard library. 343 | intersphinx_mapping = {'http://docs.python.org/': None} 344 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | Welcome to django-confy's documentation! 2 | ======================================== 3 | 4 | Contents: 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | installation 10 | usage 11 | 12 | 13 | 14 | Indices and tables 15 | ================== 16 | 17 | * :ref:`genindex` 18 | * :ref:`modindex` 19 | * :ref:`search` 20 | 21 | -------------------------------------------------------------------------------- /docs/installation.rst: -------------------------------------------------------------------------------- 1 | Installation 2 | ~~~~~~~~~~~~ 3 | 4 | .. code-block:: sh 5 | 6 | pip install django-confy -------------------------------------------------------------------------------- /docs/usage.rst: -------------------------------------------------------------------------------- 1 | Usage 2 | ~~~~~ 3 | 4 | 5 | Import from confy needed modules and use them. 6 | Example for settings.py: 7 | 8 | .. code-block:: py 9 | 10 | from confy import env, database, cache 11 | 12 | DEBUG = env('DEV') 13 | SECRET_KEY = env('SECRET_KEY') 14 | 15 | DATABASES = {'default': database.config()} 16 | 17 | CACHES = {'default': cache.config()} 18 | 19 | 20 | Create .env file and place it into project's root directory(where manage.py is located) 21 | And add into it environment variable like these: 22 | 23 | .. code-block:: sh 24 | 25 | DJANGO_SETTINGS_MODULE=project_name.settings 26 | DEV=True 27 | DATABASE_URL=sqlite:////server/apps/project_name/project_name.sqlite3 28 | CACHE_URL=uwsgi:// 29 | 30 | 31 | Modify your manage.py file to read environment variables(if you don't read them other ways like honcho, uwsgi etc.) 32 | 33 | .. code-block:: py 34 | 35 | #!/usr/bin/env python 36 | import sys 37 | import confy 38 | confy.read_environment_file() 39 | if __name__ == "__main__": 40 | from django.core.management import execute_from_command_line 41 | execute_from_command_line(sys.argv) 42 | 43 | 44 | Since environment variables exists you don't need to use os.environ.setdefault for wsgi.py and manage.py 45 | 46 | .. code-block:: py 47 | 48 | from django.core.wsgi import get_wsgi_application 49 | application = get_wsgi_application() 50 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | try: 4 | from setuptools import setup, find_packages 5 | except ImportError: 6 | from distutils.core import setup 7 | 8 | from confy import __version__ 9 | 10 | 11 | 12 | os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir))) 13 | 14 | 15 | setup( 16 | name="django-confy", 17 | version=__version__, 18 | description="Django project configuration helpers", 19 | long_description=open('README.rst').read(), 20 | url='http://github.com/MechanisM/django-confy', 21 | author='Eugene MechanisM', 22 | author_email='eugene@mechanism.name', 23 | license='MIT', 24 | zip_safe = False, 25 | classifiers=[ 26 | 'Development Status :: 4 - Beta', 27 | 'Intended Audience :: Developers', 28 | 'Topic :: Software Development :: Build Tools', 29 | 'License :: OSI Approved :: MIT License', 30 | 'Programming Language :: Python :: 2.7', 31 | 'Programming Language :: Python :: 3.4', 32 | ], 33 | keywords='django, config, env, 12factor', 34 | packages=find_packages(), 35 | include_package_data=True, 36 | ) 37 | --------------------------------------------------------------------------------