예제 #1
0
    def test_milestone(self):
        milestone = Milestone(self.env)
        milestone.name = 'New target date'
        milestone.description = 'Lorem ipsum dolor sit amet'
        milestone.insert()
        so = self._get_so()
        self.assertEquals('%s:milestone:New target date' % self.basename,
                          so.doc_id)
        self.assertEquals('milestone', so.realm),
        self.assertEquals('New target date', so.id)
        self.assertTrue('New target date' in so.title)
        self.assertTrue('Lorem ipsum' in so.title)
        self.assertTrue('Lorem ipsum' in so.oneline)
        self.assertTrue('Lorem ipsum' in so.body)

        milestone.description = 'No latin filler here'
        milestone.due = datetime(2001, 01, 01, tzinfo=utc)
        milestone.update()
        so = self._get_so()
        self.assertEquals('%s:milestone:New target date' % self.basename,
                          so.doc_id)
        self.assertEquals('milestone', so.realm),
        self.assertEquals('New target date', so.id)
        self.assertEquals(milestone.due, so.changed)
        self.assertFalse('Lorem ipsum' in so.body)
        self.assertTrue('No latin filler here' in so.body)
예제 #2
0
    def process_request(self, req):
        milestone_id = req.args.get('id')
        req.perm('milestone', milestone_id).require('MILESTONE_VIEW')
        
        add_link(req, 'up', req.href.roadmap(), _('Roadmap'))

        action = req.args.get('action', 'view')
        try:
            milestone = Milestone(self.env, milestone_id)
        except ResourceNotFound:
            if 'MILESTONE_CREATE' not in req.perm('milestone', milestone_id):
                raise
            milestone = Milestone(self.env, None)
            milestone.name = milestone_id
            action = 'edit' # rather than 'new' so that it works for POST/save

        if req.method == 'POST':
            if req.args.has_key('cancel'):
                if milestone.exists:
                    req.redirect(req.href.milestone(milestone.name))
                else:
                    req.redirect(req.href.roadmap())
            elif action == 'edit':
                return self._do_save(req, milestone)
            elif action == 'delete':
                self._do_delete(req, milestone)
        elif action in ('new', 'edit'):
            return self._render_editor(req, milestone)
        elif action == 'delete':
            return self._render_confirm(req, milestone)

        if not milestone.name:
            req.redirect(req.href.roadmap())

        return self._render_view(req, milestone)
예제 #3
0
    def process_request(self, req):
        milestone_id = req.args.get('id')
        req.perm('milestone', milestone_id).require('MILESTONE_VIEW')

        add_link(req, 'up', req.href.roadmap(), _('Roadmap'))

        action = req.args.get('action', 'view')
        try:
            milestone = Milestone(self.env, milestone_id)
        except ResourceNotFound:
            if 'MILESTONE_CREATE' not in req.perm('milestone', milestone_id):
                raise
            milestone = Milestone(self.env, None)
            milestone.name = milestone_id
            action = 'edit'  # rather than 'new' so that it works for POST/save

        if req.method == 'POST':
            if req.args.has_key('cancel'):
                if milestone.exists:
                    req.redirect(req.href.milestone(milestone.name))
                else:
                    req.redirect(req.href.roadmap())
            elif action == 'edit':
                return self._do_save(req, milestone)
            elif action == 'delete':
                self._do_delete(req, milestone)
        elif action in ('new', 'edit'):
            return self._render_editor(req, milestone)
        elif action == 'delete':
            return self._render_confirm(req, milestone)

        if not milestone.name:
            req.redirect(req.href.roadmap())

        return self._render_view(req, milestone)
예제 #4
0
 def change_milestone(self, name_to_change, name=None, description=None):
     milestone = Milestone(self.env, name_to_change)
     if name is not None:
         milestone.name = name
     if description is not None:
         milestone.description = description
     milestone.update()
     return milestone
