Exemplo n.º 1
0
    def _group_sprints_by_milestone(self, req, milestones_to_show):
        """
        Returns a dict which holds the sprints grouped by milestone 
        (key: milestone, value: list of tuples (sprint, progress bar data)).
        The dict contains only sprints for milestones in milestones_to_show.
        """
        # save sprints in dictionary, key is the associated milestone
        provider = DefaultTicketGroupStatsProvider(self.env)
        
        milestone_names = [milestone.name for milestone in milestones_to_show]
        
        sprints = {}
        sp_controller = SprintController(self.env)
        list_sprints = SprintController.ListSprintsCommand(self.env,
                                                           criteria={'milestone': 'in %s' % \
                                                                     milestone_names})
        for s in sp_controller.process_command(list_sprints):
#            milestone_name = sprint.milestone
#            if (not milestone_name) or (milestone_name not in milestone_names):
#                continue
            milestone_name = s.milestone
            if milestone_name not in sprints:
                sprints[milestone_name] = []
            sprint_stats = self.build_sprint_story_statistics(req, s.name,
                                                              provider=provider)
            sprint_data = (s, sprint_stats)
            sprints[milestone_name].append(sprint_data)
        return sprints
Exemplo n.º 2
0
class AgiloRoadmapModule(RoadmapModule):
    implements(IRequestHandler)
    
    def __init__(self):
        """Initialize a Sprint Controller"""
        self.controller = SprintController(self.env)
    
    # --------------------------------------------------------------------------
    # Felix Schwarz, 11.10.2008: Copied from trac.ticket.roadmap (0.11), we
    # initially needed our own copy of that because we want to filter the ticket 
    # by sprint name and not by milestone name. Now we want to filter by type, too.
    def _build_sprint_stats_data(self, req, stat, sprint_name, grouped_by='component', 
                                 group=None, type_names=None):
        all_type_names = AgiloConfig(self.env).get_available_types()
        
        def query_href(extra_args):
            args = {'sprint': sprint_name, grouped_by: group, 
                    'group': 'status'}
            # custom addition to show only certain types
            if type_names != None:
                if len(type_names) == 1:
                    args[Key.TYPE] = type_names[0]
                elif len(type_names) > 1:
                    uninteresting_types = set(all_type_names).difference(set(type_names))
                    args[Key.TYPE] = ['!' + name for name in uninteresting_types]
            # end of custom addition
            args.update(extra_args)
            return req.href.query(args)
        
        return {'stats': stat,
                'stats_href': query_href(stat.qry_args),
                'interval_hrefs': [query_href(interval['qry_args'])
                                   for interval in stat.intervals]}
    # --------------------------------------------------------------------------

    def _build_story_statistics(self, req, stats_provider, sprint_name):
        """
        Assemble statistics for all stories in the given sprint_name so 
        that the progress bar can be displayed.
        """
        sprint_stats = dict()
        
        if not sprint_name:
            return sprint_stats
        
        cmd_get_stories = SprintController.ListTicketsHavingPropertiesCommand(self.env,
                                                                              sprint=sprint_name,
                                                                              properties=[Key.STORY_POINTS])
        stories = self.controller.process_command(cmd_get_stories)
        type_dict = dict()
        closed_stories = list()
        inprogress_stories = list()
        for story in stories:
            if story[Key.STATUS] == Status.CLOSED:
                closed_stories.append(story)
            elif story[Key.STATUS] != Status.NEW:
                inprogress_stories.append(story)
            type_dict[story[Key.TYPE]] = True
        type_names = type_dict.keys()
        number_open_stories = len(stories) - (len(closed_stories) + \
                                              len(inprogress_stories))
        
        try:
            stat = TicketGroupStats('User Stories status', 'stories')
            stat.add_interval(_('Completed'), len(closed_stories), 
                              qry_args={Key.STATUS: Status.CLOSED},
                              css_class='closed', overall_completion=True)
            stat.add_interval(_('In Progress'), len(inprogress_stories), 
                              qry_args={Key.STATUS: Status.ACCEPTED},
                              css_class='inprogress')
            stat.add_interval(_('Open'), number_open_stories, 
                              qry_args={Key.STATUS: [Status.NEW, 
                                                     Status.REOPENED]},
                              css_class='open')
            stat.refresh_calcs()
            sprint_stats = self._build_sprint_stats_data(req, stat, sprint_name, 
                                                         type_names=type_names)
        except Exception, e:
            # The DB is closed? And we don't break for statistics
            error(stats_provider, "ERROR: %s" % to_unicode(e))
        return sprint_stats