Ejemplo n.º 1
0
    def test_invalid_date_format_add_warning(self):
        """Warning is added when date format is invalid."""
        req = MockRequest(self.env, args={
            'from': '2011-02-02T11:38:50 01:00',
        })

        TimelineModule(self.env).process_request(req)

        self.assertIn(u'"2011-02-02T11:38:50 01:00" is an invalid date, '
                      u'or the date format is not known. Try "%s" or "%s" '
                      u'instead.' % (get_date_format_hint(locale_en),
                                     get_date_format_hint('iso8601')),
                      req.chrome['warnings'])
Ejemplo n.º 2
0
    def _process_add(self, req, ticket):
        if req.method == "POST" and self._validate_add(req):
            if req.args.get('reminder_type') == 'interval':
                time = clear_time(to_datetime(None))
                delta = _time_intervals[req.args.get('unit')](req.args.get('interval'))
                time += delta
                time = to_utimestamp(time)
            else:
                time = to_utimestamp(parse_date(req.args.get('date')))
            origin = to_utimestamp(to_datetime(None))

            self.env.db_transaction("""
                INSERT INTO ticketreminder
                 (ticket, time, author, origin, reminded, description)
                VALUES (%s, %s, %s, %s, 0, %s)
                """, (ticket.id, time, get_reporter_id(req, 'author'),
                      origin, req.args.get('description')))

            add_notice(req, "Reminder has been added.")
            req.redirect(get_resource_url(self.env, ticket.resource, req.href) + "#reminders")

        add_script(req, 'ticketreminder/js/ticketreminder.js')

        data = {
            'ticket': ticket,
            'date_hint': get_date_format_hint(),
        }

        return ("ticket_reminder_add.html", data, None)
Ejemplo n.º 3
0
    def _render_editor(self, req, db, milestone):
        data = {
            'milestone': milestone,
            'ticket': milestone.ticket,
            'datefields' : self.date_fields,
            'date_hint': get_date_format_hint(),
            'datetime_hint': get_datetime_format_hint(),
            'milestone_groups': [],
            'jump_to' : req.args.get('jump_to') or referer_module(req)
        }

        if milestone.exists:
            req.perm(milestone.resource).require('MILESTONE_VIEW')
            milestones = [m for m in StructuredMilestone.select(self.env, db=db)
                          if m.name != milestone.name
                          and 'MILESTONE_VIEW' in req.perm(m.resource)]
            data['milestone_groups'] = group_milestones(milestones,
                'TICKET_ADMIN' in req.perm)
        else:
            req.perm(milestone.resource).require('MILESTONE_CREATE')

        TicketModule(self.env)._insert_ticket_data(req, milestone.ticket, data, 
                                         get_reporter_id(req, 'author'), {})
        self._add_tickets_report_data(milestone, req, data)
        context = Context.from_request(req, milestone.resource)
        
        data['attachments']=AttachmentModule(self.env).attachment_data(context)

        return 'itteco_milestone_edit.html', data, None
Ejemplo n.º 4
0
    def _process_add(self, req, ticket):
        if req.method == "POST" and self._validate_add(req):
            if req.args.get('reminder_type') == 'interval':
                time = clear_time(to_datetime(None))
                delta = _time_intervals[req.args.get('unit')](
                    req.args.get('interval'))
                time += delta
                time = to_utimestamp(time)
            else:
                time = to_utimestamp(parse_date(req.args.get('date')))
            origin = to_utimestamp(to_datetime(None))

            self.env.db_transaction(
                """
                INSERT INTO ticketreminder
                 (ticket, time, author, origin, reminded, description)
                VALUES (%s, %s, %s, %s, 0, %s)
                """, (ticket.id, time, get_reporter_id(
                    req, 'author'), origin, req.args.get('description')))

            add_notice(req, "Reminder has been added.")
            req.redirect(
                get_resource_url(self.env, ticket.resource, req.href) +
                "#reminders")

        add_script(req, 'ticketreminder/js/ticketreminder.js')

        data = {
            'ticket': ticket,
            'date_hint': get_date_format_hint(),
        }

        return ("ticket_reminder_add.html", data, None)
Ejemplo n.º 5
0
    def _render_editor(self, req, db, milestone):
        data = {
            'milestone': milestone,
            'ticket': milestone.ticket,
            'datefields': self.date_fields,
            'date_hint': get_date_format_hint(),
            'datetime_hint': get_datetime_format_hint(),
            'milestone_groups': [],
            'jump_to': req.args.get('jump_to') or referer_module(req)
        }

        if milestone.exists:
            req.perm(milestone.resource).require('MILESTONE_VIEW')
            milestones = [
                m for m in StructuredMilestone.select(self.env, db=db)
                if m.name != milestone.name
                and 'MILESTONE_VIEW' in req.perm(m.resource)
            ]
            data['milestone_groups'] = group_milestones(
                milestones, 'TICKET_ADMIN' in req.perm)
        else:
            req.perm(milestone.resource).require('MILESTONE_CREATE')

        TicketModule(self.env)._insert_ticket_data(
            req, milestone.ticket, data, get_reporter_id(req, 'author'), {})
        self._add_tickets_report_data(milestone, req, data)
        context = Context.from_request(req, milestone.resource)

        data['attachments'] = AttachmentModule(
            self.env).attachment_data(context)

        return 'itteco_milestone_edit.html', data, None
