Skip to content

Instantly share code, notes, and snippets.

@derega
Created December 6, 2009 20:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save derega/250391 to your computer and use it in GitHub Desktop.
Save derega/250391 to your computer and use it in GitHub Desktop.
Managing Django projects
from __future__ import with_statement
from fabric.api import *
def _read_config(conf_file=None):
import ConfigParser
CACHE_FILE = 'config.cache'
c = ConfigParser.ConfigParser()
if not conf_file:
conf_file = CACHE_FILE
else:
c.readfp(open('defaults.conf'))
config = c.read(conf_file)
with open(CACHE_FILE, 'wb') as cf:
c.write(cf)
return c
def _out(f):
"""Decorator for directing output from function to a file or stdout
If kwarg 'fn' is set it is used as a filename where the output is redirected.
"""
def new_f(*args, **kwargs):
fn = kwargs.pop('fn', None)
result = f(*args, **kwargs)
if fn:
with open(fn, 'wb') as of:
of.write(result)
else:
print(result)
new_f.__doc__ = f.__doc__
return new_f
def _need_config(f):
"""Decorator for checking if we already processed the needed configs"""
def new_f(*args, **kwargs):
env.c = _read_config()
if not env.c:
abort("Run 'setup' before this command'")
return f(*args, **kwargs)
new_f.__doc__ = f.__doc__
return new_f
def setup(conf_file=None):
"""Setup this instance.
"""
if not conf_file:
conf_file = 'local.conf'
env.c = _read_config(conf_file)
@_need_config
def install():
"""Install all dependencies.
"""
local('virtualenv %s' % env.c.get('Instance', 'virtualenv'), capture=False)
local('pip install -r requirements.txt', capture=False)
local('python setup.py install')
@_need_config
def init_db():
local('manage.py syncdb')
@_need_config
def perms(owner, group):
"""Set permissions"""
with settings(warn_only=True):
local('chown -R %s:%s %s' % (owner, group, env.c.get('Instance', 'virtualenv')), capture=False)
local('chmod -R g+rwX %s' % (env.c.get('Instance', 'virtualenv')), capture=False)
local('chmod -R u+rwX %s' % (env.c.get('Instance', 'virtualenv')), capture=False)
def deploy():
"""Deploy instance for local access.
Runs all necessary steps to deploy fully functional instance
for local access. E.g. manage.py runserver
Handy for development use.
"""
install()
setup()
def deploy_nginx():
"""Deploy instance for use with NGINX.
Runs all necessary steps to deploy fully functional instance
for running with NGINX.
Generates NGINX config file for including in master NGINX config.
Uses local socket for communication between Django and NGINX.
"""
install()
setup()
nginx_config('http.conf')
@_need_config
@_out
def cfg_nginx():
"""Creates NGINX config file.
"""
return """
server {
listen %(port)s;
server_name %(servername)s;
access_log %(accesslog)s main;
error_log %(errorlog)s info;
location / {
fastcgi_pass unix:%(socket)s;
fastcgi_param PATH_INFO $fastcgi_script_name;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param SERVER_PORT $server_port;
fastcgi_pass_header Authorization;
fastcgi_intercept_errors off;
}
}
""" % {
'port': env.c.getint('Instance', 'port'),
'servername': env.c.get('Instance', 'servername'),
'accesslog': env.c.get('Instance', 'accesslog'),
'errorlog': env.c.get('Instance', 'errorlog'),
'socket': env.c.get('Instance', 'socket'),
}
@_need_config
@_out
def cfg_supervise():
"""Create runner for supervise"""
return """#!/bin/sh
source %(virtualenv)s/bin/activate
exec setuidgid wwwdaemon manage.py runfcgi --traceback socket=%(socket)s daemonize=false \
maxchildren=20 \
maxspare=2 \
method=threaded \
""" % {
'virtualenv': env.c.get('Instance', 'virtualenv'),
'socket': env.c.get('Instance', 'socket'),
}
#!/usr/bin/env python
"""setup.py for Django project"""
import os
from distutils.core import setup
def fullsplit(path, result=None):
"""
Split a pathname into components (the opposite of os.path.join) in a
platform-neutral way.
"""
if result is None:
result = []
head, tail = os.path.split(path)
if head == '':
return [tail] + result
if head == path:
return result
return fullsplit(head, [tail] + result)
# Compile the list of packages available, because distutils doesn't have
# an easy way to do this.
packages, data_files = [], []
root_dir = os.path.dirname(__file__)
if root_dir != '':
os.chdir(root_dir)
for dirpath, dirnames, filenames in os.walk('app'):
# Ignore dirnames that start with '.'
for i, dirname in enumerate(dirnames):
if dirname.startswith('.'): del dirnames[i]
if '__init__.py' in filenames:
packages.append('.'.join(fullsplit(dirpath)))
elif filenames:
data_files.append([dirpath, [os.path.join(dirpath, f) for f in filenames]])
version = "0.1"
try:
import subprocess
p = subprocess.Popen(['hg', 'parents', '--template={node}'], shell=False, stdout=subprocess.PIPE)
version = p.communicate()[0]
except:
pass
setup(
name='app',
version=version,
packages=packages,
scripts=['app/manage.py']
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment