Merge lp:~elachuni/ubuntu-webcatalog/deploy into lp:ubuntu-webcatalog

Proposed by Anthony Lenton
Status: Merged
Approved by: Łukasz Czyżykowski
Approved revision: no longer in the source branch.
Merged at revision: 22
Proposed branch: lp:~elachuni/ubuntu-webcatalog/deploy
Merge into: lp:ubuntu-webcatalog
Diff against target: 749 lines (+437/-167)
13 files modified
.bzrignore (+3/-0)
debian/control (+8/-1)
django_project/config/main.cfg (+98/-0)
django_project/settings.py (+24/-156)
django_project/urls.py (+8/-0)
fabtasks/bootstrap.py (+32/-0)
fabtasks/upgrade_from_package.py (+4/-3)
requirements.txt (+8/-3)
setup.py (+20/-4)
src/webcatalog/context_processors.py (+26/-0)
src/webcatalog/middleware/exception.py (+127/-0)
src/webcatalog/schema.py (+61/-0)
src/webcatalog/wsgi.py (+18/-0)
To merge this branch: bzr merge lp:~elachuni/ubuntu-webcatalog/deploy
Reviewer Review Type Date Requested Status
Canonical ISD hackers Pending
Review via email: mp+65276@code.launchpad.net

Commit message

Added several infrastructure modules and classes.

Description of the change

Overview
========
This branch adds standard ISD modules and classes, prepping for a deployment.

Details
=======
Integration for the following was added in this branch:
 - (django-)configglue
 - django-preflight
 - django-adminaudit
 - django-pgtools
 - Google analytics
 - django_openid_auth (for admin authentication)
 - wsgi-oops

To post a comment you must log in.
Revision history for this message
Łukasz Czyżykowski (lukasz-czyzykowski) wrote :

There are still some RnR/SCA leftovers in the code, lines:
- 54 (mentions devportal),
- 676 (comment mentions sca-deploy)

Also, if you add user=postgres in [default_database], will enable to run against PostgreSQL without the need for one bit of config (and this setting is ignored by SQLite).

Revision history for this message
ISD Branch Mangler (isd-branches-mangler) wrote :

There are additional revisions which have not been approved in review. Please seek review and approval of these new revisions.

22. By Anthony Lenton