Ejemplo n.º 6
0
def better_parse_date(text, tzinfo=None):
    tzinfo = tzinfo or localtz
    if text == 'now':  # TODO: today, yesterday, etc.
        return datetime.now(utc)
    tm = None
    text = text.strip()
    # normalize ISO time
    match = datefmt._ISO_8601_RE.match(text)
    if match:
        try:
            g = match.groups()
            years = g[0]
            months = g[1] or '01'
            days = g[2] or '01'
            hours, minutes, seconds = [x or '00' for x in g[3:6]]
            z, tzsign, tzhours, tzminutes = g[6:10]
            if z:
                tz = timedelta(hours=int(tzhours or '0'),
                               minutes=int(tzminutes or '0')).seconds / 60
                if tz == 0:
                    tzinfo = utc
                else:
                    tzinfo = datefmt.FixedOffset(
                        tzsign == '-' and -tz or tz,
                        '%s%s:%s' % (tzsign, tzhours, tzminutes))
            tm = strptime(
                '%s ' * 6 % (years, months, days, hours, minutes, seconds),
                '%Y %m %d %H %M %S ')
        except ValueError:
            pass
    else:
        for format in [
                '%x %X', '%x, %X', '%X %x', '%X, %x', '%x', '%c', '%b %d, %Y'
        ]:
            try:
                tm = strptime(text, format)
                break
            except ValueError:
                continue
    if tm == None:
        hint = datefmt.get_date_format_hint()
        raise TracError(
            '"%s" is an invalid date, or the date format '
            'is not known. Try "%s" instead.' % (text, hint), 'Invalid Date')
    if not hasattr(tzinfo, 'localize'):
        # This is a tzinfo define by trac which don't have to deal with dst
        dt = datetime(*(tm[0:6] + (0, tzinfo)))
    else:
        # We need to detect daylight saving correctly - see #...
        dt = tzinfo.localize(datetime(*tm[0:6]))
    # Make sure we can convert it to a timestamp and back - fromtimestamp()
    # may raise ValueError if larger than platform C localtime() or gmtime()
    try:
        datefmt.to_datetime(datefmt.to_timestamp(dt), tzinfo)
    except ValueError:
        raise TracError(
            'The date "%s" is outside valid range. '
            'Try a date closer to present time.' % (text, ), 'Invalid Date')
    return dt
Ejemplo n.º 7
0
 def list_view(self, req, cat, page):
     data = {
         'view': 'list',
         'sprints': self.sm.select(),
         'format_datetime': datefmt.format_datetime,
         'date_hint': datefmt.get_date_format_hint(),
         'datetime_hint': datefmt.get_datetime_format_hint(),
         'milestones': [m.name for m in Milestone.select(self.env)],
     }
     data.update(req.args)
     return 'agilo_admin_sprint.html', data
Ejemplo n.º 8
0
 def list_view(self, req, cat, page):
     data = {
         'view': 'list',
         'sprints': self.sm.select(),
         'format_datetime' : datefmt.format_datetime,
         'date_hint' : datefmt.get_date_format_hint(),
         'datetime_hint' : datefmt.get_datetime_format_hint(),
         'milestones' : [m.name for m in Milestone.select(self.env)],
     }
     data.update(req.args)
     return 'agilo_admin_sprint.html', data
Ejemplo n.º 9
0
def better_parse_date(text, tzinfo=None):
    tzinfo = tzinfo or localtz
    if text == "now":  # TODO: today, yesterday, etc.
        return datetime.now(utc)
    tm = None
    text = text.strip()
    # normalize ISO time
    match = datefmt._ISO_8601_RE.match(text)
    if match:
        try:
            g = match.groups()
            years = g[0]
            months = g[1] or "01"
            days = g[2] or "01"
            hours, minutes, seconds = [x or "00" for x in g[3:6]]
            z, tzsign, tzhours, tzminutes = g[6:10]
            if z:
                tz = timedelta(hours=int(tzhours or "0"), minutes=int(tzminutes or "0")).seconds / 60
                if tz == 0:
                    tzinfo = utc
                else:
                    tzinfo = datefmt.FixedOffset(tzsign == "-" and -tz or tz, "%s%s:%s" % (tzsign, tzhours, tzminutes))
            tm = strptime("%s " * 6 % (years, months, days, hours, minutes, seconds), "%Y %m %d %H %M %S ")
        except ValueError:
            pass
    else:
        for format in ["%x %X", "%x, %X", "%X %x", "%X, %x", "%x", "%c", "%b %d, %Y"]:
            try:
                tm = strptime(text, format)
                break
            except ValueError:
                continue
    if tm == None:
        hint = datefmt.get_date_format_hint()
        raise TracError(
            '"%s" is an invalid date, or the date format ' 'is not known. Try "%s" instead.' % (text, hint),
            "Invalid Date",
        )
    if not hasattr(tzinfo, "localize"):
        # This is a tzinfo define by trac which don't have to deal with dst
        dt = datetime(*(tm[0:6] + (0, tzinfo)))
    else:
        # We need to detect daylight saving correctly - see #...
        dt = tzinfo.localize(datetime(*tm[0:6]))
    # Make sure we can convert it to a timestamp and back - fromtimestamp()
    # may raise ValueError if larger than platform C localtime() or gmtime()
    try:
        datefmt.to_datetime(datefmt.to_timestamp(dt), tzinfo)
    except ValueError:
        raise TracError(
            'The date "%s" is outside valid range. ' "Try a date closer to present time." % (text,), "Invalid Date"
        )
    return dt
