Example #1
0
def copy_milestone(source_env, dest_env, name, dest_db=None):
    # In case a string gets passed in
    if not isinstance(source_env, Environment):
        source_env = _open_environment(source_env)
    if not isinstance(dest_env, Environment):
        dest_env = _open_environment(dest_env)
        
    # Log message
    source_env.log.info('DatamoverPlugin: Moving milestone %s to the environment at %s', name, dest_env.path)
    dest_env.log.info('DatamoverPlugin: Moving milestone %s from the environment at %s', name, source_env.path)
    
    # Open databases
    source_db = source_env.get_db_cnx()
    source_cursor = source_db.cursor()
    handle_commit = True
    if not dest_db:
        dest_db, handle_commit = dest_env.get_db_cnx(), False
    dest_cursor = dest_db.cursor()
    
    # Remove the milestone from the destination
    try:
        dest_milestone = Milestone(dest_env, name, db=dest_db)
        dest_milestone.delete(retarget_to=name, db=dest_db)
    except TracError:
        pass

    # Copy each entry in the milestone table
    source_cursor.execute('SELECT * FROM milestone WHERE name=%s',(name,))
    for row in source_cursor:
        milestone_data = dict(zip([d[0] for d in source_cursor.description], row))
        q = make_query(milestone_data, 'milestone')
        dest_cursor.execute(*q)
       
    if handle_commit:
        dest_db.commit()
Example #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 'cancel' in req.args:
                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)
    def test_reset_milestone(self):
        self.env.config.set('ticket', 'workflow',
            'ConfigurableTicketWorkflow,TicketWorkflowOpResetMilestone')
        self._config_set('ticket-workflow', [
            ('reset-milestone', '* -> *'),
            ('reset-milestone.operations', 'reset_milestone'),
        ])
        tktid = self._insert_ticket(when=datetime(2017, 3, 9, tzinfo=utc),
                                    summary='reset milestone',
                                    milestone='milestone1',
                                    reporter='anonymous', owner='joe')

        ticket = Ticket(self.env, tktid)
        req = self._post_req('reset-milestone', ticket)
        self.assertTrue(self.tktmod.match_request(req))
        self.assertRaises(RequestDone, self.tktmod.process_request, req)
        ticket = Ticket(self.env, tktid)
        self.assertEqual('milestone1', ticket['milestone'])

        milestone = Milestone(self.env, ticket['milestone'])
        milestone.completed = datetime(2017, 3, 8, tzinfo=utc)
        milestone.update()
        req = self._post_req('reset-milestone', ticket)
        self.assertTrue(self.tktmod.match_request(req))
        self.assertRaises(RequestDone, self.tktmod.process_request, req)
        ticket = Ticket(self.env, tktid)
        self.assertEqual('', ticket['milestone'])

        ticket['milestone'] = 'unknown-milestone'
        ticket.save_changes(when=datetime(2017, 3, 8, 1, tzinfo=utc))
        req = self._post_req('reset-milestone', ticket)
        self.assertTrue(self.tktmod.match_request(req))
        self.assertRaises(RequestDone, self.tktmod.process_request, req)
        ticket = Ticket(self.env, tktid)
        self.assertEqual('unknown-milestone', ticket['milestone'])
Example #4
0
    def test_delete_milestone(self):
        self.env.db_transaction("INSERT INTO milestone (name) VALUES ('Test')")

        milestone = Milestone(self.env, 'Test')
        milestone.delete()
        self.assertEqual(False, milestone.exists)
        self.assertEqual([],
            self.env.db_query("SELECT * FROM milestone WHERE name='Test'"))
Example #5
0
    def test_update_milestone_without_name(self):
        cursor = self.db.cursor()
        cursor.execute("INSERT INTO milestone (name) VALUES ('Test')")
        cursor.close()

        milestone = Milestone(self.env, 'Test')
        milestone.name = None
        self.assertRaises(TracError, milestone.update)