예제 #5
0
 def create_milestone(self, name, due=None, duration=20, db=None):
     """
     Creates a milestone with the given name and due
     date, the latter should be a datetime object
     """
     db, handle_ta = get_db_for_write(self.env, db)
     # Try to load the milestone first
     try:
         m = Milestone(self.env, name=name, db=db)
     except ResourceNotFound:
         # than we create it
         m = Milestone(self.env, db=db)
         m.name = name
         if due is not None and isinstance(due, datetime):
             dueo = due.toordinal() + duration
             m.due = mktime(datetime.fromordinal(dueo).timetuple())
         m.insert()
         if handle_ta:
             try:
                 db.commit()
                 # workaround for the fact that trac in 0.11.1 doesn't set exists correctly...
                 m._old_name = m.name
             except Exception, e:
                 self.env.log.warning(exception_to_unicode(e))
                 db.rollback()
    def test_milestone(self):
        milestone = Milestone(self.env)
        milestone.name = 'New target date'
        milestone.description = 'Lorem ipsum dolor sit amet'
        milestone.insert()
        so = self._get_so()
        self.assertEquals('%s:milestone:New target date' % self.basename,
                          so.doc_id)
        self.assertEquals('milestone', so.realm),
        self.assertEquals('New target date', so.id)
        self.assertTrue('New target date' in so.title)
        self.assertTrue('Lorem ipsum' in so.title)
        self.assertTrue('Lorem ipsum' in so.oneline)
        self.assertTrue('Lorem ipsum' in so.body)

        milestone.description = 'No latin filler here'
        milestone.due = datetime(2001, 01, 01, tzinfo=utc)
        milestone.update()
        so = self._get_so()
        self.assertEquals('%s:milestone:New target date' % self.basename,
                          so.doc_id)
        self.assertEquals('milestone', so.realm),
        self.assertEquals('New target date', so.id)
        self.assertEquals(milestone.due, so.changed)
        self.assertFalse('Lorem ipsum' in so.body)
        self.assertTrue('No latin filler here' in so.body)
예제 #7
0
 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
예제 #8
0
 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 []
예제 #9
0
    def process_request(self, req):
        milestone_id = req.args.get('id')

        req.perm.assert_permission('MILESTONE_VIEW')

        add_link(req, 'up', req.href.roadmap(), 'Roadmap')

        db = self.env.get_db_cnx()
        milestone = Milestone(self.env, milestone_id, db)
        action = req.args.get('action', 'view')

        if req.method == 'POST':
            if req.args.has_key('cancel'):
                if milestone.exists:
                    req.redirect(req.href.milestone(milestone.name))
                else:
                    req.redirect(req.href.roadmap())
            elif action == 'edit':
                self._do_save(req, db, milestone)
            elif action == 'delete':
                self._do_delete(req, db, milestone)
        elif action in ('new', 'edit'):
            self._render_editor(req, db, milestone)
        elif action == 'delete':
            self._render_confirm(req, db, milestone)
        else:
            self._render_view(req, db, milestone)

        if not milestone_id and action != 'new':
            req.redirect(req.href.roadmap())

        add_stylesheet(req, 'common/css/roadmap.css')
        return 'milestone.cs', None
예제 #10
0
    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
예제 #11
0
    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 test_remove_milestone(self):
     test_name = sys._getframe().f_code.co_name
     expected = self.expected_results[test_name]
     ticket = Ticket(self.env)
     ticket.populate({'reporter': 'santa', 'summary': 'Summary line',
                      'description': 'Lorem ipsum dolor sit amet',
                      })
     ticket.insert()
     milestone = Milestone(self.env)
     milestone.name = 'New target date'
     milestone.description = 'Lorem ipsum dolor sit amet'
     milestone.insert()
     self.assertEqual(2, len(self._get_docs()))
     rv, output = self._execute('fulltext remove milestone')
     self.assertEqual(expected, output)
     self.assertEqual(1, len(self._get_docs()))
예제 #13
0
    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
예제 #14
0
파일: hook.py 프로젝트: willat8/extras
    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)
예제 #15
0
 def _create_milestone(self, name, duedate, description):
     m = Milestone(self.env)
     m.name = name
     m.description = description
     if duedate:
         if isinstance(duedate, type("")):
             m.due = parse_date(duedate)
         else:
             m.due = duedate
     m.insert()
예제 #16
0
 def create_milestone(self, name, due=None, duration=20, db=None):
     """
     Creates a milestone with the given name and due
     date, the latter should be a datetime object
     """
     db, handle_ta = get_db_for_write(self.env, db)
     # Try to load the milestone first
     try:
         m = Milestone(self.env, name=name, db=db)
     except ResourceNotFound:
         # than we create it
         m = Milestone(self.env, db=db)
         m.name = name
         if due is not None and isinstance(due, datetime):
             dueo = due.toordinal() + duration
             m.due = mktime(datetime.fromordinal(dueo).timetuple())
         m.insert()
         if handle_ta:
             try:
                 db.commit()
                 # workaround for the fact that trac in 0.11.1 doesn't set exists correctly...
                 m._old_name = m.name
             except Exception, e:
                 self.env.log.warning(exception_to_unicode(e))
                 db.rollback()