Ejemplo n.º 10
0
 def test_help_ok(self):
     """
     Tests the 'help' command in trac-admin.  Since the 'help' command
     has no command arguments, it is hard to call it incorrectly.  As
     a result, there is only this one test.
     """
     rv, output = self.execute('help')
     self.assertEqual(0, rv, output)
     self.assertExpectedResult(output, {
         'version': self.env.trac_version,
         'date_format_hint': get_date_format_hint()
     })
     self.assertTrue(all(len(line) < 80 for line in output.split('\n')),
                     "Lines should be less than 80 characters in length.")
Ejemplo n.º 11
0
    def test_help_ok(self):
        """
        Tests the 'help' command in trac-admin.  Since the 'help' command
        has no command arguments, it is hard to call it incorrectly.  As
        a result, there is only this one test.
        """
        from trac import __version__

        test_name = sys._getframe().f_code.co_name
        d = {'version': __version__,
             'date_format_hint': get_date_format_hint()}
        expected_results = self.expected_results[test_name] % d
        rv, output = self._execute('help')
        self.assertEqual(0, rv)
        self.assertEqual(expected_results, output)
Ejemplo n.º 12
0
    def detail_view(self, req, cat, page, name):
        sprint = self.sm.get(name=name)
        if not sprint or not sprint.exists:
            return req.redirect(req.href.admin(cat, page))

        data = {
            'view': 'detail',
            'sprint': sprint,
            'teams': self.tm.select(),
            'format_datetime': datefmt.format_datetime,
            'date_hint': datefmt.get_date_format_hint(),
            'datetime_hint': datefmt.get_datetime_format_hint(),
            'milestones': [m.name for m in Milestone.select(self.env)],
        }
        data.update(req.args)
        add_script(req, 'common/js/wikitoolbar.js')
        return 'agilo_admin_sprint.html', data
Ejemplo n.º 13
0
    def test_help_ok(self):
        """
        Tests the 'help' command in trac-admin.  Since the 'help' command
        has no command arguments, it is hard to call it incorrectly.  As
        a result, there is only this one test.
        """
        from trac import __version__

        test_name = sys._getframe().f_code.co_name
        d = {
            'version': __version__,
            'date_format_hint': get_date_format_hint()
        }
        expected_results = self.expected_results[test_name] % d
        rv, output = self._execute('help')
        self.assertEqual(0, rv)
        self.assertEqual(expected_results, output)
Ejemplo n.º 14
0
    def detail_view(self, req, cat, page, name):
        sprint = self.sm.get(name=name)
        if not sprint or not sprint.exists:
            return req.redirect(req.href.admin(cat, page))

        data = {
            'view': 'detail',
            'sprint': sprint,
            'teams': self.tm.select(),
            'format_datetime': datefmt.format_datetime,
            'date_hint': datefmt.get_date_format_hint(),
            'datetime_hint': datefmt.get_datetime_format_hint(),
            'milestones': [m.name for m in Milestone.select(self.env)],
        }
        data.update(req.args)
        add_script(req, 'common/js/wikitoolbar.js')
        return 'agilo_admin_sprint.html', data
Ejemplo n.º 15
0
    def _render_editor(self, req, db, milestone):
        data = {
            'milestone': milestone,
            'date_hint': get_date_format_hint(),
            'datetime_hint': get_datetime_format_hint(),
            'milestone_groups': [],
        }

        if milestone.exists:
            req.perm(milestone.resource).require('MILESTONE_MODIFY')
            milestones = [m for m in Milestone.select(self.env, db=db)
                          if m.name != milestone.name
                          and 'MILESTONE_VIEW' in req.perm(m.resource)]
            data['milestone_groups'] = group_milestones(milestones,
                'TICKET_ADMIN' in req.perm)
        else:
            req.perm(milestone.resource).require('MILESTONE_CREATE')

        return 'milestone_edit.html', data, None
