def copy_version(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 version %s to the environment at %s', name, dest_env.path) dest_env.log.info('DatamoverPlugin: Moving version %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 version from the destination try: dest_version = Version(dest_env, name, db=dest_db) dest_version.delete(db=dest_db) except TracError: pass # Copy each entry in the version table source_cursor.execute('SELECT * FROM version WHERE name=%s',(name,)) for row in source_cursor: version_data = dict(zip([d[0] for d in source_cursor.description], row)) q = make_query(version_data, 'version') dest_cursor.execute(*q) if handle_commit: dest_db.commit()
def copy_wiki_page(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 page %s to the environment at %s', name, dest_env.path) dest_env.log.info('DatamoverPlugin: Moving page %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 page from the destination dest_page = WikiPage(dest_env, name, db=dest_db) if dest_page.exists: dest_page.delete(db=dest_db) # Copy each entry in the wiki table source_cursor.execute('SELECT * FROM wiki WHERE name=%s',(name,)) for row in source_cursor: wiki_data = dict(zip([d[0] for d in source_cursor.description], row)) q = make_query(wiki_data, 'wiki') dest_cursor.execute(*q) if handle_commit: dest_db.commit()
def copy_enum(source_env, dest_env, etype, 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 enum (%s,%s) to the environment at %s', etype, name, dest_env.path) dest_env.log.info('DatamoverPlugin: Moving enum (%s,%s) from the environment at %s', etype, 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 enum from the destination dest_cursor.execute('DELETE FROM enum WHERE type=%s AND name=%s', (etype, name)) # Copy each entry in the component table source_cursor.execute('SELECT * FROM enum WHERE type=%s AND name=%s',(etype,name)) for row in source_cursor: enum_data = dict(zip([d[0] for d in source_cursor.description], row)) q = make_query(enum_data, 'enum') dest_cursor.execute(*q) if handle_commit: dest_db.commit()
def copy_ticket(source_env, dest_env, source_id, dest_db=None): """Copy a ticket from {{{source_env}}} #{{{source_id}}} to {{{dest_env}}}.""" # 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) # 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() # Copy the 'ticket' table entry source_cursor.execute('SELECT * FROM ticket WHERE id=%s', (source_id, )) ticket_data = dict( zip([d[0] for d in source_cursor.description], source_cursor.fetchone())) del ticket_data['id'] q = make_query(ticket_data, 'ticket') dest_cursor.execute(*q) dest_id = dest_db.get_last_id(dest_cursor, 'ticket') # Copy the 'ticket_changes' entries source_cursor.execute('SELECT * FROM ticket_change WHERE ticket=%s', (source_id, )) for row in source_cursor: ticket_change_data = dict( zip([d[0] for d in source_cursor.description], row)) ticket_change_data['ticket'] = dest_id q = make_query(ticket_change_data, 'ticket_change') dest_cursor.execute(*q) # Copy the 'ticket_custom' entries source_cursor.execute('SELECT * FROM ticket_custom WHERE ticket=%s', (source_id, )) for row in source_cursor: ticket_custom_data = dict( zip([d[0] for d in source_cursor.description], row)) ticket_change_data['ticket'] = dest_id q = make_query(ticket_change_data, 'ticket_custom') dest_cursor.execute(*q) if handle_commit: dest_db.commit()
class TracForgeLoginModule(LoginModule): """Replacement for LoginModule to slave to another environment.""" master_path = Option('tracforge', 'master_path', doc='Path to master Trac') master_env = property(lambda self: _open_environment(self.master_path)) master_href = property(lambda self: Href(self.master_env.base_url)) # INavigationContributor methods def get_active_navigation_item(self, req): return 'login' def get_navigation_items(self, req): if req.authname and req.authname != 'anonymous': yield ('metanav', 'login', 'logged in as %s' % req.authname) yield ('metanav', 'logout', html.A('Logout', href=self.master_href.logout())) else: yield ('metanav', 'login', html.A('Login', href=self.master_href.login())) # IRequestHandler methods def process_request(self, req): if req.path_info.startswith('/login'): if req.authname and req.authname != 'anonymous': # Already logged in, reconstruct last path req.redirect(req.href()) else: # Safe, send to master req.redirect(self.master_href.login()) raise TracError # Internal methods def _get_name_for_cookie(self, req, cookie): return LoginModule(self.master_env)._get_name_for_cookie(req, cookie)
def _get_env(self): if not self._env: assert self.exists, "Can't use a non-existant project" try: self._env = _open_environment(self.env_path) self._valid = True except Exception, e: self._env = BadEnv(self.env_path, e)
def copy_ticket(source_env, dest_env, source_id, dest_db=None): """Copy a ticket from {{{source_env}}} #{{{source_id}}} to {{{dest_env}}}.""" # 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) # 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() # Copy the 'ticket' table entry source_cursor.execute('SELECT * FROM ticket WHERE id=%s',(source_id,)) ticket_data = dict(zip([d[0] for d in source_cursor.description], source_cursor.fetchone())) del ticket_data['id'] q = make_query(ticket_data, 'ticket') dest_cursor.execute(*q) dest_id = dest_db.get_last_id(dest_cursor, 'ticket') # Copy the 'ticket_changes' entries source_cursor.execute('SELECT * FROM ticket_change WHERE ticket=%s',(source_id,)) for row in source_cursor: ticket_change_data = dict(zip([d[0] for d in source_cursor.description], row)) ticket_change_data['ticket'] = dest_id q = make_query(ticket_change_data, 'ticket_change') dest_cursor.execute(*q) # Copy the 'ticket_custom' entries source_cursor.execute('SELECT * FROM ticket_custom WHERE ticket=%s', (source_id,)) for row in source_cursor: ticket_custom_data = dict(zip([d[0] for d in source_cursor.description], row)) ticket_change_data['ticket'] = dest_id q = make_query(ticket_change_data, 'ticket_custom') dest_cursor.execute(*q) if handle_commit: dest_db.commit()
def process_admin_request(self, req, cat, page, path_info): envs = DatamoverSystem(self.env).all_environments() source_db = self.env.get_db_cnx() source_cursor = source_db.cursor() source_cursor.execute('SELECT type, name FROM enum') hashed_enums = {} for enum_type, enum_name in source_cursor: hashed_enums.setdefault(enum_type, []).append(enum_name) if req.method == 'POST': source_type = req.args.get('source') if not source_type or source_type not in ('type', 'enum', '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] enum_filter = None if source_type == 'type': sel_type = req.args.get('enumtype') enum_filter = lambda e: e[0] == sel_type elif source_type == 'enum': sel_enums = [(k, v) for k, v in req.args.items() if k.startswith('enum[')] enum_filter = lambda e: ('enum[%s]' % e[0], e[1]) in sel_enums elif source_type == 'all': enum_filter = lambda c: True try: filtered_enums = [e for e in enums if enum_filter(e)] dest_db = _open_environment(dest).get_db_cnx() for enum in filtered_enums: copy_enum(self.env, dest, enum[0], enum[1], dest_db) dest_db.commit() if action == 'move': for enum in filtered_enums: source_cursor.execute( 'DELETE FROM enum WHERE type=%s AND name=%s', enum) req.hdf['datamover.message'] = '%s enums %s' % ( action_verb, ', '.join( ['%s:%s' % e for e in filtered_enums])) 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 _get_env(req): """Get the Environment object for a request.""" # Find the env_path from the Apache config options = req.get_options() if 'TracEnv' not in options: req.log_error('mod_auth_acctmgr: Must specify a Trac environment') return None env_path = options['TracEnv'] # Try loading the env from the global cache, add it it if needed return _open_environment(env_path)
def process_admin_request(self, req, cat, page, path_info): envs = DatamoverSystem(self.env).all_environments() source_db = self.env.get_db_cnx() source_cursor = source_db.cursor() source_cursor.execute("SELECT id FROM attachment WHERE type = 'wiki'") wiki_pages = list(set([a for (a,) in source_cursor])) # kill duplicates wiki_pages.sort() if req.method == 'POST': source_type = req.args.get('source') if not source_type or source_type not in ('type', 'wiki', 'ticket', '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] att_filter = None if source_type == 'type': in_type = req.args.get('type') att_filter = lambda a: a.parent_type == in_type elif source_type == 'wiki': in_pages = req.args.getlist('wiki') att_filter = lambda a: a.parent_type == 'wiki' and a.parent_id in in_pages elif source_type == 'ticket': in_ticket = req.args.get('ticket') att_filter = lambda a: a.parent_type == 'ticket' and a.parent_id == in_ticket elif source_type == 'all': att_filter = lambda c: True try: source_cursor.execute('SELECT type,id,filename FROM attachment') attachments = [Attachment(self.env,t,i,f) for (t,i,f) in source_cursor] sel_attachments = [a for a in attachments if att_filter(a)] dest_db = _open_environment(dest).get_db_cnx() for att in sel_attachments: copy_attachment(self.env, dest, att.parent_type, att.parent_id, att.filename, dest_db) dest_db.commit() if action == 'move': for att in sel_attachments: att.delete() req.hdf['datamover.message'] = '%s attachments %s'%(action_verb, ', '.join(["%s:%s" % (a.parent_id, a.filename) for a in sel_attachments])) 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 copy_attachment(source_env, dest_env, parent_type, parent_id, filename, 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 attachment (%s,%s,%s) to the environment at %s', parent_type, parent_id, filename, dest_env.path) dest_env.log.info('DatamoverPlugin: Moving attachment (%s,%s,%s) from the environment at %s', parent_type, parent_id, filename, 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 attachment from the destination try: dest_attachment = Attachment(dest_env, parent_type, parent_id, filename, db=dest_db) dest_attachment.delete(db=dest_db) except TracError: pass # Copy each entry in the attachments table source_cursor.execute('SELECT * FROM attachment WHERE type=%s AND id=%s AND filename=%s',(parent_type, parent_id, filename)) for row in source_cursor: att_data = dict(zip([d[0] for d in source_cursor.description], row)) q = make_query(att_data, 'attachment') dest_cursor.execute(*q) # now copy the file itself old_att = Attachment(source_env, parent_type, parent_id, filename, db=source_db) new_att = Attachment(dest_env, parent_type, parent_id, filename, db=dest_db) if not os.path.isdir(os.path.dirname(new_att.path)): os.makedirs(os.path.dirname(new_att.path)) copyfile(old_att.path, new_att.path) if handle_commit: dest_db.commit()
def copy_version(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 version %s to the environment at %s', name, dest_env.path) dest_env.log.info( 'DatamoverPlugin: Moving version %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 version from the destination try: dest_version = Version(dest_env, name, db=dest_db) dest_version.delete(db=dest_db) except TracError: pass # Copy each entry in the version table source_cursor.execute('SELECT * FROM version WHERE name=%s', (name, )) for row in source_cursor: version_data = dict(zip([d[0] for d in source_cursor.description], row)) q = make_query(version_data, 'version') dest_cursor.execute(*q) if handle_commit: dest_db.commit()
def process_admin_request(self, req, cat, page, path_info): envs = DatamoverSystem(self.env).all_environments() permissions = PermissionSystem(self.env).get_all_permissions() if req.method == 'POST': source_type = req.args.get('source') if not source_type or source_type not in ('permission', '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] perm_filter = None if source_type == 'permission': in_permissions = [ tuple(p.split(':', 2)) for p in req.args.getlist('perm') ] perm_filter = lambda p: p in in_permissions elif source_type == 'all': perm_filter = lambda p: True try: sel_permissions = [p for p in permissions if perm_filter(p)] dest_env = _open_environment(dest) for perm in sel_permissions: # revoke first in case it's already there # also, go directly to the store to bypass validity checks PermissionSystem(dest_env).store.revoke_permission( perm[0], perm[1]) PermissionSystem(dest_env).store.grant_permission( perm[0], perm[1]) if action == 'move': for perm in sel_permissions: PermissionSystem(self.env).revoke_permission( perm[0], perm[1]) req.hdf['datamover.message'] = '%s permissions %s' % ( action_verb, ', '.join( ["%s:%s" % (u, a) for u, a in sel_permissions])) 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 all_environments(self): """Returns a dictionary of the form {env_path: {'name', 'muable', 'providers'}}.""" envs = {} for provider in self.env_providers: for env in provider.get_environments(): mutable = not hasattr(provider, 'mutable') or provider.mutable envs[env] = { 'name': _open_environment(env).project_name, 'mutable': mutable and envs.get(env, {'mutable': True}).get('mutable'), 'providers': envs.get(env, {'providers': []}).get('providers') + [provider], # TODO: This could be better written (list.setdefault) } return envs
def process_admin_request(self, req, cat, page, path_info): envs = DatamoverSystem(self.env).all_environments() source_db = self.env.get_db_cnx() source_cursor = source_db.cursor() source_cursor.execute('SELECT type, name FROM enum') hashed_enums = {} for enum_type, enum_name in source_cursor: hashed_enums.setdefault(enum_type, []).append(enum_name) if req.method == 'POST': source_type = req.args.get('source') if not source_type or source_type not in ('type', 'enum', '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] enum_filter = None if source_type == 'type': sel_type = req.args.get('enumtype') enum_filter = lambda e: e[0] == sel_type elif source_type == 'enum': sel_enums = [(k,v) for k,v in req.args.items() if k.startswith('enum[')] enum_filter = lambda e: ('enum[%s]' % e[0], e[1]) in sel_enums elif source_type == 'all': enum_filter = lambda c: True try: filtered_enums = [e for e in enums if enum_filter(e)] dest_db = _open_environment(dest).get_db_cnx() for enum in filtered_enums: copy_enum(self.env, dest, enum[0], enum[1], dest_db) dest_db.commit() if action == 'move': for enum in filtered_enums: source_cursor.execute('DELETE FROM enum WHERE type=%s AND name=%s', enum) req.hdf['datamover.message'] = '%s enums %s'%(action_verb, ', '.join(['%s:%s'%e for e in filtered_enums])) 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 process_admin_request(self, req, cat, page, path_info): 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 ('prefix', 'glob', 'regex', '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] page_filter = None if source_type == 'prefix': page_filter = lambda p: p.startswith(source.strip()) elif source_type == 'glob': page_filter = lambda p: fnmatch.fnmatch(p, source) elif source_type == 'regex': page_filter = lambda p: re.search(re.compile(source, re.U), p) elif source_type == 'all': page_filter = lambda p: True try: pages = [ p for p in WikiSystem(self.env).get_pages() if page_filter(p) ] dest_db = _open_environment(dest).get_db_cnx() for page in pages: copy_wiki_page(self.env, dest, page, dest_db) dest_db.commit() if action == 'move': for page in pages: WikiPage(self.env, page).delete() req.hdf['datamover.message'] = '%s pages %s' % ( action_verb, ', '.join(pages)) 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 copy_enum(source_env, dest_env, etype, 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 enum (%s,%s) to the environment at %s', etype, name, dest_env.path) dest_env.log.info( 'DatamoverPlugin: Moving enum (%s,%s) from the environment at %s', etype, 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 enum from the destination dest_cursor.execute('DELETE FROM enum WHERE type=%s AND name=%s', (etype, name)) # Copy each entry in the component table source_cursor.execute('SELECT * FROM enum WHERE type=%s AND name=%s', (etype, name)) for row in source_cursor: enum_data = dict(zip([d[0] for d in source_cursor.description], row)) q = make_query(enum_data, 'enum') dest_cursor.execute(*q) if handle_commit: dest_db.commit()
def copy_wiki_page(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 page %s to the environment at %s', name, dest_env.path) dest_env.log.info( 'DatamoverPlugin: Moving page %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 page from the destination dest_page = WikiPage(dest_env, name, db=dest_db) if dest_page.exists: dest_page.delete(db=dest_db) # Copy each entry in the wiki table source_cursor.execute('SELECT * FROM wiki WHERE name=%s', (name, )) for row in source_cursor: wiki_data = dict(zip([d[0] for d in source_cursor.description], row)) q = make_query(wiki_data, 'wiki') dest_cursor.execute(*q) if handle_commit: dest_db.commit()
def get_navigation_items(self, req): projects = [] search_path, this_project = os.path.split(self.env.path) base_url, _ = posixpath.split(req.abs_href()) for project in os.listdir(search_path): if project != this_project: proj_env = _open_environment(os.path.join(search_path, project)) proj_elm = tag.OPTION(proj_env.project_name, value=posixpath.join(base_url, project)) projects.append((proj_elm, proj_env.project_name)) projects.sort(lambda a,b: cmp(a[1],b[1])) # Sort on the project names projects.insert(0, (tag.OPTION(self.env.project_name, value=''), None)) add_script(req, 'projectmenu/projectmenu.js') yield 'metanav', 'projectmenu', tag.SELECT([e for e,_ in projects], name='projectmenu', id='projectmenu', onchange='return on_projectmenu_change();')
def process_admin_request(self, req, cat, page, path_info): 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 ('prefix', 'glob', 'regex', '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] page_filter = None if source_type == 'prefix': page_filter = lambda p: p.startswith(source.strip()) elif source_type == 'glob': page_filter = lambda p: fnmatch.fnmatch(p, source) elif source_type == 'regex': page_filter = lambda p: re.search(re.compile(source, re.U), p) elif source_type == 'all': page_filter = lambda p: True try: pages = [p for p in WikiSystem(self.env).get_pages() if page_filter(p)] dest_db = _open_environment(dest).get_db_cnx() for page in pages: copy_wiki_page(self.env, dest, page, dest_db) dest_db.commit() if action == 'move': for page in pages: WikiPage(self.env, page).delete() req.hdf['datamover.message'] = '%s pages %s'%(action_verb, ', '.join(pages)) 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 process_admin_request(self, req, cat, page, path_info): envs = DatamoverSystem(self.env).all_environments() permissions = PermissionSystem(self.env).get_all_permissions() if req.method == 'POST': source_type = req.args.get('source') if not source_type or source_type not in ('permission', '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] perm_filter = None if source_type == 'permission': in_permissions = [tuple(p.split(':', 2)) for p in req.args.getlist('perm')] perm_filter = lambda p: p in in_permissions elif source_type == 'all': perm_filter = lambda p: True try: sel_permissions = [p for p in permissions if perm_filter(p)] dest_env = _open_environment(dest) for perm in sel_permissions: # revoke first in case it's already there # also, go directly to the store to bypass validity checks PermissionSystem(dest_env).store.revoke_permission(perm[0], perm[1]) PermissionSystem(dest_env).store.grant_permission(perm[0], perm[1]) if action == 'move': for perm in sel_permissions: PermissionSystem(self.env).revoke_permission(perm[0], perm[1]) req.hdf['datamover.message'] = '%s permissions %s'%(action_verb, ', '.join(["%s:%s" % (u,a) for u,a in sel_permissions])) 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 process_admin_request(self, req, cat, page, path_info): envs = DatamoverSystem(self.env).all_environments() versions = [v.name for v in Version.select(self.env)] if req.method == 'POST': source_type = req.args.get('source') if not source_type or source_type not in ('version', '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] ver_filter = None if source_type == 'version': in_versions = req.args.getlist('version') ver_filter = lambda c: c in in_versions elif source_type == 'all': ver_filter = lambda c: True try: sel_versions = [v for v in versions if ver_filter(v)] dest_db = _open_environment(dest).get_db_cnx() for version in sel_versions: copy_version(self.env, dest, version, dest_db) dest_db.commit() if action == 'move': for version in sel_versions: Version(self.env, version).delete() req.hdf['datamover.message'] = '%s versions %s' % ( action_verb, ', '.join(sel_versions)) 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 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 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)
def accessor(self, *args, **kwords): val = super(EnvironmentOption,self).accessor(*args, **kwords) assert val, 'You must configure a valid Trac environment path for [%s] %s'%(self.section, self.name) return _open_environment(val)
def process_admin_request(self, req, cat, page, path_info): envs = DatamoverSystem(self.env).all_environments() source_db = self.env.get_db_cnx() source_cursor = source_db.cursor() source_cursor.execute("SELECT id FROM attachment WHERE type = 'wiki'") wiki_pages = list(set([a for (a, ) in source_cursor])) # kill duplicates wiki_pages.sort() if req.method == 'POST': source_type = req.args.get('source') if not source_type or source_type not in ('type', 'wiki', 'ticket', '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] att_filter = None if source_type == 'type': in_type = req.args.get('type') att_filter = lambda a: a.parent_type == in_type elif source_type == 'wiki': in_pages = req.args.getlist('wiki') att_filter = lambda a: a.parent_type == 'wiki' and a.parent_id in in_pages elif source_type == 'ticket': in_ticket = req.args.get('ticket') att_filter = lambda a: a.parent_type == 'ticket' and a.parent_id == in_ticket elif source_type == 'all': att_filter = lambda c: True try: source_cursor.execute( 'SELECT type,id,filename FROM attachment') attachments = [ Attachment(self.env, t, i, f) for (t, i, f) in source_cursor ] sel_attachments = [a for a in attachments if att_filter(a)] dest_db = _open_environment(dest).get_db_cnx() for att in sel_attachments: copy_attachment(self.env, dest, att.parent_type, att.parent_id, att.filename, dest_db) dest_db.commit() if action == 'move': for att in sel_attachments: att.delete() req.hdf['datamover.message'] = '%s attachments %s' % ( action_verb, ', '.join([ "%s:%s" % (a.parent_id, a.filename) for a in sel_attachments ])) 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 accessor(self, *args, **kwords): val = super(EnvironmentOption, self).accessor(*args, **kwords) assert val, 'You must configure a valid Trac environment path for [%s] %s' % ( self.section, self.name) return _open_environment(val)
def copy_attachment(source_env, dest_env, parent_type, parent_id, filename, 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 attachment (%s,%s,%s) to the environment at %s', parent_type, parent_id, filename, dest_env.path) dest_env.log.info( 'DatamoverPlugin: Moving attachment (%s,%s,%s) from the environment at %s', parent_type, parent_id, filename, 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 attachment from the destination try: dest_attachment = Attachment(dest_env, parent_type, parent_id, filename, db=dest_db) dest_attachment.delete(db=dest_db) except TracError: pass # Copy each entry in the attachments table source_cursor.execute( 'SELECT * FROM attachment WHERE type=%s AND id=%s AND filename=%s', (parent_type, parent_id, filename)) for row in source_cursor: att_data = dict(zip([d[0] for d in source_cursor.description], row)) q = make_query(att_data, 'attachment') dest_cursor.execute(*q) # now copy the file itself old_att = Attachment(source_env, parent_type, parent_id, filename, db=source_db) new_att = Attachment(dest_env, parent_type, parent_id, filename, db=dest_db) if not os.path.isdir(os.path.dirname(new_att.path)): os.makedirs(os.path.dirname(new_att.path)) copyfile(old_att.path, new_att.path) if handle_commit: dest_db.commit()