Ejemplo n.º 1
0
    def apply_preset(self, req, tickets, preset=None):
        if preset is None:
            return tickets
            
        presets = preset and [kw.split('=', 1) for kw in preset.split('&')] or []
        fields = dict([(field, value) for field, value in presets])

        warn = []
        modified_tickets = []
        if tickets and presets:
            db = self.env.get_db_cnx()
            ticket_module = TicketModule(self.env)
            action = fields.get('action')

            for ticket_id in tickets:
                if 'TICKET_CHGPROP' in req.perm('ticket', ticket_id):
                    ticket  = Ticket(self.env, ticket_id, db)
                    ticket.populate(fields)
                    if action:
                        field_changes, problems = ticket_module.get_ticket_changes(req, ticket, action)
                        if problems:
                            for problem in problems:
                                warn.append(problem)
                        ticket_module._apply_ticket_changes(ticket, field_changes) # Apply changes made by the workflow

                    ticket.save_changes(req.authname, None, db=db)
                    modified_tickets.append(ticket_id)
                else:
                    warn.append(_("You have no permission to modify ticket '%(ticket)s'", ticket=ticket_id))
            db.commit()
        return { 'tickets' : modified_tickets, 'warnings': warn}
Ejemplo n.º 2
0
    def wake_up(self, *args):
        db = self.env.get_db_cnx()
        cursor = db.cursor()
        # find still opened more recent milestone
        # select ticket whom milestone are due in less than specified delay
        cursor.execute("""
                SELECT m.name  FROM milestone m                        
                WHERE  m.completed is NULL or m.completed = 0
                AND m.due not NULL and m.due > 0
                ORDER BY m.due ASC LIMIT 1            
            """)
        next_milestone = None
        for name, in cursor:
            next_milestone = name

        # select ticket whom milestone are due in less than specified delay
        cursor.execute("""
                SELECT t.id , t.milestone  FROM ticket t, milestone m                        
                WHERE t.status != 'closed'
                AND    t.milestone = m.name  
                AND    m.completed not NULL and m.completed > 0            
            """)
        if next_milestone:
            for id, milestone in cursor:
                mess = "ticket %s is opened in closed milestone %s. Should postpone this ticket to %s" % (
                    id, milestone, next_milestone)
                self.env.log.debug(mess)
                ticket = Ticket(self.env, id)
                ticket.populate({'milestone': next_milestone})
                ticket.save_changes(self.getId(), mess)
        else:
            self.env.log.debug(
                "No opened milestone found. Cannot postpone tickets")
Ejemplo n.º 3
0
 def test_title_and_description_with_sub_vars_in_sql(self):
     with self.env.db_transaction:
         id_ = self._insert_report(
             'Tickets on $M for $USER', '-- M=milestone1\r\n'
             'SELECT * FROM ticket WHERE milestone=$M AND owner=$USER\r\n',
             'Show tickets on $M for $USER')
         for milestone in ('milestone1', 'milestone2'):
             ticket = Ticket(self.env)
             ticket.populate({
                 'status': 'new',
                 'summary': 'Test 1',
                 'owner': 'joe',
                 'milestone': milestone
             })
             ticket.insert()
     req = MockRequest(self.env,
                       path_info='/report/%d' % id_,
                       authname='joe')
     self.assertTrue(self.report_module.match_request(req))
     data = self.report_module.process_request(req)[1]
     self.assertEqual('{%d} Tickets on milestone1 for joe' % id_,
                      data['title'])
     self.assertEqual('Show tickets on milestone1 for joe',
                      data['description'])
     self.assertIsNone(data['message'])
     self.assertEqual(1, data['numrows'])
Ejemplo n.º 4
0
    def test_populate_ticket(self):
        data = {
            "summary": "Hello world",
            "reporter": "john",
            "foo": "bar",
            "checkbox_cbon": "",
            "cbon": "on",
            "checkbox_cboff": "",
        }
        ticket = Ticket(self.env)
        ticket.populate(data)

        # Standard fields
        self.assertEqual("Hello world", ticket["summary"])
        self.assertEqual("john", ticket["reporter"])

        # An unknown field
        assert ticket["bar"] is None

        # Custom field
        self.assertEqual("bar", ticket["foo"])

        # Custom field of type 'checkbox'
        self.assertEqual("on", ticket["cbon"])
        self.assertEqual("0", ticket["cboff"])
Ejemplo n.º 5
0
    def test_new_component_has_no_owner(self):
        """Ticket is not disowned when the component is changed to a
        component with no owner.
        """
        self._add_component('component3', 'cowner3')
        self._add_component('component4', '')

        ticket = Ticket(self.env)
        ticket.populate({
            'reporter': 'reporter1',
            'summary': 'the summary',
            'component': 'component3',
            'owner': 'cowner3',
            'status': 'new',
        })
        tkt_id = ticket.insert()

        req = MockRequest(self.env, method='POST', args={
            'id': tkt_id,
            'field_component': 'component4',
            'submit': True,
            'action': 'leave',
            'view_time': str(to_utimestamp(ticket['changetime'])),
        })
        self.assertRaises(RequestDone, self.ticket_module.process_request, req)
        ticket = Ticket(self.env, tkt_id)

        self.assertEqual('component4', ticket['component'])
        self.assertEqual('cowner3', ticket['owner'])
Ejemplo n.º 6
0
 def wake_up(self, *args):
     db = self.env.get_db_cnx()        
     cursor = db.cursor()
     # find still opened more recent milestone
     # select ticket whom milestone are due in less than specified delay
     cursor.execute("""
             SELECT m.name  FROM milestone m                        
             WHERE  m.completed is NULL or m.completed = 0
             AND m.due not NULL and m.due > 0
             ORDER BY m.due ASC LIMIT 1            
         """ )
     next_milestone = None
     for name, in cursor:
         next_milestone = name            
             
     # select ticket whom milestone are due in less than specified delay
     cursor.execute("""
             SELECT t.id , t.milestone  FROM ticket t, milestone m                        
             WHERE t.status != 'closed'
             AND    t.milestone = m.name  
             AND    m.completed not NULL and m.completed > 0            
         """ )        
     if next_milestone:          
         for id, milestone in cursor:
             mess = "ticket %s is opened in closed milestone %s. Should postpone this ticket to %s" % (id, milestone, next_milestone)
             self.env.log.debug(mess)
             ticket = Ticket(self.env, id)
             ticket.populate({'milestone':next_milestone})
             ticket.save_changes(self.getId(),mess)
     else:
         self.env.log.debug("No opened milestone found. Cannot postpone tickets")
