mirror of
https://github.com/kennethreitz/heroku-buildpack-python.git
synced 2026-06-05 23:10:16 +00:00
new python langpack playground; ast aware settings.py code injection
This commit is contained in:
@@ -0,0 +1 @@
|
||||
*.pyc
|
||||
@@ -0,0 +1,18 @@
|
||||
virtualenv
|
||||
----------
|
||||
|
||||
pip
|
||||
---
|
||||
|
||||
Django settings.py
|
||||
------------------
|
||||
|
||||
Sets up a db for every ENV ${NAME}_URL => postgres:// var:
|
||||
DATABASES["DATABASE"]
|
||||
DATABASES["SHARED_DATABASE"]
|
||||
DATABASES["HEROKU_POSTGRESQL_ONYX"]
|
||||
|
||||
Aliases DATABASE_URL to default database:
|
||||
DATABASES["default"] = DATABASES["DATABASE"]
|
||||
|
||||
Injected right after DATABASES = {...}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
|
||||
##########
|
||||
# BEGIN HEROKU PYTHON/DJANGO LANGUAGE PACK
|
||||
# Dynamically set DATABASES from ENV vars
|
||||
|
||||
import os, urlparse
|
||||
urlparse.uses_netloc.append("postgres")
|
||||
key_re = re.compile(r"^(?P<name>[A-Z_]+)_URL$")
|
||||
|
||||
for k,v in os.environ.items():
|
||||
url = urlparse.urlparse(v)
|
||||
matches = key_re.match(k)
|
||||
if not matches or url.scheme != "postgres":
|
||||
continue
|
||||
|
||||
DATABASES[matches.group("name")] = {
|
||||
"ENGINE": "django.db.backends.postgresql_psycopg2",
|
||||
"NAME": url.path[1:],
|
||||
"USER": url.username,
|
||||
"PASSWORD": url.password,
|
||||
"HOST": url.hostname,
|
||||
"PORT": url.port,
|
||||
}
|
||||
|
||||
# alias "default" to DATABASE_URL
|
||||
if DATABASES["DATABASE"]:
|
||||
DATABASES["default"] = DATABASES["DATABASE"]
|
||||
|
||||
#
|
||||
# END HEROKU PYTHON/DJANGO LANGUAGE PACK
|
||||
##########
|
||||
Executable
+41
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env python2.7
|
||||
import os
|
||||
import sys
|
||||
from lib2to3 import pygram, pytree
|
||||
from lib2to3.pgen2 import driver
|
||||
|
||||
ROOTDIR = os.path.dirname(__file__)
|
||||
|
||||
def find(node, leaf):
|
||||
if node == leaf:
|
||||
return node
|
||||
for c in node.children:
|
||||
if find(c, leaf):
|
||||
return find(c, leaf)
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) != 2:
|
||||
print "Usage: inject_dbs.py FILENAME"
|
||||
sys.exit(1)
|
||||
|
||||
src = sys.argv[1]
|
||||
patch = os.path.join(ROOTDIR, "dbs.py")
|
||||
dest = "_settings.py"
|
||||
|
||||
drv = driver.Driver(pygram.python_grammar, pytree.convert)
|
||||
root = drv.parse_file(src)
|
||||
|
||||
node = find(root, pytree.Leaf(1, "DATABASES")) # Find first DATABASES
|
||||
end = node.parent.next_sibling
|
||||
|
||||
with open(src) as _src:
|
||||
head = [_src.next() for x in xrange(end.lineno)]
|
||||
tail = [l for x,l in enumerate(_src)]
|
||||
|
||||
with open(patch) as _patch:
|
||||
body = [l for x,l in enumerate(_patch)]
|
||||
|
||||
with open(dest, "w") as _dest:
|
||||
_dest.writelines(head)
|
||||
_dest.writelines(body)
|
||||
_dest.writelines(tail)
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
# Django settings for myapp project.
|
||||
|
||||
DEBUG = True
|
||||
TEMPLATE_DEBUG = DEBUG
|
||||
|
||||
ADMINS = (
|
||||
# ('Your Name', 'your_email@example.com'),
|
||||
)
|
||||
|
||||
MANAGERS = ADMINS
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
|
||||
'NAME': '', # Or path to database file if using sqlite3.
|
||||
'USER': '', # Not used with sqlite3.
|
||||
'PASSWORD': '', # Not used with sqlite3.
|
||||
'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
|
||||
'PORT': '', # Set to empty string for default. Not used with sqlite3.
|
||||
}
|
||||
}
|
||||
|
||||
# Local time zone for this installation. Choices can be found here:
|
||||
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
|
||||
# although not all choices may be available on all operating systems.
|
||||
# On Unix systems, a value of None will cause Django to use the same
|
||||
# timezone as the operating system.
|
||||
# If running in a Windows environment this must be set to the same as your
|
||||
# system time zone.
|
||||
TIME_ZONE = 'America/Chicago'
|
||||
|
||||
# Language code for this installation. All choices can be found here:
|
||||
# http://www.i18nguy.com/unicode/language-identifiers.html
|
||||
LANGUAGE_CODE = 'en-us'
|
||||
|
||||
SITE_ID = 1
|
||||
|
||||
# If you set this to False, Django will make some optimizations so as not
|
||||
# to load the internationalization machinery.
|
||||
USE_I18N = True
|
||||
|
||||
# If you set this to False, Django will not format dates, numbers and
|
||||
# calendars according to the current locale
|
||||
USE_L10N = True
|
||||
|
||||
# Absolute filesystem path to the directory that will hold user-uploaded files.
|
||||
# Example: "/home/media/media.lawrence.com/media/"
|
||||
MEDIA_ROOT = ''
|
||||
|
||||
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
|
||||
# trailing slash.
|
||||
# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
|
||||
MEDIA_URL = ''
|
||||
|
||||
# Absolute path to the directory static files should be collected to.
|
||||
# Don't put anything in this directory yourself; store your static files
|
||||
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
|
||||
# Example: "/home/media/media.lawrence.com/static/"
|
||||
STATIC_ROOT = ''
|
||||
|
||||
# URL prefix for static files.
|
||||
# Example: "http://media.lawrence.com/static/"
|
||||
STATIC_URL = '/static/'
|
||||
|
||||
# URL prefix for admin static files -- CSS, JavaScript and images.
|
||||
# Make sure to use a trailing slash.
|
||||
# Examples: "http://foo.com/static/admin/", "/static/admin/".
|
||||
ADMIN_MEDIA_PREFIX = '/static/admin/'
|
||||
|
||||
# Additional locations of static files
|
||||
STATICFILES_DIRS = (
|
||||
# Put strings here, like "/home/html/static" or "C:/www/django/static".
|
||||
# Always use forward slashes, even on Windows.
|
||||
# Don't forget to use absolute paths, not relative paths.
|
||||
)
|
||||
|
||||
# List of finder classes that know how to find static files in
|
||||
# various locations.
|
||||
STATICFILES_FINDERS = (
|
||||
'django.contrib.staticfiles.finders.FileSystemFinder',
|
||||
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
|
||||
# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
|
||||
)
|
||||
|
||||
# Make this unique, and don't share it with anybody.
|
||||
SECRET_KEY = 'urj6yp&_y^_%9*yf0=qtp+6=8%8eschux+m*a4)!s4xp5!$ldy'
|
||||
|
||||
# List of callables that know how to import templates from various sources.
|
||||
TEMPLATE_LOADERS = (
|
||||
'django.template.loaders.filesystem.Loader',
|
||||
'django.template.loaders.app_directories.Loader',
|
||||
# 'django.template.loaders.eggs.Loader',
|
||||
)
|
||||
|
||||
MIDDLEWARE_CLASSES = (
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
)
|
||||
|
||||
ROOT_URLCONF = 'myapp.urls'
|
||||
|
||||
TEMPLATE_DIRS = (
|
||||
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
|
||||
# Always use forward slashes, even on Windows.
|
||||
# Don't forget to use absolute paths, not relative paths.
|
||||
)
|
||||
|
||||
INSTALLED_APPS = (
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.sites',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
# Uncomment the next line to enable the admin:
|
||||
# 'django.contrib.admin',
|
||||
# Uncomment the next line to enable admin documentation:
|
||||
# 'django.contrib.admindocs',
|
||||
)
|
||||
|
||||
# A sample logging configuration. The only tangible logging
|
||||
# performed by this configuration is to send an email to
|
||||
# the site admins on every HTTP 500 error.
|
||||
# See http://docs.djangoproject.com/en/dev/topics/logging for
|
||||
# more details on how to customize your logging configuration.
|
||||
LOGGING = {
|
||||
'version': 1,
|
||||
'disable_existing_loggers': False,
|
||||
'handlers': {
|
||||
'mail_admins': {
|
||||
'level': 'ERROR',
|
||||
'class': 'django.utils.log.AdminEmailHandler'
|
||||
}
|
||||
},
|
||||
'loggers': {
|
||||
'django.request': {
|
||||
'handlers': ['mail_admins'],
|
||||
'level': 'ERROR',
|
||||
'propagate': True,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
import os
|
||||
import re
|
||||
import unittest
|
||||
|
||||
DATABASES = {}
|
||||
ROOTDIR = os.path.dirname(__file__)
|
||||
|
||||
class TestInjectDBs(unittest.TestCase):
|
||||
def setUp(self):
|
||||
DATABASES = {}
|
||||
os.environ.update({
|
||||
"DATABASE_URL": "postgres://victor:xray@localhost:5432/alfa",
|
||||
"HEROKU_POSTGRESQL_ONYX_URL": "postgres://victor:xray@localhost:5432/alfa",
|
||||
"HEROKU_POSTGRESQL_RED_URL": "postgres://juliet:zulu@localhost:5432/beta",
|
||||
"SHARED_DATABASE_URL": "postgres://quebec:kilo@localhost:5432/echo",
|
||||
"THUNK": "postgres://localhost/db",
|
||||
"FOO": "bar",
|
||||
})
|
||||
|
||||
def testCode(self):
|
||||
"""
|
||||
Test the code injected into settings.py to map ENV to settings.DATABASES hash
|
||||
"""
|
||||
# read and exec code in this context
|
||||
with open(os.path.join(ROOTDIR, "..", "opt/dbs.py")) as _src:
|
||||
exec compile(_src.read(), "dbs.py", "exec")
|
||||
|
||||
self.assertEqual(5, len(DATABASES)) # default, DATABASE, ONYX, RED, SHARED_DATABASE
|
||||
|
||||
self.assertDictEqual({
|
||||
"ENGINE": "django.db.backends.postgresql_psycopg2",
|
||||
"NAME": "alfa",
|
||||
"USER": "victor",
|
||||
"PASSWORD": "xray",
|
||||
"HOST": "localhost",
|
||||
"PORT": 5432
|
||||
}, DATABASES["HEROKU_POSTGRESQL_ONYX"])
|
||||
|
||||
self.assertDictEqual({
|
||||
"ENGINE": "django.db.backends.postgresql_psycopg2",
|
||||
"NAME": "beta",
|
||||
"USER": "juliet",
|
||||
"PASSWORD": "zulu",
|
||||
"HOST": "localhost",
|
||||
"PORT": 5432
|
||||
}, DATABASES["HEROKU_POSTGRESQL_RED"])
|
||||
|
||||
self.assertDictEqual({
|
||||
"ENGINE": "django.db.backends.postgresql_psycopg2",
|
||||
"NAME": "echo",
|
||||
"USER": "quebec",
|
||||
"PASSWORD": "kilo",
|
||||
"HOST": "localhost",
|
||||
"PORT": 5432
|
||||
}, DATABASES["SHARED_DATABASE"])
|
||||
|
||||
# aliases
|
||||
self.assertDictEqual(DATABASES["HEROKU_POSTGRESQL_ONYX"], DATABASES["DATABASE"])
|
||||
self.assertDictEqual(DATABASES["HEROKU_POSTGRESQL_ONYX"], DATABASES["default"])
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user