예제 #17
0
 def testMilestoneRenamePropagatesToSprints(self):
     """Tests that the rename of a Milestone, propagates to the Sprints, this
     is an AgiloMilestone feature"""
     m = Milestone(self.env)
     m.name = 'test_me'
     m.insert()
     s = self.teh.create_sprint('my sprint', milestone=m.name)
     self.assert_equals(m.name, s.milestone)
     # AT: we need to reload the milestone as there is a problem in trac,
     # that the insert is not updating the _old_name, making the update
     # silently fail. I sent a patch for this
     m = Milestone(self.env, m.name)
     m.name = 'test_me_not'
     m.update()
     smm = SprintModelManager(self.env)
     smm.get_cache().invalidate()
     s = smm.get(name=s.name)
     self.assert_equals(m.name, s.milestone)
예제 #18
0
    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)]
예제 #19
0
	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) ]
예제 #20
0
파일: hook.py 프로젝트: nilknarf0/extras
    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)
예제 #21
0
    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
예제 #22
0
 def test_can_index_delete(self):
     #arrange
     self.insert_milestone(self.DUMMY_MILESTONE_NAME)
     results = self.search_api.query("*")
     self.assertEqual(1, results.hits)
     #act
     Milestone(self.env, self.DUMMY_MILESTONE_NAME).delete()
     #assert
     results = self.search_api.query("*")
     self.print_result(results)
     self.assertEqual(0, results.hits)
예제 #23
0
    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
예제 #24
0
 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
예제 #25
0
 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
예제 #26
0
    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
예제 #27
0
    def process_request(self, req):
        req.perm.assert_permission('TICKET_CREATE')

        db = self.env.get_db_cnx()

        if req.method == 'POST' and not req.args.has_key('preview'):
            self._do_create(req, db)

        ticket = Ticket(self.env, db=db)
        ticket.populate(req.args)
        ticket.values.setdefault('reporter', util.get_reporter_id(req))

        if ticket.values.has_key('description'):
            description = wiki_to_html(ticket['description'], self.env, req, db)
            req.hdf['newticket.description_preview'] = description

        req.hdf['title'] = 'New Ticket'
        req.hdf['newticket'] = dict(zip(ticket.values.keys(),
                                        [util.escape(value) for value
                                         in ticket.values.values()]))

        field_names = [field['name'] for field in ticket.fields
                       if not field.get('custom')]
        if 'owner' in field_names:
            curr_idx = field_names.index('owner')
            if 'cc' in field_names:
                insert_idx = field_names.index('cc')
            else:
                insert_idx = len(field_names)
            if curr_idx < insert_idx:
                ticket.fields.insert(insert_idx, ticket.fields[curr_idx])
                del ticket.fields[curr_idx]

        for field in ticket.fields:
            name = field['name']
            del field['name']
            if name in ('summary', 'reporter', 'description', 'type', 'status',
                        'resolution'):
                field['skip'] = True
            elif name == 'owner':
                field['label'] = 'Assign to'
            elif name == 'milestone':
                # Don't make completed milestones available for selection
                options = field['options'][:]
                for option in field['options']:
                    milestone = Milestone(self.env, option, db=db)
                    if milestone.is_completed:
                        options.remove(option)
                field['options'] = [util.escape(option) for option in options]
            req.hdf['newticket.fields.' + name] = field

        add_stylesheet(req, 'common/css/ticket.css')
        return 'newticket.cs', None
예제 #28
0
    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
예제 #29
0
	def _create_milestone(self, name, duedate, description):
		m = Milestone(self.env)
		m.name = name
		m.description = description
		if duedate:
			if isinstance(duedate, type("")):
				m.due = parse_date(duedate)
			else:
				m.due = duedate
		m.insert()
예제 #30
0
 def test_can_save_due_date(self):
     # Added when Trac 0.12 was released as the format of the timestamp has changed in 0.12
     milestone = Milestone(self.env)
     milestone.name = 'fnord'
     milestone.insert()
     # in trac 0.11.1, milestone._old_name is not set to "fnord" at
     # insert() time, only on init() or update()
     # so we need to reload the object to be able to run update() on it
     milestone = Milestone(self.env, name='fnord')
     
     expected_time = now().replace(microsecond=0)
     milestone.due = expected_time
     milestone.completed = expected_time
     milestone.update()
     
     loaded_milestone = Milestone(self.env, name='fnord')
     self.assert_equals(expected_time, loaded_milestone.due)
     self.assert_equals(expected_time, loaded_milestone.completed)