Ejemplo n.º 7
0
    def add_tickets(self, project, customerrequest, tickets, reporter, notify=False):
        from trac.ticket.notification import TicketNotifyEmail
        from trac.util.text import exception_to_unicode
        from penelope.core.models.dashboard import User

        settings = get_current_registry().settings
        tracenvs = settings.get('penelope.trac.envs')
        request = get_current_request()

        for trac in project.tracs:
            for t in tickets:
                owner = DBSession.query(User).get(t['owner'])
                ticket = {'summary': t['summary'],
                        'description': t['description'],
                        'customerrequest': customerrequest.id,
                        'reporter': reporter.email,
                        'type': 'task',
                        'priority': 'major',
                        'milestone': 'Backlog',
                        'owner': owner.email,
                        'status': 'new'}
                tracenv = Environment('%s/%s' % (tracenvs, trac.trac_name))
                tracenv.abs_href.base = trac.api_uri
                t = Ticket(tracenv)
                t.populate(ticket)
                t.insert()
                if notify:
                    try:
                        tn = TicketNotifyEmail(tracenv)
                        tn.notify(t, newticket=True)
                    except Exception, e:
                        request.add_message('Failure sending notification on creation '
                        'of a ticket #%s: %s' % (t.id, exception_to_unicode(e)), 'error')
Ejemplo n.º 8
0
    def test_populate_ticket(self):
        data = {
            'summary': 'Hello world',
            'reporter': 'john',
            'foo': 'bar',
            'foo': 'bar',
            'checkbox_cbon': '',
            'cbon': 'on',
            'checkbox_cboff': ''
        }
        ticket = Ticket(self.env)
        ticket.populate(data)

        # Standard fields
        self.assertEqual('Hello world', ticket['summary'])
        self.assertEqual('john', ticket['reporter'])

        # An unknown field
        self.assertRaises(KeyError, ticket.__getitem__, 'bar')

        # Custom field
        self.assertEqual('bar', ticket['foo'])

        # Custom field of type 'checkbox'
        self.assertEqual('on', ticket['cbon'])
        self.assertEqual('0', ticket['cboff'])
Ejemplo n.º 9
0
 def test_title_and_description_with_sub_vars(self):
     with self.env.db_transaction as db:
         cursor = db.cursor()
         cursor.execute(
             """INSERT INTO report (title,query,description)
                VALUES (%s,%s,%s)""",
             ('Tickets on $M for $USER',
              'SELECT * FROM ticket WHERE milestone=$M AND owner=$USER',
              'Show tickets on $M for $USER'))
         id_ = db.get_last_id(cursor, 'report')
         for milestone in ('milestone1', 'milestone2'):
             ticket = Ticket(self.env)
             ticket.populate({'status': 'new', 'summary': 'Test 1',
                              'owner': 'joe', 'milestone': milestone})
             ticket.insert()
     req = MockRequest(self.env, path_info='/report/%d' % id_,
                       authname='joe', args={'M': 'milestone2'})
     self.assertTrue(self.report_module.match_request(req))
     data = self.report_module.process_request(req)[1]
     self.assertEqual('{%d} Tickets on milestone2 for joe' % id_,
                      data['title'])
     self.assertEqual('Show tickets on milestone2 for joe',
                      data['description'])
     self.assertIsNone(data['message'])
     self.assertEqual(1, data['numrows'])
Ejemplo n.º 10
0
    def test_component_change(self):
        """New ticket owner is updated when the component is changed.
        """
        self._add_component('component3', 'cowner3')
        self._add_component('component4', 'cowner4')

        ticket = Ticket(self.env)
        ticket.populate({
            'reporter': 'reporter1',
            'summary': 'the summary',
            'component': 'component3',
            'owner': 'cowner3',
            'status': 'new',
        })
        tkt_id = ticket.insert()

        req = self._create_request(method='POST', args={
            'id': tkt_id,
            'field_component': 'component4',
            'submit': True,
            'action': 'leave',
            'view_time': str(to_utimestamp(ticket['changetime'])),
        })
        self.assertRaises(RequestDone, self.ticket_module.process_request, req)
        ticket = Ticket(self.env, tkt_id)

        self.assertEqual('component4', ticket['component'])
        self.assertEqual('cowner4', ticket['owner'])
Ejemplo n.º 11
0
Archivo: model.py Proyecto: t2y/trac
    def test_prop_whitespace_change_is_not_saved(self):
        ticket = Ticket(self.env)
        ticket.populate({'summary': 'ticket summary'})
        ticket.insert()

        ticket['summary'] = ' ticket summary '
        ticket.save_changes()
        self.assertEqual(0, len(ticket.get_changelog()))
Ejemplo n.º 12
0
    def test_prop_whitespace_change_is_not_saved(self):
        ticket = Ticket(self.env)
        ticket.populate({'summary': 'ticket summary'})
        ticket.insert()

        ticket['summary'] = ' ticket summary '
        ticket.save_changes()
        self.assertEqual(0, len(ticket.get_changelog()))
Ejemplo n.º 13
0
 def _create_ticket_with_change(self, old_props, new_props):
     """Create a ticket with `old_props` and apply properties
     in `new_props`.
     """
     t = Ticket(self.env)
     t.populate(old_props)
     t.insert()
     t.populate(new_props)
     t.save_changes('actor')
     return t
Ejemplo n.º 14
0
def ticket_setup(tc):
    config = tc.env.config
    config.set('ticket-custom', 'custom1', 'text')
    config.save()
    ticket = Ticket(tc.env)

    ticket.populate({'reporter': 'santa',
                     'summary': 'This is the summary',
                     'status': 'new'})
    ticket.insert()
Ejemplo n.º 15
0
def query2_setup(tc):
    ticket = Ticket(tc.env)
    ticket.populate({'reporter': 'santa',
                     'summary': 'This is the summary',
                     'status': 'new'})
    ticket.insert()
    ticket = Ticket(tc.env)
    ticket.populate({'reporter': 'claus',
                     'summary': 'This is another summary',
                     'status': 'new'})
    ticket.insert()
Ejemplo n.º 16
0
    def _save_ticket_changes(self, req, selected_tickets, new_values, comment,
                             action):
        """Save changes to tickets."""
        valid = True
        for manipulator in self.ticket_manipulators:
            if hasattr(manipulator, 'validate_comment'):
                for message in manipulator.validate_comment(req, comment):
                    valid = False
                    add_warning(req, tag_("The ticket %(field)s is invalid: "
                                          "%(message)s",
                                          field=tag.strong(_('comment')),
                                          message=message))

        tickets = []
        for id_ in selected_tickets:
            t = Ticket(self.env, id_)
            values = self._get_updated_ticket_values(req, t, new_values)
            for ctlr in self._get_action_controllers(req, t, action):
                values.update(ctlr.get_ticket_changes(req, t, action))
            t.populate(values)
            for manipulator in self.ticket_manipulators:
                for field, message in manipulator.validate_ticket(req, t):
                    valid = False
                    if field:
                        add_warning(req, tag_("The ticket field %(field)s is "
                                              "invalid: %(message)s",
                                              field=tag.strong(field),
                                              message=message))
                    else:
                        add_warning(req, message)
            tickets.append(t)

        if not valid:
            return

        when = datetime_now(utc)
        with self.env.db_transaction:
            for t in tickets:
                t.save_changes(req.authname, comment, when=when)
                for ctlr in self._get_action_controllers(req, t, action):
                    ctlr.apply_action_side_effects(req, t, action)

        event = BatchTicketChangeEvent(selected_tickets, when,
                                       req.authname, comment, new_values,
                                       action)
        try:
            NotificationSystem(self.env).notify(event)
        except Exception as e:
            self.log.error("Failure sending notification on ticket batch"
                           "change: %s", exception_to_unicode(e))
            add_warning(req,
                        tag_("The changes have been saved, but an error "
                             "occurred while sending notifications: "
                             "%(message)s", message=to_unicode(e)))
