def redirect(self, location, next_location=None): """Effect an http redirect to a new location.""" if next_location: url = lib.join_url(location, {"next": next_location}) else: url = location raise server.RedirectException, url
def handle_get(self, session_id, values, wfile): user = self.application.get_user(session_id) if user: status = values.pop("status", None) sort_by = values.pop("sort_by", None) order = values.pop("order", None) show_method_name = "_show_%s" % status if hasattr(self, show_method_name): show_method = getattr(self, show_method_name) templates.header(wfile) show_method(session_id, wfile, sort_by, order) templates.footer(wfile) else: templates.header(wfile) templates.title(wfile, "List bugs") templates.bullets( wfile, 'Each bug list is designed for a particular objective.', 'Use the <a href="/search">Search bugs</a> page ' 'for hand-crafted listings.') status_counts = self.application.get_status_counts(session_id) templates.list_form(wfile, self.path, status_counts) templates.footer(wfile) else: values["next"] = self.path path = lib.join_url(Login.path, values) self.redirect(path)
def handle_post(self, session_id, values, post_data, wfile): next_location = values.pop("next", None) or Home.path username = post_data.get("username", None) password = post_data.get("password", None) if username and password and \ self.application.login(session_id, username, password): path = lib.join_url(next_location, values) self.redirect(path) else: user = self.application.get_user(session_id) templates.header(wfile) templates.title(wfile, "Login failed!") if username: templates.paragraph( wfile, "You entered an incorrect password for user of username " "<b>%s</b>." % username) templates.paragraph( wfile, "Use the back-button of your browser to try again, " "or click below to request that your password be emailed " "to you.") templates.possible_actions( wfile, ("emailpassword?username=%s" % username, "Email me my password")) else: templates.paragraph( wfile, "You did not provide a username. " "Use the back-button of your browser to try again.") templates.footer(wfile)
def handle_get(self, session_id, values, wfile): user = self.application.get_user(session_id) if user: bug_id = values.get('bug_id') if bug_id: templates.header(wfile, "Bug %s" % bug_id) try: bug = self.application.get_bug(session_id, bug_id) templates.title(wfile, bug.title) self._show_status_and_comments_and_form(wfile, bug) except application.NoSuchBugException: templates.title(wfile, "No such Bug!") templates.paragraph( wfile, 'No bug with number = "%s" exists. ' % bug_id) else: templates.header(wfile) templates.title(wfile, "View particular bug") templates.paragraph( wfile, 'To view a particular bug, enter the bug ' 'number in the the "Find bug" box and either click ' 'the "Go" button or press return.') templates.paragraph( wfile, '(The "Find bug" box may be found in the header and ' 'the footer of every page.)') templates.footer(wfile) else: values["next"] = self.path path = lib.join_url(Login.path, values) self.redirect(path)
def handle_get(self, session_id, values, wfile): user = self.application.get_user(session_id) if user: templates.header(wfile) templates.title( wfile, "Daily progress") progress = self.application.bugs.summary.get_progress() if len(progress.rows) > 0: templates.bullets( wfile, "The following table summarises activity" " over the last %d days" % config.History.progress_max_age, "Each row displays the net change in the number of" " bugs in each status over each day.", "The table is updated every hour on the hour, so todays row" " potentially changes throughout the day.") templates.table_of_progress(wfile, progress) else: templates.paragraph( wfile, "No history available (yet).") templates.footer(wfile) else: values["next"] = self.path path = lib.join_url(Login.path, values) self.redirect(path)
def _sortable_table_headings(wfile, path, titles, variables, sorted_by, ordered): wfile.write(''' <tr>''') for heading, variable in zip(titles, variables): if variable == sorted_by: new_order = {"ascending": "descending", "descending": "ascending"}[ordered] else: new_order = "ascending" url = lib.html_entity_escape( lib.join_url(path, {"sort_by": variable, "order": new_order})) if variable == variables[-1]: css_class = "last-column-heading" else: css_class = "column-heading" wfile.write(''' <th class="%(css_class)s"> <a href="%(url)s"> %(heading)s </a>''' % {"heading": heading, "url": url, "css_class": css_class}) if variable == sorted_by: direction = {"ascending": "up", "descending": "down"}[ordered] wfile.write(''' <img src="/images?name=%(direction)s.gif" alt="%(direction)s"/>''' % {"direction": direction}) wfile.write(''' </th>''') wfile.write(''' </tr>''')
def _search(self, session_id, wfile, values): sort_by = values.pop("sort_by", "bug_id") order = values.pop("order", "ascending") criteria = {} columns = ["bug_id", "title"] for key, value in values.items(): if value: if key.endswith("_column"): columns.append(key[:-len("_column")]) else: criteria[key] = value search = application.Search(columns, sort_by, order, **criteria) try: self.application.search(session_id, search) templates.title(wfile, "Search result (%d)" % len(search.rows)) self._pretty_print_search(wfile, criteria, values) if search.rows: url = lib.join_url(self.path, values) templates.table_of_bugs(wfile, url, search) else: templates.paragraph( wfile, "No bugs match these criteria!") except application.InvalidSearchException, e: templates.title(wfile, "Invalid search criteria!") templates.paragraph( wfile, "Use the back-button of your browser " "to correct your search.") templates.paragraph( wfile, "Malformed regex expressions are a probable cause. " "For example, mismatched parentheses.")
def handle_get(self, session_id, values, wfile): user = self.application.get_user(session_id) if user: templates.header(wfile) templates.title(wfile, "Recent changes") sort_by = values.get("sort_by", "date") order = values.get("order", "descending") changes = self.application.bugs.changes.get_recent_changes( sort_by, order) if len(changes.rows) > 0: templates.bullets( wfile, "The following table displays the last" " %d days of changes made to bugs." % config.History.changes_max_age, "This includes the addition of new bugs.", "The table is updated every hour on the hour.") templates.table_of_changes(wfile, self.path, changes) else: templates.paragraph( wfile, "There have been no changes made in the last" " %d days." % config.History.changes_max_age) templates.footer(wfile) else: values["next"] = self.path path = lib.join_url(Login.path, values) self.redirect(path)
def handle_get(self, session_id, values, wfile): if "next" not in values: values["next"] = Home.path user = self.application.get_user(session_id) templates.header(wfile) templates.title(wfile, "User login") if user: templates.paragraph( wfile, 'Note that you are already logged in as ' '<b>%s</b> with a username of <b>%s</b>.' % (user.name, user.username)) templates.paragraph( wfile, 'To change user, enter a new username and password and click ' 'the "Login" button.') templates.login_form(wfile, self.path, self.application.usernames) else: path = lib.join_url(self.path, values) templates.paragraph( wfile, 'If you have not yet created a user account, ' 'do so now.') templates.possible_actions(wfile, ("adduser", "Create new account")) templates.login_form(wfile, path, self.application.usernames) templates.footer(wfile)
def _reload_if_url_can_be_simplified(self, values): new_values = {} for k,v in values.iteritems(): if v: new_values[k] = v if new_values != values: self.redirect(lib.join_url(self.path, new_values))
def handle_post(self, session_id, values, post_data, wfile): user = self.application.get_user(session_id) if user: templates.header(wfile, "Bug %s" % post_data.get("bug_id")) try: self._make_changes(session_id, user, post_data, wfile) except application.InvalidValueException: templates.title(wfile, "Unable to change bug!") templates.paragraph( wfile, 'One of the new values you have entered is invalid. ' 'Use the back-button of your browser to correct.') templates.footer(wfile) else: self.redirect(Login.path, lib.join_url(self.path, values))
def handle_get(self, session_id, values, wfile): user = self.application.get_user(session_id) if user: templates.header(wfile) templates.title(wfile, "History") templates.bullets( wfile, '<a href="/changes">Recent changes</a> made to bugs</a>,' ' including addition of new bugs.', '<a href="/progress">Daily progress</a>, as indicated' ' by changes in the number of bugs in each status</a>.') templates.footer(wfile) else: values["next"] = self.path path = lib.join_url(Login.path, values) self.redirect(path)
def handle_get(self, session_id, values, wfile): self._reload_if_url_can_be_simplified(values) user = self.application.get_user(session_id) if user: templates.header(wfile) if len(values) == 0: templates.title(wfile, "Search for bugs") self._search_form(wfile, values) elif "refine" in values: templates.title(wfile, "Refine search for bugs") self._search_form(wfile, values) else: self._search(session_id, wfile, values) templates.footer(wfile) else: self.redirect(Login.path, lib.join_url(self.path, values))
def _pretty_print_search(self, wfile, criteria, values): def clean_name(s): s = s.replace("regex", "(regex)") s = s.replace("_", " ") return s.capitalize() bullets = [] for k,v in criteria.iteritems(): bullets.append("%s = %s" % (clean_name(k),v)) copy_of_values = values.copy() copy_of_values["refine"] = "yes" url = lib.html_entity_escape(lib.join_url(self.path, copy_of_values)) bullets.append('<a href="%s">Refine search</a>' % url) templates.bullets(wfile, *bullets)
def _show_new(self, session_id, wfile, sort_by, order): if not sort_by: sort_by = "category" if not order: order = "ascending" search = application.Search( ("bug_id", "category", "reported_in", "title"), sort_by, order, status="new") self.application.search(session_id, search) templates.title(wfile, "All new bugs (%d)" % len(search.rows)) if search.rows: templates.bullets( wfile, "Bugs that are new and need to be reviewed.") url = lib.join_url(self.path, {"status": "new"}) templates.table_of_bugs(wfile, url, search) else: templates.paragraph(wfile, "There are no new bugs.")
def _show_closed(self, session_id, wfile, sort_by, order): if not sort_by: sort_by = "tested_ok_in" if not order: order = "ascending" search = application.Search( ("bug_id", "priority", "resolution", "category", "tested_ok_in", "title"), sort_by, order, status="closed") self.application.search(session_id, search) templates.title(wfile, "All closed bugs (%d)" % len(search.rows)) if search.rows: templates.bullets( wfile, "Bugs which require no further action.") url = lib.join_url(self.path, {"status": "closed"}) templates.table_of_bugs(wfile, url, search) else: templates.paragraph(wfile, "There are no closed bugs.")
def _show_reviewed(self, session_id, wfile, sort_by, order): if not sort_by: sort_by = "priority" if not order: order = "descending" search = application.Search( ("bug_id", "priority", "category", "reported_in", "title"), sort_by, order, status="reviewed") self.application.search(session_id, search) templates.title(wfile, "All reviewed bugs (%d)" % len(search.rows)) if search.rows: templates.bullets( wfile, "Bugs that are ready to be scheduled.") url = lib.join_url(self.path, {"status": "reviewed"}) templates.table_of_bugs(wfile, url, search) else: templates.paragraph(wfile, "There are no bugs in the reviewed state.")