source: worklogplugin/trunk/worklog/webui.py

Last change on this file was 15698, checked in by Ryan J Ollos, 7 years ago

1.0dev: Add file headers

Refs #12845.

  • Property svn:eol-style set to native
File size: 5.9 KB
Line 
1# -*- coding: utf-8 -*-
2#
3# Copyright (c) 2007-2012 Colin Guthrie <trac@colin.guthr.ie>
4# Copyright (c) 2011-2016 Ryan J Ollos <ryan.j.ollos@gmail.com>
5# All rights reserved.
6#
7# This software is licensed as described in the file COPYING, which
8# you should have received as part of this distribution.
9
10import csv
11import re
12from StringIO import StringIO
13
14from trac.core import *
15from trac.perm import IPermissionRequestor
16from trac.util import Markup
17from trac.web import IRequestHandler
18from trac.web.chrome import (
19    INavigationContributor, ITemplateProvider, add_stylesheet
20)
21
22from manager import WorkLogManager
23from usermanual import *
24
25
26class WorkLogPage(Component):
27
28    implements(IPermissionRequestor, INavigationContributor,
29               IRequestHandler, ITemplateProvider)
30
31    # IPermissionRequestor methods
32
33    def get_permission_actions(self):
34        return ['WORK_LOG', ('WORK_VIEW', ['WORK_LOG']),
35                ('WORK_ADMIN', ['WORK_VIEW'])]
36
37    # INavigationContributor methods
38
39    def get_active_navigation_item(self, req):
40        return 'worklog'
41
42    def get_navigation_items(self, req):
43        url = req.href.worklog()
44        if req.perm.has_permission("WORK_VIEW"):
45            yield 'mainnav', "worklog", \
46                  Markup('<a href="%s">%s</a>'
47                         % (url, "Work Log"))
48
49    # Internal Methods
50
51    def worklog_csv(self, req, log):
52        req.send_header('Content-Type', 'text/csv;charset=utf-8')
53        req.send_header('Content-Disposition', 'filename=worklog.csv')
54
55        # Headers
56        fields = ['user',
57                  'name',
58                  'starttime',
59                  'endtime',
60                  'ticket',
61                  'summary',
62                  'comment']
63        sep = ','
64
65        content = StringIO()
66        writer = csv.writer(content, delimiter=sep, quoting=csv.QUOTE_MINIMAL)
67        writer.writerow([unicode(c).encode('utf-8') for c in fields])
68
69        # Rows
70        for row in log:
71            values = []
72            for field in fields:
73                values.append(unicode(row[field]).encode('utf-8'))
74            writer.writerow(values)
75
76        req.send_header('Content-Length', content.len)
77        req.write(content.getvalue())
78
79    # IRequestHandler methods
80
81    def match_request(self, req):
82        if re.search('^/worklog', req.path_info):
83            return True
84        return None
85
86    def process_request(self, req):
87        req.perm.require('WORK_VIEW')
88
89        messages = []
90
91        def addMessage(s):
92            messages.extend([s])
93
94        # General protection (not strictly needed if Trac behaves itself)
95        if not re.search('/worklog', req.path_info):
96            return None
97
98        add_stylesheet(req, "worklog/worklogplugin.css")
99
100        # Specific pages:
101        match = re.search('/worklog/users/(.*)', req.path_info)
102        if match:
103            mgr = WorkLogManager(self.env, self.config, match.group(1))
104            if 'format' in req.args and req.args['format'] == 'csv':
105                self.worklog_csv(req, mgr.get_work_log('user'))
106                return None
107
108            data = {
109                'worklog': mgr.get_work_log('user'),
110                'ticket_href': req.href.ticket(),
111                'usermanual_href': req.href.wiki(user_manual_wiki_title),
112                'usermanual_title': user_manual_title
113            }
114            return 'worklog_user.html', data, None
115
116        match = re.search('/worklog/stop/([0-9]+)', req.path_info)
117        if match:
118            ticket = match.group(1)
119            data = {'worklog_href': req.href.worklog(),
120                    'ticket_href':  req.href.ticket(ticket),
121                    'ticket':       ticket,
122                    'action':       'stop',
123                    'label':        'Stop Work'}
124            xhr = req.get_header('X-Requested-With') == 'XMLHttpRequest'
125            if xhr:
126                data['xhr'] = True
127            return 'worklog_stop.html', data, None
128
129        mgr = WorkLogManager(self.env, self.config, req.authname)
130        if 'format' in req.args and req.args['format'] == 'csv':
131            self.worklog_csv(req, mgr.get_work_log())
132            return None
133
134        # Not any specific page, so process POST actions here.
135        if req.method == 'POST':
136            if 'startwork' in req.args and 'ticket' in req.args:
137                if not mgr.start_work(req.args['ticket']):
138                    addMessage(mgr.get_explanation())
139                else:
140                    addMessage('You are now working on ticket #%s.'
141                               % (req.args['ticket'],))
142
143                req.redirect(req.args['source_url'])
144                return None
145            elif 'stopwork' in req.args:
146                stoptime = None
147                if 'stoptime' in req.args and req.args['stoptime']:
148                    stoptime = int(req.args['stoptime'])
149
150                comment = ''
151                if 'comment' in req.args:
152                    comment = req.args['comment']
153
154                if not mgr.stop_work(stoptime, comment):
155                    addMessage(mgr.get_explanation())
156                else:
157                    addMessage('You have stopped working.')
158
159                req.redirect(req.args['source_url'])
160                return None
161
162        # no POST, so they're just wanting a list of the worklog entries
163        data = {"messages": messages,
164                "worklog": mgr.get_work_log('summary'),
165                "worklog_href": req.href.worklog(),
166                "ticket_href": req.href.ticket(),
167                "usermanual_href": req.href.wiki(user_manual_wiki_title),
168                "usermanual_title": user_manual_title
169                }
170        return 'worklog.html', data, None
171
172    # ITemplateProvider methods
173
174    def get_htdocs_dirs(self):
175        from pkg_resources import resource_filename
176        return [('worklog', resource_filename(__name__, 'htdocs'))]
177
178    def get_templates_dirs(self):
179        from pkg_resources import resource_filename
180        return [resource_filename(__name__, 'templates')]
Note: See TracBrowser for help on using the repository browser.