def _render_milestone_list(self, req): project_id = req.data['project_id'] milestones = Milestone.select(self.env, project_id, include_completed=True) data = { 'milestones': milestones, } return 'mdashboard.html', data, None
def _render_editor(self, req, milestone): # Suggest a default due time of 18:00 in the user's timezone default_due = datetime.now(req.tz).replace(hour=18, minute=0, second=0, microsecond=0) if default_due <= datetime.now(utc): default_due += timedelta(days=1) data = { 'milestone': milestone, 'datetime_hint': get_datetime_format_hint(req.lc_time), 'default_due': default_due, 'milestone_groups': [], } if milestone.exists: req.perm(milestone.resource).require('MILESTONE_MODIFY') milestones = [ m for m in Milestone.select(self.env) 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') chrome = Chrome(self.env) chrome.add_jquery_ui(req) chrome.add_wiki_toolbars(req) return 'milestone_edit.html', data, None
def _get_options(self, field_name): """Return a list of options for the given [dynvars] field: [dynvars] myfield.options = value1|value2|value3 If no [dynvars] field is found, a select field is searched and its options returned. For the milestone field, completed milestones are omitted. If no select field is found, then an empty list is returned.""" # look for [dynvars] field for key, val in self.env.config.options('dynvars'): if key == field_name + '.options': return val.split('|') # handle milestone special - skip completed milestones if field_name == 'milestone': return [''] + [ m.name for m in Milestone.select(self.env, include_completed=False) ] # lookup select field for field in TicketSystem(self.env).get_ticket_fields(): if field['name'] == field_name and 'options' in field: return field['options'] return []
def _render_editor(self, req, db, milestone): # Suggest a default due time of 18:00 in the user's timezone default_due = datetime.now(req.tz).replace(hour=18, minute=0, second=0, microsecond=0) if default_due <= datetime.now(utc): default_due += timedelta(days=1) data = { 'milestone': milestone, 'datetime_hint': get_datetime_format_hint(), 'default_due': default_due, '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') Chrome(self.env).add_wiki_toolbars(req) return 'milestone_edit.html', data, None
def _get_options(self, field_name): """Return a list of options for the given [dynvars] field: [dynvars] myfield.options = value1|value2|value3 If no [dynvars] field is found, a select field is searched and its options returned. For the milestone field, completed milestones are omitted. If no select field is found, then an empty list is returned.""" # look for [dynvars] field for key,val in self.env.config.options('dynvars'): if key == field_name+'.options': return val.split('|') # handle milestone special - skip completed milestones if field_name == 'milestone': return [''] + [m.name for m in Milestone.select(self.env, include_completed=False)] # lookup select field for field in TicketSystem(self.env).get_ticket_fields(): if field['name'] == field_name and 'options' in field: return field['options'] return []
def process(self, commit, status, branch): self.closestatus = status milestones = [ m.name for m in Milestone.select(self.env) if m.name != 'unknown' ] if branch.startswith('fixes/'): branch = branch[6:] milestones = [m for m in milestones if m.startswith(branch)] self.milestone = sorted(milestones)[-1] msg = commit['message'] self.env.log.debug("Processing Commit: %s", msg) msg = "%s \n Branch: %s \n Changeset: %s" % (msg, branch, commit['id']) # author = commit['author']['name'] author = 'Github' timestamp = datetime.now(utc) cmd_groups = command_re.findall(msg) self.env.log.debug("Function Handlers: %s" % cmd_groups) tickets = {} for cmd, tkts in cmd_groups: funcname = self.__class__._supported_cmds.get(cmd.lower(), '') self.env.log.debug("Function Handler: %s" % funcname) if funcname: for tkt_id in ticket_re.findall(tkts): if (branch == "master") or branch.startswith("fixes/"): tickets.setdefault(tkt_id, []).append(getattr(self, funcname)) # disable this stuff for now, it causes duplicates on merges # proper implementation of this will require tracking commit hashes # else: # tickets.setdefault(tkt_id, []).append(self._cmdRefs) for tkt_id, cmds in tickets.iteritems(): try: db = self.env.get_db_cnx() ticket = Ticket(self.env, int(tkt_id), db) for cmd in cmds: cmd(ticket) # determine sequence number... cnum = 0 tm = TicketModule(self.env) for change in tm.grouped_changelog_entries(ticket, db): if change['permanent']: cnum += 1 ticket.save_changes(author, msg, timestamp, db, cnum + 1) db.commit() tn = TicketNotifyEmail(self.env) tn.notify(ticket, newticket=0, modtime=timestamp) except Exception, e: import traceback traceback.print_exc(file=sys.stderr)
def _find_milestones(self): """Return a string list of Milestone names A smarter approach would return a dictionary of milestones: key = name value = tuple (name, due, completed, description) """ return [ "%s" % m.name for m in Milestone.select(self.env) ]
def _find_milestones(self): """Return a string list of Milestone names A smarter approach would return a dictionary of milestones: key = name value = tuple (name, due, completed, description) """ return ["%s" % m.name for m in Milestone.select(self.env)]
def process(self, commit, status, branch): self.closestatus = status milestones = [m.name for m in Milestone.select(self.env) if m.name != "unknown"] if branch.startswith("fixes/"): branch = branch[6:] milestones = [m for m in milestones if m.startswith(branch)] self.milestone = sorted(milestones)[-1] msg = commit["message"] self.env.log.debug("Processing Commit: %s", msg) msg = "%s \n Branch: %s \n Changeset: %s" % (msg, branch, commit["id"]) # author = commit['author']['name'] author = "Github" timestamp = datetime.now(utc) cmd_groups = command_re.findall(msg) self.env.log.debug("Function Handlers: %s" % cmd_groups) tickets = {} for cmd, tkts in cmd_groups: funcname = self.__class__._supported_cmds.get(cmd.lower(), "") self.env.log.debug("Function Handler: %s" % funcname) if funcname: for tkt_id in ticket_re.findall(tkts): if (branch == "master") or branch.startswith("fixes/"): tickets.setdefault(tkt_id, []).append(getattr(self, funcname)) # disable this stuff for now, it causes duplicates on merges # proper implementation of this will require tracking commit hashes # else: # tickets.setdefault(tkt_id, []).append(self._cmdRefs) for tkt_id, cmds in tickets.iteritems(): try: db = self.env.get_db_cnx() ticket = Ticket(self.env, int(tkt_id), db) for cmd in cmds: cmd(ticket) # determine sequence number... cnum = 0 tm = TicketModule(self.env) for change in tm.grouped_changelog_entries(ticket, db): if change["permanent"]: cnum += 1 ticket.save_changes(author, msg, timestamp, db, cnum + 1) db.commit() tn = TicketNotifyEmail(self.env) tn.notify(ticket, newticket=0, modtime=timestamp) except Exception, e: import traceback traceback.print_exc(file=sys.stderr)
def _render_confirm(self, req, db, milestone): req.perm.assert_permission('MILESTONE_DELETE') req.hdf['title'] = 'Jalon %s' % milestone.name req.hdf['milestone'] = milestone_to_hdf(self.env, db, req, milestone) req.hdf['milestone.mode'] = 'delete' for idx,other in enumerate(Milestone.select(self.env, False, db)): if other.name == milestone.name: continue req.hdf['milestones.%d' % idx] = other.name
def _render_confirm(self, req, db, milestone): req.perm.assert_permission('MILESTONE_DELETE') req.hdf['title'] = 'Milestone %s' % milestone.name req.hdf['milestone'] = milestone_to_hdf(self.env, db, req, milestone) req.hdf['milestone.mode'] = 'delete' for idx, other in enumerate(Milestone.select(self.env, False, db)): if other.name == milestone.name: continue req.hdf['milestones.%d' % idx] = other.name
def _get_milestone(self, req): """Extract the milestone from the referer url. If not found then return the current milestone.""" path = req.environ.get('HTTP_REFERER', '') milestone_re = re.compile(r"/milestone/(?P<milestone>[^?]+)") match = milestone_re.search(path) if match: name = urllib.unquote(match.groupdict()['milestone']) for m in Milestone.select(self.env, include_completed=True): if m.name == name: return m else: raise Exception("Milestone %s not found" % name) else: # milestone not found in url, so assume current milestone for m in Milestone.select(self.env, include_completed=False): return m else: raise Exception("No provided or current milestone") return None
def _get_milestone(self, req): """Extract the milestone from the referer url. If not found then return the current milestone.""" path = req.environ.get('HTTP_REFERER','') milestone_re = re.compile(r"/milestone/(?P<milestone>[^?]+)") match = milestone_re.search(path) if match: name = urllib.unquote(match.groupdict()['milestone']) for m in Milestone.select(self.env, include_completed=True): if m.name == name: return m else: raise Exception("Milestone %s not found" % name) else: # milestone not found in url, so assume current milestone for m in Milestone.select(self.env, include_completed=False): return m else: raise Exception("No provided or current milestone") return None
def _render_confirm(self, req, milestone): req.perm(milestone.resource).require('MILESTONE_DELETE') milestones = [m for m in Milestone.select(self.env) if m.name != milestone.name and 'MILESTONE_VIEW' in req.perm(m.resource)] data = { 'milestone': milestone, 'milestone_groups': group_milestones(milestones, 'TICKET_ADMIN' in req.perm) } return 'milestone_delete.html', data, None
def _render_confirm(self, req, db, milestone): req.perm(milestone.resource).require('MILESTONE_DELETE') 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': milestone, 'milestone_groups': group_milestones(milestones, 'TICKET_ADMIN' in req.perm) } return 'milestone_delete.html', data, None
def execute(hdf, txt, env): out = StringIO() out.write('<ul>\n') for milestone in Milestone.select(env, include_completed=False): if milestone.due > 0: date = format_date(milestone.due) else: date = Markup('<i>(later)</i>') out.write(Markup('<li>%s - <a href="%s">%s</a></li>\n', date, env.href.milestone(milestone.name), milestone.name)) out.write('</ul>\n') return out.getvalue()
def execute(hdf, txt, env): out = StringIO() out.write('<ul>\n') for milestone in Milestone.select(env, include_completed=False): if milestone.due > 0: date = format_date(milestone.due) else: date = Markup('<i>(later)</i>') out.write( Markup('<li>%s - <a href="%s">%s</a></li>\n', date, env.href.milestone(milestone.name), milestone.name)) out.write('</ul>\n') return out.getvalue()
def process_request(self, req): req.perm.require('MILESTONE_VIEW') show = req.args.getlist('show') if 'all' in show: show = ['completed'] db = self.env.get_db_cnx() milestones = Milestone.select(self.env, 'completed' in show, db) if 'noduedate' in show: milestones = [ m for m in milestones if m.due is not None or m.completed ] milestones = [ m for m in milestones if 'MILESTONE_VIEW' in req.perm(m.resource) ] stats = [] queries = [] for milestone in milestones: tickets = get_tickets_for_milestone(self.env, db, milestone.name, 'owner') tickets = apply_ticket_permissions(self.env, req, tickets) stat = get_ticket_stats(self.stats_provider, tickets) stats.append( milestone_stats_data(self.env, req, stat, '^' + milestone.name)) #milestone['tickets'] = tickets # for the iCalendar view if req.args.get('format') == 'ics': self.render_ics(req, db, milestones) return # FIXME should use the 'webcal:' scheme, probably username = None if req.authname and req.authname != 'anonymous': username = req.authname icshref = req.href.roadmap(show=show, user=username, format='ics') add_link(req, 'alternate', icshref, _('iCalendar'), 'text/calendar', 'ics') data = { 'milestones': milestones, 'milestone_stats': stats, 'queries': queries, 'show': show, } add_stylesheet(req, 'common/css/roadmap.css') return 'roadmap.html', data, None
def expand_macro(self, formatter, name, content): arg, kwarg = parse_args(content) includepattern = kwarg.get('include', '') #excludepattern = kwarg.get('exclude', '') length = int(kwarg.get('max', -1)) ignorenoduedate = kwarg.get('ignore') == 'noduedate' or None if length == -1: length = None out = StringIO() include = re.compile(includepattern) #exclude = re.compile(excludepattern) milestones = [] for milestone in Milestone.select(self.env, include_completed=False): if include.match( milestone.name): # and not exclude.match(milestone.name): milestones.append(milestone) out.write('<ul>\n') for milestone in milestones[0:length]: if milestone.due: #TODO: add one day to tdelta tdelta = (to_timestamp(milestone.due) - to_timestamp(datetime.now(formatter.req.tz))) if tdelta > 0: date = format_date(milestone.due, '%Y-%m-%d', formatter.req.tz) else: date = None elif not ignorenoduedate: date = Markup('<i>(Unspecified)</i>') else: date = None if date: out.write('<li>%s - <a href="%s">%s</a></li>\n' % (date, self.env.href.milestone( milestone.name), milestone.name)) out.write('</ul>\n') return Markup(out.getvalue())
def process_request(self, req): req.perm.require('MILESTONE_VIEW') show = req.args.getlist('show') if 'all' in show: show = ['completed'] db = self.env.get_db_cnx() milestones = Milestone.select(self.env, 'completed' in show, db) if 'noduedate' in show: milestones = [m for m in milestones if m.due is not None or m.completed] milestones = [m for m in milestones if 'MILESTONE_VIEW' in req.perm(m.resource)] stats = [] queries = [] for milestone in milestones: tickets = get_tickets_for_milestone(self.env, db, milestone.name, 'owner') tickets = apply_ticket_permissions(self.env, req, tickets) stat = get_ticket_stats(self.stats_provider, tickets) stats.append(milestone_stats_data(self.env, req, stat, milestone.name)) #milestone['tickets'] = tickets # for the iCalendar view if req.args.get('format') == 'ics': self.render_ics(req, db, milestones) return # FIXME should use the 'webcal:' scheme, probably username = None if req.authname and req.authname != 'anonymous': username = req.authname icshref = req.href.roadmap(show=show, user=username, format='ics') add_link(req, 'alternate', icshref, _('iCalendar'), 'text/calendar', 'ics') data = { 'milestones': milestones, 'milestone_stats': stats, 'queries': queries, 'show': show, } add_stylesheet(req, 'common/css/roadmap.css') return 'roadmap.html', data, None
def expand_macro(self, formatter, name, content): arg,kwarg = parse_args(content) includepattern = kwarg.get('include', '') #excludepattern = kwarg.get('exclude', '') length = int(kwarg.get('max', -1)) ignorenoduedate = kwarg.get('ignore') == 'noduedate' or None if length==-1: length = None out = StringIO() include = re.compile(includepattern) #exclude = re.compile(excludepattern) milestones = [] for milestone in Milestone.select(self.env, include_completed=False): if include.match(milestone.name): # and not exclude.match(milestone.name): milestones.append(milestone) out.write('<ul>\n') for milestone in milestones[0:length]: if milestone.due: #TODO: add one day to tdelta tdelta = (to_timestamp(milestone.due) - to_timestamp(datetime.now(formatter.req.tz))) if tdelta > 0: date = format_date(milestone.due, '%Y-%m-%d', formatter.req.tz) else: date = None elif not ignorenoduedate: date = Markup('<i>(Unspecified)</i>') else: date = None if date: out.write('<li>%s - <a href="%s">%s</a></li>\n' % (date, self.env.href.milestone(milestone.name), milestone.name)) out.write('</ul>\n') return Markup(out.getvalue())
def process_admin_request(self, req, cat, page, path_info): req.perm.assert_permission('RT_ADMIN') update = "" for key in req.args.keys(): if key.startswith("update_"): update = key[len("update_"):] break if update: # update now base_path = self.env.config.get('rtadmin', 'base_path') run_burndown = "python " + os.path.join( base_path, "run_burndown.py %s" % update.encode("utf-8")) os.system(run_burndown) elif req.args.get('save') and req.args.get('sel'): # empty table first RT_Template.deleteAll(self.env) # insert selected milestone into table sel = req.args.get('sel') sel = isinstance(sel, list) and sel or [sel] db = self.env.get_db_cnx() for milestone in sel: RT_Template.insert(self.env, milestone) db.commit() req.redirect(self.env.href.admin(cat, page)) # get all enabled milestones enabledMilestones = RT_Template.getMilestones(self.env) ms = Milestone.select(self.env) ms.sort(cmp=lambda x, y: cmp(x.name, y.name)) req.hdf['milestones'] = [{ 'name': m.name, 'href': self.env.href.admin(cat, page, m.name), 'enabled': m.name in enabledMilestones, 'update': stripMilestoneName(m.name), } for m in ms] return 'admin_relaticket.cs', None
def process_request(self, req, chrome, projects): milestones = [] stats = [] for project in projects: env = project["env"] for m in Milestone.select(env, False, env.get_db_cnx()): req.href = env.href milestone = milestone_to_hdf(env, env.get_db_cnx(), req, m) milestone['project'] = project milestones.append(milestone) milestones.sort(milestone_cmp) idx = 0 for m in milestones: project = m['project'] env = project['env'] milestone_name = unescape(m['name']) # Kludge prefix = 'roadmap.milestones.%d.' % idx tickets = get_tickets_for_milestone(env, env.get_db_cnx(), milestone_name, 'owner') stat = calc_ticket_stats(tickets) stats.append({'stats': stat}) m['queries'] = {} for k, v in get_query_links(env, milestone_name).items(): m['queries'][k] = v m['tickets'] = tickets # for the iCalendar view idx += 1 # make milestone names unique m["name"] = project["name"] + " " + m["name"] data = { 'milestones': milestones, 'milestone_stats': stats } data["chrome.nav.mainnav.roadmap.active"] = 1 data['title'] = _('Roadmap') template_dir = os.path.dirname(__file__) + '/templates/' chrome.populate_data(req, data) output = chrome.render_template(req, template_dir + "roadmap.html", data) req.session.save() req.send(output, 'text/html')
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()
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
def process_admin_request(self, req, cat, page, path_info): req.perm.assert_permission('RT_ADMIN') update = "" for key in req.args.keys(): if key.startswith("update_"): update = key[len("update_"):] break if update: # update now base_path = self.env.config.get('rtadmin', 'base_path') run_burndown = "python " + os.path.join(base_path, "run_burndown.py %s" % update.encode("utf-8")) os.system(run_burndown) elif req.args.get('save') and req.args.get('sel'): # empty table first RT_Template.deleteAll(self.env) # insert selected milestone into table sel = req.args.get('sel') sel = isinstance(sel, list) and sel or [sel] db = self.env.get_db_cnx() for milestone in sel: RT_Template.insert(self.env, milestone) db.commit() req.redirect(self.env.href.admin(cat, page)) # get all enabled milestones enabledMilestones = RT_Template.getMilestones(self.env) ms = Milestone.select(self.env) ms.sort(cmp=lambda x,y: cmp(x.name, y.name)) req.hdf['milestones'] = [{'name': m.name, 'href': self.env.href.admin(cat, page, m.name), 'enabled': m.name in enabledMilestones, 'update': stripMilestoneName(m.name), } for m in ms] return 'admin_relaticket.cs', None
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()
def process_request(self, req): req.perm.assert_permission('ROADMAP_VIEW') req.hdf['title'] = 'Roadmap' showall = req.args.get('show') == 'all' req.hdf['roadmap.showall'] = showall db = self.env.get_db_cnx() milestones = [ milestone_to_hdf(self.env, db, req, m) for m in Milestone.select(self.env, showall, db) ] req.hdf['roadmap.milestones'] = milestones for idx, milestone in enumerate(milestones): milestone_name = unescape(milestone['name']) # Kludge prefix = 'roadmap.milestones.%d.' % idx tickets = get_tickets_for_milestone(self.env, db, milestone_name, 'owner') req.hdf[prefix + 'stats'] = calc_ticket_stats(tickets) for k, v in get_query_links(req, milestone_name).items(): req.hdf[prefix + 'queries.' + k] = v milestone['tickets'] = tickets # for the iCalendar view if req.args.get('format') == 'ics': self.render_ics(req, db, milestones) return add_stylesheet(req, 'common/css/roadmap.css') # FIXME should use the 'webcal:' scheme, probably username = None if req.authname and req.authname != 'anonymous': username = req.authname icshref = req.href.roadmap(show=req.args.get('show'), user=username, format='ics') add_link(req, 'alternate', icshref, 'iCalendar', 'text/calendar', 'ics') return 'roadmap.cs', None
def _get_start_date(self, milestone): """Returns the start date for the given milestone based on the prior milestone as follows - this milestone's start date = * the day after the prior milestone's completed date (if completed) * else the day after the prior milestone's due date (if due) * else today """ prior = None for m in Milestone.select(self.env, include_completed=True): if m.name == milestone.name: break prior = m else: raise Exception("Milestone %s not found" % milestone.name) if prior: if prior.completed: return self._get_day(prior.completed, 'next') if prior.due: return self._get_day(prior.due, 'next') return self._get_day(datetime.utcnow(), 'end')
def process_request(self, req): req.perm.assert_permission('ROADMAP_VIEW') req.hdf['title'] = u'Feuille de route' showall = req.args.get('show') == 'all' req.hdf['roadmap.showall'] = showall db = self.env.get_db_cnx() milestones = [milestone_to_hdf(self.env, db, req, m) for m in Milestone.select(self.env, showall, db)] req.hdf['roadmap.milestones'] = milestones for idx, milestone in enumerate(milestones): milestone_name = unescape(milestone['name']) # Kludge prefix = 'roadmap.milestones.%d.' % idx tickets = get_tickets_for_milestone(self.env, db, milestone_name, 'owner') req.hdf[prefix + 'stats'] = calc_ticket_stats(tickets) for k, v in get_query_links(req, milestone_name).items(): req.hdf[prefix + 'queries.' + k] = v milestone['tickets'] = tickets # for the iCalendar view if req.args.get('format') == 'ics': self.render_ics(req, db, milestones) return add_stylesheet(req, 'common/css/roadmap.css') # FIXME should use the 'webcal:' scheme, probably username = None if req.authname and req.authname != 'anonymous': username = req.authname icshref = req.href.roadmap(show=req.args.get('show'), user=username, format='ics') add_link(req, 'alternate', icshref, 'iCalendar', 'text/calendar', 'ics') return 'roadmap.cs', None
def _render_view(self, req, milestone): milestone_groups = [] available_groups = [] component_group_available = False ticket_fields = TicketSystem(self.env).get_ticket_fields() # collect fields that can be used for grouping for field in ticket_fields: if field['type'] == 'select' and field['name'] != 'milestone' \ or field['name'] in ('owner', 'reporter'): available_groups.append({ 'name': field['name'], 'label': field['label'] }) if field['name'] == 'component': component_group_available = True # determine the field currently used for grouping by = None if component_group_available: by = 'component' elif available_groups: by = available_groups[0]['name'] by = req.args.get('by', by) tickets = get_tickets_for_milestone(self.env, milestone=milestone.name, field=by) tickets = apply_ticket_permissions(self.env, req, tickets) stat = get_ticket_stats(self.stats_provider, tickets) context = web_context(req, milestone.resource) data = { 'context': context, 'milestone': milestone, 'attachments': AttachmentModule(self.env).attachment_data(context), 'available_groups': available_groups, 'grouped_by': by, 'groups': milestone_groups } data.update(milestone_stats_data(self.env, req, stat, milestone.name)) if by: def per_group_stats_data(gstat, group_name): return milestone_stats_data(self.env, req, gstat, milestone.name, by, group_name) milestone_groups.extend( grouped_stats_data(self.env, self.stats_provider, tickets, by, per_group_stats_data)) add_stylesheet(req, 'common/css/roadmap.css') add_script(req, 'common/js/folding.js') def add_milestone_link(rel, milestone): href = req.href.milestone(milestone.name, by=req.args.get('by')) add_link(req, rel, href, _('Milestone "%(name)s"', name=milestone.name)) milestones = [ m for m in Milestone.select(self.env) if 'MILESTONE_VIEW' in req.perm(m.resource) ] idx = [i for i, m in enumerate(milestones) if m.name == milestone.name] if idx: idx = idx[0] if idx > 0: add_milestone_link('first', milestones[0]) add_milestone_link('prev', milestones[idx - 1]) if idx < len(milestones) - 1: add_milestone_link('next', milestones[idx + 1]) add_milestone_link('last', milestones[-1]) prevnext_nav(req, _('Previous Milestone'), _('Next Milestone'), _('Back to Roadmap')) return 'milestone_view.html', data, None
def get_entries_for_index(self): for milestone in Milestone.select(self.env, include_completed=True): yield self.build_doc(milestone)
def process_admin_request(self, req, cat, page, milestone): req.perm.assert_permission('MMV_ADMIN') if req.args.get('save'): # save # empty table first MMV_List.deleteAll(self.env) # insert selected milestone into table db = self.env.get_db_cnx() selReq = req.args.get('sel') milestoneReq = req.args.get('milestone') startdateReq = req.args.get('startdate') enddateReq = req.args.get('enddate') selList = isinstance(selReq, list) and selReq or [selReq] milestoneList = isinstance(milestoneReq, list) and milestoneReq or [milestoneReq] startdateList = isinstance(startdateReq, list) and startdateReq or [startdateReq] enddateList = isinstance(enddateReq, list) and enddateReq or [enddateReq] for milestone, startdate, enddate in zip(milestoneList, startdateList, enddateList): startdate = getDateFromStr(startdate) enddate = getDateFromStr(enddate) if milestone in selList: enabled = True else: enabled = False MMV_List.insert(self.env, milestone, startdate, enddate, enabled) db.commit() req.redirect(self.env.href.admin(cat, page)) elif req.args.get('repair'): # repair # empty table first MMV_List.deleteAllHistory(self.env) req.redirect(self.env.href.admin(cat, page)) else: # display # get all enabled milestones enabledMilestones = MMV_List.getEnabledMilestones(self.env) ms = Milestone.select(self.env) ms.sort(cmp=lambda x,y: cmp(x.name, y.name)) req.hdf['date_hint'] = "Format: YYYY/MM/DD" req.hdf['milestones'] = [{'name': m.name, 'href': self.env.href.admin(cat, "milestones", m.name), 'enabled': m.name in enabledMilestones, 'startdate': formatDateFull(MMV_List.getStartdateFromDb(self.env, m.name)), 'enddate': formatDateFull(MMV_List.getEnddateFromDb(self.env, m.name)), } for m in ms] return 'mmv_admin.cs', None
def _get_milestones(self): #db = self.env.get_db_cnx() milestones = Milestone.select(self.env) return milestones
def process_request(self, req): if req.path_info == '/flashgantt/chartxml': req.perm.require('MILESTONE_VIEW') showall = req.args.get('show') == 'all' # Get the current date and time cur_dt = datetime.date.today() # Get the quarter I am in. cur_quarter = self._get_quarter(cur_dt.month) prev_quarter = self._get_prev_quarter(cur_quarter) next_quarter = self._get_next_quarter(cur_quarter) (cq_sd, cq_ed) = self._get_quarter_start_end_dates(cur_dt.year, cur_quarter) (pq_sd, pq_ed) = self._get_prev_quarters_start_end_dates(cur_dt.year, cur_quarter) (nq_sd, nq_ed) = self._get_next_quarters_start_end_dates(cur_dt.year, cur_quarter) min_date = pq_sd.strftime('%d/%m/%Y') max_date = nq_ed.strftime('%d/%m/%Y') quarters = [] quarters.append({'name': 'Q' + str(prev_quarter) + ' ' + str(pq_sd.year), 'start_date': pq_sd.strftime('%d/%m/%Y'), 'end_date': pq_ed.strftime('%d/%m/%Y')}) quarters.append({'name': 'Q' + str(cur_quarter) + ' ' + str(cq_sd.year), 'start_date': cq_sd.strftime('%d/%m/%Y'), 'end_date': cq_ed.strftime('%d/%m/%Y')}) quarters.append({'name': 'Q' + str(next_quarter) + ' ' + str(nq_sd.year), 'start_date': nq_sd.strftime('%d/%m/%Y'), 'end_date': nq_ed.strftime('%d/%m/%Y')}) months = [] for x in range(pq_sd.month, (pq_ed.month + 1)): (cm_sd, cm_ed) = self._get_month_start_end_dates(pq_sd.year, x) months.append({'name': self._get_month_name(x), 'start_date': cm_sd.strftime('%d/%m/%Y'), 'end_date': cm_ed.strftime('%d/%m/%Y')}) for x in range(cq_sd.month, (cq_ed.month + 1)): (cm_sd, cm_ed) = self._get_month_start_end_dates(cq_sd.year, x) months.append({'name': self._get_month_name(x), 'start_date': cm_sd.strftime('%d/%m/%Y'), 'end_date': cm_ed.strftime('%d/%m/%Y')}) for x in range(nq_sd.month, (nq_ed.month + 1)): (cm_sd, cm_ed) = self._get_month_start_end_dates(nq_sd.year, x) months.append({'name': self._get_month_name(x), 'start_date': cm_sd.strftime('%d/%m/%Y'), 'end_date': cm_ed.strftime('%d/%m/%Y')}) milestones = [] db = self.env.get_db_cnx() ms = [m for m in Milestone.select(self.env, showall, db) if 'MILESTONE_VIEW' in req.perm(m.resource)] cnt = 0 for m in ms: cnt = cnt + 1 comp_stat = 0 if (m.is_completed): comp_stat = 1 milestones.append({'name': m.name, 'id': str(cnt), 'start_date': pq_sd.strftime('%d/%m/%Y'), 'due_date': format_date(m.due, format='%d/%m/%Y'), 'completed_date': format_date(m.completed, format='%d/%m/%Y'), 'completed': comp_stat}) data = {'milestones': milestones, 'showall': showall, 'visible_months': months, 'quarters': quarters} # This tuple is for Genshi (template_name, data, content_type) # Without data the trac layout will not appear. return ('chart.xml', data, 'text/xml') else: req.perm.require('MILESTONE_VIEW') showall = req.args.get('show') == 'all' db = self.env.get_db_cnx() milestones = [m for m in Milestone.select(self.env, showall, db) if 'MILESTONE_VIEW' in req.perm(m.resource)] chart_height = 150 + (len(milestones) * 29) if (showall): xmlcharturl = req.href.flashgantt('/chartxml?show=all') else: xmlcharturl = req.href.flashgantt('/chartxml') data = {'milestones': milestones, 'showall': showall, 'xmlcharturl': xmlcharturl, 'chart_height': chart_height} #add_stylesheet(req, 'fg/css/flashgantt.css') # This tuple is for Genshi (template_name, data, content_type) # Without data the trac layout will not appear. return ('flashgantt.html', data, None)
def process_request(self, req): req.perm.require('TSTATS_VIEW') req_content = req.args.get('content') milestone = None 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') grab_milestone = req.args.get('milestone') if grab_milestone == "__all": milestone = None else: milestone = grab_milestone # 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) at_date = datetime.combine(at_date, time(11,59,59,0,utc)) # Add tzinfo from_date = parse_date(grab_from_date) from_date = datetime.combine(from_date, time(0,0,0,0,utc)) # Add tzinfo graph_res = int(grab_resolution) else: # default data todays_date = date.today() at_date = datetime.combine(todays_date,time(11,59,59,0,utc)) from_date = at_date - timedelta(self.default_days_back) graph_res = self.default_interval at_date_str = format_date(at_date) from_date_str= format_date(from_date) count = [] # Calculate 0th point last_date = from_date - timedelta(graph_res) last_num_open = self._get_num_open_tix(last_date, milestone, req) # Calculate remaining points for cur_date in daterange(from_date, at_date, graph_res): num_open = self._get_num_open_tix(cur_date, milestone, req) num_closed = self._get_num_closed_tix(last_date, cur_date, milestone, req) datestr = format_date(cur_date) if graph_res != 1: datestr = "%s thru %s" % (format_date(last_date), datestr) count.append( {'date' : datestr, 'new' : num_open - last_num_open + num_closed, 'closed': num_closed, 'open' : num_open }) last_num_open = num_open 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_tickets": %s,' % x['new'] jsdstr += ' "closed": %s,' % x['closed'] jsdstr += ' "open": %s},\n' % x['open'] jsdstr = jsdstr[:-2] +'\n]}' req.send(jsdstr.encode('utf-8')) return else: db = self.env.get_db_cnx() showall = req.args.get('show') == 'all' milestone_list = [ m.name for m in Milestone.select(self.env, showall, db) ] if milestone == None: milestone_num = 0 elif milestone in milestone_list: milestone_num = milestone_list.find(milestone) else: milestone_num = 0 data = {} data['ticket_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['milestones'] = milestone_list data['cmilestone'] = milestone_num data['yui_base_url'] = self.yui_base_url return 'greensauce.html', data, None
def _render_view(self, req, db): showall = req.args.get('show') == 'all' showmetrics = req.args.get('showmetrics') == 'true' # Get list of milestone object for the project milestones = list(Milestone.select(self.env, showall, db)) stats = [] queries = [] self.env.log.info("getting milestones statistics") for milestone in milestones: tickets = get_tickets_for_milestone(self.env, db, milestone.name, 'owner') stat = get_ticket_stats(self.stats_provider, tickets) stats.append(milestone_stats_data(self.env, req, stat, milestone.name)) project = { 'name': self.env.project_name, 'description': self.env.project_description } data = { 'context': Context.from_request(req), 'milestones': milestones, 'milestone_stats': stats, 'queries': queries, 'showall': showall, 'showmetrics': showmetrics, 'project' : project, 'yui_base_url': self.yui_base_url } self.env.log.info("getting project statistics") project_tickets = get_project_tickets(self.env) # Get project progress stats proj_stat = self.stats_provider.get_ticket_group_stats(project_tickets) data['proj_progress_stat'] = {'stats': proj_stat, 'stats_href': req.href.query(proj_stat.qry_args), 'interval_hrefs': [req.href.query(interval['qry_args']) for interval in proj_stat.intervals]} closed_stat = self.stats_provider.get_ticket_resolution_group_stats(project_tickets) data['proj_closed_stat'] = {'stats': closed_stat, 'stats_href': req.href.query(closed_stat.qry_args), 'interval_hrefs': [req.href.query(interval['qry_args']) for interval in closed_stat.intervals]} tkt_frequency_stats = {} tkt_duration_stats = {} bmi_stats = [] daily_backlog_chart = {} today = datetime.now() if showmetrics: self.env.log.info("getting ticket metrics") tkt_group_metrics = TicketGroupMetrics(self.env, project_tickets) tkt_frequency_stats = tkt_group_metrics.get_frequency_metrics_stats() tkt_duration_stats = tkt_group_metrics.get_duration_metrics_stats() #stat for this month first_day = datetime(today.year, today.month, 1, tzinfo=utc) last_day = last_day_of_month(today.year, today.month) bmi_stats.append(tkt_group_metrics.get_bmi_monthly_stats(first_day, last_day)) # stat for last month last_day = first_day - timedelta(days=1) first_day = datetime(last_day.year, last_day.month, 1, tzinfo=utc) bmi_stats.append(tkt_group_metrics.get_bmi_monthly_stats(first_day, last_day)) # get daily backlog history last_day = datetime(today.year, today.month, today.day, tzinfo=utc) first_day = last_day - timedelta(days=DAYS_BACK) self.env.log.info("getting backlog history") backlog_history = tkt_group_metrics.get_daily_backlog_history(first_day, last_day) daily_backlog_chart = tkt_group_metrics.get_daily_backlog_chart(backlog_history) # Get dialy commits history last_day = datetime(today.year, today.month, today.day, tzinfo=utc) first_day = last_day - timedelta(days=DAYS_BACK) changeset_group_stats = ChangesetsStats(self.env, first_day, last_day) commits_by_date = changeset_group_stats.get_commit_by_date() commits_by_date_chart = changeset_group_stats.get_commit_by_date_chart(commits_by_date) data['project_bmi_stats'] = bmi_stats #self.env.log.info(bmi_stats) data['ticket_frequency_stats'] = tkt_frequency_stats data['ticket_duration_stats'] = tkt_duration_stats data['ds_daily_backlog'] = daily_backlog_chart data['ds_commit_by_date'] = commits_by_date_chart add_stylesheet(req, 'pd/css/dashboard.css') add_stylesheet(req, 'common/css/report.css') return ('pdashboard.html', data, None)
def getMilestones(self, component, req ): milestones = [] for m in Milestone.select(component.env) : milestones.append(m.name) return milestones
def _render_project_stats(self, req, data): project_id = req.data['project_id'] defaults = { # summary 'tkt_summary': True, 'milestones_stats': True, 'tkt_extra_stats': False, # time range 'tkt_activity': False, 'repos_stats': True, 'backlog_daily': True, # time groups 'repos_activity': True, 'backlog_table': False, 'wiki_activity': True, } metrics = self._enabled_metrics(req, defaults) show_completed = req.args.has_key('show_completed') data.update({ 'metrics': metrics, 'show_completed': show_completed, }) groupsize = data['groupsize'] groupcnt = data['groupcnt'] first_day = data['first_day'] first_day_group = data['first_day_group'] last_day = data['last_day'] db = self.env.get_read_db() if metrics['milestones_stats']: # Get list of milestone object for the project milestones = list(Milestone.select(self.env, project_id, show_completed, db)) stats = [] for milestone in milestones: tickets = get_tickets_for_milestone(self.env, db, milestone, 'owner') stat = get_ticket_stats(self.stats_provider, tickets, project_id) stats.append(milestone_stats_data(self.env, req, stat, milestone)) add_stylesheet(req, 'common/css/roadmap.css') data.update({ 'milestones': milestones, 'milestone_stats': stats, }) project_tickets = get_project_tickets(self.env, project_id) if metrics['tkt_summary']: # Get project progress stats proj_stat = self.stats_provider.get_ticket_group_stats(project_tickets, project_id) data['proj_progress_stat'] = {'stats': proj_stat, 'stats_href': req.href.query(proj_stat.qry_args, project_id=project_id), 'interval_hrefs': [req.href.query(interval['qry_args']) for interval in proj_stat.intervals]} closed_stat = self.stats_provider.get_ticket_resolution_group_stats(project_tickets, project_id) data['proj_closed_stat'] = {'stats': closed_stat, 'stats_href': req.href.query(closed_stat.qry_args, project_id=project_id), 'interval_hrefs': [req.href.query(interval['qry_args']) for interval in closed_stat.intervals]} if metrics['backlog_daily'] or metrics['backlog_table'] or metrics['tkt_extra_stats']: tkt_group_metrics = TicketGroupMetrics(self.env, project_tickets) if metrics['tkt_extra_stats']: tkt_frequency_stats = tkt_group_metrics.get_frequency_metrics_stats() tkt_duration_stats = tkt_group_metrics.get_duration_metrics_stats() data.update({ 'ticket_frequency_stats': tkt_frequency_stats, 'ticket_duration_stats': tkt_duration_stats, }) if metrics['backlog_table']: bmi_stats = [] d = first_day_group fday = datetime(d.year, d.month, d.day, tzinfo=req.tz) for _i in xrange(groupcnt): lday = fday + timedelta(groupsize, microseconds=-1) bstats = tkt_group_metrics.get_bmi_stats(fday, lday) bmi_stats.append(('%s - %s' % (format_date(fday), format_date(lday)),) + bstats) fday += timedelta(groupsize) data['project_bmi_stats'] = bmi_stats if metrics['backlog_daily']: # get daily backlog history backlog_history = tkt_group_metrics.get_daily_backlog_history(first_day, last_day) daily_backlog_chart = tkt_group_metrics.get_daily_backlog_chart(backlog_history) data['ds_daily_backlog'] = daily_backlog_chart if metrics['repos_stats']: # Get daily commits history changeset_group_stats = ChangesetsStats(self.env, project_id, first_day, last_day) commits_by_date = changeset_group_stats.get_commit_by_date() commits_by_date_chart = changeset_group_stats.get_commit_by_date_chart(commits_by_date) data['ds_commit_by_date'] = commits_by_date_chart data_json = {} if metrics['tkt_activity']: data['ticket_activity'] = reports.ticket_activity(project_id, first_day, last_day, db, req) data_json['ticket_activity'] = simplejson.dumps(data['ticket_activity'].get_data()) if metrics['repos_activity']: data['repository_activity'] = reports.repository_activity(project_id, first_day_group, last_day, groupsize, groupcnt, db, req, authors_limit=self.tm.authors_limit_repos) data_json['repository_activity'] = simplejson.dumps(data['repository_activity'].get_data()) if metrics['wiki_activity']: data['wiki_activity'] = reports.wiki_activity(project_id, first_day, last_day, groupsize, groupcnt, db, req, authors_limit=self.tm.authors_limit_wiki) data_json['wiki_activity'] = simplejson.dumps(data['wiki_activity'].get_data()) data['json'] = data_json return ('pdashboard.html', data, None)
def process_request(self, req): req.perm.require('REPORT_VIEW') req_content = req.args.get('content') milestone = None 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') grab_milestone = req.args.get('milestone') if grab_milestone == "__all": milestone = None else: milestone = grab_milestone # 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) at_date = datetime.combine(at_date, time(11, 59, 59, 0, utc)) # Add tzinfo from_date = parse_date(grab_from_date) from_date = datetime.combine(from_date, time(0, 0, 0, 0, utc)) # Add tzinfo graph_res = int(grab_resolution) else: # default data todays_date = date.today() at_date = datetime.combine(todays_date, time(11, 59, 59, 0, utc)) from_date = at_date - timedelta(self.default_days_back) graph_res = self.default_interval count = [] db = self.env.get_db_cnx() # Calculate 0th point last_date = from_date - timedelta(graph_res) last_num_open = get_num_open_tix(db, last_date, milestone) # Calculate remaining points for cur_date in date_range(from_date, at_date, graph_res): num_open = get_num_open_tix(db, cur_date, milestone) num_closed = get_num_closed_tix(db, last_date, cur_date, milestone) date_str = format_date(cur_date) if graph_res != 1: date_str = "%s thru %s" % (format_date(last_date), date_str) count.append({ 'date': date_str, 'new': num_open - last_num_open + num_closed, 'closed': num_closed, 'open': num_open }) last_num_open = num_open last_date = cur_date # if chart data is requested, raw text is returned rather than data # object for templating if req_content is not None and req_content == "chartdata": js_data = '{"chartdata": [\n' for x in count: js_data += '{"date": "%s",' % x['date'] js_data += ' "new_tickets": %s,' % x['new'] js_data += ' "closed": %s,' % x['closed'] js_data += ' "open": %s},\n' % x['open'] js_data = js_data[:-2] + '\n]}' req.send(js_data.encode('utf-8')) return else: show_all = req.args.get('show') == 'all' milestone_list = [ m.name for m in Milestone.select(self.env, show_all) ] if milestone in milestone_list: milestone_num = milestone_list.index(milestone) + 1 else: milestone_num = 0 data = { 'ticket_data': count, 'start_date': format_date(from_date), 'end_date': format_date(at_date), 'resolution': str(graph_res), 'baseurl': req.base_url, 'milestones': milestone_list, 'cmilestone': milestone_num, 'yui_base_url': self.yui_base_url, 'debug': 'debug' in req.args } if hasattr(Chrome, 'add_jquery_ui'): Chrome(self.env).add_jquery_ui(req) return 'ticketstats.html', data, None
def _render_view(self, req, milestone): milestone_groups = [] available_groups = [] component_group_available = False ticket_fields = TicketSystem(self.env).get_ticket_fields() # collect fields that can be used for grouping for field in ticket_fields: if field['type'] == 'select' and field['name'] != 'milestone' \ or field['name'] in ('owner', 'reporter'): available_groups.append({ 'name': field['name'], 'label': field['label'] }) if field['name'] == 'component': component_group_available = True # determine the field currently used for grouping by = None if component_group_available: by = 'component' elif available_groups: by = available_groups[0]['name'] by = req.args.get('by', by) tickets = get_tickets_for_milestone(self.env, milestone=milestone.name, field=by) tickets = apply_ticket_permissions(self.env, req, tickets) stat = get_ticket_stats(self.stats_provider, tickets) context = web_context(req, milestone.resource) data = { 'context': context, 'milestone': milestone, 'attachments': AttachmentModule(self.env).attachment_data(context), 'available_groups': available_groups, 'grouped_by': by, 'groups': milestone_groups } data.update(milestone_stats_data(self.env, req, stat, milestone.name)) if by: groups = [] for field in ticket_fields: if field['name'] == by: if 'options' in field: groups = field['options'] if field.get('optional'): groups.insert(0, '') else: groups = [ group for group, in self.env.db_query(""" SELECT DISTINCT COALESCE(%s, '') FROM ticket ORDER BY COALESCE(%s, '') """ % (by, by)) ] max_count = 0 group_stats = [] for group in groups: values = (group, ) if group else (None, group) group_tickets = [t for t in tickets if t[by] in values] if not group_tickets: continue gstat = get_ticket_stats(self.stats_provider, group_tickets) if gstat.count > max_count: max_count = gstat.count group_stats.append(gstat) gs_dict = {'name': group} gs_dict.update( milestone_stats_data(self.env, req, gstat, milestone.name, by, group)) milestone_groups.append(gs_dict) for idx, gstat in enumerate(group_stats): gs_dict = milestone_groups[idx] percent = 1.0 if max_count: percent = float(gstat.count) / float(max_count) * 100 gs_dict['percent_of_max_total'] = percent add_stylesheet(req, 'common/css/roadmap.css') add_script(req, 'common/js/folding.js') def add_milestone_link(rel, milestone): href = req.href.milestone(milestone.name, by=req.args.get('by')) add_link(req, rel, href, _('Milestone "%(name)s"', name=milestone.name)) milestones = [ m for m in Milestone.select(self.env) if 'MILESTONE_VIEW' in req.perm(m.resource) ] idx = [i for i, m in enumerate(milestones) if m.name == milestone.name] if idx: idx = idx[0] if idx > 0: add_milestone_link('first', milestones[0]) add_milestone_link('prev', milestones[idx - 1]) if idx < len(milestones) - 1: add_milestone_link('next', milestones[idx + 1]) add_milestone_link('last', milestones[-1]) prevnext_nav(req, _('Previous Milestone'), _('Next Milestone'), _('Back to Roadmap')) return 'milestone_view.html', data, None
def _render_view(self, req, milestone): milestone_groups = [] available_groups = [] component_group_available = False ticket_fields = TicketSystem(self.env).get_ticket_fields() # collect fields that can be used for grouping for field in ticket_fields: if field['type'] == 'select' and field['name'] != 'milestone' \ or field['name'] in ('owner', 'reporter'): available_groups.append({'name': field['name'], 'label': field['label']}) if field['name'] == 'component': component_group_available = True # determine the field currently used for grouping by = None if component_group_available: by = 'component' elif available_groups: by = available_groups[0]['name'] by = req.args.get('by', by) tickets = get_tickets_for_milestone(self.env, milestone=milestone.name, field=by) tickets = apply_ticket_permissions(self.env, req, tickets) stat = get_ticket_stats(self.stats_provider, tickets) context = web_context(req, milestone.resource) data = { 'context': context, 'milestone': milestone, 'attachments': AttachmentModule(self.env).attachment_data(context), 'available_groups': available_groups, 'grouped_by': by, 'groups': milestone_groups } data.update(milestone_stats_data(self.env, req, stat, milestone.name)) if by: def per_group_stats_data(gstat, group_name): return milestone_stats_data(self.env, req, gstat, milestone.name, by, group_name) milestone_groups.extend( grouped_stats_data(self.env, self.stats_provider, tickets, by, per_group_stats_data)) add_stylesheet(req, 'common/css/roadmap.css') add_script(req, 'common/js/folding.js') def add_milestone_link(rel, milestone): href = req.href.milestone(milestone.name, by=req.args.get('by')) add_link(req, rel, href, _('Milestone "%(name)s"', name=milestone.name)) milestones = [m for m in Milestone.select(self.env) if 'MILESTONE_VIEW' in req.perm(m.resource)] idx = [i for i, m in enumerate(milestones) if m.name == milestone.name] if idx: idx = idx[0] if idx > 0: add_milestone_link('first', milestones[0]) add_milestone_link('prev', milestones[idx - 1]) if idx < len(milestones) - 1: add_milestone_link('next', milestones[idx + 1]) add_milestone_link('last', milestones[-1]) prevnext_nav(req, _('Previous Milestone'), _('Next Milestone'), _('Back to Roadmap')) return 'milestone_view.html', data, None
def process_request(self, req): if req.path_info == '/flashgantt/chartxml': req.perm.require('MILESTONE_VIEW') showall = req.args.get('show') == 'all' # Get the current date and time cur_dt = datetime.date.today() # Get the quarter I am in. cur_quarter = self._get_quarter(cur_dt.month) prev_quarter = self._get_prev_quarter(cur_quarter) next_quarter = self._get_next_quarter(cur_quarter) (cq_sd, cq_ed) = self._get_quarter_start_end_dates( cur_dt.year, cur_quarter) (pq_sd, pq_ed) = self._get_prev_quarters_start_end_dates( cur_dt.year, cur_quarter) (nq_sd, nq_ed) = self._get_next_quarters_start_end_dates( cur_dt.year, cur_quarter) min_date = pq_sd.strftime('%d/%m/%Y') max_date = nq_ed.strftime('%d/%m/%Y') quarters = [] quarters.append({ 'name': 'Q' + str(prev_quarter) + ' ' + str(pq_sd.year), 'start_date': pq_sd.strftime('%d/%m/%Y'), 'end_date': pq_ed.strftime('%d/%m/%Y') }) quarters.append({ 'name': 'Q' + str(cur_quarter) + ' ' + str(cq_sd.year), 'start_date': cq_sd.strftime('%d/%m/%Y'), 'end_date': cq_ed.strftime('%d/%m/%Y') }) quarters.append({ 'name': 'Q' + str(next_quarter) + ' ' + str(nq_sd.year), 'start_date': nq_sd.strftime('%d/%m/%Y'), 'end_date': nq_ed.strftime('%d/%m/%Y') }) months = [] for x in range(pq_sd.month, (pq_ed.month + 1)): (cm_sd, cm_ed) = self._get_month_start_end_dates(pq_sd.year, x) months.append({ 'name': self._get_month_name(x), 'start_date': cm_sd.strftime('%d/%m/%Y'), 'end_date': cm_ed.strftime('%d/%m/%Y') }) for x in range(cq_sd.month, (cq_ed.month + 1)): (cm_sd, cm_ed) = self._get_month_start_end_dates(cq_sd.year, x) months.append({ 'name': self._get_month_name(x), 'start_date': cm_sd.strftime('%d/%m/%Y'), 'end_date': cm_ed.strftime('%d/%m/%Y') }) for x in range(nq_sd.month, (nq_ed.month + 1)): (cm_sd, cm_ed) = self._get_month_start_end_dates(nq_sd.year, x) months.append({ 'name': self._get_month_name(x), 'start_date': cm_sd.strftime('%d/%m/%Y'), 'end_date': cm_ed.strftime('%d/%m/%Y') }) milestones = [] db = self.env.get_db_cnx() ms = [ m for m in Milestone.select(self.env, showall, db) if 'MILESTONE_VIEW' in req.perm(m.resource) ] cnt = 0 for m in ms: cnt = cnt + 1 comp_stat = 0 if (m.is_completed): comp_stat = 1 milestones.append({ 'name': m.name, 'id': str(cnt), 'start_date': pq_sd.strftime('%d/%m/%Y'), 'due_date': format_date(m.due, format='%d/%m/%Y'), 'completed_date': format_date(m.completed, format='%d/%m/%Y'), 'completed': comp_stat }) data = { 'milestones': milestones, 'showall': showall, 'visible_months': months, 'quarters': quarters } # This tuple is for Genshi (template_name, data, content_type) # Without data the trac layout will not appear. return ('chart.xml', data, 'text/xml') else: req.perm.require('MILESTONE_VIEW') showall = req.args.get('show') == 'all' db = self.env.get_db_cnx() milestones = [ m for m in Milestone.select(self.env, showall, db) if 'MILESTONE_VIEW' in req.perm(m.resource) ] chart_height = 150 + (len(milestones) * 29) if (showall): xmlcharturl = req.href.flashgantt('/chartxml?show=all') else: xmlcharturl = req.href.flashgantt('/chartxml') data = { 'milestones': milestones, 'showall': showall, 'xmlcharturl': xmlcharturl, 'chart_height': chart_height } #add_stylesheet(req, 'fg/css/flashgantt.css') # This tuple is for Genshi (template_name, data, content_type) # Without data the trac layout will not appear. return ('flashgantt.html', data, None)
def process_request(self, req): req.perm.require('REPORT_VIEW') req_content = req.args.get('content') milestone = None 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') grab_milestone = req.args.get('milestone') if grab_milestone == "__all": milestone = None else: milestone = grab_milestone # 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) at_date = datetime.combine(at_date, time(11, 59, 59, 0, utc)) # Add tzinfo from_date = parse_date(grab_from_date) from_date = datetime.combine(from_date, time(0, 0, 0, 0, utc)) # Add tzinfo graph_res = int(grab_resolution) else: # default data todays_date = date.today() at_date = datetime.combine(todays_date, time(11, 59, 59, 0, utc)) from_date = at_date - timedelta(self.default_days_back) graph_res = self.default_interval count = [] db = self.env.get_db_cnx() # Calculate 0th point last_date = from_date - timedelta(graph_res) last_num_open = get_num_open_tix(db, last_date, milestone) # Calculate remaining points for cur_date in date_range(from_date, at_date, graph_res): num_open = get_num_open_tix(db, cur_date, milestone) num_closed = get_num_closed_tix(db, last_date, cur_date, milestone) date_str = format_date(cur_date) if graph_res != 1: date_str = "%s thru %s" % (format_date(last_date), date_str) count.append({'date': date_str, 'new': num_open - last_num_open + num_closed, 'closed': num_closed, 'open': num_open}) last_num_open = num_open last_date = cur_date # if chart data is requested, raw text is returned rather than data # object for templating if req_content is not None and req_content == "chartdata": js_data = '{"chartdata": [\n' for x in count: js_data += '{"date": "%s",' % x['date'] js_data += ' "new_tickets": %s,' % x['new'] js_data += ' "closed": %s,' % x['closed'] js_data += ' "open": %s},\n' % x['open'] js_data = js_data[:-2] + '\n]}' req.send(js_data.encode('utf-8')) return else: show_all = req.args.get('show') == 'all' milestone_list = [m.name for m in Milestone.select(self.env, show_all)] if milestone in milestone_list: milestone_num = milestone_list.index(milestone) + 1 else: milestone_num = 0 data = { 'ticket_data': count, 'start_date': format_date(from_date), 'end_date': format_date(at_date), 'resolution': str(graph_res), 'baseurl': req.base_url, 'milestones': milestone_list, 'cmilestone': milestone_num, 'yui_base_url': self.yui_base_url, 'debug': 'debug' in req.args } if hasattr(Chrome, 'add_jquery_ui'): Chrome(self.env).add_jquery_ui(req) return 'ticketstats.html', data, None