Ejemplo n.º 16
0
    def _render_editor(self, req, db, milestone):
        if milestone.exists:
            req.perm.assert_permission('MILESTONE_MODIFY')
            req.hdf['title'] = u'Jalon %s' % milestone.name
            req.hdf['milestone.mode'] = 'edit'
            req.hdf['milestones'] = [m.name for m in
                                     Milestone.select(self.env)
                                     if m.name != milestone.name]
        else:
            req.perm.assert_permission('MILESTONE_CREATE')
            req.hdf['title'] = u'Nouveau jalon'
            req.hdf['milestone.mode'] = 'new'

        from trac.util.datefmt import get_date_format_hint, \
                                       get_datetime_format_hint
        req.hdf['milestone'] = milestone_to_hdf(self.env, db, req, milestone)
        req.hdf['milestone.date_hint'] = get_date_format_hint()
        req.hdf['milestone.datetime_hint'] = get_datetime_format_hint()
        req.hdf['milestone.datetime_now'] = format_datetime()
Ejemplo n.º 17
0
    def get_data_burndown(self,printer):
        self.log.debug("get_data_burndown") 
        database = self.env.get_db_cnx()
        cursor = database.cursor()
        
        data = {
                'milestones' : [],
                'date_hint': get_date_format_hint(),
                'printmilestone': printer,
                }
        
		# get all milestones
        milestones = [m for m in Milestone.select(self.env, True, database)]
        
		# prepare data for each milestone
        p = re.compile('[0-9]+')
        for milest in milestones:
            self.log.debug(milest.completed)
            tickets = _get_tickets_for_milestone(self.env, database, milest.name, 'history_size')
            self.log.debug(tickets)
            tasks = _get_tasks_for_milestone(self, database, milest.name)
            
            # calculate totalpoints of sprint
            totalpoints = 0
            for idx, ticket in enumerate(tickets):
                if ticket['history_size'] and p.match(ticket['history_size']):
                    totalpoints += int(ticket['history_size'])
            
			# prepare graph data
            graphdata = {'points': totalpoints, 'tasks': tasks, 'printer': printer}
            self.log.debug(graphdata)

			# if totalpoints and total tasks equal the zero not display burndown chart
            if totalpoints > 0 and len(tasks) > 0:
                graph_image_path = _get_graphflash_sprintburndown(self,milest.name,graphdata)
            else:
                graph_image_path = None
            
    		# data the all milestones
            d = {'milestone' : milest, 'tickets' : tickets, 'tasks': tasks, 'graph': graph_image_path, 'teste': totalpoints}
            data['milestones'].append(d);
            
        return data;
Ejemplo n.º 18
0
        def test_i18n_date_hint(self):
            en_US = Locale.parse("en_US")
            en_GB = Locale.parse("en_GB")
            fr = Locale.parse("fr")
            ja = Locale.parse("ja")
            vi = Locale.parse("vi")
            zh_CN = Locale.parse("zh_CN")

            self.assert_(datefmt.get_date_format_hint(en_US) in ("MMM d, yyyy", "MMM d, y"))
            self.assert_(datefmt.get_date_format_hint(en_GB) in ("d MMM yyyy", "d MMM y"))
            self.assert_(datefmt.get_date_format_hint(fr) in ("d MMM yyyy", "d MMM y"))
            self.assertEqual("yyyy/MM/dd", datefmt.get_date_format_hint(ja))
            self.assertEqual("dd-MM-yyyy", datefmt.get_date_format_hint(vi))
            self.assertEqual("yyyy-M-d", datefmt.get_date_format_hint(zh_CN))
Ejemplo n.º 19
0
    def _render_editor(self, req, db, milestone):
        if milestone.exists:
            req.perm.assert_permission('MILESTONE_MODIFY')
            req.hdf['title'] = 'Milestone %s' % milestone.name
            req.hdf['milestone.mode'] = 'edit'
            req.hdf['milestones'] = [
                m.name for m in Milestone.select(self.env)
                if m.name != milestone.name
            ]
        else:
            req.perm.assert_permission('MILESTONE_CREATE')
            req.hdf['title'] = 'New Milestone'
            req.hdf['milestone.mode'] = 'new'

        from trac.util.datefmt import get_date_format_hint, \
                                       get_datetime_format_hint
        req.hdf['milestone'] = milestone_to_hdf(self.env, db, req, milestone)
        req.hdf['milestone.date_hint'] = get_date_format_hint()
        req.hdf['milestone.datetime_hint'] = get_datetime_format_hint()
        req.hdf['milestone.datetime_now'] = format_datetime()
