def setMilestoneDate(self, db, milestone, date_attr_name, t): old_t = self.getMilestoneDate(db, milestone, date_attr_name) if old_t and old_t > 0: raise TracError( "Milestone '%s' was already %s on %s" % (milestone, date_attr_name, format_date(int(old_t)))) cursor = db.cursor() sql = "UPDATE milestone SET " + date_attr_name + "=%s WHERE name=%s" cursor.execute(sql, (str(int(t)), milestone)) db.commit()
def setMilestoneDate(self, db, milestone, date_attr_name, t): old_t = self.getMilestoneDate(db, milestone, date_attr_name) if old_t and old_t > 0: raise TracError( "Milestone '%s' was already %s on %s" % (milestone, date_attr_name, format_date(int(old_t))) ) cursor = db.cursor() sql = "UPDATE milestone SET " + date_attr_name + "=%s WHERE name=%s" cursor.execute(sql, (str(int(t)), milestone)) db.commit()
def update_burndown_data(self): db = self.env.get_db_cnx() cursor = db.cursor() # today's date today = format_date(int(time.time())) milestones = dbhelper.get_milestones(db) components = dbhelper.get_components(db) for mile in milestones: if mile['started'] and not mile['completed']: # milestone started, but not completed for comp in components: sqlSelect = "SELECT est.value AS estimate, ts.value AS spent "\ "FROM ticket t "\ " LEFT OUTER JOIN ticket_custom est ON (t.id = est.ticket AND est.name = 'estimatedhours') "\ " LEFT OUTER JOIN ticket_custom ts ON (t.id = ts.ticket AND ts.name = 'totalhours') "\ "WHERE t.component = %s AND t.milestone = %s"\ " AND status IN ('new', 'assigned', 'reopened', 'accepted') " cursor.execute(sqlSelect, [comp['name'], mile['name']]) rows = cursor.fetchall() hours = 0 estimate = 0 spent = 0 if rows: for estimate, spent in rows: if not estimate: estimate = 0 if not spent: spent = 0 if (float(estimate) - float(spent)) > 0: hours += float(estimate) - float(spent) cursor.execute("SELECT id FROM burndown WHERE date = %s AND milestone_name = %s"\ "AND component_name = %s", [today, mile['name'], comp['name']]) row = cursor.fetchone() try: if row: cursor.execute("UPDATE burndown SET hours_remaining = %s WHERE date = %s AND milestone_name = %s"\ "AND component_name = %s", [hours, today, mile['name'], comp['name']]) else: cursor.execute("INSERT INTO burndown(component_name, milestone_name, date, hours_remaining) "\ " VALUES(%s,%s,%s,%s)", [comp['name'], mile['name'], today, hours]) except Exception, inst: self.log.debug(type(inst)) # the exception instance self.log.debug(inst.args) # arguments stored in .args self.log.debug(inst) # __str__ allows args to printed directly cursor.connection.rollback() else: db.commit()
def execute(hdf, txt, env): out = StringIO() out.write('<ul>\n') for milestone in Milestone.select(env, include_completed=False): if milestone.due > 0: date = format_date(milestone.due) else: date = Markup('<i>(later)</i>') out.write(Markup('<li>%s - <a href="%s">%s</a></li>\n', date, env.href.milestone(milestone.name), milestone.name)) out.write('</ul>\n') return out.getvalue()
def execute(hdf, txt, env): out = StringIO() out.write('<ul>\n') for milestone in Milestone.select(env, include_completed=False): if milestone.due > 0: date = format_date(milestone.due) else: date = Markup('<i>(later)</i>') out.write( Markup('<li>%s - <a href="%s">%s</a></li>\n', date, env.href.milestone(milestone.name), milestone.name)) out.write('</ul>\n') return out.getvalue()
def buildCommentHTML(self, comment, nodesIn, LineNum, IDFile, first): if nodesIn > 50: return "" childrenHTML = "" keys = comment.Children.keys() keys.sort(); for key in keys: child = comment.Children[key] childrenHTML += self.buildCommentHTML(child, nodesIn+1, LineNum, IDFile, False) factor = 15 width = (5+nodesIn*factor); html = "<table width=\"400px\" style=\"border-collapse: collapse\" id=\"" + str(comment.IDParent) + ":" + str(comment.IDComment) + "\">" if not first: html += "<tr><td width=\"" + `width` + "px\"></td>" html += "<td colspan=\"3\" width=\"" + `(400-width)` + "px\" style=\"border-top: 1px solid #C0C0C0;\"></td></tr>" html += "<tr><td width=\"" + `width` + "px\"></td>" html += "<td colspan=\"2\" align=\"left\" width=\"" + `(400-100-width)` + "px\">Author: " + comment.Author + "</td>" html += "<td width=\"100px\" align=\"right\">" + util.format_date(comment.DateCreate) + "</td></tr>" html += "<tr><td width=\"" + `width` + "px\"></td><td valign=\"top\" width=\"" + `factor` + "px\" id=\"" + str(comment.IDComment) + "TreeButton\">" if not childrenHTML == "": html += "<img src=\"" + self.env.href.chrome() + "/hw/images/minus.gif\" onclick=\"collapseComments(" + str(comment.IDComment) + ");\">" html += "</td>" html += "<td colspan=\"2\" align=\"left\" width=\"" + `(400-width-factor)` + "px\" bgcolor=\"#F7F7F0\" style=\"border: 1px solid #999999\">" + comment.Text + "</td></tr>" html += "<tr><td width=\"" + `width` + "px\"></td><td width=\"" + `factor` + "px\"></td>" html += "<td width=\"" + `(400-100-factor-width)` + "px\" align=\"left\">" if comment.AttachmentPath != "": html += "<a border=0 alt=\"Code Attachment\" href=\"" + self.env.href.peerReviewCommentCallback() + "?actionType=getCommentFile&fileName=" + comment.AttachmentPath + "&IDFile=" + IDFile + "\"><img src=\"" + self.env.href.chrome() + "/hw/images/paper_clip.gif\"> " + comment.AttachmentPath + "</a>" html += "</td>" html += "<td width=\"100px\" align=\"right\">" html += "<a href=\"javascript:addComment(" + str(LineNum) + ", " + str(IDFile) + ", " + str(comment.IDComment) + ")\">Reply</a></td></tr>" html += "<tr height=\"3\"><td width=\"" + `width` + "px\"></td><td width=\"" + `factor` + "px\"></td><td width=\"" + `(400-width-factor)` + "px\" colspan=\"2\"></td></tr>" html += "</table>" html += childrenHTML return html
def buildCommentHTML(self, comment, nodesIn, LineNum, IDFile, first): if nodesIn > 50: return "" childrenHTML = "" keys = comment.Children.keys() keys.sort(); for key in keys: child = comment.Children[key] childrenHTML += self.buildCommentHTML(child, nodesIn+1, LineNum, IDFile, False) factor = 15 width = (5+nodesIn*factor); html = "<table width=\"400px\" style=\"border-collapse: collapse\" id=\"" + comment.IDParent + ":" + comment.IDComment + "\">" if not first: html += "<tr><td width=\"" + `width` + "px\"></td>" html += "<td colspan=\"3\" width=\"" + `(400-width)` + "px\" style=\"border-top: 1px solid #C0C0C0;\"></td></tr>" html += "<tr><td width=\"" + `width` + "px\"></td>" html += "<td colspan=\"2\" align=\"left\" width=\"" + `(400-100-width)` + "px\">Author: " + comment.Author + "</td>" html += "<td width=\"100px\" align=\"right\">" + util.format_date(comment.DateCreate) + "</td></tr>" html += "<tr><td width=\"" + `width` + "px\"></td><td valign=\"top\" width=\"" + `factor` + "px\" id=\"" + comment.IDComment + "TreeButton\">" if not childrenHTML == "": html += "<img src=\"" + self.env.href.chrome() + "/hw/images/minus.gif\" onclick=\"collapseComments(" + comment.IDComment + ");\">" html += "</td>" html += "<td colspan=\"2\" align=\"left\" width=\"" + `(400-width-factor)` + "px\" bgcolor=\"#F7F7F0\" style=\"border: 1px solid #999999\">" + comment.Text + "</td></tr>" html += "<tr><td width=\"" + `width` + "px\"></td><td width=\"" + `factor` + "px\"></td>" html += "<td width=\"" + `(400-100-factor-width)` + "px\" align=\"left\">" if comment.AttachmentPath != "": html += "<a border=0 alt=\"Code Attachment\" href=\"" + self.env.href.peerReviewCommentCallback() + "?actionType=getCommentFile&fileName=" + comment.AttachmentPath + "&IDFile=" + IDFile + "\"><img src=\"" + self.env.href.chrome() + "/hw/images/paper_clip.gif\"> " + comment.AttachmentPath + "</a>" html += "</td>" html += "<td width=\"100px\" align=\"right\">" html += "<a href=\"javascript:addComment(" + LineNum + ", " + IDFile + ", " + comment.IDComment + ")\">Reply</a></td></tr>" html += "<tr height=\"3\"><td width=\"" + `width` + "px\"></td><td width=\"" + `factor` + "px\"></td><td width=\"" + `(400-width-factor)` + "px\" colspan=\"2\"></td></tr>" html += "</table>" html += childrenHTML return html
def render_macro(self, req, name, content): prefix = limit = None if content: argv = [arg.strip() for arg in content.split(',')] if len(argv) > 0: prefix = argv[0].replace('\'', '\'\'') if len(argv) > 1: limit = int(argv[1]) db = self.env.get_db_cnx() cursor = db.cursor() sql = 'SELECT name, max(time) FROM wiki ' if prefix: sql += "WHERE name LIKE '%s%%' " % prefix sql += 'GROUP BY name ORDER BY max(time) DESC' if limit: sql += ' LIMIT %d' % limit cursor.execute(sql) buf = StringIO() prevdate = None for name, time in cursor: date = format_date(time) if date != prevdate: if prevdate: buf.write('</ul>') buf.write('<h3>%s</h3><ul>' % date) prevdate = date buf.write('<li><a href="%s">%s</a></li>\n' % (escape(self.env.href.wiki(name)), escape(name))) if prevdate: buf.write('</ul>') return buf.getvalue()
def process_request(self, req): # test whether this user is a manager or not if req.perm.has_permission('CODE_REVIEW_MGR'): req.hdf['author'] = "manager" req.hdf['manager'] = 1 else: req.perm.assert_permission('CODE_REVIEW_DEV') req.hdf['author'] = "notmanager" req.hdf['manager'] = 0 # set up dynamic links req.hdf['trac.href.peerReviewMain'] = self.env.href.peerReviewMain() req.hdf['trac.href.peerReviewNew'] = self.env.href.peerReviewNew() req.hdf['trac.href.peerReviewSearch'] = self.env.href.peerReviewSearch() req.hdf['trac.href.peerReviewOptions'] = self.env.href.peerReviewOptions() req.hdf['main'] = "yes" req.hdf['create'] = "no" req.hdf['search'] = "no" req.hdf['options'] = "no" req.hdf['trac.href.peerReviewView'] = self.env.href.peerReviewView() req.hdf['username'] = util.get_reporter_id(req) db = self.env.get_db_cnx() codeReview = CodeReviewStruct(None) dbBack = dbBackend(db) codeReviewArray = dbBack.getMyCodeReviews(util.get_reporter_id(req)) assignedReviewArray = dbBack.getCodeReviews(util.get_reporter_id(req)) managerReviewArray = dbBack.getCodeReviewsByStatus("Ready for inclusion") reviewReturnArray = [] assignedReturnArray = [] managerReturnArray = [] dataArray = [] # fill the table of currently open reviews for struct in codeReviewArray: if struct.Status != "Closed": dataArray.append(struct.IDReview) dataArray.append(struct.Author) dataArray.append(struct.Status) dataArray.append(util.format_date(struct.DateCreate)) dataArray.append(struct.Name) reviewReturnArray.append(dataArray) dataArray = [] dataArray = [] # fill the table of code reviews currently assigned to you for struct in assignedReviewArray: if struct.Status != "Closed" and struct.Status != "Ready for inclusion": dataArray.append(struct.IDReview) dataArray.append(struct.Author) dataArray.append(struct.Name) dataArray.append(util.format_date(struct.DateCreate)) reviewstruct = dbBack.getReviewerEntry(struct.IDReview, util.get_reporter_id(req)) if reviewstruct.Vote == "-1": dataArray.append('Not voted') elif reviewstruct.Vote == "0": dataArray.append('Rejected') elif reviewstruct.Vote == "1": dataArray.append('Accepted') assignedReturnArray.append(dataArray) dataArray = [] dataArray = [] # fill the table of reviews assigned to you in a manager role for struct in managerReviewArray: if struct.Status != "Closed": dataArray.append(struct.IDReview) dataArray.append(struct.Author) dataArray.append(struct.Name) dataArray.append(util.format_date(struct.DateCreate)) managerReturnArray.append(dataArray) dataArray = [] req.hdf['reviewReturnArrayLength'] = len(reviewReturnArray) req.hdf['assignedReturnArrayLength'] = len(assignedReturnArray) req.hdf['managerReviewArrayLength'] = len(managerReviewArray) req.hdf['myCodeReviews'] = reviewReturnArray req.hdf['assignedReviews'] = assignedReturnArray req.hdf['managerReviews'] = managerReturnArray add_stylesheet(req, 'common/css/code.css') add_stylesheet(req, 'common/css/browser.css') return 'peerReviewMain.cs', None
def process_request(self, req): req.perm.assert_permission('TIMELINE_VIEW') format = req.args.get('format') maxrows = int(req.args.get('max', 0)) # Parse the from date and adjust the timestamp to the last second of # the day t = time.localtime() if req.args.has_key('from'): try: t = time.strptime(req.args.get('from'), '%x') except: pass fromdate = time.mktime( (t[0], t[1], t[2], 23, 59, 59, t[6], t[7], t[8])) try: daysback = max(0, int(req.args.get('daysback', ''))) except ValueError: daysback = int(self.config.get('timeline', 'default_daysback')) req.hdf['timeline.from'] = format_date(fromdate) req.hdf['timeline.daysback'] = daysback available_filters = [] for event_provider in self.event_providers: available_filters += event_provider.get_timeline_filters(req) filters = [] # check the request or session for enabled filters, or use default for test in (lambda f: req.args.has_key(f[0]), lambda f: req.session.get('timeline.filter.%s' % f[0], '')\ == '1', lambda f: len(f) == 2 or f[2]): if filters: break filters = [f[0] for f in available_filters if test(f)] # save the results of submitting the timeline form to the session if req.args.has_key('update'): for filter in available_filters: key = 'timeline.filter.%s' % filter[0] if req.args.has_key(filter[0]): req.session[key] = '1' elif req.session.has_key(key): del req.session[key] stop = fromdate start = stop - (daysback + 1) * 86400 events = [] for event_provider in self.event_providers: events += event_provider.get_timeline_events( req, start, stop, filters) events.sort(lambda x, y: cmp(y[3], x[3])) if maxrows and len(events) > maxrows: del events[maxrows:] req.hdf['title'] = 'Timeline' # Get the email addresses of all known users email_map = {} for username, name, email in self.env.get_known_users(): if email: email_map[username] = email idx = 0 for kind, href, title, date, author, message in events: event = { 'kind': kind, 'title': title, 'href': escape(href), 'author': escape(author or 'anonymous'), 'date': format_date(date), 'time': format_time(date, '%H:%M'), 'message': message } if format == 'rss': # Strip/escape HTML markup event['title'] = re.sub(r'</?\w+(?: .*?)?>', '', title) event['message'] = escape(message) if author: # For RSS, author must be an email address if author.find('@') != -1: event['author.email'] = escape(author) elif email_map.has_key(author): event['author.email'] = escape(email_map[author]) event['date'] = http_date(date) req.hdf['timeline.events.%s' % idx] = event idx += 1 if format == 'rss': return 'timeline_rss.cs', 'application/rss+xml' add_stylesheet(req, 'common/css/timeline.css') rss_href = self.env.href.timeline([(f, 'on') for f in filters], daysback=90, max=50, format='rss') add_link(req, 'alternate', rss_href, 'RSS Feed', 'application/rss+xml', 'rss') for idx, fltr in enum(available_filters): req.hdf['timeline.filters.%d' % idx] = { 'name': fltr[0], 'label': fltr[1], 'enabled': int(fltr[0] in filters) } return 'timeline.cs', None
def _expand_recent_topics(self, formatter, name, content): self.log.debug("Rendering RecentTopics macro...") # Check permission if not formatter.perm.has_permission('DISCUSSION_VIEW'): return # Create request context. context = Context.from_request(formatter.req) context.realm = 'discussion-wiki' # Check if TracTags plugin is enabled. context.has_tags = is_tags_enabled(self.env) # Get database access. db = self.env.get_db_cnx() context.cursor = db.cursor() # Get API object. api = self.env[DiscussionApi] # Get list of Trac users. context.users = api.get_users(context) # Parse macro arguments. arguments = [] forum_id = None limit = 10 if content: arguments = [argument.strip() for argument in content.split(',')] if len(arguments) == 1: limit = arguments[0] elif len(arguments) == 2: forum_id = arguments[0] limit = arguments[1] else: raise TracError("Invalid number of macro arguments.") # Construct and execute SQL query. columns = ('forum', 'topic', 'time') values = [] if forum_id: values.append(forum_id) if limit: values.append(limit) values = tuple(values) sql = ("SELECT forum, topic, MAX(time) as max_time " "FROM " " (SELECT forum, topic, time " " FROM message " " UNION " " SELECT forum, id as topic, time " " FROM topic)" + (forum_id and " WHERE forum = %s" or "") + " GROUP BY topic " " ORDER BY max_time DESC" + (limit and " LIMIT %s" or "")) self.log.debug(sql % values) context.cursor.execute(sql, values) # Collect recent topics. entries = [] for row in context.cursor: row = dict(zip(columns, row)) entries.append(row) self.log.debug(entries) # Format entries data. entries_per_date = [] prevdate = None for entry in entries: date = format_date(entry['time']) if date != prevdate: prevdate = date entries_per_date.append((date, [])) forum_name = api.get_forum(context, entry['forum'])['name'] topic_subject = api.get_topic_subject(context, entry['topic']) entries_per_date[-1][1].append((entry['forum'], forum_name, entry['topic'], topic_subject)) # Format result. return tag.div((tag.h3(date), tag.ul(tag.li(tag.a(forum_name, href = formatter.href.discussion('forum', forum_id)), ': ', tag.a( topic_subject, href = formatter.href.discussion('topic', topic_id))) for forum_id, forum_name, topic_id, topic_subject in entries)) for date, entries in entries_per_date)
def process_request(self, req): testmanagersystem = TestManagerSystem(self.env) tc_statuses = testmanagersystem.get_tc_statuses_by_color() if 'testmanager' in self.config: self.default_days_back = self.config.getint( 'testmanager', 'default_days_back', TESTMANAGER_DEFAULT_DAYS_BACK) self.default_interval = self.config.getint( 'testmanager', 'default_interval', TESTMANAGER_DEFAULT_INTERVAL) req_content = req.args.get('content') testplan = None catpath = None testplan_contains_all = True self.env.log.debug("Test Stats - process_request: %s" % req_content) grab_testplan = req.args.get('testplan') if grab_testplan and not grab_testplan == "__all": testplan = grab_testplan.partition('|')[0] catpath = grab_testplan.partition('|')[2] tp = TestPlan(self.env, testplan, catpath) testplan_contains_all = tp['contains_all'] today = datetime.today() today = today.replace(tzinfo=req.tz) + timedelta(2) # Stats start from two years back beginning = today - timedelta(720) if (not req_content == None) and (req_content == "piechartdata"): num_successful = 0 for tc_outcome in tc_statuses['green']: num_successful += self._get_num_tcs_by_status( beginning, today, tc_outcome, testplan, req) num_failed = 0 for tc_outcome in tc_statuses['red']: num_failed += self._get_num_tcs_by_status( beginning, today, tc_outcome, testplan, req) num_to_be_tested = 0 if testplan_contains_all: num_to_be_tested = self._get_num_testcases( beginning, today, catpath, req) - num_successful - num_failed else: for tc_outcome in tc_statuses['yellow']: num_to_be_tested += self._get_num_tcs_by_status( beginning, today, tc_outcome, testplan, req) jsdstr = """ [ {"response": "%s", "count": %s}, {"response": "%s", "count": %s}, {"response": "%s", "count": %s} ] """ % (_("Successful"), num_successful, _("Failed"), num_failed, _("To be tested"), num_to_be_tested) jsdstr = jsdstr.strip() if isinstance(jsdstr, unicode): jsdstr = jsdstr.encode('utf-8') req.send_header("Content-Length", len(jsdstr)) req.write(jsdstr) return if not None in [ req.args.get('end_date'), req.args.get('start_date'), req.args.get('resolution') ]: # form submit grab_at_date = req.args.get('end_date') grab_from_date = req.args.get('start_date') grab_resolution = req.args.get('resolution') # validate inputs if None in [grab_at_date, grab_from_date]: raise TracError('Please specify a valid range.') if None in [grab_resolution]: raise TracError('Please specify the graph interval.') if 0 in [ len(grab_at_date), len(grab_from_date), len(grab_resolution) ]: raise TracError( 'Please ensure that all fields have been filled in.') if not grab_resolution.isdigit(): raise TracError( 'The graph interval field must be an integer, days.') at_date = parse_date(grab_at_date, req.tz) + timedelta(2) from_date = parse_date(grab_from_date, req.tz) graph_res = int(grab_resolution) else: # default data todays_date = datetime.today() at_date = todays_date #+ timedelta(1) # datetime.combine(todays_date,time(23,59,59,0,req.tz)) at_date = at_date.replace(tzinfo=req.tz) + timedelta(2) from_date = at_date - timedelta(self.default_days_back) graph_res = self.default_interval count = [] # Calculate 0th point last_date = from_date - timedelta(graph_res) # Calculate remaining points for cur_date in daterange(from_date, at_date, graph_res): datestr = format_date(cur_date) if graph_res != 1: datestr = "%s thru %s" % (format_date(last_date), datestr) if (not req_content == None) and (req_content == "ticketchartdata"): num_total = self._get_num_tickets_total( beginning, cur_date, testplan, req) num_closed = self._get_num_tickets_by_status( beginning, cur_date, 'closed', testplan, req) num_active = num_total - num_closed count.append({ 'from_date': format_date(last_date), 'to_date': datestr, 'date': datestr, 'active_tickets': num_active, 'closed_tickets': num_closed, 'tot_tickets': num_total }) else: # Handling custom test case outcomes here num_new = self._get_num_testcases(last_date, cur_date, catpath, req) num_successful = 0 for tc_outcome in tc_statuses['green']: num_successful += self._get_num_tcs_by_status( last_date, cur_date, tc_outcome, testplan, req) num_failed = 0 for tc_outcome in tc_statuses['red']: num_failed += self._get_num_tcs_by_status( last_date, cur_date, tc_outcome, testplan, req) num_all_successful = 0 for tc_outcome in tc_statuses['green']: num_all_successful += self._get_num_tcs_by_status( from_date, cur_date, tc_outcome, testplan, req) num_all_failed = 0 for tc_outcome in tc_statuses['red']: num_all_failed += self._get_num_tcs_by_status( from_date, cur_date, tc_outcome, testplan, req) num_all = 0 num_all_untested = 0 if testplan_contains_all: num_all = self._get_num_testcases(None, cur_date, catpath, req) num_all_untested = num_all - num_all_successful - num_all_failed else: for tc_outcome in tc_statuses['yellow']: num_all_untested += self._get_num_tcs_by_status( from_date, cur_date, tc_outcome, testplan, req) num_all = num_all_untested + num_all_successful + num_all_failed count.append({ 'from_date': format_date(last_date), 'to_date': datestr, 'date': datestr, 'new_tcs': num_new, 'successful': num_successful, 'failed': num_failed, 'all_tcs': num_all, 'all_successful': num_all_successful, 'all_untested': num_all_untested, 'all_failed': num_all_failed }) last_date = cur_date # if chartdata is requested, raw text is returned rather than data object # for templating if (not req_content == None) and (req_content == "chartdata"): jsdstr = '{"chartdata": [\n' for x in count: jsdstr += '{"date": "%s",' % x['date'] jsdstr += ' "new_tcs": %s,' % x['new_tcs'] jsdstr += ' "successful": %s,' % x['successful'] jsdstr += ' "failed": %s,' % x['failed'] jsdstr += ' "all_tcs": %s,' % x['all_tcs'] jsdstr += ' "all_successful": %s,' % x['all_successful'] jsdstr += ' "all_untested": %s,' % x['all_untested'] jsdstr += ' "all_failed": %s},\n' % x['all_failed'] jsdstr = jsdstr[:-2] + '\n]}' if isinstance(jsdstr, unicode): jsdstr = jsdstr.encode('utf-8') req.send_header("Content-Length", len(jsdstr)) req.write(jsdstr) return elif (not req_content == None) and (req_content == "downloadcsv"): csvstr = "Date from;Date to;New Test Cases;Successful;Failed;Total Test Cases;Total Successful;Total Untested;Total Failed\r\n" for x in count: csvstr += '%s;' % x['from_date'] csvstr += '%s;' % x['to_date'] csvstr += '%s;' % x['new_tcs'] csvstr += '%s;' % x['successful'] csvstr += '%s;' % x['failed'] csvstr += '%s;' % x['all_tcs'] csvstr += '%s;' % x['all_successful'] csvstr += '%s;' % x['all_untested'] csvstr += '%s\r\n' % x['all_failed'] if isinstance(csvstr, unicode): csvstr = csvstr.encode('utf-8') req.send_header("Content-Length", len(csvstr)) req.send_header("Content-Disposition", "attachment;filename=Test_stats.csv") req.write(csvstr) return elif (not req_content == None) and (req_content == "ticketchartdata"): jsdstr = '{"ticketchartdata": [\n' for x in count: jsdstr += '{"date": "%s",' % x['date'] jsdstr += ' "tot_tickets": %s,' % x['tot_tickets'] jsdstr += ' "active_tickets": %s,' % x['active_tickets'] jsdstr += ' "closed_tickets": %s},\n' % x['closed_tickets'] jsdstr = jsdstr[:-2] + '\n]}' if isinstance(jsdstr, unicode): jsdstr = jsdstr.encode('utf-8') req.send_header("Content-Length", len(jsdstr)) req.write(jsdstr) return else: # Normal rendering of first chart db = self.env.get_db_cnx() showall = req.args.get('show') == 'all' testplan_list = [] for planid, catid, catpath, name, author, ts_str in testmanagersystem.list_all_testplans( ): testplan_list.append({ 'planid': planid, 'catpath': catpath, 'name': name }) data = {} data['testcase_data'] = count data['start_date'] = format_date(from_date) data['end_date'] = format_date(at_date) data['resolution'] = str(graph_res) data['baseurl'] = req.base_url data['testplans'] = testplan_list data['ctestplan'] = testplan return 'testmanagerstats.html', data, None
def buildCommentHTML(self, comment, nodesIn, LineNum, IDFile, first): if nodesIn > 50: return "" childrenHTML = "" keys = comment.Children.keys() keys.sort() for key in keys: child = comment.Children[key] childrenHTML += self.buildCommentHTML(child, nodesIn + 1, LineNum, IDFile, False) factor = 15 width = 5 + nodesIn * factor html = ( '<table width="400px" style="border-collapse: collapse" id="' + comment.IDParent + ":" + comment.IDComment + '">' ) if not first: html += '<tr><td width="' + ` width ` + 'px"></td>' html += ( '<td colspan="3" width="' + ` (400 - width) ` + 'px" style="border-top: 1px solid #C0C0C0;"></td></tr>' ) html += '<tr><td width="' + ` width ` + 'px"></td>' html += ( '<td colspan="2" align="left" width="' + ` (400 - 100 - width) ` + 'px">Author: ' + comment.Author + "</td>" ) html += '<td width="100px" align="right">' + util.format_date(comment.DateCreate) + "</td></tr>" html += ( '<tr><td width="' + ` width ` + 'px"></td><td valign="top" width="' + ` factor ` + 'px" id="' + comment.IDComment + 'TreeButton">' ) if not childrenHTML == "": html += ( '<img src="' + self.env.href.chrome() + '/hw/images/minus.gif" onclick="collapseComments(' + comment.IDComment + ');">' ) html += "</td>" html += ( '<td colspan="2" align="left" width="' + ` (400 - width - factor) ` + 'px" bgcolor="#F7F7F0" style="border: 1px solid #999999">' + comment.Text + "</td></tr>" ) html += '<tr><td width="' + ` width ` + 'px"></td><td width="' + ` factor ` + 'px"></td>' html += '<td width="' + ` (400 - 100 - factor - width) ` + 'px" align="left">' if comment.AttachmentPath != "": html += ( '<a border=0 alt="Code Attachment" href="' + self.env.href.peerReviewCommentCallback() + "?actionType=getCommentFile&fileName=" + comment.AttachmentPath + "&IDFile=" + IDFile + '"><img src="' + self.env.href.chrome() + '/hw/images/paper_clip.gif"> ' + comment.AttachmentPath + "</a>" ) html += "</td>" html += '<td width="100px" align="right">' html += ( '<a href="javascript:addComment(' + LineNum + ", " + IDFile + ", " + comment.IDComment + ')">Reply</a></td></tr>' ) html += ( '<tr height="3"><td width="' + ` width ` + 'px"></td><td width="' + ` factor ` + 'px"></td><td width="' + ` (400 - width - factor) ` + 'px" colspan="2"></td></tr>' ) html += "</table>" html += childrenHTML return html
def process_request(self, req): testmanagersystem = TestManagerSystem(self.env) tc_statuses = testmanagersystem.get_tc_statuses_by_color() if 'testmanager' in self.config: self.default_days_back = self.config.getint('testmanager', 'default_days_back', TESTMANAGER_DEFAULT_DAYS_BACK) self.default_interval = self.config.getint('testmanager', 'default_interval', TESTMANAGER_DEFAULT_INTERVAL) req_content = req.args.get('content') testplan = None catpath = None testplan_contains_all = True self.env.log.debug("Test Stats - process_request: %s" % req_content) grab_testplan = req.args.get('testplan') if grab_testplan and not grab_testplan == "__all": testplan = grab_testplan.partition('|')[0] catpath = grab_testplan.partition('|')[2] tp = TestPlan(self.env, testplan, catpath) testplan_contains_all = tp['contains_all'] today = datetime.today() today = today.replace(tzinfo = req.tz)+timedelta(2) # Stats start from two years back beginning = today - timedelta(720) if (not req_content == None) and (req_content == "piechartdata"): num_successful = 0 for tc_outcome in tc_statuses['green']: num_successful += self._get_num_tcs_by_status(beginning, today, tc_outcome, testplan, req) num_failed = 0 for tc_outcome in tc_statuses['red']: num_failed += self._get_num_tcs_by_status(beginning, today, tc_outcome, testplan, req) num_to_be_tested = 0 if testplan_contains_all: num_to_be_tested = self._get_num_testcases(beginning, today, catpath, req) - num_successful - num_failed else: for tc_outcome in tc_statuses['yellow']: num_to_be_tested += self._get_num_tcs_by_status(beginning, today, tc_outcome, testplan, req) jsdstr = """ [ {"response": "%s", "count": %s}, {"response": "%s", "count": %s}, {"response": "%s", "count": %s} ] """ % (_("Successful"), num_successful, _("Failed"), num_failed, _("To be tested"), num_to_be_tested) jsdstr = jsdstr.strip() if isinstance(jsdstr, unicode): jsdstr = jsdstr.encode('utf-8') req.send_header("Content-Length", len(jsdstr)) req.write(jsdstr) return if not None in [req.args.get('end_date'), req.args.get('start_date'), req.args.get('resolution')]: # form submit grab_at_date = req.args.get('end_date') grab_from_date = req.args.get('start_date') grab_resolution = req.args.get('resolution') # validate inputs if None in [grab_at_date, grab_from_date]: raise TracError('Please specify a valid range.') if None in [grab_resolution]: raise TracError('Please specify the graph interval.') if 0 in [len(grab_at_date), len(grab_from_date), len(grab_resolution)]: raise TracError('Please ensure that all fields have been filled in.') if not grab_resolution.isdigit(): raise TracError('The graph interval field must be an integer, days.') at_date = parse_date(grab_at_date, req.tz)+timedelta(2) from_date = parse_date(grab_from_date, req.tz) graph_res = int(grab_resolution) else: # default data todays_date = datetime.today() at_date = todays_date #+ timedelta(1) # datetime.combine(todays_date,time(23,59,59,0,req.tz)) at_date = at_date.replace(tzinfo = req.tz)+timedelta(2) from_date = at_date - timedelta(self.default_days_back) graph_res = self.default_interval count = [] # Calculate 0th point last_date = from_date - timedelta(graph_res) # Calculate remaining points for cur_date in daterange(from_date, at_date, graph_res): datestr = format_date(cur_date) if graph_res != 1: datestr = "%s thru %s" % (format_date(last_date), datestr) if (not req_content == None) and (req_content == "ticketchartdata"): num_total = self._get_num_tickets_total(beginning, cur_date, testplan, req) num_closed = self._get_num_tickets_by_status(beginning, cur_date, 'closed', testplan, req) num_active = num_total - num_closed count.append( {'from_date': format_date(last_date), 'to_date': datestr, 'date' : datestr, 'active_tickets' : num_active, 'closed_tickets': num_closed, 'tot_tickets' : num_total} ) else: # Handling custom test case outcomes here num_new = self._get_num_testcases(last_date, cur_date, catpath, req) num_successful = 0 for tc_outcome in tc_statuses['green']: num_successful += self._get_num_tcs_by_status(last_date, cur_date, tc_outcome, testplan, req) num_failed = 0 for tc_outcome in tc_statuses['red']: num_failed += self._get_num_tcs_by_status(last_date, cur_date, tc_outcome, testplan, req) num_all_successful = 0 for tc_outcome in tc_statuses['green']: num_all_successful += self._get_num_tcs_by_status(from_date, cur_date, tc_outcome, testplan, req) num_all_failed = 0 for tc_outcome in tc_statuses['red']: num_all_failed += self._get_num_tcs_by_status(from_date, cur_date, tc_outcome, testplan, req) num_all = 0 num_all_untested = 0 if testplan_contains_all: num_all = self._get_num_testcases(None, cur_date, catpath, req) num_all_untested = num_all - num_all_successful - num_all_failed else: for tc_outcome in tc_statuses['yellow']: num_all_untested += self._get_num_tcs_by_status(from_date, cur_date, tc_outcome, testplan, req) num_all = num_all_untested + num_all_successful + num_all_failed count.append( {'from_date': format_date(last_date), 'to_date': datestr, 'date' : datestr, 'new_tcs' : num_new, 'successful': num_successful, 'failed': num_failed, 'all_tcs' : num_all, 'all_successful': num_all_successful, 'all_untested': num_all_untested, 'all_failed': num_all_failed }) last_date = cur_date # if chartdata is requested, raw text is returned rather than data object # for templating if (not req_content == None) and (req_content == "chartdata"): jsdstr = '{"chartdata": [\n' for x in count: jsdstr += '{"date": "%s",' % x['date'] jsdstr += ' "new_tcs": %s,' % x['new_tcs'] jsdstr += ' "successful": %s,' % x['successful'] jsdstr += ' "failed": %s,' % x['failed'] jsdstr += ' "all_tcs": %s,' % x['all_tcs'] jsdstr += ' "all_successful": %s,' % x['all_successful'] jsdstr += ' "all_untested": %s,' % x['all_untested'] jsdstr += ' "all_failed": %s},\n' % x['all_failed'] jsdstr = jsdstr[:-2] +'\n]}' if isinstance(jsdstr, unicode): jsdstr = jsdstr.encode('utf-8') req.send_header("Content-Length", len(jsdstr)) req.write(jsdstr) return elif (not req_content == None) and (req_content == "downloadcsv"): csvstr = "Date from;Date to;New Test Cases;Successful;Failed;Total Test Cases;Total Successful;Total Untested;Total Failed\r\n" for x in count: csvstr += '%s;' % x['from_date'] csvstr += '%s;' % x['to_date'] csvstr += '%s;' % x['new_tcs'] csvstr += '%s;' % x['successful'] csvstr += '%s;' % x['failed'] csvstr += '%s;' % x['all_tcs'] csvstr += '%s;' % x['all_successful'] csvstr += '%s;' % x['all_untested'] csvstr += '%s\r\n' % x['all_failed'] if isinstance(csvstr, unicode): csvstr = csvstr.encode('utf-8') req.send_header("Content-Length", len(csvstr)) req.send_header("Content-Disposition", "attachment;filename=Test_stats.csv") req.write(csvstr) return elif (not req_content == None) and (req_content == "ticketchartdata"): jsdstr = '{"ticketchartdata": [\n' for x in count: jsdstr += '{"date": "%s",' % x['date'] jsdstr += ' "tot_tickets": %s,' % x['tot_tickets'] jsdstr += ' "active_tickets": %s,' % x['active_tickets'] jsdstr += ' "closed_tickets": %s},\n' % x['closed_tickets'] jsdstr = jsdstr[:-2] +'\n]}' if isinstance(jsdstr, unicode): jsdstr = jsdstr.encode('utf-8') req.send_header("Content-Length", len(jsdstr)) req.write(jsdstr) return else: # Normal rendering of first chart db = self.env.get_db_cnx() showall = req.args.get('show') == 'all' testplan_list = [] for planid, catid, catpath, name, author, ts_str in testmanagersystem.list_all_testplans(): testplan_list.append({'planid': planid, 'catpath': catpath, 'name': name}) data = {} data['testcase_data'] = count data['start_date'] = format_date(from_date) data['end_date'] = format_date(at_date) data['resolution'] = str(graph_res) data['baseurl'] = req.base_url data['testplans'] = testplan_list data['ctestplan'] = testplan return 'testmanagerstats.html', data, None
value['hidehtml'] = 1 column = column[1:] if column in ['id', 'ticket', '#', 'summary']: id_cols = [idx for idx, col in util.enum(cols) if col[0] in ('ticket', 'id')] if id_cols: id_val = row[id_cols[0]] value['ticket_href'] = self.env.href.autotrac("ticket/" + str(id_val)) elif column == 'description': value['parsed'] = wiki_to_html(cell, self.env, req, db) elif column == 'reporter' and cell.find('@') != -1: value['rss'] = cell elif column == 'report': value['report_href'] = self.env.href.report(cell) elif column in ['time', 'date','changetime', 'created', 'modified']: value['date'] = util.format_date(cell) value['time'] = util.format_time(cell) value['datetime'] = util.format_datetime(cell) value['gmt'] = util.http_date(cell) prefix = 'report.items.%d.%s' % (row_idx, str(column)) req.hdf[prefix] = str(cell) for key in value.keys(): req.hdf[prefix + '.' + key] = value[key] col_idx += 1 row_idx += 1 req.hdf['report.numrows'] = row_idx format = req.args.get('format') if format == 'rss': self._render_rss(req)
def performSearch(self, req): #create a code review struct to hold the search parameters crStruct = CodeReviewStruct(None) #get the search parameters from POST author = req.args.get('Author') name = req.args.get('CodeReviewName') status = req.args.get('Status') month = req.args.get('DateMonth') day = req.args.get('DateDay') year = req.args.get('DateYear') #check for entered date values, if none are set #default to 0 if(month == None): month = '0'; if(day == None): day = '0'; if(year == None): year = '0'; #store date values for ClearSilver - used to reset values to #search parameters after a search is performed req.hdf['searchValues.month'] = month; req.hdf['searchValues.day'] = day; req.hdf['searchValues.year'] = year; req.hdf['searchValues.status'] = status; req.hdf['searchValues.author'] = author; req.hdf['searchValues.name'] = name; #dates are ints in TRAC - convert search date to int fromdate = "-1"; if((month != '0') and (day != '0') and (year != '0')): t = time.strptime(month + '/' + day + '/' + year[2] + year[3], '%x') #I have no idea what this is doing - obtained from TRAC source fromdate = time.mktime((t[0], t[1], t[2], 23, 59, 59, t[6], t[7], t[8])) #convert to string for database lookup fromdate = `fromdate` selectString = 'Select...' req.hdf['dateSelected'] = fromdate; #if user has not selected parameter - leave #value in struct NULL if(author != selectString): crStruct.Author = author if(name != selectString): crStruct.Name = name; if(status != selectString): crStruct.Status = status crStruct.DateCreate = fromdate; #get the database db = self.env.get_db_cnx() dbBack = dbBackend(db) #perform search results = dbBack.searchCodeReviews(crStruct) returnArray = [] tempArray = [] if(results == None): return returnArray #fill ClearSilver friendly array with #search results for struct in results: tempArray.append(struct.IDReview) tempArray.append(struct.Author) tempArray.append(struct.Status) tempArray.append(format_date(struct.DateCreate)) tempArray.append(struct.Name) returnArray.append(tempArray) tempArray = [] return returnArray;
def update_burndown_data(self): db = self.env.get_db_cnx() cursor = db.cursor() # today's date today = format_date(int(time.time())) milestones = dbhelper.get_milestones(db) components = dbhelper.get_components(db) for mile in milestones: if mile['started'] and not mile['completed']: for comp in components: cursor.execute(""" SELECT est.value AS estimate, ts.value AS spent FROM ticket t LEFT OUTER JOIN ticket_custom est ON (t.id = est.ticket AND est.name = 'estimatedhours') LEFT OUTER JOIN ticket_custom ts ON (t.id = ts.ticket AND ts.name = 'totalhours') WHERE t.component = %s AND t.milestone = %s AND status IN ('new', 'assigned', 'reopened', 'accepted')""", (comp['name'], mile['name'])) rows = cursor.fetchall() hours = 0 if rows: for estimate, spent in rows: if not estimate: estimate = 0 if not spent: spent = 0 if (float(estimate) - float(spent)) > 0: hours += float(estimate) - float(spent) cursor.execute(""" SELECT id FROM burndown WHERE date = %s AND milestone_name = %s AND component_name = %s """, (today, mile['name'], comp['name'])) row = cursor.fetchone() try: if row: cursor.execute(""" UPDATE burndown SET hours_remaining = %s WHERE date = %s AND milestone_name = %s AND component_name = %s """, (hours, today, mile['name'], comp['name'])) else: cursor.execute(""" INSERT INTO burndown(component_name, milestone_name, date, hours_remaining) VALUES(%s,%s,%s,%s) """, (comp['name'], mile['name'], today, hours)) except Exception, inst: self.log.debug(type(inst)) self.log.debug(inst.args) self.log.debug(inst) cursor.connection.rollback() else: db.commit()
def process_request(self, req): # test whether this user is a manager or not if req.perm.has_permission('CODE_REVIEW_MGR'): req.hdf['author'] = "manager" req.hdf['manager'] = 1 else: req.perm.assert_permission('CODE_REVIEW_DEV') req.hdf['author'] = "notmanager" req.hdf['manager'] = 0 # set up dynamic links req.hdf['trac.href.peerReviewMain'] = self.env.href.peerReviewMain() req.hdf['trac.href.peerReviewNew'] = self.env.href.peerReviewNew() req.hdf['trac.href.peerReviewSearch'] = self.env.href.peerReviewSearch( ) req.hdf[ 'trac.href.peerReviewOptions'] = self.env.href.peerReviewOptions() req.hdf['main'] = "yes" req.hdf['create'] = "no" req.hdf['search'] = "no" req.hdf['options'] = "no" req.hdf['trac.href.peerReviewView'] = self.env.href.peerReviewView() req.hdf['username'] = util.get_reporter_id(req) db = self.env.get_db_cnx() codeReview = CodeReviewStruct(None) dbBack = dbBackend(db) codeReviewArray = dbBack.getMyCodeReviews(util.get_reporter_id(req)) assignedReviewArray = dbBack.getCodeReviews(util.get_reporter_id(req)) managerReviewArray = dbBack.getCodeReviewsByStatus( "Ready for inclusion") reviewReturnArray = [] assignedReturnArray = [] managerReturnArray = [] dataArray = [] # fill the table of currently open reviews for struct in codeReviewArray: if struct.Status != "Closed": dataArray.append(struct.IDReview) dataArray.append(struct.Author) dataArray.append(struct.Status) dataArray.append(util.format_date(struct.DateCreate)) dataArray.append(struct.Name) reviewReturnArray.append(dataArray) dataArray = [] dataArray = [] # fill the table of code reviews currently assigned to you for struct in assignedReviewArray: if struct.Status != "Closed" and struct.Status != "Ready for inclusion": dataArray.append(struct.IDReview) dataArray.append(struct.Author) dataArray.append(struct.Name) dataArray.append(util.format_date(struct.DateCreate)) reviewstruct = dbBack.getReviewerEntry( struct.IDReview, util.get_reporter_id(req)) if reviewstruct.Vote == "-1": dataArray.append('Not voted') elif reviewstruct.Vote == "0": dataArray.append('Rejected') elif reviewstruct.Vote == "1": dataArray.append('Accepted') assignedReturnArray.append(dataArray) dataArray = [] dataArray = [] # fill the table of reviews assigned to you in a manager role for struct in managerReviewArray: if struct.Status != "Closed": dataArray.append(struct.IDReview) dataArray.append(struct.Author) dataArray.append(struct.Name) dataArray.append(util.format_date(struct.DateCreate)) managerReturnArray.append(dataArray) dataArray = [] req.hdf['reviewReturnArrayLength'] = len(reviewReturnArray) req.hdf['assignedReturnArrayLength'] = len(assignedReturnArray) req.hdf['managerReviewArrayLength'] = len(managerReviewArray) req.hdf['myCodeReviews'] = reviewReturnArray req.hdf['assignedReviews'] = assignedReturnArray req.hdf['managerReviews'] = managerReturnArray add_stylesheet(req, 'common/css/code.css') add_stylesheet(req, 'common/css/browser.css') return 'peerReviewMain.cs', None
value['hidehtml'] = 1 column = column[1:] if column in ['id', 'ticket', '#', 'summary']: id_cols = [idx for idx, col in util.enum(cols) if col[0] in ('ticket', 'id')] if id_cols: id_val = row[id_cols[0]] value['ticket_href'] = self.env.href.ticket(id_val) elif column == 'description': value['parsed'] = wiki_to_html(cell, self.env, req, db) elif column == 'reporter' and cell.find('@') != -1: value['rss'] = util.escape(cell) elif column == 'report': value['report_href'] = self.env.href.report(cell) elif column in ['time', 'date','changetime', 'created', 'modified']: value['date'] = util.format_date(cell) value['time'] = util.format_time(cell) value['datetime'] = util.format_datetime(cell) value['gmt'] = util.http_date(cell) prefix = 'report.items.%d.%s' % (row_idx, str(column)) req.hdf[prefix] = util.escape(str(cell)) for key in value.keys(): req.hdf[prefix + '.' + key] = value[key] col_idx += 1 row_idx += 1 req.hdf['report.numrows'] = row_idx format = req.args.get('format') if format == 'rss': self._render_rss(req)
def update_burndown_data(self): db = self.env.get_db_cnx() cursor = db.cursor() # today's date today = format_date(int(time.time())) milestones = dbhelper.get_milestones(db) components = dbhelper.get_components(db) for mile in milestones: if mile['started'] and not mile['completed']: for comp in components: cursor.execute( """ SELECT est.value AS estimate, ts.value AS spent FROM ticket t LEFT OUTER JOIN ticket_custom est ON (t.id = est.ticket AND est.name = 'estimatedhours') LEFT OUTER JOIN ticket_custom ts ON (t.id = ts.ticket AND ts.name = 'totalhours') WHERE t.component = %s AND t.milestone = %s AND status IN ('new', 'assigned', 'reopened', 'accepted')""", (comp['name'], mile['name'])) rows = cursor.fetchall() hours = 0 if rows: for estimate, spent in rows: if not estimate: estimate = 0 if not spent: spent = 0 if (float(estimate) - float(spent)) > 0: hours += float(estimate) - float(spent) cursor.execute( """ SELECT id FROM burndown WHERE date = %s AND milestone_name = %s AND component_name = %s """, (today, mile['name'], comp['name'])) row = cursor.fetchone() try: if row: cursor.execute( """ UPDATE burndown SET hours_remaining = %s WHERE date = %s AND milestone_name = %s AND component_name = %s """, (hours, today, mile['name'], comp['name'])) else: cursor.execute( """ INSERT INTO burndown(component_name, milestone_name, date, hours_remaining) VALUES(%s,%s,%s,%s) """, (comp['name'], mile['name'], today, hours)) except Exception, inst: self.log.debug(type(inst)) self.log.debug(inst.args) self.log.debug(inst) cursor.connection.rollback() else: db.commit()
def process_request(self, req): # check to see if the user is a manager of this page or not if req.perm.has_permission('CODE_REVIEW_MGR'): req.hdf['manager'] = 1 else: req.perm.assert_permission('CODE_REVIEW_DEV') req.hdf['manager'] = 0 # set up dynamic links req.hdf['trac.href.peerReviewMain'] = self.env.href.peerReviewMain() req.hdf['trac.href.peerReviewNew'] = self.env.href.peerReviewNew() req.hdf['trac.href.peerReviewSearch'] = self.env.href.peerReviewSearch() req.hdf['trac.href.peerReviewPerform'] = self.env.href.peerReviewPerform() req.hdf['trac.href.peerReviewView'] = self.env.href.peerReviewView() req.hdf['trac.href.peerReviewOptions'] = self.env.href.peerReviewOptions() # reviewID argument checking reviewID = req.args.get('Review') if reviewID == None or not reviewID.isdigit(): req.hdf['error.type'] = "TracError" req.hdf['error.title'] = "Review ID error" req.hdf['error.message'] = "Invalid review ID supplied - unable to load page." return 'error.cs', None req.hdf['main'] = "no" req.hdf['create'] = "no" req.hdf['search'] = "no" req.hdf['options'] = "no" # set up to display the files that are in this review db = self.env.get_db_cnx() dbBack = dbBackend(db) files = dbBack.getReviewFiles(reviewID) returnfiles = [] newfile = [] for struct in files: newfile.append(struct.IDFile) newfile.append(struct.IDReview) newfile.append(struct.Path) newfile.append(struct.LineStart) newfile.append(struct.LineEnd) newfile.append(struct.Version) returnfiles.append(newfile) newfile = [] req.hdf['files'] = returnfiles req.hdf['filesLength'] = len(returnfiles) req.hdf['reviewID'] = reviewID req.hdf['users'] = dbBack.getPossibleUsers() review = dbBack.getCodeReviewsByID(reviewID) # error if review id does not exist in the database if review == None: req.hdf['error.type'] = "TracError" req.hdf['error.title'] = "Review error" req.hdf['error.message'] = "Review does not exist in database - unable to load page." return 'error.cs', None # set up the fields that will be displayed on the page req.hdf['name'] = review.Name req.hdf['notes'] = review.Notes req.hdf['status'] = review.Status req.hdf['author'] = review.Author req.hdf['myname'] = util.get_reporter_id(req) req.hdf['datecreate'] = util.format_date(review.DateCreate) req.hdf['voteyes'] = dbBack.getVotesByID("1", reviewID) req.hdf['voteno'] = dbBack.getVotesByID("0", reviewID) req.hdf['notvoted'] = dbBack.getVotesByID("-1", reviewID) req.hdf['total_votes_possible'] = float(req.hdf['voteyes']) + float(req.hdf['voteno']) + float(req.hdf['notvoted']) req.hdf['threshold'] = float(dbBack.getThreshold())/100 # figure out whether I can vote on this review or not entry = dbBack.getReviewerEntry(reviewID, req.hdf['myname']) if entry != None: req.hdf['canivote'] = 1 req.hdf['myvote'] = entry.Vote else: req.hdf['canivote'] = 0 #display vote summary only if I have voted or am the author/manager, or if the review is "Ready for inclusion" or "Closed req.hdf['viewvotesummary'] = 0 if req.hdf['author'] == req.hdf['myname'] or req.hdf['manager'] == '1' or (dbBack.getReviewerEntry(reviewID, req.hdf['myname']) != None and dbBack.getReviewerEntry(reviewID, req.hdf['myname']).Vote != '-1') or req.hdf['status']=="Closed" or req.hdf['status']=="Ready for inclusion": req.hdf['viewvotesummary'] = 1 else: req.hdf['viewvotesummary'] = 0 rvs = [] # reviewer/vote pairs reviewers = dbBack.getReviewers(reviewID) newrvpair = [] # if we are the manager, list who has voted and what their vote was. # if we are the author, list who has voted and who has not. # if we are neither, list the users who are participating in this review. if req.hdf['manager'] == '1': for reviewer in reviewers: newrvpair.append(reviewer.Reviewer) if reviewer.Vote == '-1': newrvpair.append("Not voted") elif reviewer.Vote == '0': newrvpair.append("No") elif reviewer.Vote == '1': newrvpair.append("Yes") rvs.append(newrvpair) newrvpair = [] elif review.Author == util.get_reporter_id(req): for reviewer in reviewers: newrvpair.append(reviewer.Reviewer) if reviewer.Vote == '-1': newrvpair.append("Not voted") else: newrvpair.append("Voted") rvs.append(newrvpair) newrvpair = [] else: for reviewer in reviewers: newrvpair.append(reviewer.Reviewer) rvs.append(newrvpair) newrvpair = [] req.hdf['rvs'] = rvs req.hdf['rvsLength'] = len(rvs) # execute based on URL arguments if req.args.get('Vote') == 'yes': self.vote("1", reviewID, req) if req.args.get('Vote') == 'no': self.vote("0", reviewID, req) # process state (Open for review, ready for inclusion, etc.) change by manager mc = req.args.get('ManagerChoice') if mc == "Open for review" or mc == "Reviewed" or mc == "Ready for inclusion" or mc == "Closed": self.manager_change_status(mc, reviewID, req) if req.args.get('Close') == '1': self.close_review(reviewID, req) if req.args.get('Inclusion') == '1': self.submit_for_inclusion(reviewID, req) add_stylesheet(req, 'common/css/code.css') add_stylesheet(req, 'common/css/browser.css') return 'peerReviewView.cs', None
def update_burndown_data(self): db = self.env.get_db_cnx() cursor = db.cursor() # today's date today = format_date(int(time.time())) milestones = dbhelper.get_milestones(db) components = dbhelper.get_components(db) for mile in milestones: if mile["started"] and not mile["completed"]: # milestone started, but not completed for comp in components: sqlSelect = ( "SELECT est.value AS estimate, ts.value AS spent " "FROM ticket t " " LEFT OUTER JOIN ticket_custom est ON (t.id = est.ticket AND est.name = 'estimatedhours') " " LEFT OUTER JOIN ticket_custom ts ON (t.id = ts.ticket AND ts.name = 'totalhours') " "WHERE t.component = %s AND t.milestone = %s" " AND status IN ('new', 'assigned', 'reopened', 'accepted') " ) cursor.execute(sqlSelect, [comp["name"], mile["name"]]) rows = cursor.fetchall() hours = 0 estimate = 0 spent = 0 if rows: for estimate, spent in rows: if not estimate: estimate = 0 if not spent: spent = 0 if (float(estimate) - float(spent)) > 0: hours += float(estimate) - float(spent) cursor.execute( "SELECT id FROM burndown WHERE date = %s AND milestone_name = %s" "AND component_name = %s", [today, mile["name"], comp["name"]], ) row = cursor.fetchone() try: if row: cursor.execute( "UPDATE burndown SET hours_remaining = %s WHERE date = %s AND milestone_name = %s" "AND component_name = %s", [hours, today, mile["name"], comp["name"]], ) else: cursor.execute( "INSERT INTO burndown(component_name, milestone_name, date, hours_remaining) " " VALUES(%s,%s,%s,%s)", [comp["name"], mile["name"], today, hours], ) except Exception, inst: self.log.debug(type(inst)) # the exception instance self.log.debug(inst.args) # arguments stored in .args self.log.debug(inst) # __str__ allows args to printed directly cursor.connection.rollback() else: db.commit()