simplify settings, remove log application, add development scripts

This commit is contained in:
Benjamin Dauvergne 2013-06-24 14:55:55 +02:00
parent 34ca15ec9b
commit cafd11b1fa
19 changed files with 459 additions and 87 deletions

12
docbow-ctl Executable file
View File

@ -0,0 +1,12 @@
#!/usr/bin/env python
import sys
import os.path
if __name__ == "__main__":
from django.core.management import execute_from_command_line
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "docbow_project.settings")
os.environ.setdefault('DEBUG', '1')
execute_from_command_line(sys.argv)

View File

@ -1,29 +0,0 @@
import django.contrib.admin as admin
import models
from docbow_project.utils import filter_link, add_link
from ..docbow.models import DocbowUser
import docbow_project.actions as actions
cache = {}
class LogLineAdmin(admin.ModelAdmin):
list_display = [ 'timestamp', 'levelname', 'ip2', 'user2', 'message' ]
fields = [ 'timestamp', 'levelname', 'ip', 'user3', 'message']
readonly_fields = fields
list_filter = [ 'name', 'levelname', 'user' ]
date_hierarchy = 'timestamp'
actions = [ actions.export_as_csv ]
search_fields = [ 'user', 'ip', 'message' ]
class Media:
css = {
'all': ('log/css/logline.css',),
}
ip2 = filter_link('ip', 'Adresse IP')
user2 = add_link('user', DocbowUser, 'username', filter_link('user', 'Utilisateur'))
user3 = add_link('user', DocbowUser, 'username', metamodel=models.LogLine)
admin.site.register(models.LogLine, LogLineAdmin)

View File

@ -1,22 +0,0 @@
import logging
import datetime as dt
class LogToDbHandler(logging.Handler):
models = None
def __init__(self, *args, **kwargs):
logging.Handler.__init__(self, *args, **kwargs)
def emit(self, record):
if not self.models:
import models
self.models = models
message = self.format(record)
log_line = self.models.LogLine(timestamp=dt.datetime.now(),
levelname=record.levelname,
name=record.name,
ip=getattr(record, 'ip', 'None'),
user=str(getattr(record, 'user', 'Anonymous')),
message=message)
log_line.save(using='log')

View File

@ -1,14 +0,0 @@
from django.db.models import Model, CharField, TextField, DateTimeField, IntegerField
class LogLine(Model):
timestamp = DateTimeField()
name = CharField(max_length=128)
levelname = CharField(max_length=10)
ip = CharField(max_length=15)
user = CharField(max_length=30)
message = TextField()
class Meta:
ordering = [ '-timestamp' ]
verbose_name = 'Trace'
app_label = 'auth'

View File

@ -1,4 +0,0 @@
.external-link {
background: url('/static/images/external-link-ltr-icon.png') center right no-repeat;
padding-right: 13px
}

View File

@ -1,3 +1,3 @@
from django.conf import settings
PLONE_GED_DIRECTORY = getattr(settings, 'PLONE_GED_DIRECTORY', None)
PLONE_GED_DIRECTORY = getattr(settings, 'DOCBOW_PLONE_GED_DIRECTORY', None)

268
docbow_project/settings.py Normal file
View File