Ejemplo n.º 20
0
        def test_i18n_date_hint(self):
            en_US = Locale.parse('en_US')
            en_GB = Locale.parse('en_GB')
            fr = Locale.parse('fr')
            ja = Locale.parse('ja')
            vi = Locale.parse('vi')
            zh_CN = Locale.parse('zh_CN')

            self.assertEqual('MMM d, yyyy',
                             datefmt.get_date_format_hint(en_US))
            self.assertEqual('d MMM yyyy', datefmt.get_date_format_hint(en_GB))
            self.assertEqual('d MMM yyyy', datefmt.get_date_format_hint(fr))
            self.assertEqual('yyyy/MM/dd', datefmt.get_date_format_hint(ja))
            self.assertEqual('dd-MM-yyyy', datefmt.get_date_format_hint(vi))
            self.assertEqual('yyyy-M-d', datefmt.get_date_format_hint(zh_CN))
Ejemplo n.º 21
0
    def render_admin_panel(self, req, cat, page, milestone):
        req.perm.assert_permission('BURNDOWN_ADMIN')
        db = self.env.get_db_cnx()            

        if milestone:
            mil = dbhelper.get_milestone(db, milestone)
            if req.method == 'POST':
                if req.args.get('save'):
                    mil['started'] = None
                    started = req.args.get('started', '')
                    if started:
                        startdate = parse_date(started, req.tz)
                        # todo: fill empty dates in
                        mil['started'] = startdate
                        dbhelper.set_startdate_for_milestone(db, mil['name'], to_timestamp(mil['started']))

                    req.redirect(req.href.admin(cat, page))
                elif req.args.get('cancel'):
                    req.redirect(req.href.admin(cat, page))
            
            data = {'view': 'detail', 
                    'milestone': mil
                    }
        else:
            db = self.env.get_db_cnx()
            cursor = db.cursor()
            milestones = []
            for milestone in dbhelper.get_milestones(db):
                milestones.append(milestone)

            data = {'view': 'list',
                    'milestones': milestones,
                    'default': self.config.get('ticket', 'default_milestone')
                    }
            
        data.update({
            'date_hint': get_date_format_hint(),
            'datetime_hint': get_datetime_format_hint()
        })

        return 'config.html', data
    def render_admin_panel(self, req, cat, page, milestone):
        req.perm.assert_permission('BURNDOWN_ADMIN')
        db = self.env.get_db_cnx()

        if milestone:
            mil = dbhelper.get_milestone(db, milestone)
            if req.method == 'POST':
                if req.args.get('save'):
                    mil['started'] = None
                    started = req.args.get('started', '')
                    if started:
                        startdate = parse_date(started, req.tz)
                        # todo: fill empty dates in
                        mil['started'] = startdate
                        dbhelper.set_startdate_for_milestone(
                            db, mil['name'], to_timestamp(mil['started']))

                    req.redirect(req.href.admin(cat, page))
                elif req.args.get('cancel'):
                    req.redirect(req.href.admin(cat, page))

            data = {'view': 'detail', 'milestone': mil}
        else:
            db = self.env.get_db_cnx()
            cursor = db.cursor()
            milestones = []
            for milestone in dbhelper.get_milestones(db):
                milestones.append(milestone)

            data = {
                'view': 'list',
                'milestones': milestones,
                'default': self.config.get('ticket', 'default_milestone')
            }

        data.update({
            'date_hint': get_date_format_hint(),
            'datetime_hint': get_datetime_format_hint()
        })

        return 'config.html', data
Ejemplo n.º 23
0
    def test_help_ok(self):
        """
        Tests the 'help' command in trac-admin.  Since the 'help' command
        has no command arguments, it is hard to call it incorrectly.  As
        a result, there is only this one test.
        """
        from trac import __version__

        test_name = sys._getframe().f_code.co_name
        d = {'version': __version__,
             'date_format_hint': get_date_format_hint()}
        expected_results = self.expected_results[test_name] % d
        rv, output = self._execute('help')
        self.assertEqual(0, rv)
        # Create a useful delta between the output and the expected output
        output_lines = ['%s\n' % x for x in output.split('\n')]
        expected_lines = ['%s\n' % x for x in expected_results.split('\n')]
        output_diff = ''.join(list(
            difflib.unified_diff(expected_lines, output_lines)
        ))
        failure_message = "%r != %r\n" % (output, expected_results) + output_diff
        self.assertEqual(expected_results, output, failure_message)
Ejemplo n.º 24
0
        def test_i18n_date_hint(self):
            en_US = Locale.parse('en_US')
            en_GB = Locale.parse('en_GB')
            fr = Locale.parse('fr')
            ja = Locale.parse('ja')
            vi = Locale.parse('vi')
            zh_CN = Locale.parse('zh_CN')

            self.assert_(datefmt.get_date_format_hint(en_US)
                         in ('MMM d, yyyy', 'MMM d, y'))
            self.assert_(datefmt.get_date_format_hint(en_GB)
                         in ('d MMM yyyy', 'd MMM y'))
            self.assert_(datefmt.get_date_format_hint(fr)
                         in ('d MMM yyyy', 'd MMM y'))
            self.assertEqual('yyyy/MM/dd',
                             datefmt.get_date_format_hint(ja))
            self.assertEqual('dd-MM-yyyy',
                             datefmt.get_date_format_hint(vi))
            self.assertEqual('yyyy-M-d',
                             datefmt.get_date_format_hint(zh_CN))
