switch from ddportfolio to debianmemberportfolio
[debianmemberportfolio.git] / debianmemberportfolio / controllers / portfolio.py
1 # -*- python -*-
2 # -*- coding: utf-8 -*-
3 #
4 # Debian Member Portfolio Service PortfolioController
5 #
6 # Copyright © 2009-2014 Jan Dittberner <jan@dittberner.info>
7 #
8 # This file is part of the Debian Member Portfolio Service.
9 #
10 # Debian Member Portfolio Service is free software: you can redistribute it
11 # and/or modify it under the terms of the GNU Affero General Public License as
12 # published by the Free Software Foundation, either version 3 of the License,
13 # or (at your option) any later version.
14 #
15 # Debian Member Portfolio Service is distributed in the hope that it will be
16 # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero
18 # General Public License for more details.
19 #
20 # You should have received a copy of the GNU Affero General Public License
21 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 #
23 """
24 This module defines the PortfolioController class used to render the portfolio
25 of a person.
26 """
27
28 import logging
29 import simplejson
30
31 from pylons import request, response, tmpl_context as c
32 from pylons.i18n import N_, _
33 import formencode.api
34 import formencode.validators
35
36 from debianmemberportfolio.lib.base import BaseController, render
37 from debianmemberportfolio.model.form import DDDataRequest, DeveloperData
38 from debianmemberportfolio.model.urlbuilder import build_urls
39 from debianmemberportfolio.model import dddatabuilder
40
41 log = logging.getLogger(__name__)
42
43
44 class PortfolioController(BaseController):
45     """
46     Main controller for the Debian Member Portfolio Service.
47     """
48     #: This dictionary defines groups of labeled portfolio items.
49     _LABELS = {
50         'overview': {
51             'label': N_('Overview'),
52             'ddpo': N_("Debian Member's Package Overview"),
53             'alladdresses': N_("""Debian Member's Package Overview
54 ... showing all email addresses"""),
55         },
56         'bugs': {
57             'label': N_('Bugs'),
58             'received': N_('''bugs received
59 (note: co-maintainers not listed, see \
60 <a href="http://bugs.debian.org/cgi-bin/bugreport.cgi?\
61 bug=430986">#430986</a>)'''),
62             'reported': N_('bugs reported'),
63             'usertags': N_('user tags'),
64             'searchall': N_('all messages (i.e., full text search for \
65 developer name on all bug logs)'),
66             'wnpp': N_('<a href="http://wiki.debian.org/WNPP">WNPP</a>'),
67             'correspondent': N_('correspondent for bugs'),
68             'graph': N_('one year open bug history graph'),
69         },
70         'build': {
71             'label': N_('Build'),
72             'buildd': N_('buildd.d.o'),
73             'igloo': N_('igloo'),
74         },
75         'qa': {
76             'label': N_('Quality Assurance'),
77             'dmd': N_('maintainer dashboard'),
78             'lintian': N_('lintian reports'),
79             'lintianfull': N_('full lintian reports (i.e. including \
80 "info"-level messages)'),
81             'piuparts': N_('piuparts'),
82             'patchtracker': N_('Debian patch tracking system'),
83             'duck': N_('Debian Url ChecKer'),
84         },
85         'lists': {
86             'label': N_('Mailing Lists'),
87             'dolists': N_('lists.d.o'),
88             'adolists': N_('lists.a.d.o'),
89             'gmane': N_('gmane'),
90         },
91         'files': {
92             'label': N_('Files'),
93             'people': N_('people.d.o'),
94             'oldpeople': N_('oldpeople'),
95             'alioth': N_('Alioth'),
96         },
97         'membership': {
98             'label': N_('Membership'),
99             'nm': N_('NM'),
100             'dbfinger': N_('DB information via finger'),
101             'db': N_('DB information via HTTP'),
102             'webid': N_('FOAF profile'),
103             'alioth': N_('Alioth'),
104             'wiki': N_('Wiki'),
105             'forum': N_('Forum'),
106         },
107         'miscellaneous': {
108             'label': N_('Miscellaneous'),
109             'debtags': N_('debtags'),
110             'planetname': N_('Planet Debian (name)'),
111             'planetuser': N_('Planet Debian (username)'),
112             'links': N_('links'),
113             'website': N_('Debian website'),
114             'search': N_('Debian search'),
115             'gpgfinger': N_('GPG public key via finger'),
116             'gpgweb': N_('GPG public key via HTTP'),
117             'nm': N_('NM, AM participation'),
118             'contrib': N_('Contribution information'),
119         },
120         'ssh': {
121             'label': N_('Information reachable via ssh (for Debian Members)'),
122             'owndndoms': N_('owned debian.net domains'),
123             'miainfo': N_('<a href="http://wiki.debian.org/qa.debian.org/'
124                           'MIATeam">MIA</a> database information'),
125             'groupinfo': N_('Group membership information'),
126         },
127         'ubuntu': {
128             'label': N_('Ubuntu'),
129             'ubuntudiff': N_('Available patches from Ubuntu'),
130         },
131     }
132
133     #: list of field name tuples for Debian Maintainers
134     DM_TUPLES = (('name', 'name'),
135                  ('gpgfp', 'gpgfp'),
136                  ('nonddemail', 'email'))
137
138     #: list of field name tuples for Debian Developers
139     DD_TUPLES = (('username', 'username'),
140                  ('aliothusername', 'username'))
141
142     def _get_label(self, section, url=None):
143         if section in self._LABELS:
144             if url:
145                 if url in self._LABELS[section]:
146                     return self._LABELS[section][url]
147             elif 'label' in self._LABELS[section]:
148                 return self._LABELS[section]['label']
149         if url:
150             return "%s.%s" % (section, url)
151         return section
152
153     def index(self):
154         """
155         Render the input form.
156         """
157         return render('/showform.mako')
158
159     def _build_request_params(self):
160         schema = DDDataRequest()
161         formencode.api.set_stdtranslation(
162             domain="FormEncode",
163             languages=[lang[0:2] for lang in request.languages])
164         form_result = schema.to_python(request.params)
165         fields = dddatabuilder.build_data(form_result['email'])
166         rp = request.params.copy()
167
168         if fields['type'] in (dddatabuilder.TYPE_DD, dddatabuilder.TYPE_DM):
169             for tuple in self.DM_TUPLES:
170                 if not tuple[0] in rp or not rp[tuple[0]]:
171                     rp[tuple[0]] = fields[tuple[1]]
172         if fields['type'] == dddatabuilder.TYPE_DD:
173             for tuple in self.DD_TUPLES:
174                 if not tuple[0] in rp or not rp[tuple[0]]:
175                     rp[tuple[0]] = fields[tuple[1]]
176
177         return rp
178
179     def urllist(self):
180         """Handle the actual data."""
181         try:
182             rp = self._build_request_params()
183         except formencode.validators.Invalid as error:
184             c.messages = {'errors': error.unpack_errors()}
185             return render('/showform.mako')
186
187         schema = DeveloperData()
188         try:
189             formencode.api.set_stdtranslation(
190                 domain="FormEncode",
191                 languages=[lang[0:2] for lang in request.languages])
192             form_result = schema.to_python(rp)
193         except formencode.validators.Invalid, error:
194             c.messages = {'errors': error.unpack_errors()}
195             return render('/showform.mako')
196         if form_result['wikihomepage'] is None:
197             log.debug('generate wikihomepage from name')
198             form_result['wikihomepage'] = "".join(
199                 [part.capitalize() for part in form_result['name'].split()])
200         data = build_urls(form_result)
201         if form_result['mode'] == 'json':
202             response.headers['Content-Type'] = 'text/javascript'
203             return simplejson.dumps(
204                 dict([("%s.%s" % (entry[1], entry[2].name), entry[3])
205                       for entry in data if entry[0] == 'url']))
206         for entry in data:
207             if entry[0] in ('url', 'error'):
208                 entry.append(_(self._get_label(entry[1], entry[2].name)))
209             elif entry[0] == 'section':
210                 entry.append(_(self._get_label(entry[1])))
211         c.urldata = data
212         return render('/showurls.mako')