5 from turbogears import controllers, expose, validate, redirect, identity
7 from libbe.bugdir import tree_root, NoRootEntry
8 from config import projects
9 from prest import PrestHandler, provide_action
12 from beweb import json
14 log = logging.getLogger("beweb.controllers")
16 def project_tree(project):
18 return tree_root(projects[project][1])
20 raise Exception("Unknown project %s" % project)
22 def comment_url(project, bug, comment, **kwargs):
23 return turbogears.url("/project/%s/bug/%s/comment/%s" %
24 (project, bug, comment), kwargs)
26 class Comment(PrestHandler):
27 @identity.require( identity.has_permission("editbugs"))
28 @provide_action("action", "New comment")
29 def new_comment(self, comment_data, comment, *args, **kwargs):
30 bug_tree = project_tree(comment_data['project'])
31 bug = bug_tree.get_bug(comment_data['bug'])
32 comment = new_comment(bug, "")
33 comment.From = identity.current.user.userId
34 comment.content_type = "text/restructured"
36 raise cherrypy.HTTPRedirect(comment_url(comment=comment.uuid,
39 @identity.require( identity.has_permission("editbugs"))
40 @provide_action("action", "Reply")
41 def reply_comment(self, comment_data, comment, *args, **kwargs):
42 bug_tree = project_tree(comment_data['project'])
43 bug = bug_tree.get_bug(comment_data['bug'])
44 reply_comment = new_comment(bug, "")
45 reply_comment.From = identity.current.user.userId
46 reply_comment.in_reply_to = comment.uuid
48 reply_data = dict(comment_data)
49 del reply_data["comment"]
50 raise cherrypy.HTTPRedirect(comment_url(comment=reply_comment.uuid,
53 @identity.require( identity.has_permission("editbugs"))
54 @provide_action("action", "Update")
55 def update(self, comment_data, comment, comment_body, *args, **kwargs):
56 comment.body = comment_body
58 raise cherrypy.HTTPRedirect(bug_url(comment_data['project'],
61 def instantiate(self, project, bug, comment):
62 bug_tree = project_tree(project)
63 bug = bug_tree.get_bug(bug)
64 return bug.get_comment(comment)
66 def dispatch(self, comment_data, comment, *args, **kwargs):
67 return self.edit_comment(comment_data['project'], comment)
69 @turbogears.expose(html="beweb.templates.edit_comment")
70 def edit_comment(self, project, comment):
71 return {"comment": comment, "project_id": project}
73 class Bug(PrestHandler):
75 @turbogears.expose(html="beweb.templates.edit_bug")
76 def index(self, project, bug):
77 return {"bug": bug, "project_id": project}
79 def dispatch(self, bug_data, bug, *args, **kwargs):
81 return self.list(bug_data['project'], **kwargs)
83 return self.index(bug_data['project'], bug)
85 @turbogears.expose(html="beweb.templates.bugs")
86 def list(self, project, sort_by=None, show_closed=False, action=None,
88 if action == "New bug":
90 if show_closed == "False":
92 bug_tree = project_tree(project)
93 bugs = list(bug_tree.list())
96 return {"project_id" : project,
97 "project_name" : projects[project][0],
99 "show_closed" : show_closed,
103 @identity.require( identity.has_permission("editbugs"))
104 @provide_action("action", "New bug")
105 def new_bug(self, bug_data, bug, **kwargs):
106 bug = project_tree(bug_data['project']).new_bug()
107 bug.creator = identity.current.user.userId
109 raise cherrypy.HTTPRedirect(bug_url(bug_data['project'], bug.uuid))
111 @identity.require( identity.has_permission("editbugs"))
112 @provide_action("action", "Update")
113 def update(self, bug_data, bug, status, severity, summary, assigned,
116 bug.severity = severity
117 bug.summary = summary
120 bug.assigned = assigned
122 # bug.rcs.precommit(bug.path)
123 # bug.rcs.commit(bug.path, "Auto-commit")
124 # bug.rcs.postcommit(bug.path)
125 raise cherrypy.HTTPRedirect(bug_list_url(bug_data["project"]))
127 def instantiate(self, project, bug):
128 return project_tree(project).get_bug(bug)
130 @provide_action("action", "New comment")
131 def new_comment(self, bug_data, bug, *args, **kwargs):
133 self.update(bug_data, bug, *args, **kwargs)
134 except cherrypy.HTTPRedirect:
136 return self.comment.new_comment(bug_data, comment=None, *args,
140 def project_url(project_id=None):
141 project_url = "/project/"
142 if project_id is not None:
143 project_url += "%s/" % project_id
144 return turbogears.url(project_url)
146 def bug_url(project_id, bug_uuid=None):
147 bug_url = "/project/%s/bug/" % project_id
148 if bug_uuid is not None:
149 bug_url += "%s/" % bug_uuid
150 return turbogears.url(bug_url)
152 def bug_list_url(project_id, show_closed=False, search=None):
153 bug_url = "/project/%s/bug/?show_closed=%s" % (project_id,
155 if search is not None:
156 bug_url = "%s&search=%s" % (bug_url, search)
157 return turbogears.url(str(bug_url))
160 class Project(PrestHandler):
162 @turbogears.expose(html="beweb.templates.projects")
163 def dispatch(self, project_data, project, *args, **kwargs):
164 if project is not None:
165 raise cherrypy.HTTPRedirect(bug_url(project))
167 return {"projects": projects}
169 def instantiate(self, project):
173 class Root(controllers.Root):
174 prest = PrestHandler()
175 prest.project = Project()
178 raise cherrypy.HTTPRedirect(project_url())
180 @expose(template="beweb.templates.login")
181 def login(self, forward_url=None, previous_url=None, *args, **kw):
183 if not identity.current.anonymous and identity.was_login_attempted():
184 raise redirect(forward_url)
187 previous_url= cherrypy.request.path
189 if identity.was_login_attempted():
190 msg=_("The credentials you supplied were not correct or "\
191 "did not grant access to this resource.")
192 elif identity.get_identity_errors():
193 msg=_("You must provide your credentials before accessing "\
196 msg=_("Please log in.")
197 forward_url= cherrypy.request.headers.get("Referer", "/")
198 cherrypy.response.status=403
199 return dict(message=msg, previous_url=previous_url, logging_in=True,
200 original_parameters=cherrypy.request.params,
201 forward_url=forward_url)
205 identity.current.logout()
208 @turbogears.expose('beweb.templates.about')
209 def about(self, *paths, **kwargs):
213 def default(self, *args, **kwargs):
214 return self.prest.default(*args, **kwargs)
216 def _cp_on_error(self):
217 import traceback, StringIO
218 bodyFile = StringIO.StringIO()
219 traceback.print_exc(file = bodyFile)
220 trace_text = bodyFile.getvalue()
223 except cherrypy.NotFound:
224 self.handle_error('Not Found', str(e), trace_text, '404 Not Found')
226 except NoRootEntry, e:
227 self.handle_error('Project Misconfiguration', str(e), trace_text)
230 self.handle_error('Internal server error', str(e), trace_text)
232 def handle_error(self, heading, body, traceback=None,
233 status='500 Internal Server Error'):
234 cherrypy.response.headerMap['Status'] = status
235 cherrypy.response.body = [self.errorpage(heading, body, traceback)]
238 @turbogears.expose(html='beweb.templates.error')
239 def errorpage(self, heading, body, traceback):
240 return {'heading': heading, 'body': body, 'traceback': traceback}