diff --git a/ddportfolioservice/config/environment.py b/ddportfolioservice/config/environment.py index a1fe3ba..3d666fa 100644 --- a/ddportfolioservice/config/environment.py +++ b/ddportfolioservice/config/environment.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- # # DDPortfolio service environment configuration -# Copyright © 2009, 2010 Jan Dittberner +# Copyright © 2009, 2010, 2011, 2012 Jan Dittberner # # This file is part of DDPortfolio service. # @@ -31,9 +31,10 @@ import ddportfolioservice.lib.app_globals as app_globals import ddportfolioservice.lib.helpers from ddportfolioservice.config.routing import make_map + def load_environment(global_conf, app_conf): - """Configure the Pylons environment via the ``pylons.config`` - object + """ + Configure the Pylons environment via the ``pylons.config`` object """ config = PylonsConfig() @@ -45,7 +46,8 @@ def load_environment(global_conf, app_conf): templates=[os.path.join(root, 'templates')]) # Initialize config with the basic options - config.init_app(global_conf, app_conf, package='ddportfolioservice', paths=paths) + config.init_app( + global_conf, app_conf, package='ddportfolioservice', paths=paths) config['routes.map'] = make_map(config) config['pylons.app_globals'] = app_globals.Globals(config) @@ -54,7 +56,6 @@ def load_environment(global_conf, app_conf): # Setup cache object as early as possible import pylons pylons.cache._push_object(config['pylons.app_globals'].cache) - # Create the Mako TemplateLookup, with the default auto-escaping config['pylons.app_globals'].mako_lookup = TemplateLookup( diff --git a/ddportfolioservice/config/middleware.py b/ddportfolioservice/config/middleware.py index 6e87b2d..4f075ce 100644 --- a/ddportfolioservice/config/middleware.py +++ b/ddportfolioservice/config/middleware.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- # # DDPortfolio service middleware configuration -# Copyright © 2009, 2010 Jan Dittberner +# Copyright © 2009, 2010, 2011, 2012 Jan Dittberner # # This file is part of DDPortfolio service. # @@ -32,6 +32,7 @@ from routes.middleware import RoutesMiddleware from ddportfolioservice.config.environment import load_environment + def make_app(global_conf, full_stack=True, static_files=True, **app_conf): """Create a Pylons WSGI application and return it diff --git a/ddportfolioservice/config/routing.py b/ddportfolioservice/config/routing.py index d197181..196b33c 100644 --- a/ddportfolioservice/config/routing.py +++ b/ddportfolioservice/config/routing.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- # # DDPortfolio service routing configuration -# Copyright © 2009, 2010 Jan Dittberner +# Copyright © 2009, 2010, 2011, 2012 Jan Dittberner # # This file is part of DDPortfolio service. # @@ -28,6 +28,7 @@ refer to the routes manual at http://routes.groovie.org/docs/ """ from routes import Mapper + def make_map(config): """Create, configure and return the routes Mapper""" map = Mapper(directory=config['pylons.paths']['controllers'], diff --git a/ddportfolioservice/controllers/ddportfolio.py b/ddportfolioservice/controllers/ddportfolio.py index c3ee39c..7464345 100644 --- a/ddportfolioservice/controllers/ddportfolio.py +++ b/ddportfolioservice/controllers/ddportfolio.py @@ -35,91 +35,92 @@ from ddportfolioservice.model import dddatabuilder log = logging.getLogger(__name__) + class DdportfolioController(BaseController): _LABELS = { - 'overview' : { - 'label' : N_('Overview'), - 'ddpo' : N_("Debian Member's Package Overview"), - 'alladdresses' : N_("""Debian Member's Package Overview + 'overview': { + 'label': N_('Overview'), + 'ddpo': N_("Debian Member's Package Overview"), + 'alladdresses': N_("""Debian Member's Package Overview ... showing all email addresses"""), }, - 'bugs' : { - 'label' : N_('Bugs'), - 'received' : N_('''bugs received + 'bugs': { + 'label': N_('Bugs'), + 'received': N_('''bugs received (note: co-maintainers not listed, see \ #430986)'''), - 'reported' : N_('bugs reported'), - 'bugstats' : N_('bugstats AKA karma'), - 'usertags' : N_('user tags'), - 'searchall' : N_('all messages (i.e., full text search for \ + 'reported': N_('bugs reported'), + 'bugstats': N_('bugstats AKA karma'), + 'usertags': N_('user tags'), + 'searchall': N_('all messages (i.e., full text search for \ developer name on all bug logs)'), - 'wnpp' : N_('WNPP'), - 'correspondent' : N_('correspondent for bugs'), - 'graph' : N_('one year open bug history graph'), + 'wnpp': N_('WNPP'), + 'correspondent': N_('correspondent for bugs'), + 'graph': N_('one year open bug history graph'), }, - 'build' : { - 'label' : N_('Build'), - 'buildd' : N_('buildd.d.o'), - 'igloo' : N_('igloo'), + 'build': { + 'label': N_('Build'), + 'buildd': N_('buildd.d.o'), + 'igloo': N_('igloo'), }, - 'qa' : { - 'label' : N_('Quality Assurance'), - 'lintian' : N_('lintian reports'), - 'lintianfull' : N_('full lintian reports (i.e. including \ + 'qa': { + 'label': N_('Quality Assurance'), + 'lintian': N_('lintian reports'), + 'lintianfull': N_('full lintian reports (i.e. including \ "info"-level messages)'), - 'dehs' : N_('DEHS (Debian External Health Status)'), - 'piuparts' : N_('piuparts'), - 'patchtracker' : N_('Debian patch tracking system'), + 'dehs': N_('DEHS (Debian External Health Status)'), + 'piuparts': N_('piuparts'), + 'patchtracker': N_('Debian patch tracking system'), }, - 'upload' : { - 'label' : N_('Upload'), - 'keylog' : N_('''keylog (per-key upload list) + 'upload': { + 'label': N_('Upload'), + 'keylog': N_('''keylog (per-key upload list) (note: uses key fingerprint)'''), }, - 'lists' : { - 'label' : N_('Mailing Lists'), - 'dolists' : N_('lists.d.o'), - 'adolists' : N_('lists.a.d.o'), - 'gmane' : N_('gmane'), + 'lists': { + 'label': N_('Mailing Lists'), + 'dolists': N_('lists.d.o'), + 'adolists': N_('lists.a.d.o'), + 'gmane': N_('gmane'), }, - 'files' : { - 'label' : N_('Files'), - 'people' : N_('people.d.o'), - 'oldpeople' : N_('oldpeople'), - 'alioth' : N_('Alioth'), + 'files': { + 'label': N_('Files'), + 'people': N_('people.d.o'), + 'oldpeople': N_('oldpeople'), + 'alioth': N_('Alioth'), }, - 'membership' : { - 'label' : N_('Membership'), - 'nm' : N_('NM'), - 'dbfinger' : N_('DB information via finger'), - 'db' : N_('DB information via HTTP'), - 'alioth' : N_('Alioth'), - 'wiki' : N_('Wiki'), - 'forum' : N_('Forum'), + 'membership': { + 'label': N_('Membership'), + 'nm': N_('NM'), + 'dbfinger': N_('DB information via finger'), + 'db': N_('DB information via HTTP'), + 'alioth': N_('Alioth'), + 'wiki': N_('Wiki'), + 'forum': N_('Forum'), }, - 'miscellaneous' : { - 'label' : N_('Miscellaneous'), - 'debtags' : N_('debtags'), - 'links' : N_('links'), - 'website' : N_('Debian website'), - 'search' : N_('Debian search'), - 'gpgfinger' : N_('GPG public key via finger'), - 'gpgweb' : N_('GPG public key via HTTP'), + 'miscellaneous': { + 'label': N_('Miscellaneous'), + 'debtags': N_('debtags'), + 'links': N_('links'), + 'website': N_('Debian website'), + 'search': N_('Debian search'), + 'gpgfinger': N_('GPG public key via finger'), + 'gpgweb': N_('GPG public key via HTTP'), }, - 'ssh' : { - 'label' : N_('Information reachable via ssh (for Debian Members)'), - 'owndndoms' : N_('owned debian.net domains'), - 'miainfo' : N_('MIA database information'), - 'groupinfo' : N_('Group membership information'), + 'ssh': { + 'label': N_('Information reachable via ssh (for Debian Members)'), + 'owndndoms': N_('owned debian.net domains'), + 'miainfo': N_('MIA database information'), + 'groupinfo': N_('Group membership information'), }, - 'ubuntu' : { - 'label' : N_('Ubuntu'), - 'ubuntudiff' : N_('Available patches from Ubuntu'), + 'ubuntu': { + 'label': N_('Ubuntu'), + 'ubuntudiff': N_('Available patches from Ubuntu'), }, } - def _get_label(self, section, url=None): if section in self._LABELS: if url: @@ -132,9 +133,9 @@ developer name on all bug logs)'), return section def index(self): - # Return a rendered template - # return render('/some/template.mako') - # or, Return a response + """ + Render the input form. + """ return render('/showform.mako') def urllist(self): @@ -146,7 +147,7 @@ developer name on all bug logs)'), languages=[lang[0:2] for lang in request.languages]) form_result = schema.to_python(request.params) except formencode.validators.Invalid, error: - c.messages = { 'errors' : error.unpack_errors() } + c.messages = {'errors': error.unpack_errors()} return render('/showform.mako') fields = dddatabuilder.build_data(form_result['email']) rp = request.params.copy() @@ -173,7 +174,7 @@ developer name on all bug logs)'), languages=[lang[0:2] for lang in request.languages]) form_result = schema.to_python(rp) except formencode.validators.Invalid, error: - c.messages = { 'errors' : error.unpack_errors() } + c.messages = {'errors': error.unpack_errors()} return render('/showform.mako') if form_result['wikihomepage'] is None: log.debug('generate wikihomepage from name') diff --git a/ddportfolioservice/controllers/error.py b/ddportfolioservice/controllers/error.py index c20d41e..67bc56d 100644 --- a/ddportfolioservice/controllers/error.py +++ b/ddportfolioservice/controllers/error.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- # # DDPortfolio service ErrorController -# Copyright © 2009, 2010 Jan Dittberner +# Copyright © 2009, 2010, 2011, 2012 Jan Dittberner # # This file is part of DDPortfolio service. # @@ -30,8 +30,8 @@ from webhelpers.html.builder import literal from ddportfolioservice.lib.base import BaseController -class ErrorController(BaseController): +class ErrorController(BaseController): """Generates error documents as and when they are required. The ErrorDocuments middleware forwards to ErrorController when error @@ -39,16 +39,17 @@ class ErrorController(BaseController): This behaviour can be altered by changing the parameters to the ErrorDocuments middleware in your config/middleware.py file. - """ def document(self): """Render the error document""" resp = request.environ.get('pylons.original_response') - content = literal(resp.body) or cgi.escape(request.GET.get('message', '')) + content = literal(resp.body) or cgi.escape( + request.GET.get('message', '')) page = error_document_template % \ dict(prefix=request.environ.get('SCRIPT_NAME', ''), - code=cgi.escape(request.GET.get('code', str(resp.status_int))), + code=cgi.escape( + request.GET.get('code', str(resp.status_int))), message=content) return page @@ -61,8 +62,9 @@ class ErrorController(BaseController): return self._serve_file('/'.join(['media/style', id])) def _serve_file(self, path): - """Call Paste's FileApp (a WSGI application) to serve the file - at the specified path + """ + Call Paste's FileApp (a WSGI application) to serve the file at + the specified path """ request.environ['PATH_INFO'] = '/%s' % path return forward(PkgResourcesParser('pylons', 'pylons')) diff --git a/ddportfolioservice/controllers/showformscripts.py b/ddportfolioservice/controllers/showformscripts.py index 9e2980c..6b826bf 100644 --- a/ddportfolioservice/controllers/showformscripts.py +++ b/ddportfolioservice/controllers/showformscripts.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- # # DDPortfolio service ShowformscriptController. -# Copyright © 2009, 2010 Jan Dittberner +# Copyright © 2009, 2010, 2011, 2012 Jan Dittberner # # This file is part of DDPortfolio service. # @@ -34,6 +34,7 @@ from ddportfolioservice.model import dddatabuilder log = logging.getLogger(__name__) + class ShowformscriptsController(BaseController): """This controller is used to support data entry in showform. @@ -41,12 +42,17 @@ class ShowformscriptsController(BaseController): responses for autocompletion of fields.""" def index(self): - """This action generates the helper script for the showform - page.""" + """ + This action generates the helper script for the showform page. + """ response.headers['Content-Type'] = 'text/javascript; charset=utf-8' return render('/showformscript.mako') def fetchdddata(self): + """ + This action fetches the data for a given mail address and + returns them as JSON. + """ schema = DDDataRequest() try: formencode.api.set_stdtranslation( diff --git a/ddportfolioservice/controllers/template.py b/ddportfolioservice/controllers/template.py index 0cc70b2..ce5352c 100644 --- a/ddportfolioservice/controllers/template.py +++ b/ddportfolioservice/controllers/template.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- # # DDPortfolio service TemplateController -# Copyright © 2009, 2010 Jan Dittberner +# Copyright © 2009, 2010, 2011, 2012 Jan Dittberner # # This file is part of DDPortfolio service. # @@ -22,6 +22,7 @@ # from ddportfolioservice.lib.base import BaseController + class TemplateController(BaseController): def view(self, url): diff --git a/ddportfolioservice/lib/app_globals.py b/ddportfolioservice/lib/app_globals.py index e66df3d..e39071d 100644 --- a/ddportfolioservice/lib/app_globals.py +++ b/ddportfolioservice/lib/app_globals.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- # # DDPortfolio service application Globals -# Copyright © 2009, 2010 Jan Dittberner +# Copyright © 2009, 2010, 2011, 2012 Jan Dittberner # # This file is part of DDPortfolio service. # @@ -25,17 +25,17 @@ from beaker.cache import CacheManager from beaker.util import parse_cache_config_options + class Globals(object): - - """Globals acts as a container for objects available throughout the + """ + Globals acts as a container for objects available throughout the life of the application - """ def __init__(self, config): - """One instance of Globals is created during application + """ + One instance of Globals is created during application initialization and is available during requests via the 'app_globals' variable - """ self.cache = CacheManager(**parse_cache_config_options(config)) diff --git a/ddportfolioservice/lib/base.py b/ddportfolioservice/lib/base.py index 24d0cc4..4a93095 100644 --- a/ddportfolioservice/lib/base.py +++ b/ddportfolioservice/lib/base.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- # # DDPortfolio service base controller -# Copyright © 2009, 2010 Jan Dittberner +# Copyright © 2009, 2010, 2011, 2012 Jan Dittberner # # This file is part of DDPortfolio service. # @@ -29,6 +29,7 @@ from pylons.controllers import WSGIController from pylons.i18n import add_fallback from pylons.templating import render_mako as render + class BaseController(WSGIController): def __call__(self, environ, start_response): @@ -42,5 +43,5 @@ class BaseController(WSGIController): add_fallback(lang) except: pass - c.messages = { 'errors': [], 'messages': [] } + c.messages = {'errors': [], 'messages': []} return WSGIController.__call__(self, environ, start_response) diff --git a/ddportfolioservice/model/form.py b/ddportfolioservice/model/form.py index 3f672fb..fb9e2dc 100644 --- a/ddportfolioservice/model/form.py +++ b/ddportfolioservice/model/form.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- # # DDPortfolio service form handling model -# Copyright © 2009, 2010 Jan Dittberner +# Copyright © 2009, 2010, 2011, 2012 Jan Dittberner # # This file is part of DDPortfolio service. # @@ -22,6 +22,7 @@ # import formencode + class DeveloperData(formencode.Schema): """Validation schema for DeveloperData.""" allow_extra_fields = True diff --git a/ddportfolioservice/model/keyfinder.py b/ddportfolioservice/model/keyfinder.py index ba60228..d857f4d 100644 --- a/ddportfolioservice/model/keyfinder.py +++ b/ddportfolioservice/model/keyfinder.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- # # DDPortfolio service key finder module -# Copyright (c) 2009 Jan Dittberner +# Copyright (c) 2009, 2010, 2011, 2012 Jan Dittberner # # This file is part of DDPortfolio service. # @@ -30,6 +30,7 @@ import time db = None cachetimestamp = 0 + def _get_keyring_cache(): global db, cachetimestamp if db is None or (time.time() - cachetimestamp) > 86300: @@ -44,6 +45,7 @@ def _get_keyring_cache(): cachetimestamp = time.time() return db + def _get_cached(cachekey): cache = _get_keyring_cache() logging.debug('cache lookup for %s', cachekey) @@ -52,25 +54,33 @@ def _get_cached(cachekey): return cache[cachekey] return None + def getFingerprintByEmail(email): - """Gets the fingerprints associated with the given email address - if available.""" + """ + Gets the fingerprints associated with the given email address if + available. + """ return _get_cached('fpr:email:%s' % email) def getRealnameByEmail(email): - """Gets the real names associated with the given email address if - available.""" + """ + Gets the real names associated with the given email address if + available. + """ return _get_cached('name:email:%s' % email) def getLoginByEmail(email): - """Gets the logins associated with the given email address if - available.""" + """ + Gets the logins associated with the given email address if + available. + """ return _get_cached('login:email:%s' % email) def getLoginByFingerprint(fpr): - """Gets the login associated with the given fingerprint if - available.""" + """ + Gets the login associated with the given fingerprint if available. + """ return _get_cached('login:fpr:%s' % fpr) diff --git a/ddportfolioservice/model/keyringanalyzer.py b/ddportfolioservice/model/keyringanalyzer.py index dc847d3..cc501c6 100644 --- a/ddportfolioservice/model/keyringanalyzer.py +++ b/ddportfolioservice/model/keyringanalyzer.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- # # DDPortfolio service application key ring analyzer tool -# Copyright © 2009, 2010 Jan Dittberner +# Copyright © 2009, 2010, 2011, 2012 Jan Dittberner # # This file is part of DDPortfolio service. # @@ -38,10 +38,13 @@ import sys def _get_keyrings(): - """Gets the available keyring files from the keyring directory - configured in ddportfolio.ini.""" + """ + Gets the available keyring files from the keyring directory + configured in ddportfolio.ini. + """ my_config = ConfigParser.ConfigParser() - my_config.readfp(pkg_resources.resource_stream(__name__, 'ddportfolio.ini')) + my_config.readfp(pkg_resources.resource_stream( + __name__, 'ddportfolio.ini')) keyringdir = os.path.expanduser(my_config.get('DEFAULT', 'keyring.dir')) logging.debug("keyring dir is %s", keyringdir) keyrings = glob.glob(os.path.join(keyringdir, '*.gpg')) @@ -51,20 +54,22 @@ def _get_keyrings(): def _parse_uid(uid): - """Parse a uid of the form 'Real Name ' into - email and realname parts.""" + """ + Parse a uid of the form 'Real Name ' into email + and realname parts. + """ uid = uid.strip() - # First, strip comment + # First, strip comment s = uid.find('(') e = uid.find(')') if s >= 0 and e >= 0: - uid = uid[:s] + uid[e+1:] + uid = uid[:s] + uid[e + 1:] s = uid.find('<') e = uid.find('>') email = None if s >= 0 and e >= 0: - email = uid[s+1:e] - uid = uid[:s] + uid[e+1:] + email = uid[s + 1:e] + uid = uid[:s] + uid[e + 1:] uid = uid.strip() if not email and uid.find('@') >= 0: email, uid = uid, email @@ -72,6 +77,7 @@ def _parse_uid(uid): resultdict = {} + def _get_canonical(key): if not key in resultdict: resultdict[key] = [] @@ -96,7 +102,7 @@ def process_keyrings(): stdout=subprocess.PIPE) fpr = None entry = None - lastpub = None + lastpub = None for line in proc.stdout.readlines(): items = line.split(':') uid = None diff --git a/ddportfolioservice/model/urlbuilder.py b/ddportfolioservice/model/urlbuilder.py index f374fa4..966ebed 100644 --- a/ddportfolioservice/model/urlbuilder.py +++ b/ddportfolioservice/model/urlbuilder.py @@ -2,7 +2,7 @@ # -*- coding: utf8 -*- # # DDPortfolio service url builder -# Copyright © 2009, 2010, 2012 Jan Dittberner +# Copyright © 2009, 2010, 2011, 2012 Jan Dittberner # # This file is part of DDPortfolio service. # @@ -37,12 +37,12 @@ my_config = ConfigParser() my_config.readfp(pkg_resources.resource_stream(__name__, 'ddportfolio.ini')) _FIELDNAMES_MAP = { - 'email' : N_('Email address'), - 'name' : N_('Name'), - 'gpgfp' : N_('GPG fingerprint'), - 'username' : N_('Debian user name'), - 'nonddemail' : N_('Non Debian email address'), - 'aliothusername' : N_('Alioth user name'), + 'email': N_('Email address'), + 'name': N_('Name'), + 'gpgfp': N_('GPG fingerprint'), + 'username': N_('Debian user name'), + 'nonddemail': N_('Non Debian email address'), + 'aliothusername': N_('Alioth user name'), } @@ -82,8 +82,9 @@ def build_urls(fields): 'urlbuilder.sections').split(',')]: data.append(['section', section]) if my_config.has_option(section, 'urls'): - for entry in ([DDPortfolioEntry(my_config, section, url) for url in \ - my_config.get(section, 'urls').split(',')]): + for entry in ([ + DDPortfolioEntry(my_config, section, url) for url in \ + my_config.get(section, 'urls').split(',')]): try: data.append( ['url', section, entry, diff --git a/ddportfolioservice/tests/__init__.py b/ddportfolioservice/tests/__init__.py index 4e03c0c..0e1d22f 100644 --- a/ddportfolioservice/tests/__init__.py +++ b/ddportfolioservice/tests/__init__.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- # # DDPortfolio service tests package -# Copyright © 2009, 2010 Jan Dittberner +# Copyright © 2009, 2010, 2011, 2012 Jan Dittberner # # This file is part of DDPortfolio service. # @@ -49,6 +49,7 @@ SetupCommand('setup-app').run([pylons.test.pylonsapp.config['__file__']]) environ = {} + class TestController(TestCase): def __init__(self, *args, **kwargs): diff --git a/ddportfolioservice/tests/functional/test_showformscripts.py b/ddportfolioservice/tests/functional/test_showformscripts.py index 3302743..b8b3347 100644 --- a/ddportfolioservice/tests/functional/test_showformscripts.py +++ b/ddportfolioservice/tests/functional/test_showformscripts.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- # # DDPortfolio service DdportfolioController test -# Copyright © 2009, 2010 Jan Dittberner +# Copyright © 2009, 2010, 2011, 2012 Jan Dittberner # # This file is part of DDPortfolio service. # @@ -22,8 +22,10 @@ # from ddportfolioservice.tests import TestController, url + class TestShowformscriptsController(TestController): def test_index(self): - response = self.app.get(url(controller='showformscripts', action='index')) + response = self.app.get( + url(controller='showformscripts', action='index')) # Test response... diff --git a/ddportfolioservice/websetup.py b/ddportfolioservice/websetup.py index 2a52f84..355544e 100644 --- a/ddportfolioservice/websetup.py +++ b/ddportfolioservice/websetup.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- # # DDPortfolio service websetup -# Copyright (c) 2009 Jan Dittberner +# Copyright (c) 2009, 2010, 2011, 2012 Jan Dittberner # # This file is part of DDPortfolio service. # @@ -31,6 +31,7 @@ from ddportfolioservice.config.environment import load_environment log = logging.getLogger(__name__) + def setup_config(command, filename, section, vars): """Place any commands to setup ddportfolioservice here""" conf = appconfig('config:' + filename)