Options for including attachments when moving tickets
Template changes
Option to copy_ticket method to include_attachments
Make handle_commit an option to copy_attachment
Use suboption scripts for source options on tickets template
Include script on tickets template
Version bump
Index: datamover/templates/datamover_ticket.cs
===================================================================
--- datamover/templates/datamover_ticket.cs (revision 4963)
+++ datamover/templates/datamover_ticket.cs (revision 4992)
@@ -46,6 +46,11 @@
+
+ Include attachments
+
+
+
@@ -65,26 +70,16 @@
Index: datamover/util.py
===================================================================
--- datamover/util.py (revision 4963)
+++ datamover/util.py (revision 4992)
@@ -15,18 +15,18 @@
'(' + ', '.join(data.keys()) + ') ' + \
'VALUES (' + ', '.join(['%s']*len(data)) + ')'
return (sql, data.values())
+def copy_ticket(source_env, dest_env, source_id, dest_db=None, include_attachments=False, action='copy'):
+ """Copy a ticket from {{{source_env}}} #{{{source_id}}} to {{{dest_env}}}."""
-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()
@@ -58,7 +56,18 @@
ticket_custom_data['ticket'] = dest_id
q = make_query(ticket_custom_data, 'ticket_custom')
dest_cursor.execute(*q)
+ # Copy the attachments
+ if include_attachments:
+ source_cursor.execute("SELECT id,filename FROM attachment where type='ticket' and id=%s" % (source_id,))
+ for row in source_cursor:
+ t_att_data = dict(zip([d[0] for d in source_cursor.description], row))
+ copy_attachment(source_env, dest_env, 'ticket', source_id, t_att_data['filename'], dest_db, dest_id, False)
+ # TODO: move all the if-move-then-delete-object clauses into util?
+ if action == 'move':
+ att = Attachment(source_env, 'ticket', t_att_data['id'], t_att_data['filename'])
+ att.delete()
+
if handle_commit:
dest_db.commit()
@@ -199,11 +208,11 @@
milestone_data = dict(zip([d[0] for d in source_cursor.description], row))
q = make_query(milestone_data, 'milestone')
dest_cursor.execute(*q)
if handle_commit:
dest_db.commit()
-def copy_attachment(source_env, dest_env, parent_realm, parent_id, filename, dest_db=None, dest_parent_id=None):
+def copy_attachment(source_env, dest_env, parent_realm, parent_id, filename, dest_db=None, dest_parent_id=None, handle_commit = True):
# In case a string gets passed in
if not isinstance(source_env, Environment):
source_env = open_environment(source_env)
@@ -217,15 +226,14 @@
# Log message
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()
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_realm, dest_parent_id, filename, db=dest_db)
Index: datamover/ticket.py
===================================================================
--- datamover/ticket.py (revision 4963)
+++ datamover/ticket.py (revision 4992)
@@ -4,6 +4,7 @@
from trac.ticket.query import Query
from trac.admin.api import IAdminPanelProvider
+from trac.web.chrome import add_script
from api import DatamoverSystem
from util import copy_ticket
@@ -12,18 +13,19 @@
"""The ticket moving component of the datamover plugin."""
implements(IAdminPanelProvider)
# IAdminPanelProvider methods
def get_admin_panels(self, req):
if req.perm.has_permission('TICKET_ADMIN'):
yield ('mover', 'Data Mover', 'ticket', 'Tickets')
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')
+ include_attachments = req.args.get('include_attachments',False)
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)
@@ -63,16 +65,16 @@
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)
+ copy_ticket(self.env, dest, id, dest_db, include_attachments, action)
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:
@@ -80,8 +82,8 @@
except TracError, e:
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.components'] = components
req.hdf['datamover.envs'] = envs
Index: setup.py
===================================================================
--- setup.py (revision 4963)
+++ setup.py (revision 4992)
@@ -5,7 +5,7 @@
setup(
name = 'TracDatamoverPlugin',
- version = '1.3.7.t',
+ version = '1.3.7.u',
packages = ['datamover'],
package_data={ 'datamover' : [ 'templates/*.cs', "htdocs/*.js" ] },
author = "Noah Kantrowitz",