Beispiel #1
0
 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()
Beispiel #2
0
 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()
Beispiel #3
0
    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()
Beispiel #5
0
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
Beispiel #8
0
    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()
Beispiel #9
0
    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
Beispiel #10
0
    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
Beispiel #11
0
    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)
Beispiel #12
0
    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
Beispiel #14
0
    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
Beispiel #15
0
                    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)
Beispiel #16
0
    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;
Beispiel #17
0
    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()
Beispiel #18
0
    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
Beispiel #19
0
                    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)
Beispiel #20
0
    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()
Beispiel #21
0
    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
Beispiel #22
0
    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()