Ejemplo n.º 17
0
    def update_ticket_on_db(self, ticketId, author, comment, req):
        db = self.env.get_db_cnx()
        ticket = Ticket(self.env, ticketId, db=db)

        ticket.populate(req.args)

        now = int(time.time())
        ticket.save_changes(author, comment, when=now, db=db)
        db.commit()

        return True
Ejemplo n.º 18
0
def ticket_setup(tc):
    config = tc.env.config
    config.set('ticket-custom', 'custom1', 'text')
    config.save()
    ticket = Ticket(tc.env)

    ticket.populate({
        'reporter': 'santa',
        'summary': 'This is the summary',
        'status': 'new'
    })
    ticket.insert()
Ejemplo n.º 19
0
 def _create_ticket_with_change(self, old_props, new_props,
                                author='anonymous'):
     """Create a ticket with `old_props` and apply properties
     in `new_props`.
     """
     t = Ticket(self.env)
     t.populate(old_props)
     t.insert()
     comment = new_props.pop('comment', None)
     t.populate(new_props)
     t.save_changes(author, comment=comment)
     return t
Ejemplo n.º 20
0
 def _create_ticket_with_change(self, old_props, new_props,
                                author='anonymous'):
     """Create a ticket with `old_props` and apply properties
     in `new_props`.
     """
     t = Ticket(self.env)
     t.populate(old_props)
     t.insert()
     comment = new_props.pop('comment', None)
     t.populate(new_props)
     t.save_changes(author, comment=comment)
     return t
Ejemplo n.º 21
0
    def test_ignores_other_operations(self):
        """Ignores operations not defined by ConfigurableTicketWorkflow.
        """
        self.env.config.set('ticket-workflow', 'review', 'assigned -> review')
        self.env.config.set('ticket-workflow', 'review.operations',
                            'CodeReview')
        ctw = ConfigurableTicketWorkflow(self.env)
        ticket = Ticket(self.env)
        ticket.populate({'summary': '#13013', 'status': 'assigned'})
        ticket.insert()
        req = MockRequest(self.env)

        self.assertNotIn((0, 'review'), ctw.get_ticket_actions(req, ticket))
Ejemplo n.º 22
0
 def test_empty_set_resolution(self):
     config = self.env.config['ticket-workflow']
     config.set('resolve.set_resolution', '')
     self._reload_workflow()
     ticket = Ticket(self.env)
     ticket.populate({'summary': '#12882', 'status': 'new'})
     ticket.insert()
     req = MockRequest(self.env, path_info='/ticket/%d' % ticket.id)
     try:
         self.ctlr.render_ticket_action_control(req, ticket, 'resolve')
         self.fail('ConfigurationError not raised')
     except ConfigurationError as e:
         self.assertIn('but none is defined', unicode(e))
Ejemplo n.º 23
0
def comment_setup(tc):
    ticket1 = Ticket(tc.env)
    ticket1.populate({'reporter': 'santa',
                      'summary': 'This is the summary for ticket 1',
                      'status': 'new'})
    ticket1.insert()
    ticket1.save_changes(comment='This is the comment for ticket 1')
    ticket2 = Ticket(tc.env)
    ticket2.populate({'reporter': 'claws',
                      'summary': 'This is the summary for ticket 2',
                      'status': 'closed'})
    ticket2.insert()
    ticket2.save_changes(comment='This is the comment for ticket 2')
Ejemplo n.º 24
0
	def add_ticket(self, request, cleaned_data):
		"""Initializes a trac ticket, saves it to the database, and returns
		the result."""
		# Trac's version: trac.ticket.web_ui:375 (_process_newticket_request)
		data = {
			'summary': cleaned_data['summary'],
			'description': cleaned_data['description'],
			'reporter': self._get_trac_user(request.user),
		}
		ticket = Ticket(self.env)
		ticket.populate(data)
		ticket_id = ticket.insert()
		return ticket_id
Ejemplo n.º 25
0
 def fix_issue(self, db, data, author):
     """This base fix updates a ticket with the field/value pairs in
     data.  The data object can either be a dict or a list of dicts
     with the 'ticket' field of each identifying the ticket to change."""
     if not isinstance(data,list):
         data = [data]
     
     # update each ticket
     for changes in data:
         ticket = Ticket(self.env, changes['ticket'])
         del changes['ticket']
         ticket.populate(changes)
         ticket.save_changes(author=author, comment='')
     return None
Ejemplo n.º 26
0
    def fix_issue(self, db, data, author):
        """This base fix updates a ticket with the field/value pairs in
        data.  The data object can either be a dict or a list of dicts
        with the 'ticket' field of each identifying the ticket to change."""
        if not isinstance(data, list):
            data = [data]

        # update each ticket
        for changes in data:
            ticket = Ticket(self.env, changes['ticket'])
            del changes['ticket']
            ticket.populate(changes)
            ticket.save_changes(author=author, comment='')
        return None
Ejemplo n.º 27
0
def query2_setup(tc):
    ticket = Ticket(tc.env)
    ticket.populate({
        'reporter': 'santa',
        'summary': 'This is the summary',
        'status': 'new'
    })
    ticket.insert()
    ticket = Ticket(tc.env)
    ticket.populate({
        'reporter': 'claus',
        'summary': 'This is another summary',
        'status': 'new'
    })
    ticket.insert()
Ejemplo n.º 28
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'])
Ejemplo n.º 29
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'])
Ejemplo n.º 30
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'])
Ejemplo n.º 31
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'])
Ejemplo n.º 32
0
    def display_ticket_page(self, req, ticketId):
        # This method is based on process_request() in TicketModule.

        # todo: security check should go here
        # --- For security, only display ticket if it's 
        req.perm.assert_permission('TICKET_VIEW')

        action = req.args.get('action', 'view')

        db = self.env.get_db_cnx()

        ticket = Ticket(self.env, ticketId, db=db)
        reporter_id = req.args.get('author')

        req.hdf['ticket.debug'] = self.debug

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

            else:
                # Use user supplied values
                ticket.populate(req.args)
                req.hdf['ticket.action'] = action
                req.hdf['ticket.ts'] = req.args.get('ts')
                req.hdf['ticket.reassign_owner'] = req.args.get('reassign_owner') \
                                                   or req.authname
                req.hdf['ticket.resolve_resolution'] = req.args.get('resolve_resolution')

                reporter_id = req.args.get('author')
                comment = req.args.get('comment')
                if comment:
                    req.hdf['ticket.comment'] = comment
                    # Wiki format a preview of comment
                    req.hdf['ticket.comment_preview'] = wiki_to_html(comment,
                                                                     self.env,
                                                                     req, db)
                                    
        else:
            req.hdf['ticket.reassign_owner'] = req.authname
            # Store a timestamp in order to detect "mid air collisions"
            req.hdf['ticket.ts'] = ticket.time_changed

        self.insert_ticket_data_to_hdf(req, db, ticket)

        add_stylesheet(req, 'common/css/ticket.css')
        return 'autotracticket.cs', None