Ejemplo n.º 25
0
    def _render_admin_panel(self, req, cat, page, milestone):
        req.perm.require('TICKET_ADMIN')
        add_stylesheet(req, 'itteco/css/common.css')
        add_jscript(
            req, 
            [
                'stuff/ui/ui.core.js',
                'stuff/ui/ui.resizable.js',
                'custom_select.js'
            ],
            IttecoEvnSetup(self.env).debug
        )
        # Detail view?
        if milestone:
            mil = StructuredMilestone(self.env, milestone)
            if req.method == 'POST':
                if req.args.get('save'):
                    mil.name = req.args.get('name')
                    mil.due = mil.completed = None
                    due = req.args.get('duedate', '')
                    if due:
                        mil.due = parse_date(due, req.tz)
                    if req.args.get('completed', False):
                        completed = req.args.get('completeddate', '')
                        mil.completed = parse_date(completed, req.tz)
                        if mil.completed > datetime.now(utc):
                            raise TracError(_('Completion date may not be in '
                                              'the future'),
                                            _('Invalid Completion Date'))
                    mil.description = req.args.get('description', '')
                    mil.parent = req.args.get('parent', None)
                    if mil.parent and mil.parent==mil.name:
                        raise TracError(_('Milestone cannot be parent for itself,Please, give it another thought.'),
                                        _('Something is wrong with Parent Milestone. Will you check it please?'))

                    if mil.parent and not StructuredMilestone(self.env, mil.parent).exists:
                        raise TracError(_('Milestone should have a valid parent. It does not look like this is the case.'),
                                        _('Something is wrong with Parent Milestone. Will you check it please?'))
                    mil.update()
                    req.redirect(req.href.admin(cat, page))
                elif req.args.get('cancel'):
                    req.redirect(req.href.admin(cat, page))

            add_script(req, 'common/js/wikitoolbar.js')
            data = {'view': 'detail', 'milestone': mil}

        else:
            if req.method == 'POST':
                # Add Milestone
                if req.args.get('add') and req.args.get('name'):
                    name = req.args.get('name')
                    try:
                        StructuredMilestone(self.env, name)
                    except ResourceNotFound:
                        mil = StructuredMilestone(self.env)
                        mil.name = name
                        if req.args.get('duedate'):
                            mil.due = parse_date(req.args.get('duedate'),
                                                 req.tz)
                        mil.parent = req.args.get('parent', None)
                        if mil.parent and not StructuredMilestone(self.env, mil.parent).exists:
                            raise TracError(_('Milestone should have a valid parent. It does not look like this is the case'),
                                            _('Something is wrong with Parent Milestone. Will you check it please?'))

                        mil.insert()
                        req.redirect(req.href.admin(cat, page))
                    else:
                        raise TracError(_('Sorry, milestone %s already exists.') % name)

                # Remove milestone
                elif req.args.get('remove'):
                    sel = req.args.get('sel')
                    if not sel:
                        raise TracError(_('Please, select the milestone.'))
                    if not isinstance(sel, list):
                        sel = [sel]
                    db = self.env.get_db_cnx()
                    for name in sel:
                        mil = StructuredMilestone(self.env, name, db=db)
                        mil.delete(db=db)
                    db.commit()
                    req.redirect(req.href.admin(cat, page))

                # Set default milestone
                elif req.args.get('apply'):
                    if req.args.get('default'):
                        name = req.args.get('default')
                        self.config.set('ticket', 'default_milestone', name)
                        self.config.save()
                        req.redirect(req.href.admin(cat, page))

            data = {
                'view': 'list',
                'default': self.config.get('ticket', 'default_milestone'),
            }
            
        # Get ticket count
        db = self.env.get_db_cnx()
        cursor = db.cursor()
        milestones = []
        structured_milestones = StructuredMilestone.select(self.env)
        mil_names = self._get_mil_names(structured_milestones)
        
        cursor.execute("SELECT milestone, COUNT(*) FROM ticket "
                   "WHERE milestone IN (%s) GROUP BY milestone" % ("%s,"*len(mil_names))[:-1], mil_names)
        mil_tkt_quantity = {}
        for mil, cnt in cursor:
            mil_tkt_quantity[mil]=cnt

        data.update({
            'date_hint': get_date_format_hint(),
            'milestones': [(mil, 0) for mil in structured_milestones],# we recover this anyway
            'structured_milestones': structured_milestones,
            'milestone_tickets_quantity': mil_tkt_quantity,
            'max_milestone_level': self.milestone_levels and len(self.milestone_levels)-1 or 0,
            'datetime_hint': get_datetime_format_hint()
        })
        return 'itteco_admin_milestones.html', data