예제 #31
0
def execute(hdf, txt, env):
    out = StringIO()
    out.write('<ul>\n')
    for milestone in Milestone.select(env, include_completed=False):
        if milestone.due > 0:
            date = format_date(milestone.due)
        else:
            date = Markup('<i>(later)</i>')
        out.write(Markup('<li>%s - <a href="%s">%s</a></li>\n',
                         date, env.href.milestone(milestone.name),
                         milestone.name))
    out.write('</ul>\n')
    return out.getvalue()
예제 #32
0
def execute(hdf, txt, env):
    out = StringIO()
    out.write('<ul>\n')
    for milestone in Milestone.select(env, include_completed=False):
        if milestone.due > 0:
            date = format_date(milestone.due)
        else:
            date = Markup('<i>(later)</i>')
        out.write(
            Markup('<li>%s - <a href="%s">%s</a></li>\n', date,
                   env.href.milestone(milestone.name), milestone.name))
    out.write('</ul>\n')
    return out.getvalue()
예제 #33
0
파일: base.py 프로젝트: tsanov/bloodhound
 def change_milestone(self, name_to_change, name=None, description=None):
     milestone = Milestone(self.env, name_to_change)
     if name is not None:
         milestone.name = name
     if description is not None:
         milestone.description = description
     milestone.update()
     return milestone
예제 #34
0
 def testMilestoneRenamePropagatesToTickets(self):
     """Tests that the Milestone renaming is propagated to the tickets, this
     should work out of the box, as it is a Trac feature"""
     m = Milestone(self.env)
     m.name = 'test_me'
     m.insert()
     t = self.teh.create_ticket(Type.REQUIREMENT, {Key.MILESTONE: m.name})
     self.assert_equals(m.name, t[Key.MILESTONE])
     # AT: we need to reload the milestone as there is a problem in trac,
     # that the insert is not updating the _old_name, making the update
     # silently fail. I sent a patch for this
     m = Milestone(self.env, m.name)
     m.name = 'test_me_not'
     m.update()
     # test the changes happened in the DB
     db = self.env.get_db_cnx()
     cursor = db.cursor()
     cursor.execute("SELECT id, milestone FROM ticket WHERE milestone='test_me'")
     for row in cursor:
         self.fail("Found one old milestone in ticket: #%s (%s)" % \
                   (row[0], row[1]))
     t = self.teh.load_ticket(t)
     self.assert_equals(m.name, t[Key.MILESTONE])
예제 #35
0
    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
예제 #36
0
    def _render_view(self, req, db, version):

        db = self.env.get_db_cnx()
        sql = "SELECT name FROM milestone " \
              "INNER JOIN milestone_version ON (name = milestone) " \
              "WHERE version = %s " \
              "ORDER BY due"
        cursor = db.cursor()
        cursor.execute(sql, (version.name,))

        milestones = []
        tickets = []
        milestone_stats = []

        for row in cursor:
            milestone = Milestone(self.env, row[0])
            milestones.append(milestone)

            mtickets = get_tickets_for_milestone(self.env, db, milestone.name,
                                                 'owner')
            mtickets = apply_ticket_permissions(self.env, req, mtickets)
            tickets += mtickets
            stat = get_ticket_stats(self.milestone_stats_provider, mtickets)
            milestone_stats.append(milestone_stats_data(self.env, req, stat, milestone.name))

        stats = get_ticket_stats(self.version_stats_provider, tickets)
        interval_hrefs = version_interval_hrefs(self.env, req, stats,
                                                [milestone.name for milestone in milestones])

        version.resource = Resource('version', version.name)
        context = Context.from_request(req, version.resource)

        version.is_released = version.time and version.time.date() < date.today()
        version.stats = stats
        version.interval_hrefs = interval_hrefs
        version.stats_href = [] # Not implemented yet, see th:#10349
        data = {
            'context': context,
            'version': version,
            'attachments': AttachmentModule(self.env).attachment_data(context),
            'milestones': milestones,
            'milestone_stats': milestone_stats,
            'show_milestone_description': self.show_milestone_description # Not implemented yet
        }

        add_stylesheet(req, 'extendedversion/css/version.css')
        add_script(req, 'common/js/folding.js')
        add_ctxtnav(req, _("Back to Versions"), req.href.versions())
        return 'version_view.html', data, None
예제 #37
0
    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())
예제 #38
0
    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
예제 #39
0
    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())