Ejemplo n.º 33
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'])
Ejemplo n.º 34
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'])
Ejemplo n.º 35
0
def comment_setup(tc):
    ticket1 = Ticket(tc.env)
    ticket1.populate({
        'reporter': 'santa',
        'summary': 'This is the summary for ticket 1',
        'status': 'new'
    })
    ticket1.insert()
    ticket1.save_changes(comment='This is the comment for ticket 1')
    ticket2 = Ticket(tc.env)
    ticket2.populate({
        'reporter': 'claws',
        'summary': 'This is the summary for ticket 2',
        'status': 'closed'
    })
    ticket2.insert()
    ticket2.save_changes(comment='This is the comment for ticket 2')
Ejemplo n.º 36
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"])
Ejemplo n.º 37
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'])
Ejemplo n.º 38
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"])
Ejemplo n.º 39
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'])
Ejemplo n.º 40
0
    def test_undefined_resolutions(self):
        config = self.env.config['ticket-workflow']
        ticket = Ticket(self.env)
        ticket.populate({'summary': '#12882', 'status': 'new'})
        ticket.insert()
        req = MockRequest(self.env, path_info='/ticket/%d' % ticket.id)

        config.set('resolve.set_resolution',
                   'fixed,invalid,wontfix,,duplicate,worksforme,,,,,')
        self._reload_workflow()
        self.ctlr.render_ticket_action_control(req, ticket, 'resolve')

        config.set('resolve.set_resolution', 'undefined,fixed')
        self._reload_workflow()
        try:
            self.ctlr.render_ticket_action_control(req, ticket, 'resolve')
            self.fail('ConfigurationError not raised')
        except ConfigurationError as e:
            self.assertIn('but uses undefined resolutions', unicode(e))
Ejemplo n.º 41
0
def add_trac_tickets(project, customer_request, settings, users):
    g = lipsum.Generator()
    tracname = idnormalizer.normalize(project.name)
    tracenvs = settings.get('penelope.trac.envs')
    trac_path = '%s/%s' % (tracenvs, tracname)
    tracenv = Environment(trac_path)
    for i in range(50):
        ticket = Ticket(tracenv)
        ticket.populate({
            'summary': g.generate_sentence(),
            'description': g.generate_paragraph(),
            # 'project_id': project.id,
            # 'customerrequest': "%s>%s>%s" % (project.id, customer_request.id, customer_request.name),
            'owner': random.choice(users).email,
            'customerrequest': "%s" % (customer_request.id),
            'status': 'new',
        })
        ticket.insert()
        yield ticket
Ejemplo n.º 42
0
    def process_request(self, req):
        """Iterate through all the ticket validation rules and if any them evaluate
        to true then the fields specified in that rule's "hidden" config will be
        hidden from the user on the ticket entry form."""
        hiddenfields = []
        ticket = Ticket(self.env)
        ticket.populate(req.args)
        BoolOperator.ticket = ticket
        for r in [x for x in self.get_rules() if x['enabled']]:
            result = self._grammar.parseString(r['condition'])[0]
            b = bool(result)
            self.log.debug('hidden field rule "%s": %s is %s' % (r['hidden'], str(result), b))
            if b:
                for name in r['hidden']:
                    field = [f for f in ticket.fields if f['name'] == name]
                    hiddenfields.append("field-" + field[0]['name'])

        data = {'fields' : hiddenfields}
        return 'ajax_response.xml', data, 'text/xml'
Ejemplo n.º 43
0
    def test_populate_ticket(self):
        data = {'summary': 'Hello world', 'reporter': 'john',
                'foo': 'bar', 'checkbox_cbon': '', 'cbon': 'on',
                'checkbox_cboff': ''}
        ticket = Ticket(self.env)
        ticket.populate(data)

        # Standard fields
        self.assertEqual('Hello world', ticket['summary'])
        self.assertEqual('john', ticket['reporter'])

        # An unknown field
        assert ticket['bar'] is None

        # Custom field
        self.assertEqual('bar', ticket['foo'])

        # Custom field of type 'checkbox'
        self.assertEqual('on', ticket['cbon'])
        self.assertEqual('0', ticket['cboff'])
    def create_ticket_in_tasklist(cls, self, req):

        task_list = TaskList.load(self.env, id=req.args['tasklist_id'])

        ticket = Ticket(self.env)

        assert "field_summary" in req.args
        ticket_data = {field.split("field_")[1]: value for field, value in req.args.iteritems()
                       if field.startswith("field_")}
        ticket_data['status'] = "new"
        ticket_data['reporter'] = (req.args.get("field_reporter")
                                   or get_reporter_id(req, 'author'))
        ticket.populate(ticket_data)
        ticket.insert()

        with self.env.db_transaction as db:
            # @@TODO assert tasklist with tasklist_id exists
            # @@TODO assert ticket with id exists
            # @@TODO assert child ticket with (tasklist_id, id) does not exist
            db("INSERT INTO task_list_child_ticket "
               "  (task_list, ticket, `order`) VALUES "
               "  (%s, %s, %s)", [req.args['tasklist_id'], ticket.id, req.args['order']])

        task = task_list.get_ticket(ticket.id)
        task.actions =  TasklistWorkflowManager(self.env).allowed_actions(task_list, req, task.ticket)

        data = {
            "task_list": task_list,
            "task": task,
            "workflow_manager": TasklistWorkflowManager(self.env),
            }
        list_item = Chrome(self.env).render_template(req, 'show_tasklist_ticket.html',
                                                     data, 'text/html')
        return {"ok": "ok",
                "remove": False,
                "list_item": list_item,
                }
Ejemplo n.º 45
0
    def setUp(self):
        self.env = EnvironmentStub(default_data=True)

        self.milestone1 = Milestone(self.env)
        self.milestone1.name = 'Test'
        self.milestone1.insert()
        self.milestone2 = Milestone(self.env)
        self.milestone2.name = 'Test2'
        self.milestone2.insert()

        tkt1 = Ticket(self.env)
        tkt1.populate({
            'summary': 'Foo',
            'milestone': 'Test',
            'owner': 'foman',
            'status': 'new'
        })
        tkt1.insert()
        tkt2 = Ticket(self.env)
        tkt2.populate({
            'summary': 'Bar',
            'milestone': 'Test',
            'status': 'closed',
            'owner': 'barman'
        })
        tkt2.insert()
        tkt3 = Ticket(self.env)
        tkt3.populate({
            'summary': 'Sum',
            'milestone': 'Test',
            'owner': 'suman',
            'status': 'reopened'
        })
        tkt3.insert()
        self.tkt1 = tkt1
        self.tkt2 = tkt2
        self.tkt3 = tkt3

        prov = DefaultTicketGroupStatsProvider(ComponentManager())
        prov.env = self.env
        prov.config = self.env.config
        self.stats = prov.get_ticket_group_stats([tkt1.id, tkt2.id, tkt3.id])