Ejemplo n.º 26
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')

            self.env.log.debug("Start date: %s", grab_from_date)
            self.env.log.debug("End date: %s", grab_at_date)

            # 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.')

            if compatibility:
                at_date = parse_date(grab_at_date, req.tz) + timedelta(2)
                from_date = parse_date(grab_from_date, req.tz)
            else:
                at_date = user_time(req, parse_date, grab_at_date, hint='date')
                from_date = user_time(req,
                                      parse_date,
                                      grab_from_date,
                                      hint='date')

            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
            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['resolution'] = str(graph_res)
            data['baseurl'] = req.base_url
            data['testplans'] = testplan_list
            data['ctestplan'] = testplan

            if compatibility:
                data['start_date'] = format_date(from_date)
                data['end_date'] = format_date(at_date)

                return 'testmanagerstats_compatible.html', data, None

            else:
                data['start_date'] = from_date
                data['end_date'] = at_date

                Chrome(self.env).add_jquery_ui(req)

                data.update({
                    'date_hint': get_date_format_hint(req.lc_time),
                })

                is_iso8601 = req.lc_time == 'iso8601'
                add_script_data(req, jquery_ui={
                    'month_names': get_month_names_jquery_ui(req),
                    'day_names': get_day_names_jquery_ui(req),
                    'date_format': get_date_format_jquery_ui(req.lc_time),
                    'time_format': get_time_format_jquery_ui(req.lc_time),
                    'ampm': not is_24_hours(req.lc_time),
                    'first_week_day': get_first_week_day_jquery_ui(req),
                    'timepicker_separator': 'T' if is_iso8601 else ' ',
                    'show_timezone': is_iso8601,
                    'timezone_list': get_timezone_list_jquery_ui() \
                                     if is_iso8601 else [],
                    'timezone_iso8601': is_iso8601,
                })

            return 'testmanagerstats.html', data, None
Ejemplo n.º 27
0
    def _process_revtree(self, req):
        '''
        Process RevTree.

        This method is invoked to display RevTree page.

        :param req: Trac query object
        '''

        session_ctx = SessionContext(req)

        # Reset clause
        if req.args.get("reset"):
            session_ctx.clear()

        # Revisions
        revisions = self._get_ui_revisions()

        # Branches
        branches = [b for b, d in self._get_ui_branches(reverse=False)]

        # Authors
        authors = self._get_ui_authors()

        # Constraints fields name
        fields = {'author': 'author',
                  'branch': 'branch',
                  'revision': 'revision',
                  'period': 'period',
                  'date': 'date',
                  'deleted_branches': 'show deleted branches'}

        # Get session information
        clauses = session_ctx['query'] or [{'period': [u'14'],
                                            'author': [unicode(req.authname or
                                                               'all')]}]

        style = session_ctx['style'] or 'compact'
        query_options = session_ctx['query_options'] or 'false'
        query_filters = session_ctx['query_filters'] or 'false'

        properties = {k: v for k, v in fields.items()}
        periods = self._get_ui_periods()

        # Data for genshi
        data = {'title': 'Revision Tree',
                'fields': fields,
                'clauses': clauses,
                'authors': authors,
                'branches': branches,
                'periods': periods,
                'revisions': revisions,
                'style': style,
                'query_filters': query_filters,
                'query_options': query_options,
                }

        # Javascripts
        add_script(req, 'revtree/js/suggest.js')
        add_script(req, 'revtree/js/revtree_query.js')
        add_script(req, 'revtree/js/revtree_folding.js')
        add_script(req, 'revtree/js/jquery_md5.js')
        add_script(req, 'revtree/js/XMLWriter-1.0.0-min.js')

        # JQuery §UI
        Chrome(self.env).add_jquery_ui(req)

        # Stylesheet
#        add_stylesheet(req, 'revtree/css/jquery.toolbar.css')
        add_stylesheet(req, 'revtree/css/font-awesome.css')
        add_stylesheet(req, 'revtree/css/revtree.css')

        # Date format
        date_hint = get_date_format_hint(req.lc_time)
        data.update({'date_hint': date_hint})

        # Scripts data
        add_script_data(req,
                        properties=properties,
                        revisions=revisions,
                        authors=authors,
                        periods=periods,
                        date_hint_len=len(date_hint),
                        date_hint_format=_('Format: %s') % date_hint
                        )

        # REMARK: add pseudo warning for front-end usage
        add_warning(req, " ")

        return 'revtree.html', data, None