@ -0,0 +1,268 @@
# -*- coding: utf-8 -*-
import os
gettext_noop = lambda s: s
PROJECT_PATH = os.path.join(os.path.dirname(__file__), '..')
PROJECT_NAME = 'docbow'
# boolean settings
__ENVIRONMENT_DEFAULTS = dict(
# booleans
DEBUG=False,
DEBUG_PROPAGATE_EXCEPTIONS=False,
USE_DEBUG_TOOLBAR=False,
TEMPLATE_DEBUG=False,
# paths
STATIC_ROOT='/var/lib/%s/static' % PROJECT_NAME,
STATIC_URL='/static/',
MEDIA_ROOT='/var/lib/%s/media' % PROJECT_NAME,
MEDIA_URL='/media/',
ADMIN_MEDIA_PREFIX='/static/grappelli/',
# i18n/l18n
TIME_ZONE = 'Europe/Paris',
LANGUAGE_CODE = 'fr',
SITE_ID = 1,
USE_I18N=True,
USE_L10N=True,
USE_TZ=True,
# core
ROOT_URLCONF='docbow_project.urls',
TEMPLATE_DIRS=('/var/lib/%s/templates' % PROJECT_NAME,),
STATICFILES_DIRS=('/var/lib/%s/extra-static/' % PROJECT_NAME,),
GRAPPELLI_ADMIN_TITLE=u"Administration de la plate-forme d'échange sécurisée du Parlement wallon",
FILE_PER_PAGE=30,
TINYMCE_SPELLCHECKER=True,
TINYMCE_JS_URL="/static/js/tiny_mce/tiny_mce_src.js",
TINYMCE_COMPRESSOR=True,
DO_NOT_SEND_GROUPS=(
u'Administrateurs des groupes',
u'Administrateurs des types de document',
u'Administrateurs des utilisateurs',
u"Utilisateurs de l'application" ),
CONTACT_GROUPS=(u'Contact « Administrateur du système »',),
LOCALE_PATHS=(os.path.join(PROJECT_PATH, 'docbow_project', 'locale'),),
DEFAULT_FROM_EMAIL='admin@example.com',
CONTACT_SUBJECT_PREFIX='Contact depuis docbow: ',
ALLOWED_HOSTS=['*'],
LOGIN_REDIRECT_URL='/inbox',
MESSAGE_STORAGE='django.contrib.messages.storage.fallback.FallbackStorage',
AUTHENTICATION_BACKENDS=(
'django_auth_ldap.backend.LDAPBackend',
'docbow_project.auth_backend.DelegationAuthBackend',
'django.contrib.auth.backends.ModelBackend' ),
AUTH_LDAP_SERVER_URI='ldaps://ldap.libre-entreprise.org:636',
AUTH_LDAP_BIND_DN='uid=admin,ou=people,o=entrouvert,ou=companies,o=libre-entreprise',
AUTH_LDAP_BIND_PASSWORD='',
INTERNAL_IPS=('127.0.0.1','82.234.244.169'),
ADMINS=(),
SOUTH_TESTS_MIGRATE=True,
DOCBOW_BASE_URL='http://localhost:8000',
OVH_SMS_ACCOUNT='sms-db26857-1',
OVH_SMS_LOGIN='pfwb',
OVH_SMS_PASSWORD='',
OVH_SMS_FROM='Dauvergne',
DOCBOW_SMS_CARRIER_CLASS='docbow_project.sms_carrier_ovh.OVHSMSCarrier',
DOCBOW_ORGANIZATION_SHORT='PFWB',
DOCBOW_ORGANIZATION=u'Parlement de la Fédération Wallonie-Bruxelles',
DOCBOW_PLONE_GED_DIRECTORY='/var/lib/%s/ged/',
DOCBOW_NOTIFIERS=(
'docbow_project.docbow.notification.MailNotifier',
'docbow_project.docbow.notification.SMSNotifier',
),
)
for key, default in __ENVIRONMENT_DEFAULTS.iteritems():
try:
value = os.environ['DJANGO_'+key]
if default is True or default is False:
if value.isdigit():
value = bool(int(value))
else:
value = value.lower() in ('yes', 'true', 'y')
elif isinstance(default, (tuple, list)):
value = [ x.strip() for x in value.split(':')]
if len(default):
if isinstance(default[0], (tuple, list)) or key in ('ADMINS',):
value = [ x.split(';') for x in value ]
elif isinstance(default[0]. unicode):
value = [ unicode(x, 'utf8') for x in value ]
elif isinstance(default, unicode):
value = unicode(value, 'utf8')
except KeyError:
value = default
globals()[key] = value
# FIXME !! to remove in the future
TEMPLATE_DIRS = (os.path.join(PROJECT_PATH, 'docbow_project', 'templates'),) + TEMPLATE_DIRS
MANAGERS = ADMINS
DATABASES = {
'default': {
'ENGINE': os.environ.get('DATABASE_ENGINE', 'django.db.backends.sqlite3'),
'NAME': os.environ.get('DATABASE_NAME', os.path.join(PROJECT_PATH, PROJECT_NAME + '.db')),
}
}
# Hey Entr'ouvert is in France !!
LANGUAGES = (
('fr', gettext_noop('French')),
)
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.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',
'django.middleware.transaction.TransactionMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'docbow_project.docbow.middleware.KeepUserAroundMiddleware',
'django_journal.middleware.JournalMiddleware',
)
INSTALLED_APPS = (
'docbow_project.docbow',
'docbow_project.plone',
'grappelli',
'django_journal',
'uni_form',
'tinymce',
'south',
'django.contrib.admin',
'django.contrib.contenttypes',
'django.contrib.auth',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.humanize',
)
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
TINYMCE_DEFAULT_CONFIG = {
'theme': "advanced",
}
DOCBOW_MENU = [
('send-file', gettext_noop('send-file_menu')),
('inbox', gettext_noop('inbox_menu')),
('outbox', gettext_noop('outbox_menu')),
('docbow_admin:index', gettext_noop('admin_menu')),
('profile', gettext_noop('profile_menu')),
('auth_password_change', gettext_noop('password_change_menu')),
('delegate', gettext_noop('delegate_menu')),
('mailing-lists', gettext_noop('mailing-lists')),
('help', gettext_noop('help_menu')),
('contact', gettext_noop('contact_menu')),
]
import logging.handlers
LOGGING = {
'version': 1,
'disable_existing_loggers': True,
'formatters': {
'syslog': {
'format': PROJECT_NAME + '(pid=%(process)d) %(levelname)s %(name)s: %(message)s',
},
'syslog_debug': {
'format': PROJECT_NAME + '(pid=%(process)d) %(levelname)s %(asctime)s t_%(thread)s %(name)s: %(message)s',
},
},
'handlers': {
'syslog': {
'level': 'DEBUG',
'class': 'entrouvert.logging.handlers.SysLogHandler',
'formatter': 'syslog_debug' if DEBUG else 'syslog',
'facility': logging.handlers.SysLogHandler.LOG_LOCAL0,
'address': '/dev/log',
'max_length': 999,
'filters': [],
},
'mail_admins': {
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler',
'filters': [],
'include_html': True,
},
'console': {
'class': 'logging.StreamHandler',
'formatter': 'syslog_debug',
'level': 'DEBUG',
},
},
'loggers': {
'django.db': {
'handlers': [ 'mail_admins', 'syslog' ],
'level': 'INFO',
'propagate': False,
},
'docbow.mail_interface': {
'handlers': [ 'mail_admins', 'syslog' ],
'level': 'DEBUG' if DEBUG else 'INFO',
'propagate': False,
},
'docbow': {
'handlers': [ 'mail_admins', 'syslog' ],
'level': 'DEBUG' if DEBUG else 'INFO',
'propagate': False,
},
'': {
'handlers': [ 'mail_admins', 'syslog' ],
'level': 'DEBUG',
},
},
}
if DEBUG:
for logger in LOGGING['loggers']:
logger['handlers'].append('console')
# LDAP backend configuration
import ldap
from django_auth_ldap.config import LDAPSearch, GroupOfUniqueNamesType
AUTH_LDAP_USER_SEARCH = LDAPSearch("ou=people,o=entrouvert,ou=companies,o=libre-entreprise",
ldap.SCOPE_SUBTREE, "(uid=%(user)s)")
AUTH_LDAP_GROUP_TYPE = GroupOfUniqueNamesType()
AUTH_LDAP_GROUP_SEARCH = LDAPSearch("o=libre-entreprise",
ldap.SCOPE_SUBTREE, "(objectClass=legroup)")
AUTH_LDAP_USER_FLAGS_BY_GROUP = {
"is_staff": "cn=ldapadmins,ou=groups,o=entrouvert,ou=companies,o=libre-entreprise",
"is_superuser": "cn=ldapadmins,ou=groups,o=entrouvert,ou=companies,o=libre-entreprise",
}
AUTH_LDAP_USER_ATTR_MAP = {
"first_name": "givenName",
"last_name": "sn",
"email": "mail"
}
try:
from local_settings import *
except ImportError, e:
if 'local_settings' not in e.args[0]:
raise
if USE_DEBUG_TOOLBAR:
try:
import debug_toolbar
MIDDLEWARE_CLASSES += ('debug_toolbar.middleware.DebugToolbarMiddleware',)
INSTALLED_APPS += ('debug_toolbar',)
DEBUG_TOOLBAR_CONFIG = { 'INTERCEPT_REDIRECTS': False }
except ImportError:
print "Debug toolbar missing, not loaded"
# syntax checks
for admin in ADMINS:
assert len(admin) == 2, 'ADMINS setting must be a colon separated list of name and emails separated by a semi-colon'
assert '@' in admin[1], 'ADMINS setting pairs second value must be emails'