[r=lukasz-czyzykowski] Added several infrastructure modules and classes.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2011-06-07 17:27:12 +0000
3+++ .bzrignore 2011-06-21 11:33:32 +0000
4@@ -1,8 +1,11 @@
5 webcatalog.db
6 src/ubuntu_webcatalog.egg-info/
7 virtualenv/
8+django_project/adminaudit
9+django_project/django_openid_auth
10 django_project/local_settings.py
11 django_project/static/
12 django_project/media_root_dev/*
13 .backup
14 tags
15+branches/
16
17=== modified file 'debian/control'
18--- debian/control 2011-06-17 15:33:40 +0000
19+++ debian/control 2011-06-21 11:33:32 +0000
20@@ -18,6 +18,13 @@
21 python-django (>> 1.2.4),
22 python-imaging,
23 python-configglue (>> 0.9.1),
24- python-django-configglue (>> 0.3)
25+ python-django-configglue (>> 0.3),
26+ python-django-preflight,
27+ python-django-adminaudit,
28+ python-django-pgtools,
29+ python-django-south,
30+ python-django-openid-auth,
31+ python-wsgi-oops,
32+ python-apt
33 Description: Ubuntu Web Catalog
34 Providing web access to the Ubuntu Software Center.
35
36=== added directory 'django_project/config'
37=== added file 'django_project/config/main.cfg'
38--- django_project/config/main.cfg 1970-01-01 00:00:00 +0000
39+++ django_project/config/main.cfg 2011-06-21 11:33:32 +0000
40@@ -0,0 +1,98 @@
41+[__noschema__]
42+hostname = webcatalog.staging.ubuntu.com
43+
44+[django]
45+authentication_backends = django_openid_auth.auth.OpenIDBackend
46+ django.contrib.auth.backends.ModelBackend
47+
48+databases = django_databases
49+logging = django_logging
50+
51+debug = true
52+media_root = django_project/media_root_dev/
53+
54+installed_apps = django.contrib.auth
55+ django.contrib.contenttypes
56+ django.contrib.sessions
57+ django.contrib.sites
58+ django.contrib.messages
59+ django.contrib.staticfiles
60+ django.contrib.markup
61+ adminaudit
62+ django.contrib.admin
63+ django_openid_auth
64+ django_configglue
65+ webcatalog
66+ south
67+ preflight
68+ pgtools
69+login_url = /openid/login/
70+managers = %(admins)s
71+middleware_classes = django.middleware.common.CommonMiddleware
72+ django.contrib.sessions.middleware.SessionMiddleware
73+ django.middleware.csrf.CsrfViewMiddleware
74+ django.contrib.auth.middleware.AuthenticationMiddleware
75+ django.contrib.messages.middleware.MessageMiddleware
76+ webcatalog.middleware.exception.LogExceptionMiddleware
77+fixture_dirs =
78+
79+secret_key = eepu9Av5ixage9ahhodovahfaiFoorodahf6keip3eichaeW9f
80+template_debug = %(debug)s
81+time_zone = Europe/London
82+media_url = /site_media/
83+use_etags = true
84+
85+template_context_processors = django.contrib.auth.context_processors.auth
86+ django.core.context_processors.debug
87+ django.core.context_processors.i18n
88+ django.core.context_processors.media
89+ django.core.context_processors.static
90+ django.contrib.messages.context_processors.messages
91+ webcatalog.context_processors.google_analytics_id
92+
93+template_dirs = django_project/templates/
94+static_root = ./django_project/static/
95+static_url = /assets/
96+
97+# Django-1.1 backwards compatibility
98+database_engine = sqlite3
99+database_name = webcatalog.db
100+
101+
102+[django_databases]
103+default = default_database
104+
105+[default_database]
106+engine = sqlite3
107+name = webcatalog.db
108+
109+[django_logging]
110+loggers = django_loggers
111+version = 1
112+disable_existing_loggers = False
113+
114+[django_loggers]
115+
116+[openid]
117+openid_sso_server_url = https://login.staging.ubuntu.com
118+openid_create_users = true
119+openid_update_details_from_sreg = true
120+openid_launchpad_teams_mapping = openid_team_mapping
121+
122+
123+[openid_team_mapping]
124+# Structure here is: LP Team = Django Group
125+canonical-isd-hackers = admin
126+canonical-losas = admin
127+
128+[oops]
129+oops_dir = /srv/%(hostname)s/staging-logs/www-oops
130+
131+[webcatalog]
132+serve_site_media = True
133+sca_api_url = https://sc.staging.ubuntu.com/api/2.0/
134+disk_apt_cache_location = /tmp/webcat_cache
135+
136+[google]
137+google_analytics_id = UA-1018242-24
138+
139
140=== modified file 'django_project/settings.py'
141--- django_project/settings.py 2011-06-17 17:48:07 +0000
142+++ django_project/settings.py 2011-06-21 11:33:32 +0000
143@@ -1,156 +1,24 @@
144-# Django settings for django_project project.
145-
146-DEBUG = True
147-TEMPLATE_DEBUG = DEBUG
148-
149-ADMINS = (
150- # ('Your Name', 'your_email@example.com'),
151-)
152-
153-MANAGERS = ADMINS
154-
155-DATABASES = {
156- 'default': {
157- 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
158- 'NAME': 'webcatalog.db', # Or path to database file if using sqlite3.
159- 'USER': '', # Not used with sqlite3.
160- 'PASSWORD': '', # Not used with sqlite3.
161- 'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
162- 'PORT': '', # Set to empty string for default. Not used with sqlite3.
163- }
164-}
165-
166-# Local time zone for this installation. Choices can be found here:
167-# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
168-# although not all choices may be available on all operating systems.
169-# On Unix systems, a value of None will cause Django to use the same
170-# timezone as the operating system.
171-# If running in a Windows environment this must be set to the same as your
172-# system time zone.
173-TIME_ZONE = 'America/Chicago'
174-
175-# Language code for this installation. All choices can be found here:
176-# http://www.i18nguy.com/unicode/language-identifiers.html
177-LANGUAGE_CODE = 'en-us'
178-
179-SITE_ID = 1
180-
181-# If you set this to False, Django will make some optimizations so as not
182-# to load the internationalization machinery.
183-USE_I18N = True
184-
185-# If you set this to False, Django will not format dates, numbers and
186-# calendars according to the current locale
187-USE_L10N = True
188-
189-# Absolute filesystem path to the directory that will hold user-uploaded files.
190-# Example: "/home/media/media.lawrence.com/media/"
191-MEDIA_ROOT = './django_project/media_root_dev/'
192-
193-# URL that handles the media served from MEDIA_ROOT. Make sure to use a
194-# trailing slash.
195-# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
196-MEDIA_URL = '/site_media/'
197-
198-# Absolute path to the directory static files should be collected to.
199-# Don't put anything in this directory yourself; store your static files
200-# in apps' "static/" subdirectories and in STATICFILES_DIRS.
201-# Example: "/home/media/media.lawrence.com/static/"
202-STATIC_ROOT = './django_project/static/'
203-
204-# URL prefix for static files.
205-# Example: "http://media.lawrence.com/static/"
206-STATIC_URL = '/assets/'
207-
208-# URL prefix for admin static files -- CSS, JavaScript and images.
209-# Make sure to use a trailing slash.
210-# Examples: "http://foo.com/static/admin/", "/static/admin/".
211-ADMIN_MEDIA_PREFIX = '/assets/admin/'
212-
213-# Additional locations of static files
214-STATICFILES_DIRS = (
215- # Put strings here, like "/home/html/static" or "C:/www/django/static".
216- # Always use forward slashes, even on Windows.
217- # Don't forget to use absolute paths, not relative paths.
218-)
219-
220-# List of finder classes that know how to find static files in
221-# various locations.
222-STATICFILES_FINDERS = (
223- 'django.contrib.staticfiles.finders.FileSystemFinder',
224- 'django.contrib.staticfiles.finders.AppDirectoriesFinder',
225-# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
226-)
227-
228-# Make this unique, and don't share it with anybody.
229-SECRET_KEY = '5t7w7uzf&_^goikwn)!g3lmn07gw7x&193uvs#irw4h=1#*%%-'
230-
231-# List of callables that know how to import templates from various sources.
232-TEMPLATE_LOADERS = (
233- 'django.template.loaders.filesystem.Loader',
234- 'django.template.loaders.app_directories.Loader',
235-# 'django.template.loaders.eggs.Loader',
236-)
237-
238-MIDDLEWARE_CLASSES = (
239- 'django.middleware.common.CommonMiddleware',
240- 'django.contrib.sessions.middleware.SessionMiddleware',
241- 'django.middleware.csrf.CsrfViewMiddleware',
242- 'django.contrib.auth.middleware.AuthenticationMiddleware',
243- 'django.contrib.messages.middleware.MessageMiddleware',
244-)
245-
246-ROOT_URLCONF = 'django_project.urls'
247-
248-TEMPLATE_DIRS = (
249- './django_project/templates',
250-)
251-
252-INSTALLED_APPS = (
253- 'django.contrib.auth',
254- 'django.contrib.contenttypes',
255- 'django.contrib.sessions',
256- 'django.contrib.sites',
257- 'django.contrib.messages',
258- 'django.contrib.staticfiles',
259- 'django.contrib.admin',
260- 'south',
261- 'webcatalog',
262-)
263-
264-# A sample logging configuration. The only tangible logging
265-# performed by this configuration is to send an email to
266-# the site admins on every HTTP 500 error.
267-# See http://docs.djangoproject.com/en/dev/topics/logging for
268-# more details on how to customize your logging configuration.
269-LOGGING = {
270- 'version': 1,
271- 'disable_existing_loggers': False,
272- 'handlers': {
273- 'mail_admins': {
274- 'level': 'ERROR',
275- 'class': 'django.utils.log.AdminEmailHandler'
276- }
277- },
278- 'loggers': {
279- 'django.request': {
280- 'handlers': ['mail_admins'],
281- 'level': 'ERROR',
282- 'propagate': True,
283- },
284- }
285-}
286-
287-########################
288-# Ubuntu Web Catalog specific settings:
289-########################
290-
291-# Strictly for use in our dev environment:
292-SERVE_SITE_MEDIA = True
293-SCA_API_URL = 'https://sc.staging.ubuntu.com/api/2.0/'
294-DISK_APT_CACHE_LOCATION = '/tmp/webcat_cache'
295-
296-try:
297- from local_settings import *
298-except ImportError:
299- pass
300+from __future__ import absolute_import
301+
302+import os.path
303+
304+from configglue.pyschema import SchemaConfigParser
305+from django_configglue.utils import update_settings
306+
307+from webcatalog.schema import WebCatalogSchema
308+
309+
310+# get absolute path for config files
311+current_dir = os.path.dirname(os.path.abspath(__file__))
312+config_files = map(lambda x: os.path.join(current_dir, x),
313+ ['config/main.cfg', '../../local_config/local.cfg',
314+ 'local.cfg'])
315+
316+# parse config files
317+parser = SchemaConfigParser(WebCatalogSchema())
318+parser.read(config_files)
319+update_settings(parser, locals())
320+
321+# keep parser reference
322+__CONFIGGLUE_PARSER__ = parser
323+
324
325=== removed directory 'django_project/templates'
326=== modified file 'django_project/urls.py'
327--- django_project/urls.py 2011-05-06 15:03:41 +0000
328+++ django_project/urls.py 2011-06-21 11:33:32 +0000
329@@ -15,15 +15,23 @@
330 # You should have received a copy of the GNU Affero General Public License
331 # along with this program. If not, see <http://www.gnu.org/licenses/>.
332
333+import preflight
334+import adminaudit
335 from django.conf.urls.defaults import patterns, include, url
336 from django.conf import settings
337 from django.contrib import admin
338+from django.views.generic.simple import redirect_to
339
340 admin.autodiscover()
341+preflight.autodiscover()
342+adminaudit.audit_install()
343
344 urlpatterns = patterns('',
345 url(r'^cat/', include('webcatalog.urls')),
346 url(r'^admin/', include(admin.site.urls)),
347+ (r'^preflight/$', include('preflight.urls')),
348+ url(r'^$', redirect_to, {'url': '/cat/'}),
349+
350 )
351
352 if settings.SERVE_SITE_MEDIA:
353
354=== modified file 'fabtasks/bootstrap.py'
355--- fabtasks/bootstrap.py 2011-05-06 21:00:11 +0000
356+++ fabtasks/bootstrap.py 2011-06-21 11:33:32 +0000
357@@ -52,13 +52,45 @@
358 if not os.path.exists(link_name):
359 os.symlink(os.path.abspath(source), link_name)
360
361+def _get_or_pull_bzr_branch(repo, name, revision=None):
362+ if revision is None:
363+ revision = ""
364+ else:
365+ revision = "--revision={0}".format(revision)
366+ if not os.path.exists("branches"):
367+ os.mkdir('branches')
368+ branch_path = os.path.join("branches", name)
369+ if os.path.exists(branch_path):
370+ local("rm -r {0}".format(branch_path))
371+ local("bzr branch {0} {1} {2}".format(
372+ revision, repo, branch_path), capture=False)
373+
374+def pull_required_branches():
375+ _get_or_pull_bzr_branch(
376+ "lp:django-adminaudit",
377+ "django-adminaudit")
378+ _symlink(
379+ "branches/django-adminaudit/adminaudit",
380+ "django_project/adminaudit")
381+ _get_or_pull_bzr_branch(
382+ "lp:~django-openid-auth/django-openid-auth/trunk",
383+ "django-openid-auth",
384+ revision=79)
385+ _symlink(
386+ "branches/django-openid-auth/django_openid_auth",
387+ "django_project/django_openid_auth")
388
389 def bootstrap():
390 virtualenv_create()
391 install_requirements()
392+ pull_required_branches()
393
394
395 def clean():
396+ local("rm -rf branches/")
397 local("rm -rf virtualenv/")
398 local("rm -rf src/ubuntu_webcatalog.egg-info")
399 local("rm -f webcatalog.db")
400+ links = ("adminaudit", "django_openid_auth")
401+ for link in links:
402+ local("rm -f django_project/{0}".format(link))
403
404=== modified file 'fabtasks/upgrade_from_package.py'
405--- fabtasks/upgrade_from_package.py 2011-04-05 02:19:30 +0000
406+++ fabtasks/upgrade_from_package.py 2011-06-21 11:33:32 +0000
407@@ -69,7 +69,7 @@
408 recipe = dedent("""\
409 # bzr-builder format 0.2 deb-version {debupstream}-0~{revno}+{time}
410 .""")
411- recipe_path = os.path.join(build_dir, 'rnr.recipe')
412+ recipe_path = os.path.join(build_dir, 'uwc.recipe')
413 with open(recipe_path, 'w+') as recipe_file:
414 recipe_file.write(recipe)
415
416@@ -92,7 +92,7 @@
417
418 def migrate_database(config_dir=None):
419 if config_dir is None:
420- # By default, the rnr config directory is assumed to be
421+ # By default, the uwc config directory is assumed to be
422 # /home/username/django_project.
423 config_dir = 'django_project'
424 run(config_dir + '/manage.py syncdb --migrate')
425@@ -133,7 +133,8 @@
426 run("cp %s/local.cfg %s" % (backup_dir, config_dir))
427 else:
428 # Create a local.cfg on the server from our template.
429- local_file, local_path = tempfile.mkstemp()
430+ local_fd, local_path = tempfile.mkstemp()
431+ local_file = os.fdopen(local_fd, 'w')
432 local_file.write(LOCAL_CONFIG)
433 local_file.close()
434 put(local_path, "%s/local.cfg" % config_dir)
435
436=== modified file 'requirements.txt'
437--- requirements.txt 2011-06-17 14:44:34 +0000
438+++ requirements.txt 2011-06-21 11:33:32 +0000
439@@ -1,7 +1,12 @@
440+configglue==0.10
441+coverage
442 django
443+django-configglue==0.4
444+-e bzr+http://bazaar.launchpad.net/~canonical-isd-hackers/django-pgtools/trunk
445+django-preflight
446 mock
447+PIL
448+python-debian
449+python-openid
450 setuptools
451 south
452-python-debian
453-PIL
454-coverage
455
456=== modified file 'setup.py'
457--- setup.py 2011-04-05 02:19:30 +0000
458+++ setup.py 2011-06-21 11:33:32 +0000
459@@ -1,5 +1,24 @@
460+import os
461 from setuptools import setup, find_packages
462
463+def find_packages_data(start_dir):
464+ packages = {}
465+ for package_name in os.listdir(start_dir):
466+ package_dir = os.path.join(start_dir, package_name)
467+ if os.path.exists(os.path.join(package_dir, '__init__.py')):
468+ files = []
469+ packages[package_name] = files
470+ for dirpath, dirnames, filenames in os.walk(package_dir):
471+ dirpath = dirpath[len(package_dir) + 1:]
472+ for filename in filenames:
473+ ext = os.path.splitext(filename)[1]
474+ if ext not in ('.py', '.pyc', '.pyo'):
475+ file_path = os.path.join(dirpath, filename)
476+ full_file_path = os.path.join(package_dir, file_path)
477+ if os.path.isfile(full_file_path):
478+ files.append(file_path)
479+ return packages
480+
481 setup(
482 name = "ubuntu-webcatalog",
483 version = "0.1",
484@@ -18,9 +37,6 @@
485 'django',
486 'south',
487 ],
488- package_data = {
489- 'webcatalog': [
490- ],
491- },
492+ package_data = find_packages_data('src'),
493 )
494
495
496=== added file 'src/webcatalog/context_processors.py'
497--- src/webcatalog/context_processors.py 1970-01-01 00:00:00 +0000
498+++ src/webcatalog/context_processors.py 2011-06-21 11:33:32 +0000
499@@ -0,0 +1,26 @@
500+# -*- coding: utf-8 -*-
501+# This file is part of the Ubuntu Web Catalog
502+# Copyright (C) 2011 Canonical Ltd.
503+#
504+# This program is free software: you can redistribute it and/or modify
505+# it under the terms of the GNU Affero General Public License as
506+# published by the Free Software Foundation, either version 3 of the
507+# License, or (at your option) any later version.
508+#
509+# This program is distributed in the hope that it will be useful,
510+# but WITHOUT ANY WARRANTY; without even the implied warranty of
511+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
512+# GNU Affero General Public License for more details.
513+#
514+# You should have received a copy of the GNU Affero General Public License
515+# along with this program. If not, see <http://www.gnu.org/licenses/>.
516+
517+"""Context processors web catalog app."""
518+
519+from django.conf import settings
520+
521+def google_analytics_id(request):
522+ """Adds the google analytics id to the context if it's present."""
523+ return {
524+ 'google_analytics_id': getattr(settings, 'GOOGLE_ANALYTICS_ID', None),
525+ }
526
527=== added directory 'src/webcatalog/middleware'
528=== added file 'src/webcatalog/middleware/__init__.py'
529=== added file 'src/webcatalog/middleware/exception.py'
530--- src/webcatalog/middleware/exception.py 1970-01-01 00:00:00 +0000
531+++ src/webcatalog/middleware/exception.py 2011-06-21 11:33:32 +0000
532@@ -0,0 +1,127 @@
533+# -*- coding: utf-8 -*-
534+# This file is part of the Ubuntu Web Catalog
535+# Copyright (C) 2011 Canonical Ltd.
536+#
537+# This program is free software: you can redistribute it and/or modify
538+# it under the terms of the GNU Affero General Public License as
539+# published by the Free Software Foundation, either version 3 of the
540+# License, or (at your option) any later version.
541+#
542+# This program is distributed in the hope that it will be useful,
543+# but WITHOUT ANY WARRANTY; without even the implied warranty of
544+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
545+# GNU Affero General Public License for more details.
546+#
547+# You should have received a copy of the GNU Affero General Public License
548+# along with this program. If not, see <http://www.gnu.org/licenses/>.
549+
550+"""Exception logging middleware for the web catalog app."""
551+
552+import logging
553+import re
554+import sys
555+import traceback
556+
557+from django.conf import settings
558+from django.db import connection
559+from django.views import debug
560+from django.views.debug import ExceptionReporter
561+
562+default_hidden_settings = \
563+ 'SECRET|PASSWORD|PROFANITIES_LIST|PRIVATE|secret|password|private'
564+hidden_settings = getattr(settings, 'HIDDEN_SETTINGS', default_hidden_settings)
565+debug.HIDDEN_SETTINGS = re.compile(hidden_settings)
566+
567+
568+class SanitizedExceptionReporter(ExceptionReporter):
569+ def __init__(self, request, exc_type, exc_value, tb, is_email=None):
570+ request = self.sanitize_request(request)
571+ ExceptionReporter.__init__(self, request,
572+ exc_type, exc_value, tb)
573+
574+ def get_traceback_frames(self):
575+ # This method is taken from Django's views.debug.ExceptionReporter.
576+ # Please see the license file in the third-party/django directory.
577+ frames = []
578+ tb = self.tb
579+ while tb is not None:
580+ # support for __traceback_hide__ which is used by a few libraries
581+ # to hide internal frames.
582+ if tb.tb_frame.f_locals.get('__traceback_hide__'):
583+ tb = tb.tb_next
584+ continue
585+ filename = tb.tb_frame.f_code.co_filename
586+ function = tb.tb_frame.f_code.co_name
587+ lineno = tb.tb_lineno - 1
588+ loader = tb.tb_frame.f_globals.get('__loader__')
589+ module_name = tb.tb_frame.f_globals.get('__name__')
590+ pre_context_lineno, pre_context, context_line, post_context = \
591+ self._get_lines_from_file(filename, lineno, 7, loader,
592+ module_name)
593+ if pre_context_lineno is not None:
594+ frames.append({
595+ 'tb': tb,
596+ 'filename': filename,
597+ 'function': function,
598+ 'lineno': lineno + 1,
599+ # The only diff in this method: call self.sanitize_vars()
600+ 'vars': self.sanitize_vars(tb.tb_frame.f_locals.items()),
601+ 'id': id(tb),
602+ 'pre_context': pre_context,
603+ 'context_line': context_line,
604+ 'post_context': post_context,
605+ 'pre_context_lineno': pre_context_lineno + 1,
606+ })
607+ tb = tb.tb_next
608+
609+ if not frames:
610+ frames = [{
611+ 'filename': '&lt;unknown&gt;',
612+ 'function': '?',
613+ 'lineno': '?',
614+ 'context_line': '???',
615+ }]
616+
617+ return frames
618+
619+ # These two methods are new -- Sanitize the request's POST and GET dicts,
620+ # and local variables in frames, not only Django's settings.
621+ def sanitize_vars(self, items):
622+ sanitized = []
623+ for item in items:
624+ if debug.HIDDEN_SETTINGS.search(item[0]):
625+ sanitized.append((item[0], '********'))
626+ else:
627+ sanitized.append(item)
628+ return sanitized
629+
630+ def sanitize_request(self, request):
631+ """Remove sensitive from the request before it is displayed"""
632+ dup_post = request.POST.copy()
633+ for key in request.POST.iterkeys():
634+ if debug.HIDDEN_SETTINGS.search(key):
635+ dup_post[key] = '********'
636+ request.POST = dup_post
637+ dup_get = request.GET.copy()
638+ for key in request.GET.iterkeys():
639+ if debug.HIDDEN_SETTINGS.search(key):
640+ dup_get[key] = '********'
641+ request.GET = dup_get
642+ return request
643+
644+
645+debug.ExceptionReporter = SanitizedExceptionReporter
646+
647+
648+class LogExceptionMiddleware(object):
649+ def process_exception(self, request, exception):
650+ """Log the traceback, so that it can be kept in the oops file"""
651+ reporter = SanitizedExceptionReporter(request, *sys.exc_info())
652+ template_debug = settings.TEMPLATE_DEBUG
653+ settings.TEMPLATE_DEBUG = True
654+ try:
655+ logging.warn(traceback.format_exc())
656+ for query in connection.queries:
657+ logging.warn("time: %(time)s sql: %(sql)s" % query)
658+ finally:
659+ settings.TEMPLATE_DEBUG = template_debug
660
661=== added file 'src/webcatalog/schema.py'
662--- src/webcatalog/schema.py 1970-01-01 00:00:00 +0000
663+++ src/webcatalog/schema.py 2011-06-21 11:33:32 +0000
664@@ -0,0 +1,61 @@
665+import django
666+
667+from configglue.pyschema import ConfigSection
668+from configglue.pyschema.options import (BoolConfigOption, StringConfigOption,
669+ LinesConfigOption, IntConfigOption, DictConfigOption, TupleConfigOption)
670+from django_configglue.schema import (
671+ Django112Schema,
672+ schemas,
673+ )
674+
675+# Currently we've updated to latest configglue/django-configglue
676+# but they remove a registered schema for django 1.1.1, which is
677+# the currently installed django version on our servers, resulting in:
678+# http://razorgirl.info/job/software-center-agent-deploy/23/console
679+# So we register the 112 schema to match until we upgrade. Once we
680+# upgraded this should still work without updating (as the version
681+# will be 1.3).
682+schemas.register(Django112Schema, '1.1.1')
683+DjangoSchema = schemas.get(django.get_version())
684+
685+
686+class WebCatalogSchema(DjangoSchema):
687+ """Config options specific to the web catalog."""
688+ # default section
689+ extra_pythonpath = LinesConfigOption(item=StringConfigOption())
690+ pgconnect_timeout = IntConfigOption(default=10)
691+ should_serve_https = BoolConfigOption()
692+
693+ oops = ConfigSection()
694+ oops.oops_dir = StringConfigOption(help='Absolute path to the directory'
695+ ' oops reports will be stored in')
696+
697+ openid = ConfigSection()
698+ openid.openid_sso_server_url = StringConfigOption()
699+ openid.openid_create_users = BoolConfigOption()
700+ openid.openid_update_details_from_sreg = BoolConfigOption()
701+ openid.openid_launchpad_teams_mapping = DictConfigOption()
702+ openid.openid_sreg_extra_fields = LinesConfigOption(
703+ item=StringConfigOption())
704+
705+ webcatalog = ConfigSection()
706+ webcatalog.serve_site_media = BoolConfigOption(default=True)
707+ webcatalog.sca_api_url = StringConfigOption()
708+ webcatalog.disk_apt_cache_location = StringConfigOption()
709+
710+ google = ConfigSection()
711+ google.google_analytics_id = StringConfigOption()
712+
713+ logging = ConfigSection()
714+ logging.webapp_logging_config = StringConfigOption()
715+
716+ # preflight
717+ preflight = ConfigSection()
718+ preflight.preflight_base_template = StringConfigOption(
719+ default="webcatalog/base.html")
720+
721+ #adminaudit
722+ adminaudit_emails_recipients = LinesConfigOption(
723+ item=StringConfigOption())
724+ adminaudit_summary_subject = StringConfigOption(
725+ default='Admin Audit Summary')
726
727=== renamed directory 'django_project/templates/light' => 'src/webcatalog/templates/light'
728=== added file 'src/webcatalog/wsgi.py'
729--- src/webcatalog/wsgi.py 1970-01-01 00:00:00 +0000
730+++ src/webcatalog/wsgi.py 2011-06-21 11:33:32 +0000
731@@ -0,0 +1,18 @@
732+import logging.config
733+import platform
734+
735+from canonical.oops.serializer import OOPSRFC822Serializer
736+from canonical.oops.wsgi import OopsWare
737+from django.core.handlers.wsgi import WSGIHandler
738+from django.conf import settings
739+
740+def make_app():
741+ """Encapsulate our webcatalog handler in an OOPS app for error reporting."""
742+ default_id = ''.join(x for x in platform.node() if x.isalpha())
743+ appserver_id = getattr(settings, 'APPSERVER_ID', default_id)
744+ logging.config.fileConfig(settings.WEBAPP_LOGGING_CONFIG)
745+ oops_dir = getattr(settings, 'OOPS_DIR', '/tmp')
746+ oops_app = OopsWare(WSGIHandler(), oops_dir=oops_dir,
747+ key=appserver_id, hide_meta=True)
748+ oops_app.serial = OOPSRFC822Serializer(appserver_id, oops_dir, None)
749+ return oops_app

Subscribers

People subscribed via source and target branches