示例#1
0
    def test_no_disown_from_changed_component(self):
        """
        Verify that a ticket is not disowned when the component is changed to
        a non-assigned component.
        """
        component1 = Component(self.env)
        component1.name = "test1"
        component1.owner = "joe"
        component1.insert()

        component2 = Component(self.env)
        component2.name = "test2"
        component2.owner = ""
        component2.insert()

        ticket = Ticket(self.env)
        ticket["reporter"] = "santa"
        ticket["summary"] = "Foo"
        ticket["component"] = "test1"
        ticket["status"] = "new"
        tktid = ticket.insert()

        ticket = Ticket(self.env, tktid)
        ticket["component"] = "test2"
        ticket.save_changes("jane", "Testing")
        self.assertEqual("joe", ticket["owner"])
示例#2
0
文件: model.py 项目: zjj/trac_hack
    def test_owner_from_changed_component(self):
        """
        Verify that the owner of a new ticket is updated when the component is
        changed.
        """
        component1 = Component(self.env)
        component1.name = 'test1'
        component1.owner = 'joe'
        component1.insert()

        component2 = Component(self.env)
        component2.name = 'test2'
        component2.owner = 'kate'
        component2.insert()

        ticket = Ticket(self.env)
        ticket['reporter'] = 'santa'
        ticket['summary'] = 'Foo'
        ticket['component'] = 'test1'
        ticket['status'] = 'new'
        tktid = ticket.insert()

        ticket = Ticket(self.env, tktid)
        ticket['component'] = 'test2'
        ticket.save_changes('jane', 'Testing')
        self.assertEqual('kate', ticket['owner'])
示例#3
0
文件: model.py 项目: zjj/trac_hack
    def test_no_disown_from_changed_component(self):
        """
        Verify that a ticket is not disowned when the component is changed to
        a non-assigned component.
        """
        component1 = Component(self.env)
        component1.name = 'test1'
        component1.owner = 'joe'
        component1.insert()

        component2 = Component(self.env)
        component2.name = 'test2'
        component2.owner = ''
        component2.insert()

        ticket = Ticket(self.env)
        ticket['reporter'] = 'santa'
        ticket['summary'] = 'Foo'
        ticket['component'] = 'test1'
        ticket['status'] = 'new'
        tktid = ticket.insert()

        ticket = Ticket(self.env, tktid)
        ticket['component'] = 'test2'
        ticket.save_changes('jane', 'Testing')
        self.assertEqual('joe', ticket['owner'])
示例#4
0
    def test_owner_from_changed_component(self):
        """
        Verify that the owner of a new ticket is updated when the component is
        changed.
        """
        component1 = Component(self.env)
        component1.name = "test1"
        component1.owner = "joe"
        component1.insert()

        component2 = Component(self.env)
        component2.name = "test2"
        component2.owner = "kate"
        component2.insert()

        ticket = Ticket(self.env)
        ticket["reporter"] = "santa"
        ticket["summary"] = "Foo"
        ticket["component"] = "test1"
        ticket["status"] = "new"
        tktid = ticket.insert()

        ticket = Ticket(self.env, tktid)
        ticket["component"] = "test2"
        ticket.save_changes("jane", "Testing")
        self.assertEqual("kate", ticket["owner"])