21
docbow_project/wsgi.py Normal file
View File

@ -0,0 +1,21 @@
"""
WSGI config for docbow project.
This module contains the WSGI application used by Django's development server
and any production WSGI deployments. It should expose a module-level variable
named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover
this application via the ``WSGI_APPLICATION`` setting.
Usually you will have the standard Django WSGI application here, but it also
might make sense to replace the whole Django WSGI application with a custom one
that later delegates to the Django one. For example, you could introduce WSGI
middleware here, or combine a Django application with an application of another
framework.
"""
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "docbow_project.settings")
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

2
load-base-data.sh Executable file
View File

@ -0,0 +1,2 @@
#!/bin/sh
./run.sh loaddata filetype content groups

View File

@ -1,11 +0,0 @@
#!/usr/bin/env python
import sys
import os.path
from django.core.management import execute_manager
import docbow_project.settings.dev as settings
sys.path.insert(0, os.path.dirname(__file__))
if __name__ == "__main__":
execute_manager(settings)

View File

@ -8,11 +8,10 @@ django-auth-ldap<1.1
python-ldap<3.0.0
BeautifulSoup<3.3.0
M2Crypto<1.0.0
wsgiref<1.0.0
pyasn1<1.0.0
pyasn1-modules<1.0.0
rfc3161==0.1.6
psycopg2<2.5.0
gunicorn
django_journal<2.0.0
django-picklefield==0.3.0
git+git://repos.entrouvert.org/python-entrouvert.git/#egg=entrouvert-1.1.9999