예제 #40
0
 def _render_link(self, context, name, label, extra=''):
     try:
         milestone = Milestone(self.env, name)
     except TracError:
         milestone = None
     # Note: the above should really not be needed, `Milestone.exists`
     # should simply be false if the milestone doesn't exist in the db
     # (related to #4130)
     href = context.href.milestone(name)
     if milestone and milestone.exists:
         if 'MILESTONE_VIEW' in context.perm(milestone.resource):
             closed = 'closed ' if milestone.is_completed else ''
             return tag.a(label, class_='%smilestone' % closed,
                          href=href + extra)
     elif 'MILESTONE_CREATE' in context.perm('milestone', name):
         return tag.a(label, class_='missing milestone', href=href + extra,
                      rel='nofollow')
     return tag.a(label, class_='missing milestone')
예제 #41
0
파일: roadmap.py 프로젝트: jun66j5/TraM
   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')
예제 #42
0
    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
예제 #43
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()
예제 #44
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
예제 #45
0
    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
예제 #46
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()
예제 #47
0
    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
예제 #48
0
 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')
예제 #49
0
    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')
예제 #50
0
    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
예제 #51
0
 def test_remove_milestone(self):
     test_name = sys._getframe().f_code.co_name
     expected = self.expected_results[test_name]
     ticket = Ticket(self.env)
     ticket.populate({
         'reporter': 'santa',
         'summary': 'Summary line',
         'description': 'Lorem ipsum dolor sit amet',
     })
     ticket.insert()
     milestone = Milestone(self.env)
     milestone.name = 'New target date'
     milestone.description = 'Lorem ipsum dolor sit amet'
     milestone.insert()
     self.assertEqual(2, len(self._get_docs()))
     rv, output = self._execute('fulltext remove milestone')
     self.assertEqual(expected, output)
     self.assertEqual(1, len(self._get_docs()))
예제 #52
0
    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)
예제 #53
0
 def getMilestones(self, component, req ):
     milestones = []
     for m in Milestone.select(component.env) :
         milestones.append(m.name) 
     return milestones
예제 #54
0
 def create_milestone(self, name, description = None):
     milestone = Milestone(self.env)
     milestone.name = name
     if description is not None:
         milestone.description = description
     return milestone
예제 #55
0
    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
예제 #56
0
    def _do_save(self, req, milestone):
        if milestone.exists:
            req.perm(milestone.resource).require('MILESTONE_MODIFY')
        else:
            req.perm(milestone.resource).require('MILESTONE_CREATE')

        old_name = milestone.name
        new_name = req.args.get('name')

        milestone.description = req.args.get('description', '')

        if 'due' in req.args:
            due = req.args.get('duedate', '')
            milestone.due = user_time(req, parse_date, due, hint='datetime') \
                            if due else None
        else:
            milestone.due = None

        completed = req.args.get('completeddate', '')
        retarget_to = req.args.get('target')

        # Instead of raising one single error, check all the constraints and
        # let the user fix them by going back to edit mode showing the warnings
        warnings = []

        def warn(msg):
            add_warning(req, msg)
            warnings.append(msg)

        # -- check the name
        # If the name has changed, check that the milestone doesn't already
        # exist
        # FIXME: the whole .exists business needs to be clarified
        #        (#4130) and should behave like a WikiPage does in
        #        this respect.
        try:
            new_milestone = Milestone(self.env, new_name)
            if new_milestone.name == old_name:
                pass  # Creation or no name change
            elif new_milestone.name:
                warn(
                    _(
                        'Milestone "%(name)s" already exists, please '
                        'choose another name.',
                        name=new_milestone.name))
            else:
                warn(_('You must provide a name for the milestone.'))
        except ResourceNotFound:
            milestone.name = new_name

        # -- check completed date
        if 'completed' in req.args:
            completed = user_time(req, parse_date, completed,
                                  hint='datetime') if completed else None
            if completed and completed > datetime.now(utc):
                warn(_('Completion date may not be in the future'))
        else:
            completed = None
        milestone.completed = completed

        if warnings:
            return self._render_editor(req, milestone)

        # -- actually save changes
        if milestone.exists:
            milestone.update()
            # eventually retarget opened tickets associated with the milestone
            if 'retarget' in req.args and completed:
                self.env.db_transaction(
                    """
                    UPDATE ticket SET milestone=%s
                    WHERE milestone=%s and status != 'closed'
                    """, (retarget_to, old_name))
                self.log.info("Tickets associated with milestone %s "
                              "retargeted to %s" % (old_name, retarget_to))
        else:
            milestone.insert()

        add_notice(req, _("Your changes have been saved."))
        req.redirect(req.href.milestone(milestone.name))
예제 #57
0
 def get_entries_for_index(self):
     for milestone in Milestone.select(self.env, include_completed=True):
         yield self.build_doc(milestone)