Re-enable Javascript implement copying attachments to different destination tickets added dest_ticket field for attachment mover added scripts.js for selecting suboptions and use them for different attachment sources * Return htdocs dir for serving scripts from * Indicate to serve js files Switch to 0.11 API * switch from trac.web.main._open_environment to trac.env.open_environment * switch from webadmin.web_ui.IAdminPageProvider to trac.admin.api.IAdminPanelProvider * switch attachment filters to use parent_realm instead of parent_type * No longer require TracWebAdmin Version update --- ../datamoverplugin-0.10/./datamover/templates/datamover_ticket.cs 2008-02-22 22:02:18.000000000 +0200 +++ ./datamover/templates/datamover_ticket.cs 2008-02-22 22:04:56.000000000 +0200 @@ -70,7 +70,6 @@ --- ../datamoverplugin-0.10/./datamover/templates/datamover_attachment.cs 2008-02-22 22:02:18.000000000 +0200 +++ ./datamover/templates/datamover_attachment.cs 2008-02-22 22:04:56.000000000 +0200 @@ -62,34 +62,26 @@ +
 
- + - - + --- ../datamoverplugin-0.10/./datamover/templates/datamover_component.cs 2008-02-22 22:02:18.000000000 +0200 +++ ./datamover/templates/datamover_component.cs 2008-02-22 12:09:55.000000000 +0200 @@ -53,7 +53,6 @@ --- ../datamoverplugin-0.10/./datamover/templates/datamover_version.cs 2008-02-22 22:02:18.000000000 +0200 +++ ./datamover/templates/datamover_version.cs 2008-02-22 12:09:55.000000000 +0200 @@ -53,7 +53,6 @@ --- ../datamoverplugin-0.10/./datamover/templates/datamover_wiki.cs 2008-02-22 22:02:18.000000000 +0200 +++ ./datamover/templates/datamover_wiki.cs 2008-02-22 12:09:55.000000000 +0200 @@ -66,7 +66,6 @@ --- ../datamoverplugin-0.10/./datamover/templates/datamover_enum.cs 2008-02-22 22:02:18.000000000 +0200 +++ ./datamover/templates/datamover_enum.cs 2008-02-22 12:09:55.000000000 +0200 @@ -72,7 +72,6 @@ --- ../datamoverplugin-0.10/./datamover/templates/datamover_permission.cs 2008-02-22 22:02:18.000000000 +0200 +++ ./datamover/templates/datamover_permission.cs 2008-02-22 12:09:55.000000000 +0200 @@ -65,7 +65,6 @@ --- ../datamoverplugin-0.10/./datamover/templates/datamover_milestone.cs 2008-02-22 22:02:18.000000000 +0200 +++ ./datamover/templates/datamover_milestone.cs 2008-02-22 12:09:55.000000000 +0200 @@ -53,7 +53,6 @@ --- ../datamoverplugin-0.10/./datamover/htdocs/scripts.js 1970-01-01 02:00:00.000000000 +0200 +++ ./datamover/htdocs/scripts.js 2008-02-22 22:04:56.000000000 +0200 @@ -0,0 +1,27 @@ +selected_suboptions = []; + +function show_suboptions(suboption_list) { + for (i = 0; i < window.selected_suboptions.length; i++) { + opt = document.getElementById(selected_suboptions[i]); + if (opt) { + opt.style.display = 'none'; + } + } + + for (i=0; i < suboption_list.length; i++) { + opt = document.getElementById(suboption_list[i]); + if (opt) { + opt.style.display = 'block'; + } + } + + selected_suboptions = suboption_list; +} + +function add_suboption_set(option, suboption_list) { + addEvent(document.getElementById(option), 'click', function() { show_suboptions(suboption_list);}); +} + +function set_selected_suboptions(suboption_list) { + selected_suboptions = suboption_list; +} \ No newline at end of file --- ../datamoverplugin-0.10/./datamover/milestone.py 2008-02-22 22:02:18.000000000 +0200 +++ ./datamover/milestone.py 2008-02-22 12:09:55.000000000 +0200 @@ -1,8 +1,8 @@ from trac.core import * -from trac.web.main import _open_environment +from trac.env import open_environment from trac.ticket.model import Milestone -from webadmin.web_ui import IAdminPageProvider +from trac.admin.api import IAdminPanelProvider from api import DatamoverSystem from util import copy_milestone @@ -10,10 +10,10 @@ class DatamoverMilestoneModule(Component): """The milestone moving component of the datamover plugin.""" - implements(IAdminPageProvider) + implements(IAdminPanelProvider) - # IAdminPageProvider methods - def get_admin_pages(self, req): + # IAdminPanelProvider methods + def get_admin_panels(self, req): if req.perm.has_permission('TRAC_ADMIN'): yield ('mover', 'Data Mover', 'milestone', 'Milestones') @@ -46,7 +46,7 @@ try: sel_milestones = [m for m in milestones if milestone_filter(m)] - dest_db = _open_environment(dest).get_db_cnx() + dest_db = open_environment(dest).get_db_cnx() for milestone in sel_milestones: copy_milestone(self.env, dest, milestone, dest_db) dest_db.commit() --- ../datamoverplugin-0.10/./datamover/attachment.py 2008-02-22 22:02:18.000000000 +0200 +++ ./datamover/attachment.py 2008-02-22 22:04:56.000000000 +0200 @@ -1,10 +1,11 @@ from trac.core import * -from trac.web.main import _open_environment +from trac.env import open_environment from trac.attachment import Attachment from trac.wiki.api import WikiSystem from trac.wiki.model import WikiPage -from webadmin.web_ui import IAdminPageProvider +from trac.admin.api import IAdminPanelProvider +from trac.web.chrome import add_script from api import DatamoverSystem from util import copy_attachment @@ -17,10 +18,10 @@ class DatamoverAttachmentModule(Component): """The attachment moving component of the datamover plugin.""" - implements(IAdminPageProvider) + implements(IAdminPanelProvider) - # IAdminPageProvider methods - def get_admin_pages(self, req): + # IAdminPanelProvider methods + def get_admin_panels(self, req): if req.perm.has_permission('TRAC_ADMIN'): yield ('mover', 'Data Mover', 'attachment', 'Attachments') @@ -38,6 +39,7 @@ raise TracError, "Source type not specified or invalid" source = req.args.get(source_type) dest = req.args.get('destination') + dest_id = req.args.get('dest_ticket') action = None if 'copy' in req.args.keys(): action = 'copy' @@ -51,23 +53,24 @@ att_filter = None if source_type == 'type': in_type = req.args.get('type') - att_filter = lambda a: a.parent_type == in_type + att_filter = lambda a: a.parent_realm == 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 + att_filter = lambda a: a.parent_realm == '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 + att_filter = lambda a: a.parent_realm == '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() + 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) + copy_attachment(self.env, dest, att.parent_realm, att.parent_id, att.filename, dest_db, dest_id) dest_db.commit() if action == 'move': @@ -79,6 +82,7 @@ req.hdf['datamover.message'] = "An error has occured: \n"+str(e) self.log.warn(req.hdf['datamover.message'], exc_info=True) + add_script(req, "datamover/scripts.js") req.hdf['datamover.envs'] = envs req.hdf['datamover.wiki_pages'] = wiki_pages --- ../datamoverplugin-0.10/./datamover/component.py 2008-02-22 22:02:18.000000000 +0200 +++ ./datamover/component.py 2008-02-22 12:09:55.000000000 +0200 @@ -1,8 +1,8 @@ from trac.core import * -from trac.web.main import _open_environment +from trac.env import open_environment from trac.ticket.model import Component as TicketComponent -from webadmin.web_ui import IAdminPageProvider +from trac.admin.api import IAdminPanelProvider from api import DatamoverSystem from util import copy_component @@ -10,10 +10,10 @@ class DatamoverComponentModule(Component): """The ticket component moving component of the datamover plugin.""" - implements(IAdminPageProvider) + implements(IAdminPanelProvider) - # IAdminPageProvider methods - def get_admin_pages(self, req): + # IAdminPanelProvider methods + def get_admin_panels(self, req): if req.perm.has_permission('TRAC_ADMIN'): yield ('mover', 'Data Mover', 'component', 'Components') @@ -46,7 +46,7 @@ try: sel_components = [c for c in components if comp_filter(c)] - dest_db = _open_environment(dest).get_db_cnx() + dest_db = open_environment(dest).get_db_cnx() for comp in sel_components: copy_component(self.env, dest, comp, dest_db) dest_db.commit() --- ../datamoverplugin-0.10/./datamover/wiki.py 2008-02-22 22:02:18.000000000 +0200 +++ ./datamover/wiki.py 2008-02-22 12:09:55.000000000 +0200 @@ -1,9 +1,9 @@ from trac.core import * -from trac.web.main import _open_environment +from trac.env import open_environment from trac.wiki.api import WikiSystem from trac.wiki.model import WikiPage -from webadmin.web_ui import IAdminPageProvider +from trac.admin.api import IAdminPanelProvider from api import DatamoverSystem from util import copy_wiki_page @@ -15,10 +15,10 @@ class DatamoverWikiModule(Component): """The wiki page moving component of the datamover plugin.""" - implements(IAdminPageProvider) + implements(IAdminPanelProvider) - # IAdminPageProvider methods - def get_admin_pages(self, req): + # IAdminPanelProvider methods + def get_admin_panels(self, req): if req.perm.has_permission('WIKI_ADMIN'): yield ('mover', 'Data Mover', 'wiki', 'Wiki') @@ -54,7 +54,7 @@ try: pages = [p for p in WikiSystem(self.env).get_pages() if page_filter(p)] - dest_db = _open_environment(dest).get_db_cnx() + dest_db = open_environment(dest).get_db_cnx() for page in pages: copy_wiki_page(self.env, dest, page, dest_db) dest_db.commit() --- ../datamoverplugin-0.10/./datamover/enum.py 2008-02-22 22:02:18.000000000 +0200 +++ ./datamover/enum.py 2008-02-22 12:09:55.000000000 +0200 @@ -1,7 +1,7 @@ from trac.core import * -from trac.web.main import _open_environment +from trac.env import open_environment -from webadmin.web_ui import IAdminPageProvider +from trac.admin.api import IAdminPanelProvider from api import DatamoverSystem from util import copy_enum @@ -9,10 +9,10 @@ class DatamoverEnumModule(Component): """The ticket enum moving component of the datamover plugin.""" - implements(IAdminPageProvider) + implements(IAdminPanelProvider) - # IAdminPageProvider methods - def get_admin_pages(self, req): + # IAdminPanelProvider methods + def get_admin_panels(self, req): if req.perm.has_permission('TRAC_ADMIN'): yield ('mover', 'Data Mover', 'enum', 'Enums') @@ -53,7 +53,7 @@ try: filtered_enums = [e for e in enums if enum_filter(e)] - dest_db = _open_environment(dest).get_db_cnx() + 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() --- ../datamoverplugin-0.10/./datamover/version.py 2008-02-22 22:02:18.000000000 +0200 +++ ./datamover/version.py 2008-02-22 12:09:55.000000000 +0200 @@ -1,8 +1,8 @@ from trac.core import * -from trac.web.main import _open_environment +from trac.env import open_environment from trac.ticket.model import Version -from webadmin.web_ui import IAdminPageProvider +from trac.admin.api import IAdminPanelProvider from api import DatamoverSystem from util import copy_version @@ -10,10 +10,10 @@ class DatamoverVersionModule(Component): """The version moving component of the datamover plugin.""" - implements(IAdminPageProvider) + implements(IAdminPanelProvider) - # IAdminPageProvider methods - def get_admin_pages(self, req): + # IAdminPanelProvider methods + def get_admin_panels(self, req): if req.perm.has_permission('TRAC_ADMIN'): yield ('mover', 'Data Mover', 'version', 'Versions') @@ -46,7 +46,7 @@ try: sel_versions = [v for v in versions if ver_filter(v)] - dest_db = _open_environment(dest).get_db_cnx() + dest_db = open_environment(dest).get_db_cnx() for version in sel_versions: copy_version(self.env, dest, version, dest_db) dest_db.commit() --- ../datamoverplugin-0.10/./datamover/api.py 2008-02-22 22:02:18.000000000 +0200 +++ ./datamover/api.py 2008-02-22 12:09:55.000000000 +0200 @@ -1,6 +1,6 @@ # Datamover API classes from trac.core import * -from trac.web.main import _open_environment +from trac.env import open_environment from trac.config import OrderedExtensionsOption from trac.perm import IPermissionRequestor @@ -30,7 +30,7 @@ for env in provider.get_environments(): mutable = not hasattr(provider, 'mutable') or provider.mutable envs[env] = { - 'name': _open_environment(env).project_name, + '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) } --- ../datamoverplugin-0.10/./datamover/web_ui.py 2008-02-22 22:02:18.000000000 +0200 +++ ./datamover/web_ui.py 2008-02-22 12:09:55.000000000 +0200 @@ -1,17 +1,17 @@ from trac.core import * from trac.web.chrome import ITemplateProvider -from webadmin.web_ui import IAdminPageProvider +from trac.admin.api import IAdminPanelProvider from api import DatamoverSystem class DatamoverConfigurationModule(Component): """The configuration screen for the datamover plugin.""" - implements(IAdminPageProvider, ITemplateProvider) + implements(IAdminPanelProvider, ITemplateProvider) - # IAdminPageProvider methods - def get_admin_pages(self, req): + # IAdminPanelProvider methods + def get_admin_panels(self, req): if req.perm.has_permission('DATAMOVER_ADMIN'): yield ('mover', 'Data Mover', 'config', 'Configuration') @@ -42,5 +42,5 @@ return [resource_filename(__name__, 'templates')] def get_htdocs_dirs(self): - #from pkg_resources import resource_filename - return [] + from pkg_resources import resource_filename + return [('datamover', resource_filename(__name__, 'htdocs'))] --- ../datamoverplugin-0.10/./datamover/ticket.py 2008-02-22 22:02:18.000000000 +0200 +++ ./datamover/ticket.py 2008-02-22 22:04:56.000000000 +0200 @@ -1,9 +1,9 @@ from trac.core import * -from trac.web.main import _open_environment +from trac.env import open_environment from trac.ticket.model import Component as TicketComponent, Ticket from trac.ticket.query import Query -from webadmin.web_ui import IAdminPageProvider +from trac.admin.api import IAdminPanelProvider from api import DatamoverSystem from util import copy_ticket @@ -11,10 +11,10 @@ class DatamoverTicketModule(Component): """The ticket moving component of the datamover plugin.""" - implements(IAdminPageProvider) + implements(IAdminPanelProvider) - # IAdminPageProvider methods - def get_admin_pages(self, req): + # IAdminPanelProvider methods + def get_admin_panels(self, req): if req.perm.has_permission('TICKET_ADMIN'): yield ('mover', 'Data Mover', 'ticket', 'Tickets') @@ -64,7 +64,7 @@ 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() + dest_db = open_environment(dest).get_db_cnx() for id in ids: copy_ticket(self.env, dest, id, dest_db) dest_db.commit() --- ../datamoverplugin-0.10/./datamover/permission.py 2008-02-22 22:02:18.000000000 +0200 +++ ./datamover/permission.py 2008-02-22 12:09:55.000000000 +0200 @@ -1,18 +1,18 @@ from trac.core import * -from trac.web.main import _open_environment +from trac.env import open_environment from trac.perm import PermissionSystem -from webadmin.web_ui import IAdminPageProvider +from trac.admin.api import IAdminPanelProvider from api import DatamoverSystem class DatamoverPermissionModule(Component): """The permission moving component of the datamover plugin.""" - implements(IAdminPageProvider) + implements(IAdminPanelProvider) - # IAdminPageProvider methods - def get_admin_pages(self, req): + # IAdminPanelProvider methods + def get_admin_panels(self, req): if req.perm.has_permission('TRAC_ADMIN'): yield ('mover', 'Data Mover', 'permission', 'Permissions') @@ -45,7 +45,7 @@ try: sel_permissions = [p for p in permissions if perm_filter(p)] - dest_env = _open_environment(dest) + 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 --- ../datamoverplugin-0.10/./datamover/util.py 2008-02-22 22:02:18.000000000 +0200 +++ ./datamover/util.py 2008-02-22 22:04:56.000000000 +0200 @@ -1,6 +1,6 @@ from trac.core import TracError from trac.env import Environment -from trac.web.main import _open_environment +from trac.env import open_environment from trac.wiki.model import WikiPage from trac.ticket.model import Component as TicketComponent, Milestone, Version from trac.attachment import Attachment @@ -23,9 +23,9 @@ # In case a string gets passed in if not isinstance(source_env, Environment): - source_env = _open_environment(source_env) + source_env = open_environment(source_env) if not isinstance(dest_env, Environment): - dest_env = _open_environment(dest_env) + dest_env = open_environment(dest_env) # Open databases source_db = source_env.get_db_cnx() @@ -55,8 +55,8 @@ 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') + ticket_custom_data['ticket'] = dest_id + q = make_query(ticket_custom_data, 'ticket_custom') dest_cursor.execute(*q) if handle_commit: @@ -68,9 +68,9 @@ 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) + source_env = open_environment(source_env) if not isinstance(dest_env, Environment): - dest_env = _open_environment(dest_env) + 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) @@ -102,9 +102,9 @@ 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) + source_env = open_environment(source_env) if not isinstance(dest_env, Environment): - dest_env = _open_environment(dest_env) + 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) @@ -138,9 +138,9 @@ 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) + source_env = open_environment(source_env) if not isinstance(dest_env, Environment): - dest_env = _open_environment(dest_env) + 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) @@ -170,9 +170,9 @@ def copy_milestone(source_env, dest_env, name, dest_db=None): # In case a string gets passed in if not isinstance(source_env, Environment): - source_env = _open_environment(source_env) + source_env = open_environment(source_env) if not isinstance(dest_env, Environment): - dest_env = _open_environment(dest_env) + dest_env = open_environment(dest_env) # Log message source_env.log.info('DatamoverPlugin: Moving milestone %s to the environment at %s', name, dest_env.path) @@ -203,16 +203,20 @@ if handle_commit: dest_db.commit() -def copy_attachment(source_env, dest_env, parent_type, parent_id, filename, dest_db=None): +def copy_attachment(source_env, dest_env, parent_realm, parent_id, filename, dest_db=None, dest_parent_id=None): # In case a string gets passed in if not isinstance(source_env, Environment): - source_env = _open_environment(source_env) + source_env = open_environment(source_env) if not isinstance(dest_env, Environment): - dest_env = _open_environment(dest_env) - + dest_env = open_environment(dest_env) + + # The destination parent id may be different + if not dest_parent_id: + dest_parent_id = parent_id + # 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) + source_env.log.info('DatamoverPlugin: Moving attachment (%s,%s,%s) to the environment at %s', parent_realm, parent_id, filename, dest_env.path) + dest_env.log.info('DatamoverPlugin: Moving attachment (%s,%s,%s) from the environment at %s', parent_realm, parent_id, filename, source_env.path) # Open databases source_db = source_env.get_db_cnx() @@ -224,20 +228,21 @@ # Remove the attachment from the destination try: - dest_attachment = Attachment(dest_env, parent_type, parent_id, filename, db=dest_db) + dest_attachment = Attachment(dest_env, parent_realm, dest_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)) + source_cursor.execute('SELECT * FROM attachment WHERE type=%s AND id=%s AND filename=%s',(parent_realm, parent_id, filename)) for row in source_cursor: att_data = dict(zip([d[0] for d in source_cursor.description], row)) + att_data['id'] = dest_parent_id 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) + old_att = Attachment(source_env, parent_realm, parent_id, filename, db=source_db) + new_att = Attachment(dest_env, parent_realm, dest_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) @@ -248,9 +253,9 @@ 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) + source_env = open_environment(source_env) if not isinstance(dest_env, Environment): - dest_env = _open_environment(dest_env) + 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) --- ../datamoverplugin-0.10/./ --- ../datamoverplugin-0.10/./setup.py 2008-02-22 22:02:18.000000000 +0200 +++ ./setup.py 2008-02-22 22:04:56.000000000 +0200 @@ -5,9 +5,9 @@ setup( name = 'TracDatamoverPlugin', - version = '1.2', + version = '1.3.7.t', packages = ['datamover'], - package_data={ 'datamover' : [ 'templates/*.cs' ] }, + package_data={ 'datamover' : [ 'templates/*.cs', "htdocs/*.js" ] }, author = "Noah Kantrowitz", author_email = "coderanger@yahoo.com", description = "Move data between Trac instances.", @@ -31,8 +31,8 @@ ], }, - install_requires = [ 'TracWebAdmin' ], - + install_requires = [], + classifiers = [ 'Framework :: Trac', ],