14
run.sh Executable file
View File

@ -0,0 +1,14 @@
#!/bin/sh
PROJECT=docbow
CTL=${PROJECT}-ctl
VENV=${PROJECT}-venv
if [ "$VIRTUAL_ENV" != "" ]; then
deactivate
fi
if [ ! -d $VENV ]; then
./start.sh
else
. ./$VENV/bin/activate
./$CTL "${@:-runserver}"
fi

120
setup.py
View File

@ -1,13 +1,125 @@
#!/usr/bin/python
from distutils.core import setup
#!env python
from setuptools import setup, find_packages
from setuptools.command.install_lib import install_lib as _install_lib
from distutils.command.build import build as _build
from distutils.command.sdist import sdist as _sdist
from distutils.cmd import Command
class compile_translations(Command):
description = 'compile message catalogs to MO files via django compilemessages'
user_options = []
def initialize_options(self):
pass
def finalize_options(self):
pass
def run(self):
import os
import sys
from django.core.management.commands.compilemessages import \
compile_messages
for path in ['docbow_project']:
if not os.path.exists(os.path.join(path, 'locale')):
continue
curdir = os.getcwd()
os.chdir(os.path.realpath(path))
compile_messages(stderr=sys.stderr)
os.chdir(curdir)
class build(_build):
sub_commands = [('compile_translations', None)] + _build.sub_commands
class sdist(_sdist):
sub_commands = [('compile_translations', None)] + _sdist.sub_commands
class install_lib(_install_lib):
def run(self):
self.run_command('compile_translations')
_install_lib.run(self)
def get_version():
import glob
import re
import os
version = None
for d in glob.glob('*'):
if not os.path.isdir(d):
continue
module_file = os.path.join(d, '__init__.py')
if not os.path.exists(module_file):
continue
for v in re.findall("""__version__ *= *['"](.*)['"]""",
open(module_file).read()):
assert version is None
version = v
if version:
break
assert version is not None
if os.path.exists('.git'):
import subprocess
p = subprocess.Popen(['git','describe','--dirty','--match=v*'],
stdout=subprocess.PIPE)
result = p.communicate()[0]
assert p.returncode == 0, 'git returned non-zero'
new_version = result.split()[0][1:]
assert not new_version.endswith('-dirty'), 'git workdir is not clean'
assert new_version.split('-')[0] == version, '__version__ must match the last git annotated tag'
version = new_version.replace('-', '.')
return version
setup(name='docbow',
version='1.0',
license='AGPL 3.0',
description='Document box for the Wallon Parliement',
description='Document box for the Wallon Parliament',
url='https://dev.entrouvert.org/projects/docbow-pub/',
author="Entr'ouvert",
author_email='info@entrouvert.com',
maintainer='Benjamin Dauvergne',
maintainer_email='bdauvergne@entrouvert.com',
packages=['docbow_project'])
scripts=('docbow-ctl',),
package_data={
'': [
'templates/**.html',
'templates/**.txt',
'static/**.png',
'static/**.gif',
'static/**.css',
'static/**.js',
'locale/**.mo',
'fixtures/*.json',
]
},
packages=find_packages(),
install_requires=[
'Django==1.5'
'South<0.8.0'
'django-debug-toolbar<0.9.0'
'django-grappelli<2.5.0'
'django-tinymce<1.6.0'
'django-uni-form<0.9.0'
'django-auth-ldap<1.1'
'python-ldap<3.0.0'
'BeautifulSoup<3.3.0'
'M2Crypto<1.0.0'
'pyasn1<1.0.0'
'pyasn1-modules<1.0.0'
'rfc3161==0.1.6'
'gunicorn'
'django_journal<2.0.0'
'django-picklefield==0.3.0'
'entrouvert<2.0',
],
setup_requires=[
'Django==1.5',
],
dependency_links = [
'git+git://repos.entrouvert.org/python-entrouvert.git/#egg=entrouvert-1.1.9999',
],
cmdclass={'build': build, 'install_lib': install_lib,
'compile_translations': compile_translations,
'sdist': sdist})

24
start.sh Executable file
View File

@ -0,0 +1,24 @@
#!/bin/sh
PROJECT=docbow
CTL=${PROJECT}-ctl
VENV=${PROJECT}-venv
if [ "$VIRTUAL_ENV" = "" ]; then
if which mkvirtualenv >/dev/null 2>&1; then
workon $PROJECT || (mkvirtualenv $PROJECT; workon $PROJECT)
else
if [ ! -d $VENV ]; then
virtualenv --system-site-packages $VENV 2>/dev/null || virtualenv $VENV
fi
. ./$VENV/bin/activate
fi
fi
easy_install -U pip distribute
pip install -U 'django==1.5'
pip install -U -r requirements.txt
if [ ! -f $PROJECT.db ]; then
./$CTL syncdb --all --noinput
./$CTL migrate --fake
./load-base-data.sh
fi
./$CTL runserver