Ejemplo n.º 28
0
    def _render_admin_panel(self, req, cat, page, milestone):
        req.perm.require('MILESTONE_VIEW')
        
        # Detail view?
        if milestone:
            mil = model.Milestone(self.env, milestone)
            if req.method == 'POST':
                if req.args.get('save'):
                    req.perm.require('MILESTONE_MODIFY')
                    mil.name = req.args.get('name')
                    mil.due = mil.completed = None
                    due = req.args.get('duedate', '')
                    if due:
                        mil.due = parse_date(due, req.tz)
                    if req.args.get('completed', False):
                        completed = req.args.get('completeddate', '')
                        mil.completed = parse_date(completed, req.tz)
                        if mil.completed > datetime.now(utc):
                            raise TracError(_('Completion date may not be in '
                                              'the future'),
                                            _('Invalid Completion Date'))
                    mil.description = req.args.get('description', '')
                    mil.update()
                    add_notice(req, _('Your changes have been saved.'))
                    req.redirect(req.href.admin(cat, page))
                elif req.args.get('cancel'):
                    req.redirect(req.href.admin(cat, page))

            add_script(req, 'common/js/wikitoolbar.js')
            data = {'view': 'detail', 'milestone': mil}

        else:
            default = self.config.get('ticket', 'default_milestone')
            if req.method == 'POST':
                # Add Milestone
                if req.args.get('add') and req.args.get('name'):
                    req.perm.require('MILESTONE_CREATE')
                    name = req.args.get('name')
                    try:
                        model.Milestone(self.env, name=name)
                    except ResourceNotFound:
                        mil = model.Milestone(self.env)
                        mil.name = name
                        if req.args.get('duedate'):
                            mil.due = parse_date(req.args.get('duedate'),
                                                 req.tz)
                        mil.insert()
                        add_notice(req, _('The milestone "%(name)s" has been '
                                          'added.', name=name))
                        req.redirect(req.href.admin(cat, page))
                    else:
                        raise TracError(_('Milestone %s already exists.') % name)

                # Remove milestone
                elif req.args.get('remove'):
                    req.perm.require('MILESTONE_DELETE')
                    sel = req.args.get('sel')
                    if not sel:
                        raise TracError(_('No milestone selected'))
                    if not isinstance(sel, list):
                        sel = [sel]
                    db = self.env.get_db_cnx()
                    for name in sel:
                        mil = model.Milestone(self.env, name, db=db)
                        mil.delete(db=db, author=req.authname)
                    db.commit()
                    add_notice(req, _('The selected milestones have been '
                                      'removed.'))
                    req.redirect(req.href.admin(cat, page))

                # Set default milestone
                elif req.args.get('apply'):
                    name = req.args.get('default')
                    if name and name != default:
                        self.log.info('Setting default milestone to %s', name)
                        self.config.set('ticket', 'default_milestone', name)
                        _save_config(self.config, req, self.log)
                        req.redirect(req.href.admin(cat, page))

            # Get ticket count
            db = self.env.get_db_cnx()
            cursor = db.cursor()
            milestones = []
            for milestone in model.Milestone.select(self.env, db=db):
                cursor.execute("SELECT COUNT(*) FROM ticket "
                               "WHERE milestone=%s", (milestone.name, ))
                milestones.append((milestone, cursor.fetchone()[0]))
            
            data = {'view': 'list',
                    'milestones': milestones,
                    'default': default}

        data.update({
            'date_hint': get_date_format_hint(),
            'datetime_hint': get_datetime_format_hint()
        })
        return 'admin_milestones.html', data
Ejemplo n.º 29
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')

            self.env.log.debug("Start date: %s", grab_from_date)
            self.env.log.debug("End date: %s", grab_at_date)

            # 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.')

            if compatibility:
                at_date = parse_date(grab_at_date, req.tz)+timedelta(2)
                from_date = parse_date(grab_from_date, req.tz)
            else:
                at_date = user_time(req, parse_date, grab_at_date, hint='date')
                from_date = user_time(req, parse_date, grab_from_date, hint='date')

            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
            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['resolution'] = str(graph_res)
            data['baseurl'] = req.base_url
            data['testplans'] = testplan_list
            data['ctestplan'] = testplan

            if compatibility:
                data['start_date'] = format_date(from_date)
                data['end_date'] = format_date(at_date)

                return 'testmanagerstats_compatible.html', data, None

            else:
                data['start_date'] = from_date
                data['end_date'] = at_date

                Chrome(self.env).add_jquery_ui(req)
                
                data.update({
                            'date_hint': get_date_format_hint(req.lc_time),
                        })
                        
                is_iso8601 = req.lc_time == 'iso8601'
                add_script_data(req, jquery_ui={
                    'month_names': get_month_names_jquery_ui(req),
                    'day_names': get_day_names_jquery_ui(req),
                    'date_format': get_date_format_jquery_ui(req.lc_time),
                    'time_format': get_time_format_jquery_ui(req.lc_time),
                    'ampm': not is_24_hours(req.lc_time),
                    'first_week_day': get_first_week_day_jquery_ui(req),
                    'timepicker_separator': 'T' if is_iso8601 else ' ',
                    'show_timezone': is_iso8601,
                    'timezone_list': get_timezone_list_jquery_ui() \
                                     if is_iso8601 else [],
                    'timezone_iso8601': is_iso8601,
                })
                    
            return 'testmanagerstats.html', data, None