Example #6
0
    def test_create_milestone(self):
        milestone = Milestone(self.env)
        milestone.name = 'Test'
        milestone.insert()

        cursor = self.db.cursor()
        cursor.execute("SELECT name,due,completed,description FROM milestone "
                       "WHERE name='Test'")
        self.assertEqual(('Test', 0, 0, ''), cursor.fetchone())
Example #7
0
    def test_delete_milestone(self):
        cursor = self.db.cursor()
        cursor.execute("INSERT INTO milestone (name) VALUES ('Test')")
        cursor.close()

        milestone = Milestone(self.env, 'Test')
        milestone.delete()

        cursor = self.db.cursor()
        cursor.execute("SELECT * FROM milestone WHERE name='Test'")
        self.assertEqual(None, cursor.fetchone())
Example #8
0
def milestone_setup(tc):
    from datetime import datetime
    from trac.util.datefmt import utc
    boo = Milestone(tc.env)
    boo.name = 'boo'
    boo.completed = boo.due = None
    boo.insert()
    roo = Milestone(tc.env)
    roo.name = 'roo'
    roo.completed = datetime.now(utc)
    roo.due = None
    roo.insert()
Example #9
0
 def ticket_changed(self, ticket, comment, author, old_values):
     old_summary = old_values.get('summary')
     if ticket['type']==milestone_ticket_type \
         and old_summary \
         and ticket['summary'] != old_summary:
             try:
                 milestone = Milestone(self.env, old_summary)
                 if milestone.exists:
                     milestone.name = ticket['summary']
                     milestone.update()
             except ResourceNotFound:
                 pass
Example #10
0
 def select(env, include_completed=True, db=None):
     if not db:
         db = env.get_db_cnx()
         
     milestones = [ StructuredMilestone(env, milestone) \
                     for milestone in Milestone.select(env, include_completed, db)]
     return StructuredMilestone.reorganize(milestones)
 def _go_graph(self, req):
     #search all artifacts.
     artifacts = ArtifactManager.find_all(self.env)
     
     milestones = [m for m in Milestone.select(self.env)
                   if 'MILESTONE_VIEW' in req.perm(m.resource)]
     
     #add artifacts to milestone.
     for m in milestones:
         artifacts_of_m = [artifact for artifact in artifacts
                if artifact.milestone == m.name]
         setattr(m, 'artifacts', artifacts_of_m)
     
     manager = SCMManager(self.env, req)
     nodes = manager.artifacts_to_nodes(artifacts)
     
     roots = manager.get_roots(nodes)
     
     gm = GraphManager(self.env)
     nodes = gm.to_graphnode(roots)
     
     gm.to_s(nodes)
     
     graph = gm.to_graphviz(nodes, milestones)
     
     self.env.log.info('graphviz graph:\n%s' % graph)
     
     data = {'milestones':milestones, 'artifacts':artifacts, 'graph':graph}
     return 'releaseartifactgraph.html', data, None
Example #12
0
    def _render_editor(self, req, milestone):
        # Suggest a default due time of 18:00 in the user's timezone
        now = datetime.now(req.tz)
        default_due = datetime(now.year, now.month, now.day, 18)
        if now.hour > 18:
            default_due += timedelta(days=1)
        default_due = to_datetime(default_due, req.tz)

        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')
            if milestone.name:
                add_notice(req, _("Milestone %(name)s does not exist. You can"
                                  " create it here.", name=milestone.name))

        chrome = Chrome(self.env)
        chrome.add_jquery_ui(req)
        chrome.add_wiki_toolbars(req)
        return 'milestone_edit.html', data, None
Example #13
0
    def test_update_milestone_update_tickets(self):
        self.env.db_transaction("INSERT INTO milestone (name) VALUES ('Test')")

        tkt1 = Ticket(self.env)
        tkt1.populate({'summary': 'Foo', 'milestone': 'Test'})
        tkt1.insert()
        tkt2 = Ticket(self.env)
        tkt2.populate({'summary': 'Bar', 'milestone': 'Test'})
        tkt2.insert()

        milestone = Milestone(self.env, 'Test')
        milestone.name = 'Testing'
        milestone.update()

        self.assertEqual('Testing', Ticket(self.env, tkt1.id)['milestone'])
        self.assertEqual('Testing', Ticket(self.env, tkt2.id)['milestone'])
