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"])
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'])
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'])
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"])
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()
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'])
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"])
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
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()
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())
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())
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'"))
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)
def test_exists(self): """ http://trac.edgewall.org/ticket/4247 """ for c in Component.select(self.env): self.assertEqual(c.exists, True)
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"))
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))
def _insert_component(self, name): component = Component(self.env) component.name = name component.insert() return component
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)