Ejemplo n.º 46
0
 def _new_ticket(self, env, ticket_dict):
     ticket = Ticket(env)
     ticket.populate(ticket_dict)
     return ticket.insert()
 def _insert_ticket(self, when=None, **values):
     values.setdefault('status', 'new')
     values.setdefault('type', 'defect')
     ticket = Ticket(self.env)
     ticket.populate(values)
     return ticket.insert(when=when)
Ejemplo n.º 48
0
def add_trac_to_project(application,
        smtp_enabled=True,
        privatecomments=True,
        sensitivetickets=True,
        batchmod=True,
        autocompleteusers=True,
        customfieldadmin=True,
        qafields=True,
        privatetickets=False,
        tracwysiwyg=True,
        attachment_max_size=10485760,
        milestones=[],
        tickets=[],
        project_name=u'',
        ):

    from penelope.core.models.dashboard import Project

    project = DBSession.query(Project).get(application.project_id)

    settings = get_current_registry().settings or application.settings
    tracenvs = settings.get('penelope.trac.envs')

    if not os.path.exists(tracenvs):
        # TODO: logging bootstrap
        os.mkdir(tracenvs)

    tracname = None
    idx = ''
    while (not tracname):
        tracname = idnormalizer.normalize("%s%s" % (project.id, idx))
        trac_path = '%s/%s' % (tracenvs, tracname)
        if os.path.exists(trac_path):
            idx = idx and (idx+1) or 1
            tracname = None

    trac_perm = {
        'administrator': ['TRAC_ADMIN', 'EXTRA_TIMEENTRY'],
        'customer': ['TICKET_CREATE', 'TICKET_MODIFY', 'TICKET_VIEW',
            'WIKI_VIEW', 'XML_RPC',
            'CHANGESET_VIEW', 'FILE_VIEW',
            'LOG_VIEW', 'MILESTONE_VIEW',
            'REPORT_VIEW', 'REPORT_SQL_VIEW',
            'ROADMAP_VIEW', 'SEARCH_VIEW', 'TIMELINE_VIEW'],
        'developer': ['TICKET_CREATE', 'TICKET_MODIFY', 'TICKET_VIEW',
            'WIKI_VIEW', 'XML_RPC',
            'WIKI_CREATE', 'WIKI_MODIFY',
            'CHANGESET_VIEW', 'FILE_VIEW',
            'LOG_VIEW', 'MILESTONE_VIEW',
            'REPORT_VIEW', 'REPORT_SQL_VIEW',
            'ROADMAP_VIEW', 'SEARCH_VIEW',
            'TIMELINE_VIEW', 'REPORT_ADMIN'],
        'internal_developer': ['developer', 'TRAC_ADMIN', 'TIME_ENTRY_ADD'],
        'external_developer': ['developer'],
        'project_manager': ['administrator', 'TIME_ENTRY_ADD'],
    }


    pordb = str(DBSession.bind.url)
    run([trac_path, 'initenv "%s" "%s?schema=trac_%s"' % (
         tracname,
         pordb.replace('postgresql://', 'postgres://'),
         tracname)])

    tracenv = Environment(trac_path)

    # REPORTS
    cnx = tracenv.get_db_cnx().cnx
    cursor = cnx.cursor()
    cursor.executemany(\
        "INSERT INTO report (title, description, query) VALUES (%s, %s, %s)",
        get_reports(project_id=project.id))
    cursor.close()
    cnx.commit()

    # remove report 2
    cursor = cnx.cursor()
    cursor.execute("DELETE FROM report where id=2;")
    cursor.close()
    cnx.commit()

    # update reports
    cursor = cnx.cursor()
    cursor.execute("""UPDATE report set query='
        SELECT p.value AS __color__,
            t.id AS ticket, summary, t.type AS type, cr.name AS CR,
            owner, status,
            time AS created,
            changetime AS _changetime, t.description AS _description,
            reporter AS _reporter
        FROM ticket t
        LEFT JOIN enum p ON p.name = t.priority AND p.type = ''priority''
        LEFT JOIN ticket_custom tc ON t.id = tc.ticket
        LEFT JOIN public.customer_requests cr ON tc.value = cr.id
        WHERE status <> ''closed''
        AND tc.name = ''customerrequest''
        ORDER BY CAST(p.value AS int), milestone, t.type, time' where id=1;""")
    cursor.execute("""UPDATE report set query='
            SELECT p.value AS __color__,
               ''Milestone ''||milestone AS __group__,
               t.id AS ticket, summary, t.type AS type,
               cr.name AS CR,
               owner, status,
               time AS created,
               changetime AS _changetime, t.description AS _description,
               reporter AS _reporter
            FROM ticket t
            LEFT JOIN enum p ON p.name = t.priority AND p.type = ''priority''
            LEFT JOIN ticket_custom tc ON t.id = tc.ticket
            LEFT JOIN public.customer_requests cr ON tc.value = cr.id
            WHERE status <> ''closed''
            AND tc.name = ''customerrequest''
            ORDER BY (milestone IS NULL),milestone, CAST(p.value AS int), t.type, time' where id=3;""")
    cursor.execute("""UPDATE report set query='
            SELECT p.value AS __color__,
               owner AS __group__,
               t.id AS ticket, summary, milestone,  cr.name AS CR, t.type AS type, time AS created,
               changetime AS _changetime, t.description AS _description,
               reporter AS _reporter
            FROM ticket t
            LEFT JOIN enum p ON p.name = t.priority AND p.type = ''priority''
            LEFT JOIN ticket_custom tc ON t.id = tc.ticket
            LEFT JOIN public.customer_requests cr ON tc.value = cr.id
            WHERE status = ''accepted''
            AND tc.name = ''customerrequest''
            ORDER BY owner, CAST(p.value AS int), t.type, time'
            where id=4;""")
    cursor.execute("""UPDATE report set query='
            SELECT p.value AS __color__,
               owner AS __group__,
               t.id AS ticket, summary, milestone, t.type AS type, cr.name AS CR, time AS created,
               t.description AS _description_,
               changetime AS _changetime, reporter AS _reporter
            FROM ticket t
            LEFT JOIN enum p ON p.name = t.priority AND p.type = ''priority''
            LEFT JOIN ticket_custom tc ON t.id = tc.ticket
            LEFT JOIN public.customer_requests cr ON tc.value = cr.id
            WHERE status = ''accepted''
            AND tc.name = ''customerrequest''
            ORDER BY owner, CAST(p.value AS int), t.type, time'
            where id=5;""")
    cursor.execute("""UPDATE report set query='
            SELECT p.value AS __color__,
            (CASE status WHEN ''accepted'' THEN ''Accepted'' ELSE ''Owned'' END) AS __group__,
                 t.id AS ticket, summary, milestone, cr.name AS CR,
                 t.type AS type, priority, time AS created,
                 changetime AS _changetime, t.description AS _description,
                 reporter AS _reporter
            FROM ticket t
            LEFT JOIN enum p ON p.name = t.priority AND p.type = ''priority''
            LEFT JOIN ticket_custom tc ON t.id = tc.ticket
            LEFT JOIN public.customer_requests cr ON tc.value = cr.id
            WHERE t.status <> ''closed'' AND owner = $USER
            AND tc.name = ''customerrequest''
            ORDER BY (status = ''accepted'') DESC, CAST(p.value AS int), milestone, t.type, time'
            where id=7;""")
    cursor.execute("""UPDATE report set query='
            SELECT p.value AS __color__,
           (CASE owner
            WHEN $USER THEN ''My Tickets''
                ELSE ''Active Tickets''
            END) AS __group__,
                t.id AS ticket, summary, milestone, t.type AS type, cr.name AS CR,
                owner, status,
                time AS created,
                changetime AS _changetime, t.description AS _description,
                reporter AS _reporter
            FROM ticket t
            LEFT JOIN enum p ON p.name = t.priority AND p.type = ''priority''
            LEFT JOIN ticket_custom tc ON t.id = tc.ticket
            LEFT JOIN public.customer_requests cr ON tc.value = cr.id
            WHERE status <> ''closed''
            AND tc.name = ''customerrequest''
            ORDER BY (COALESCE(owner, '''') = $USER) DESC, CAST(p.value AS int), milestone, t.type, time'
            where id=8;""")
    cursor.close()
    cnx.commit()

    # remove default trac's milestones, components, versions
    cursor = cnx.cursor()
    cursor.execute("DELETE FROM milestone;")
    cursor.close()
    cnx.commit()

    cursor = cnx.cursor()
    cursor.execute("DELETE FROM component;")
    cursor.close()
    cnx.commit()

    cursor = cnx.cursor()
    cursor.execute("DELETE FROM version;")
    cursor.close()
    cnx.commit()


    # TODO: attualmente il riferimento dal trac al progetto dashboard è il project_id,
    #       considerando un'instalalzzione che condicide lo stesso stack wsgi,
    #       valutare se deve essere una uri (jsnorpc, xmlrpx, ...)
    #       o un dsn che punti al db, o ...
    tracenv.config.set('por-dashboard', 'project-id', application.project_id)

    # custom templates
    templates = settings.get('penelope.trac.templates')
    masterconfig = settings.get('penelope.trac.masterconfig')

    if templates:
        tracenv.config.set('inherit', 'templates_dir', templates)

    # master config
    if masterconfig:
        tracenv.config.set('inherit', 'file', masterconfig)

    # set name and description
    tracenv.config.set('project', 'name', project_name)
    tracenv.config.set('project', 'descr', application.name)

    tracenv.config.set('notification', 'smtp_enabled', smtp_enabled and 'true' or 'false')
    tracenv.config.set('notification', 'always_notify_owner', 'true')
    tracenv.config.set('notification', 'always_notify_reporter', 'true')
    manager_email = project.manager.email or ''
    tracenv.config.set('notification', 'smtp_always_cc', manager_email) # manager should always receiv CC

    tracenv.config.set('attachment', 'max_size', attachment_max_size)

    tracenv.config.set('components', 'penelope.trac.*', 'enabled')
    tracenv.config.set('components', 'themeengine.admin.*', 'enabled')
    tracenv.config.set('components', 'themeengine.api.*', 'enabled')
    tracenv.config.set('components', 'themeengine.web_ui.*', 'enabled')
    tracenv.config.set('components', 'ticketrelations.*', 'enabled')
    tracenv.config.set('components', 'tracopt.perm.config_perm_provider.extrapermissionsprovider', 'enabled')

    # All the custom permission names are converted to uppercase.
    # It is not possible to have lowercase and distinguish them from the standard permissions.
    tracenv.config.set('extra-permissions', 'extra_timeentry', 'TIME_ENTRY_ADD')

    tracenv.config.set('theme','theme', 'por')
    # ticket-custom
    tracenv.config.set('ticket-custom', 'customerrequest', 'select')
    tracenv.config.set('ticket-custom', 'customerrequest.label', 'Customer Request')
    tracenv.config.set('ticket-custom', 'blocking', 'text')
    tracenv.config.set('ticket-custom', 'blocking.label', 'Blocking')
    tracenv.config.set('ticket-custom', 'blockedby', 'text')
    tracenv.config.set('ticket-custom', 'blockedby.label', 'Blocked By')
    # BBB: ii valori di customerrequest vengono caricati ondemand
    tracenv.config.set('ticket-custom', 'customerrequest.options', '')

    # see ticket:80
    if qafields:
        tracenv.config.set('ticket-custom', 'issuetype', 'select')
        tracenv.config.set('ticket-custom', 'issuetype.label', 'Natura del problema')
        tracenv.config.set('ticket-custom', 'issuetype.options', '|'.join([u"",
                                u"sistemistica",
                                u"funzionalità",
                                u"design (grafica, layout...)",
                                u"prestazioni",
                                u"mi aspettavo che..."]))
        tracenv.config.set('ticket-custom', 'esogeno', 'checkbox')
        tracenv.config.set('ticket-custom', 'esogeno.label', 'Ticket aperto dal Cliente')
        tracenv.config.set('ticket-custom', 'esogeno.value', 'false')
        tracenv.config.set('ticket-custom', 'stats_exclude', 'checkbox')
        tracenv.config.set('ticket-custom', 'stats_exclude.label', 'Exclude from report stats')
        tracenv.config.set('ticket-custom', 'stats_exclude.value', 'false')
        tracenv.config.set('ticket-custom', 'fasesviluppo', 'select')
        tracenv.config.set('ticket-custom', 'fasesviluppo.label', 'Fase sviluppo')
        tracenv.config.set('ticket-custom', 'fasesviluppo.options', '|'.join([u"",
                                u"In lavorazione",
                                u"Per lo staging",
                                u"In staging",
                                u"Per la produzione",
                                u"In produzione"]))

    tracenv.config.set('ticket', 'restrict_owner', 'true')

    tracenv.config.set('ticket-custom', 'milestone.invalid_if', '')

    # WORKFLOW
    tracenv.config.set('ticket-workflow', 'accept', 'new,reviewing -> assigned')
    tracenv.config.set('ticket-workflow', 'accept.operations', 'set_owner_to_self')
    tracenv.config.set('ticket-workflow', 'accept.permissions', 'TICKET_MODIFY')
    tracenv.config.set('ticket-workflow', 'leave', '* -> *')
    tracenv.config.set('ticket-workflow', 'leave.default', '1')
    tracenv.config.set('ticket-workflow', 'leave.operations', 'leave_status')
    tracenv.config.set('ticket-workflow', 'reassign', 'new,assigned,accepted,reopened -> assigned')
    tracenv.config.set('ticket-workflow', 'reassign.operations', 'set_owner')
    tracenv.config.set('ticket-workflow', 'reassign.permissions', 'TICKET_MODIFY')
    tracenv.config.set('ticket-workflow', 'reassign_reviewing', 'reviewing -> *')
    tracenv.config.set('ticket-workflow', 'reassign_reviewing.name', 'reassign review')
    tracenv.config.set('ticket-workflow', 'reassign_reviewing.operations', 'set_owner')
    tracenv.config.set('ticket-workflow', 'reassign_reviewing.permissions', 'TICKET_MODIFY')
    tracenv.config.set('ticket-workflow', 'reopen', 'closed -> reopened')
    tracenv.config.set('ticket-workflow', 'reopen.operations', 'del_resolution')
    tracenv.config.set('ticket-workflow', 'reopen.permissions', 'TRAC_ADMIN')
    tracenv.config.set('ticket-workflow', 'resolve', 'new,assigned,reopened,reviewing -> closed')
    tracenv.config.set('ticket-workflow', 'resolve.operations', 'set_resolution')
    tracenv.config.set('ticket-workflow', 'resolve.permissions', 'TICKET_MODIFY')
    tracenv.config.set('ticket-workflow', 'review', 'new,assigned,reopened -> reviewing')
    tracenv.config.set('ticket-workflow', 'review.operations', 'set_owner')
    tracenv.config.set('ticket-workflow', 'review.permissions', 'TICKET_MODIFY')

    tracenv.config.set('milestone-groups', 'closed', 'closed')
    tracenv.config.set('milestone-groups', 'closed.order', '0')
    tracenv.config.set('milestone-groups', 'closed.query_args', 'group=resolution')
    tracenv.config.set('milestone-groups', 'closed.overall_completion', 'true')

    tracenv.config.set('milestone-groups', 'active', '*')
    tracenv.config.set('milestone-groups', 'active.order', '1')
    tracenv.config.set('milestone-groups', 'active.css_class', 'open')

    tracenv.config.set('milestone-groups', 'new', 'new,reopened')
    tracenv.config.set('milestone-groups', 'new.order', '2')


    # navigation
    tracenv.config.set('metanav', 'logout', 'disabled')

    # permissions
    tracenv.config.set('components', 'penelope.trac.users.*', 'enabled')
    tracenv.config.set('trac', 'permission_store', 'PorPermissionStore')
    tracenv.config.set('trac', 'show_email_addresses', 'true')

    # xmlrpc plugin
    tracenv.config.set('components', 'tracrpc.api.xmlrpcsystem', 'enabled')
    tracenv.config.set('components', 'tracrpc.xml_rpc.xmlrpcprotocol', 'enabled')
    tracenv.config.set('components', 'tracrpc.web_ui.rpcweb', 'enabled')
    tracenv.config.set('components', 'tracrpc.ticket.*', 'enabled')

    # DynamicFields Plugin
    tracenv.config.set('components', 'dynfields.rules.*','enabled')
    tracenv.config.set('components', 'dynfields.web_ui.*','enabled')

    # User & Roles (ReadOnly !!!)
    # tracenv.config.set('user_manager', 'user_store', 'PorUserStore')
    # tracenv.config.set('user_manager', 'attribute_provider', 'PorAttributeProvider')

    # BatchModifyPlugin
    if batchmod:
        tracenv.config.set('components', 'batchmod.web_ui.*', 'enabled')

    # Traccustomfieldadmin
    if customfieldadmin:
        tracenv.config.set('components', 'customfieldadmin.*', 'enabled')

    # PrivateCommentsPlugin
    if privatecomments:
        tracenv.config.set('components', 'privatecomments.privatecomments.*', 'enabled')

    # PrivateTicketPlugin
    if privatetickets:
        tracenv.config.set('components', 'privatetickets.policy.*', 'enabled')
        tracenv.config.set('trac', 'permission_policies',
            'PrivateTicketsPolicy, %s' % tracenv.config.get('trac', 'permission_policies'))
        trac_perm['customer'].append('TICKET_VIEW_SELF')

    # SensitiveTicketsPlugin
    if sensitivetickets:
        tracenv.config.set('components', 'sensitivetickets.*', 'enabled')
        tracenv.config.set('trac', 'permission_policies',
            'SensitiveTicketsPolicy, %s' % tracenv.config.get('trac', 'permission_policies'))
        tracenv.config.set('ticket-custom', 'sensitive.show_if_group', 'administrator|developer')
        # utilizzato se il default e' 1, se il default e' 0 non serve
        # tracenv.config.set('ticket-custom', 'sensitive.clear_on_hide', 'false')
        # tracenv.config.set('ticket-custom', 'sensitive.has_permission', 'SENSITIVE_VIEW')
        tracenv.config.set('ticket-custom', 'sensitive.value', '0')
        trac_perm['developer'].append('SENSITIVE_VIEW')

    # tracwysiwyg
    if tracwysiwyg:
        tracenv.config.set('components', 'tracwysiwyg.wysiwygmodule', 'enabled')

    # AutoCompleteUsers
    if autocompleteusers:
        tracenv.config.set('components', 'autocompleteusers.autocompleteusers', 'enabled')

    tracenv.config.set('wiki', 'max_size', 1048576)

    tracenv.config.set('logging', 'log_file', 'trac.log')
    tracenv.config.set('logging', 'log_level', 'INFO')
    tracenv.config.set('logging', 'log_type', 'file')

    tracenv.config.save()

    # let's remove notification config - it is set by the global config
    tracenv.config.remove('notification', 'smtp_from')
    tracenv.config.remove('notification', 'smtp_from_name')
    tracenv.config.remove('notification', 'replyto')
    tracenv.config.remove('notification', 'smtp_replyto')
    tracenv.config.remove('notification', 'email_sender')
    tracenv.config.remove('notification', 'smtp_enabled')
    tracenv.config.remove('notification', 'smtp_host')
    tracenv.config.remove('notification', 'smtp_port')
    tracenv.config.remove('notification', 'smtp_password')
    tracenv.config.remove('notification', 'smtp_username')

    tracenv.config.remove('trac', 'repository_sync_per_request')
    tracenv.config.save()

    run([trac_path, 'upgrade --no-backup'])

    run([trac_path, 'permission remove anonymous *'])
    run([trac_path, 'permission remove authenticated *'])
    for role, perms in trac_perm.items():
        for perm in perms:
            run([trac_path, "permission add %s %s" % (role, perm)])

    run([trac_path, "ticket_type add verification"])

    # hack to minimize config size
    run([trac_path, 'config set browser color_scale True'])

    # add properly milestones
    milestones.append({'title': 'Backlog', 'due_date': date.today().replace(year=date.today().year+1)})

    for milestone in milestones:
        due = milestone['due_date']
        if due:
            due = milestone['due_date'].strftime('%Y-%m-%d')
            run([trac_path, 'milestone add "%s" %s' % (milestone['title'], due)])
        else:
            run([trac_path, 'milestone add "%s"' % milestone['title']])

    tracenv = Environment(trac_path)
    for ticket in tickets:
        # in this moment the customer request has a proper id
        ticket['status'] = 'new'
        t = Ticket(tracenv)
        t.populate(ticket)
        t.insert()

    application.api_uri = 'trac://%s' % tracname
    application.trac_name = tracname
 def _insert_ticket(self, when=None, **values):
     values.setdefault('status', 'new')
     values.setdefault('type', 'defect')
     ticket = Ticket(self.env)
     ticket.populate(values)
     return ticket.insert(when=when)