示例#5
0
def copy_component(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 component %s to the environment at %s', name, dest_env.path)
    dest_env.log.info('DatamoverPlugin: Moving component %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 component from the destination
    try:
        dest_comp = TicketComponent(dest_env, name, db=dest_db)
        dest_comp.delete(db=dest_db)
    except TracError:
        pass

    # Copy each entry in the component table
    source_cursor.execute('SELECT * FROM component WHERE name=%s',(name,))
    for row in source_cursor:
        comp_data = dict(zip([d[0] for d in source_cursor.description], row))
        q = make_query(comp_data, 'component')
        dest_cursor.execute(*q)
       
    if handle_commit:
        dest_db.commit()
示例#6
0
文件: model.py 项目: zjj/trac_hack
    def test_owner_from_component(self):
        """
        Verify that the owner of a new ticket is set to the owner of the
        component.
        """
        component = Component(self.env)
        component.name = 'test'
        component.owner = 'joe'
        component.insert()

        ticket = Ticket(self.env)
        ticket['reporter'] = 'santa'
        ticket['summary'] = 'Foo'
        ticket['component'] = 'test'
        ticket.insert()
        self.assertEqual('joe', ticket['owner'])
示例#7
0
    def test_owner_from_component(self):
        """
        Verify that the owner of a new ticket is set to the owner of the
        component.
        """
        component = Component(self.env)
        component.name = "test"
        component.owner = "joe"
        component.insert()

        ticket = Ticket(self.env)
        ticket["reporter"] = "santa"
        ticket["summary"] = "Foo"
        ticket["component"] = "test"
        ticket.insert()
        self.assertEqual("joe", ticket["owner"])
示例#8
0
    def post_process_request(self, req, template, data, content_type):
        if req.path_info.startswith('/ticket'):
            ticket = data['ticket']

            # add custom fields to the ticket template context data
            data['milestones'] = self._sorted_milestones()
            data['components'] = [c.name for c in Component.select(self.env)]
            data['split_options'] = self._ticket_split_options(ticket)
            data['split_history'] = self._ticket_split_history(ticket)

        return template, data, content_type
示例#9
0
def copy_component(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 component %s to the environment at %s', name,
        dest_env.path)
    dest_env.log.info(
        'DatamoverPlugin: Moving component %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 component from the destination
    try:
        dest_comp = TicketComponent(dest_env, name, db=dest_db)
        dest_comp.delete(db=dest_db)
    except TracError:
        pass

    # Copy each entry in the component table
    source_cursor.execute('SELECT * FROM component WHERE name=%s', (name, ))
    for row in source_cursor:
        comp_data = dict(zip([d[0] for d in source_cursor.description], row))
        q = make_query(comp_data, 'component')
        dest_cursor.execute(*q)

    if handle_commit:
        dest_db.commit()
示例#10
0
    def test_create_and_update(self):
        component = Component(self.env)
        component.name = 'Test'
        component.insert()

        cursor = self.db.cursor()
        cursor.execute("SELECT name,owner,description FROM component "
                       "WHERE name='Test'")
        self.assertEqual(('Test', None, None), cursor.fetchone())

        # Use the same model object to update the component
        component.owner = 'joe'
        component.update()
        cursor.execute("SELECT name,owner,description FROM component "
                       "WHERE name='Test'")
        self.assertEqual(('Test', 'joe', None), cursor.fetchone())
示例#11
0
    def test_create_and_update(self):
        component = Component(self.env)
        component.name = "Test"
        component.insert()

        cursor = self.db.cursor()
        cursor.execute("SELECT name,owner,description FROM component " "WHERE name='Test'")
        self.assertEqual(("Test", None, None), cursor.fetchone())

        # Use the same model object to update the component
        component.owner = "joe"
        component.update()
        cursor.execute("SELECT name,owner,description FROM component " "WHERE name='Test'")
        self.assertEqual(("Test", "joe", None), cursor.fetchone())
示例#12
0
    def test_create_and_update(self):
        component = Component(self.env)
        component.name = 'Test'
        component.insert()

        self.assertEqual([('Test', None, None)], self.env.db_query("""
            SELECT name, owner, description FROM component
            WHERE name='Test'"""))

        # Use the same model object to update the component
        component.owner = 'joe'
        component.update()
        self.assertEqual([('Test', 'joe', None)], self.env.db_query(
            "SELECT name, owner, description FROM component WHERE name='Test'"))
示例#13
0
 def process_admin_request(self, req, cat, page, path_info):
     envs = DatamoverSystem(self.env).all_environments()
     components = [c.name for c in TicketComponent.select(self.env)]
     
     if req.method == 'POST':
         source_type = req.args.get('source')
         if not source_type or source_type not in ('component', 'all'):
             raise TracError, "Source type not specified or invalid"
         source = req.args.get(source_type)
         dest = req.args.get('destination')
         action = None
         if 'copy' in req.args.keys():
             action = 'copy'
         elif 'move' in req.args.keys():
             action = 'move'
         else:
             raise TracError, 'Action not specified or invalid'
             
         action_verb = {'copy':'Copied', 'move':'Moved'}[action]
         
         comp_filter = None
         if source_type == 'component':
             in_components = req.args.getlist('component')
             comp_filter = lambda c: c in in_components
         elif source_type == 'all':
             comp_filter = lambda c: True
         
         try:
             sel_components = [c for c in components if comp_filter(c)]
             dest_db = _open_environment(dest).get_db_cnx()
             for comp in sel_components:
                 copy_component(self.env, dest, comp, dest_db)
             dest_db.commit()
                 
             if action == 'move':
                 for comp in sel_components:
                     TicketComponent(self.env, comp).delete()
                 
             req.hdf['datamover.message'] = '%s components %s'%(action_verb, ', '.join(sel_components))
         except TracError, e:
             req.hdf['datamover.message'] = "An error has occured: \n"+str(e)
             self.log.warn(req.hdf['datamover.message'], exc_info=True)
示例#14
0
文件: model.py 项目: zjj/trac_hack
 def test_exists(self):
     """
     http://trac.edgewall.org/ticket/4247
     """
     for c in Component.select(self.env):
         self.assertEqual(c.exists, True)
示例#15
0
 def _add_component(self, name='test', owner='owner1'):
     component = Component(self.env)
     component.name = name
     component.owner = owner
     component.insert()
 def list_component_in_json(self):
     # stolen from trac.ticket.admin.py format: [(component,owner)]
     #components = [(c.name, c.owner) for c in TicketComponent.select(self.env)], [_('Name'), _('Owner')]
     components = [{'name':c.name,'owner':c.owner} for c in TicketComponent.select(self.env)]
     printout(json.dumps(components))
    def process_request(self, req):
        name = req.args.get('name')


        if not (name == 'query'):
            id = req.args.get('id')

        if name == 'ticket':
            ticket = Ticket(self.env, id)
            comm_num = 0
            attachment_num = len(self.get_attachments('ticket', id))
            ticket_log = self.changeLog(id)

            for log in ticket_log:
                if log[2] == 'comment' and log[4]:
                    comm_num += 1

            data = {'ticket': ticket,
                    'comm_num': comm_num,
                    'attachment_num': attachment_num}
            return 'bh_emb_ticket.html', data, None

        elif name == 'milestone':
            ticket_num = len(get_tickets_for_milestone(self.env, milestone=id))
            attachment_num = len(self.get_attachments('milestone', id))

            data = {'milestone': Milestone(self.env, id),
                    'product': self.env.product,
                    'ticket_number': ticket_num,
                    'attachment_number': attachment_num }
            return 'bh_emb_milestone.html', data, None

        elif name == 'products':
            product = Product(self.env, {'prefix': id})
            ticket_num = len(self.get_tickets_for_product(self.env, id))
            product_env = ProductEnvironment(self.env, product.prefix)
            milestone_num = len(Milestone.select(product_env))
            version_num = len(Version.select(product_env))
            components = component.select(product_env)
            component_num = 0

            for c in components:
                component_num += 1

            data = {'product': product,
                    'ticket_num': ticket_num,
                    'owner': product.owner,
                    'milestone_num': milestone_num,
                    'version_num': version_num,
                    'component_num': component_num}
            return 'bh_emb_product.html', data, None
        elif name == 'query':
            qstr = req.query_string
            qstr = urllib.unquote(qstr).decode('utf8')

            if qstr=='':
                qstr = 'status!=closed'

            qresults = self.query(req, qstr)
            filters = qresults[0]
            tickets = qresults[1]

            data={'tickets': tickets,
                  'query': qstr,
                  'filters': filters}
            return 'bh_emb_query.html', data, None
        else:
            msg = "It is not possible to embed this resource."
            raise ResourceNotFound((msg), ("Invalid resource"))
示例#18
0
    def create_hack(self, req, data, vars):
        import fcntl

        messages = []
        created = False
        have_lock = False
        lockfile = open(self.lockfile, "w")
        try:
            rv = fcntl.flock(lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB)
            if rv:
                raise TracError('Failed to acquire lock, error: %i' % rv)
            have_lock = True
        except IOError:
            messages.append(
                'A hack is currently being created by another user. '
                'Please wait a few seconds, then click the "Create hack" '
                'button again.'
            )

        if have_lock:
            steps_done = []
            try:
                # Step 1: create repository paths
                from os import popen

                svn_path = 'file://%s' % \
                    self.env.config.get('trac', 'repository_dir')
                svn_path = svn_path.rstrip('/')
                page_name = vars['WIKINAME']
                hack_path = vars['LCNAME']
                paths = [ '%s/%s' % (svn_path, hack_path) ]
                selected_releases = data['selected_releases']
                if isinstance(selected_releases, (basestring, unicode)):
                    selected_releases = [ selected_releases, ]
                for release in selected_releases:
                    if release == 'anyrelease': continue
                    paths.append("%s/%s/%s" % \
                        (svn_path, hack_path, release))

                cmd  = '/usr/bin/op create-hack %s ' % req.authname
                cmd += '"New hack %s, created by %s" ' % \
                        (page_name, req.authname)
                cmd += '%s 2>&1' % ' '.join(paths)
                output = popen(cmd).readlines()
                if output:
                    raise Exception(
                        "Failed to create Subversion paths:\n%s" % \
                            '\n'.join(output)
                        )
                steps_done.append('repository')

                # Step 2: Add permissions
                from svnauthz.model import User, Path, PathAcl

                authz_file = self.env.config.get('trac', 'authz_file')
                authz = AuthzFileReader().read(authz_file)

                svn_path_acl = PathAcl(User(req.authname), r=True, w=True)
                authz.add_path(Path("/%s" % hack_path, acls = [svn_path_acl,]))
                AuthzFileWriter().write(authz_file, authz)
                steps_done.append('permissions')

                # Step 3: Add component
                component = TicketComponent(self.env)
                component.name = page_name
                component.owner = req.authname
                component.insert()
                steps_done.append('component')

                # Step 4: Create wiki page
                template_page = WikiPage(self.env, self.template)
                page = WikiPage(self.env, page_name)
                page.text = Template(template_page.text).substitute(vars)
                page.save(req.authname, 'New hack %s, created by %s' % \
                          (page_name, req.authname), '0.0.0.0')
                steps_done.append('wiki')

                # Step 5: Tag the new wiki page
                res = Resource('wiki', page_name)
                tags = data['tags'].split() + selected_releases + [data['type']]
                TagSystem(self.env).set_tags(req, res, tags)
                steps_done.append('tags')

                rv = fcntl.flock(lockfile, fcntl.LOCK_UN)
                created = True
            except Exception, e:
                try:
                    if 'tags' in steps_done:
                        res = Resource('wiki', page_name)
                        tags = data['tags'].split() + selected_releases
                        TagSystem(self.env).delete_tags(req, res, tags)
                    if 'wiki' in steps_done:
                        WikiPage(self.env, page_name).delete()
                    if 'component' in steps_done:
                        TicketComponent(self.env, page_name).delete()
                    if 'permissions' in steps_done:
                        authz_file = self.env.config.get('trac', 'authz_file')
                        authz = AuthzFileReader().read(authz_file)
                        authz.del_path(Path("/%s" % hack_path))
                        AuthzFileWriter().write(authz_file, authz)
                    # TODO: rollback subversion path creation
                    rv = fcntl.flock(lockfile, fcntl.LOCK_UN)
                except:
                    self.env.log.error("Rollback failed")
                    rv = fcntl.flock(lockfile, fcntl.LOCK_UN)
                self.env.log.error(e, exc_info=True)
                raise TracError(str(e))
示例#19
0
 def _insert_component(self, name):
     component = Component(self.env)
     component.name = name
     component.insert()
     return component
示例#20
0
 def process_admin_request(self, req, cat, page, path_info):
     components = [c.name for c in TicketComponent.select(self.env)]
     envs = DatamoverSystem(self.env).all_environments()
     
     if req.method == 'POST':
         source_type = req.args.get('source')
         if not source_type or source_type not in ('component', 'ticket', 'all', 'query'):
             raise TracError, "Source type not specified or invalid"
         source = req.args.get(source_type)
         dest = req.args.get('destination')
         action = None
         if 'copy' in req.args.keys():
             action = 'copy'
         elif 'move' in req.args.keys():
             action = 'move'
         else:
             raise TracError, 'Action not specified or invalid'
             
         action_verb = {'copy':'Copied', 'move':'Moved'}[action]
         
         # Double check the ticket number is actually a number
         if source_type == 'id':
             try:
                 int(source)
             except ValueError:
                 raise TracError('Value %r is not numeric'%source)
         
         self.log.debug('DatamoverTicketModule: Source is %s (%s)', source, source_type)
         
         query_string = {
             'ticket': 'id=%s'%source,
             'component': 'component=%s'%source,
             'all': 'id!=0',
             'query': source,
         }[source_type]
             
         try:
             # Find the ids we want
             ids = None
             if source_type == 'ticket': # Special case this pending #T4119
                 ids = [int(source)]
             else:
                 self.log.debug('DatamoverTicketModule: Running query %r', query_string)
                 ids = [x['id'] for x in Query.from_string(self.env, query_string).execute(req)]
                 self.log.debug('DatamoverTicketModule: Results: %r', ids)
                 
             dest_db = _open_environment(dest).get_db_cnx()
             for id in ids:
                 copy_ticket(self.env, dest, id, dest_db)
             dest_db.commit()
                 
             if action == 'move':
                 for id in ids:
                     Ticket(self.env, id).delete()
                 
             if ids:
                 req.hdf['datamover.message'] = '%s tickets %s'%(action_verb, ', '.join([str(n) for n in ids]))
             else:
                 req.hdf['datamover.message'] = 'No tickets %s'%(action_verb.lower())
         except TracError, e:
             req.hdf['datamover.message'] = "An error has occured: \n"+str(e)
             self.log.warn(req.hdf['datamover.message'], exc_info=True)