Example #14
0
    def test_delete_milestone_retarget_tickets(self):
        self.env.db_transaction("INSERT INTO milestone (name) VALUES ('Test')")

        tkt1 = Ticket(self.env)
        tkt1.populate({'summary': 'Foo', 'milestone': 'Test'})
        tkt1.insert()
        tkt2 = Ticket(self.env)
        tkt2.populate({'summary': 'Bar', 'milestone': 'Test'})
        tkt2.insert()

        milestone = Milestone(self.env, 'Test')
        milestone.delete(retarget_to='Other')
        self.assertEqual(False, milestone.exists)

        self.assertEqual('Other', Ticket(self.env, tkt1.id)['milestone'])
        self.assertEqual('Other', Ticket(self.env, tkt2.id)['milestone'])
Example #15
0
    def _render_editor(self, req, milestone):
        data = {
            'milestone': milestone,
            'datetime_hint': get_datetime_format_hint(req.lc_time),
            'default_due': self.get_default_due(req),
            '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)
            data['num_open_tickets'] = milestone \
                                       .get_num_tickets(exclude_closed=True)
            data['retarget_to'] = self.default_retarget_to
        else:
            req.perm(milestone.resource).require('MILESTONE_CREATE')
            if milestone.name:
                add_notice(req, _("Milestone %(name)s does not exist. You can"
                                  " create it here.", name=milestone.name))

        chrome = Chrome(self.env)
        chrome.add_jquery_ui(req)
        chrome.add_wiki_toolbars(req)
        add_stylesheet(req, 'common/css/roadmap.css')
        return 'milestone_edit.html', data, None
Example #16
0
 def testBacklogForMultipleSprint(self):
     """Tests a Backlog associated to a Sprint with multiple sprints"""
     # Creates a Milestone
     m = Milestone(self.env)
     m.name = "Milestone 1"
     m.insert()
     # Create 2 Sprints
     sprint1 = self.teh.create_sprint(
                      name="Sprint 1", 
                      start=to_datetime(t=None), 
                      duration=20,
                      milestone=m.name)
     sprint2 = self.teh.create_sprint( 
                      name="Sprint 2", 
                      start=to_datetime(t=None), 
                      duration=20,
                      milestone=m.name)
     # Create some tickets
     s1 = self.teh.create_ticket(Type.USER_STORY, 
                                 props={Key.STORY_POINTS: '3', 
                                        Key.SPRINT: sprint1.name})
     self.assert_true(s1.link_to(self.teh.create_ticket(Type.TASK, 
                                                        props={Key.REMAINING_TIME: '4',
                                                               Key.SPRINT: sprint1.name})))
     self.assert_true(s1.link_to(self.teh.create_ticket(Type.TASK,
                                                        props={Key.REMAINING_TIME: '8',
                                                               Key.SPRINT: sprint1.name})))
     self.assert_true(s1.link_to(self.teh.create_ticket(Type.TASK, 
                                                        props={Key.REMAINING_TIME: '4'})))
     s2 = self.teh.create_ticket(Type.USER_STORY, props={Key.STORY_POINTS: '5', 
                                                         Key.SPRINT: sprint2.name})
     self.assert_true(s2.link_to(self.teh.create_ticket(Type.TASK, 
                                                        props={Key.REMAINING_TIME: '2',
                                                               Key.SPRINT: sprint2.name})))
     self.assert_true(s2.link_to(self.teh.create_ticket(Type.TASK, 
                                                        props={Key.REMAINING_TIME: '3'})))
     # Creates the Backlog bound to the Sprint
     backlog = BacklogConfiguration(self.env, name="Sprint-Backlog", type=BacklogType.SPRINT)
     backlog.ticket_types = [Type.USER_STORY, Type.TASK]
     backlog.save()
     # The Backlog should contains only the items planned for the Sprint, and with parents
     # planned for the Sprint too
     backlog1 =  self.bmm.get(name="Sprint-Backlog", scope=sprint1.name)
     self.assert_length(3, backlog1)
     backlog2 =  self.bmm.get(name="Sprint-Backlog", scope=sprint2.name)
     self.assert_length(2, backlog2)
Example #17
0
 def default_retarget_to(self):
     if self._default_retarget_to and \
        not any(self._default_retarget_to == m.name
                for m in Milestone.select(self.env)):
         self.log.warn('Milestone "%s" does not exist. Update the '
                       '"default_retarget_to" option in the [milestone] '
                       'section of trac.ini', self._default_retarget_to)
     return self._default_retarget_to
Example #18
0
    def test_delete_milestone_retarget_tickets(self):
        cursor = self.db.cursor()
        cursor.execute("INSERT INTO milestone (name) VALUES ('Test')")
        cursor.close()

        tkt1 = Ticket(self.env)
        tkt1.populate({'summary': 'Foo', 'milestone': 'Test'})
        tkt1.insert()
        tkt2 = Ticket(self.env)
        tkt2.populate({'summary': 'Bar', 'milestone': 'Test'})
        tkt2.insert()

        milestone = Milestone(self.env, 'Test')
        milestone.delete(retarget_to='Other')

        self.assertEqual('Other', Ticket(self.env, tkt1.id)['milestone'])
        self.assertEqual('Other', Ticket(self.env, tkt2.id)['milestone'])
    def _reindex_milestone(self, realm, feedback, finish_fb):
        resources = Milestone.select(self.env)

        def check(milestone, check):
            return True

        index = self._index_milestone
        return self._index(realm, resources, check, index, feedback, finish_fb)
Example #20
0
File: api.py Project: pkdevbox/trac
    def test_get_ticket_fields_milestone_rename(self):
        """Cached ticket fields are updated when milestone is renamed."""
        fields = self.ticket_system.get_ticket_fields()
        milestone_field = self._get_ticket_field('milestone')
        m2 = Milestone(self.env, 'milestone2')
        m2.name = 'milestone5'

        m2.update()
        updated_fields = self.ticket_system.get_ticket_fields()
        updated_milestone_field = self._get_ticket_field('milestone')

        self.assertNotEqual(fields, updated_fields)
        self.assertEqual(['milestone1', 'milestone2',
                          'milestone3', 'milestone4'],
                         milestone_field['options'])
        self.assertEqual(['milestone1', 'milestone3',
                          'milestone4', 'milestone5'],
                         updated_milestone_field['options'])
Example #21
0
    def test_delete_milestone_retarget_tickets(self):
        cursor = self.db.cursor()
        cursor.execute("INSERT INTO milestone (name) VALUES ('Test')")
        cursor.close()

        tkt1 = Ticket(self.env)
        tkt1.populate({"summary": "Foo", "milestone": "Test"})
        tkt1.insert()
        tkt2 = Ticket(self.env)
        tkt2.populate({"summary": "Bar", "milestone": "Test"})
        tkt2.insert()

        milestone = Milestone(self.env, "Test")
        milestone.delete(retarget_to="Other")
        self.assertEqual(False, milestone.exists)

        self.assertEqual("Other", Ticket(self.env, tkt1.id)["milestone"])
        self.assertEqual("Other", Ticket(self.env, tkt2.id)["milestone"])
Example #22
0
    def test_update_milestone_update_tickets(self):
        cursor = self.db.cursor()
        cursor.execute("INSERT INTO milestone (name) VALUES ('Test')")
        cursor.close()

        tkt1 = Ticket(self.env)
        tkt1.populate({"summary": "Foo", "milestone": "Test"})
        tkt1.insert()
        tkt2 = Ticket(self.env)
        tkt2.populate({"summary": "Bar", "milestone": "Test"})
        tkt2.insert()

        milestone = Milestone(self.env, "Test")
        milestone.name = "Testing"
        milestone.update()

        self.assertEqual("Testing", Ticket(self.env, tkt1.id)["milestone"])
        self.assertEqual("Testing", Ticket(self.env, tkt2.id)["milestone"])
Example #23
0
 def task(add):
     """the thread task - either we are discovering or adding events"""
     with lock:
         env = ProductEnvironment(self.global_env,
                                  self.default_product)
         if add:
             name = 'milestone_from_' + threading.current_thread().name
             milestone = Milestone(env)
             milestone.name = name
             milestone.insert()
         else:
             # collect the names of milestones reported by Milestone and
             # directly from the db - as sets to ease comparison later
             results.append({
                 'from_t': set([m.name for m in Milestone.select(env)]),
                 'from_db': set(
                     [v[0] for v in self.env.db_query(
                         "SELECT name FROM milestone")])})
Example #24
0
    def test_update_milestone_update_tickets(self):
        cursor = self.db.cursor()
        cursor.execute("INSERT INTO milestone (name) VALUES ('Test')")
        cursor.close()

        tkt1 = Ticket(self.env)
        tkt1.populate({'summary': 'Foo', 'milestone': 'Test'})
        tkt1.insert()
        tkt2 = Ticket(self.env)
        tkt2.populate({'summary': 'Bar', 'milestone': 'Test'})
        tkt2.insert()

        milestone = Milestone(self.env, 'Test')
        milestone.name = 'Testing'
        milestone.update()

        self.assertEqual('Testing', Ticket(self.env, tkt1.id)['milestone'])
        self.assertEqual('Testing', Ticket(self.env, tkt2.id)['milestone'])
Example #25
0
 def _modify_roadmap_page(self, req, template, data, content_type,
                          is_active):
     """Insert roadmap.css + products breadcrumb
     """
     add_stylesheet(req, 'dashboard/css/roadmap.css')
     self._add_products_general_breadcrumb(req, template, data,
                                           content_type, is_active)
     data['milestone_list'] = [m.name for m in Milestone.select(self.env)]
     req.chrome['ctxtnav'] = []
Example #26
0
    def test_select_milestones(self):
        cursor = self.db.cursor()
        cursor.executemany("INSERT INTO milestone (name) VALUES (%s)", [("1.0",), ("2.0",)])
        cursor.close()

        milestones = list(Milestone.select(self.env))
        self.assertEqual("1.0", milestones[0].name)
        assert milestones[0].exists
        self.assertEqual("2.0", milestones[1].name)
        assert milestones[1].exists
Example #27
0
    def test_select_milestones(self):
        self.env.db_transaction.executemany(
            "INSERT INTO milestone (name) VALUES (%s)",
            [('1.0',), ('2.0',)])

        milestones = list(Milestone.select(self.env))
        self.assertEqual('1.0', milestones[0].name)
        assert milestones[0].exists
        self.assertEqual('2.0', milestones[1].name)
        assert milestones[1].exists
Example #28
0
 def list_view(self, req, cat, page):
     data = {
         'view': 'list',
         'sprints': self.sm.select(),
         'format_datetime' : datefmt.format_datetime,
         'date_hint' : datefmt.get_date_format_hint(),
         'datetime_hint' : datefmt.get_datetime_format_hint(),
         'milestones' : [m.name for m in Milestone.select(self.env)],
     }
     data.update(req.args)
     return 'agilo_admin_sprint.html', data
Example #29
0
File: api.py Project: pkdevbox/trac
    def test_get_ticket_fields_milestone_update_due(self):
        """Cached ticket fields are updated when milestone due date is
        changed.
        """
        fields = self.ticket_system.get_ticket_fields()
        milestone_field = self._get_ticket_field('milestone')
        m2 = Milestone(self.env, 'milestone2')
        m2.due = datetime.now(utc)

        m2.update()
        updated_fields = self.ticket_system.get_ticket_fields()
        updated_milestone_field = self._get_ticket_field('milestone')

        self.assertNotEqual(fields, updated_fields)
        self.assertEqual(['milestone1', 'milestone2',
                          'milestone3', 'milestone4'],
                         milestone_field['options'])
        self.assertEqual(['milestone2', 'milestone1',
                          'milestone3', 'milestone4'],
                         updated_milestone_field['options'])
Example #30
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