Ejemplo n.º 50
0
 def _get_actions(self, ticket_dict):
     ts = TicketSystem(self.env)
     ticket = Ticket(self.env)
     ticket.populate(ticket_dict)
     id = ticket.insert()
     return ts.get_available_actions(self.req, Ticket(self.env, id))
Ejemplo n.º 51
0
 def _get_actions(self, ticket_dict):
     ts = TicketSystem(self.env)
     ticket = Ticket(self.env)
     ticket.populate(ticket_dict)
     id = ticket.insert()
     return ts.get_available_actions(self.req, Ticket(self.env, id))
Ejemplo n.º 52
0
    def _create_or_update_ticket(self, runid, testaction, comment, req):
        """ creates or updates a ticket for an action (default ticket
        type if failed, enhancement if otherwise (e.g. passed with comment))
        update means add a comment to the already created ticket
        and add keyword if neccesary
        """
        self.dbg('accordion.request._create_or_update_ticket(%s)' % req.args)
        testrun = Ticket(self.env, tkt_id=runid)
        display = get_display_states(self.env)

        # build ticket summary: <todo>: <action> of <testcase>, e.g.:
        # 'Creator checks in the model of TcCaddocCreate failed.'
        todo = STATES_DISPLAY[testaction.status]
        testcase = models.TestCaseQuery(self.env,
                                        tcid=testaction.tcid).execute()[0]
        summary = "%s of %s %s." % (
            testaction.title, testcase.wiki, display[todo])

        # build description
        description = "Related test case: %s.\n\n%s" % (
            self._build_tc_link(testaction, req),
            comment
        )
        # check if a similar ticket already exists...
        existing_tickets = Query.from_string(
            self.env, "summary=%s" % summary
        ).execute()
        if existing_tickets:
            # if yes return the ticket id
            t = Ticket(self.env, existing_tickets[0]['id'])
            tp_title = self._get_testplan_title(testrun)
            if t['keywords']:
                kws = t['keywords'].split(',')
                if not tp_title in kws:
                    t['keywords'] += ',%s' % tp_title
            else:
                t['keywords'] = tp_title
            t.save_changes(author=req.authname, comment=description)
            return t.id

        # build the ticket
        ticket = Ticket(self.env)

        # determine type of ticket
        ticket_type = ticket.get_default('type')
        if testaction.status != FAILED:
            ticket_type = 'enhancement'

        data = {
            'reporter': req.authname,
            'summary': summary,
            'type': ticket_type,
            'description': description,
            'priority': req.args.get('priority', 'major'),
            'status': 'new',
            'keywords': self._get_testplan_title(testrun),
        }
        self.dbg('ticket data: %s' % data)

        try:
            ticket.populate(data)
            tid = ticket.insert()
            ticket.save_changes()

        except TracError as e:
            self.env.log.error(e)
            raise TracError(
                safe_unicode(
                    "ticket could not be created: %s" % e.message
                )
            )

        return tid
Ejemplo n.º 53
0
    def _import_trackers(self, meta, reset):
        types = set()
        components = set()
        priorities = set()
        resolutions = set()
        for tracker in meta['trackers']:
            types.add(tracker['label'])
            v = tracker['vocabulary']
            for x in v.get('Category', []):
                components.add(x)
            for x in v.get('priority', []):
                priorities.add(x)
            for x in v.get('Resolution', []):
                resolutions.add(x)

        if reset:

            @self.env.with_transaction()
            def do_reset_components(db):
                cursor = db.cursor()
                cursor.execute("DELETE FROM component")
                cursor.execute("DELETE FROM milestone")
                cursor.execute("DELETE FROM enum")
                cursor.execute("DELETE FROM version")
                cursor.execute("DELETE FROM ticket")
                cursor.execute("DELETE FROM ticket_change")

        @self.env.with_transaction()
        def do_reset_ticket_meta(db):
            cursor = db.cursor()
            for x in sorted(components):
                cursor.execute(
                    "INSERT INTO component (name, owner, description) VALUES (%s, 'admin', %s)",
                    (x, x))
            for i, x in enumerate(sorted(types)):
                cursor.execute(
                    "INSERT INTO enum (type, name, value) VALUES ('ticket_type', %s, %s)",
                    (x, i + 1))
            for i, x in enumerate(sorted(priorities)):
                cursor.execute(
                    "INSERT INTO enum (type, name, value) VALUES ('priority', %s, %s)",
                    (x, i + 1))
            for i, x in enumerate(sorted(resolutions)):
                cursor.execute(
                    "INSERT INTO enum (type, name, value) VALUES ('resolution', %s, %s)",
                    (x, i + 1))

        for tracker in meta['trackers']:
            label = tracker['label']
            for a in tracker['artifacts']:
                owner = a.get('assigned_to', '')
                if owner == 'Nobody' or owner == 'No Change':
                    owner = ''

                ticket = Ticket(self.env)  #, a['id'])
                ticket.populate({
                    'summary': a.get('summary', ''),
                    'reporter': a.get('submitter', ''),
                    'description': a.get('description', ''),
                    'type': label,
                    'priority': a.get('priority', ''),
                    'component': a.get('Category', ''),
                    'owner': owner,
                    'status': a.get('status', ''),
                    'cc': '',
                    'keywords': '',
                })
                created = dateutil.parser.parse(a['date'])
                ticket.insert(created)

                changes = a['comments']
                changes.extend(a['history'])
                lastcom = None
                for c in sorted(changes, key=lambda x: x['date']):
                    modified = dateutil.parser.parse(c['date'])
                    if c['class'] == 'COMMENT':
                        author = c.get('submitter', '')
                        comment = c.get('comment', '')
                        if lastcom != None and lastcom == modified:
                            modified += datetime.timedelta(0, 10)
                        lastcom = modified
                    elif c['class'] == 'FIELDCHANGE':
                        author = c['by']
                        comment = None
                        field = c['field']
                        value = c['old']  # WTF?
                        if field == 'status':
                            ticket.status = value
                        elif field == 'Resolution':
                            ticket.resolution = value
                        elif field == 'assigned_to':
                            ticket.owner = value
                        elif field == 'close_date':
                            continue
                    ticket.save_changes(author, comment, modified)

        return 'OK'
Ejemplo n.º 54
0
 def _new_ticket(self, env, ticket_dict):
     ticket = Ticket(env)
     ticket.populate(ticket_dict)
     return ticket.insert()