Changeset 2772
- Timestamp:
- 11/12/07 18:19:04 (1 year ago)
- Files:
-
- batchmodifyplugin/0.10/batchmod/templates/batchmod.cs (deleted)
- batchmodifyplugin/0.11 (copied) (copied from batchmodifyplugin/0.10) (1 prop)
- batchmodifyplugin/0.11/batchmod/templates/batchmod.html (added)
- batchmodifyplugin/0.11/batchmod/web_ui.py (modified) (1 diff)
- batchmodifyplugin/0.11/setup.py (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
batchmodifyplugin/0.11
- Property svn:ignore set to
build
BatchModify.egg-info
dist
- Property svn:ignore set to
batchmodifyplugin/0.11/batchmod/web_ui.py
r1379 r2772 1 1 # -*- coding: utf-8 -*- 2 2 # Copyright (C) 2006 Ashwin Phatak 3 # Copyright (C) 2007 Dave Gynn 3 4 4 5 from trac.core import * 5 from trac.web.chrome import INavigationContributor, ITemplateProvider6 from trac.web.main import IRequestHandler7 6 from trac.perm import IPermissionRequestor 7 from trac.ticket import TicketSystem, Ticket 8 8 from trac.ticket.query import QueryModule 9 from trac.util.html import html 10 from trac.ticket import TicketSystem 11 from trac.ticket import Ticket 12 from trac.mimeview.api import IContentConverter 13 from trac.wiki import IWikiSyntaxProvider 14 from trac.wiki.macros import WikiMacroBase 15 from trac.ticket.query import TicketQueryMacro as Macro 9 from trac.web.api import ITemplateStreamFilter 10 from trac.web.chrome import ITemplateProvider, Chrome 11 from trac.web.main import IRequestFilter 12 from genshi.filters.transform import Transformer 16 13 17 __all__ = ['BatchModifyModule' ,'TicketQueryMacro']14 __all__ = ['BatchModifyModule'] 18 15 19 16 class BatchModifyModule(Component): 20 '''Allows batch modification of tickets'''17 implements(IPermissionRequestor, ITemplateProvider, IRequestFilter, ITemplateStreamFilter) 21 18 22 implements(INavigationContributor, IRequestHandler, ITemplateProvider, \ 23 IPermissionRequestor, IContentConverter, IWikiSyntaxProvider) 24 25 # INavigationContributor methods 26 27 def get_active_navigation_item(self, req): 28 return QueryModule(self.env).get_active_navigation_item(req) 29 30 def get_navigation_items(self, req): 31 from trac.ticket.report import ReportModule 32 if req.perm.has_permission('TICKET_VIEW') and \ 33 not self.env.is_component_enabled(ReportModule): 34 yield ('mainnav', 'tickets', 35 html.A('View Tickets', href=req.href.query())) 36 yield ('mainnav', 'query', 37 html.A('Custom Query', href=req.href.query())) 38 39 40 # IRequestHandler methods 41 42 def match_request(self, req): 43 return QueryModule(self.env).match_request(req) 44 45 def process_request(self, req): 46 if req.args.has_key('batchmod'): 47 req.perm.assert_permission('TICKET_BATCH_MODIFY') 48 self._batch_modify(req) 49 50 QueryModule(self.env).process_request(req) 51 self._add_ticket_fields(req) 52 53 return 'batchmod.cs', None 54 19 # IPermissionRequestor methods 20 def get_permission_actions(self): 21 yield 'TICKET_BATCH_MODIFY' 55 22 56 23 # ITemplateProvider methods 24 def get_htdocs_dirs(self): 25 return [] 57 26 58 27 def get_templates_dirs(self): 59 28 from pkg_resources import resource_filename 60 29 return [resource_filename(__name__, 'templates')] 61 62 63 # IPermissionRequestor methods64 def get_permission_actions(self):65 yield 'TICKET_BATCH_MODIFY'66 30 31 # IRequestFilter methods 32 def pre_process_request(self, req, handler): 33 """Look for QueryHandler posts and hijack them""" 34 if isinstance(handler, QueryModule): 35 if req.method=='POST' and req.args.get('batchmod'): 36 self._batch_modify(req) 37 return handler 67 38 68 # IContentConverter methods69 def get_supported_conversions(self):70 return QueryModule(self.env).get_supported_conversions()39 def post_process_request(self, req, template, content_type): 40 """No-op""" 41 return (template, content_type) 71 42 72 def convert_content(self, req, mimetype, query, key): 73 return QueryModule(self.env).convert_content(req, mimetype, query, key) 74 75 76 # IWikiSyntaxProvider methods 77 78 def get_wiki_syntax(self): 79 return QueryModule(self.env).get_wiki_syntax() 80 81 def get_link_resolvers(self): 82 return QueryModule(self.env).get_link_resolvers() 83 84 43 def post_process_request(self, req, template, data, content_type): 44 """No-op""" 45 return (template, data, content_type) 46 85 47 # Internal methods 86 48 def _batch_modify(self, req): 87 49 tickets = req.session['query_tickets'].split(' ') 88 comment = req.args.get(' comment', '')50 comment = req.args.get('bmod_value_comment', '') 89 51 values = {} 90 52 53 # TODO: improve validation and better handle advanced statuses 91 54 for field in TicketSystem(self.env).get_ticket_fields(): 92 55 name = field['name'] 93 56 if name not in ('summary', 'reporter', \ 94 'description', 'type', 'status', 95 'resolution', 'owner'): 96 if req.args.has_key('bm_' + name): 97 values[name] = req.args.get(name) 57 'description', 'status', 58 'resolution'): 59 if req.args.has_key('bmod_flag_' + name): 60 if name == 'owner': 61 values['status'] = 'assigned' 62 values[name] = req.args.get('bmod_value_' + name) 98 63 99 for id in tickets: 100 t = Ticket(self.env, id) 101 t.populate(values) 102 t.save_changes(req.authname, comment) 64 selectedTickets = req.args.get('selectedTickets') 65 selectedTickets = isinstance(selectedTickets, list) and selectedTickets or selectedTickets.split(',') 66 if not selectedTickets: 67 raise TracError, 'No Tickets selected' 68 69 for id in selectedTickets: 70 if id in tickets: 71 t = Ticket(self.env, id) 72 t.populate(values) 73 t.save_changes(req.authname, comment) 103 74 75 # TODO: Send email notifications - copied from ticket.web_ui 76 #try: 77 # tn = TicketNotifyEmail(self.env) 78 # tn.notify(ticket, newticket=False, modtime=now) 79 #except Exception, e: 80 # self.log.exception("Failure sending notification on change to " 81 # "ticket #%s: %s" % (ticket.id, e)) 82 83 # TODO: deal with actions and side effects - copied from ticket.web_ui 84 #for controller in self._get_action_controllers(req, ticket, 85 # action): 86 # controller.apply_action_side_effects(req, ticket, action) 104 87 88 # ITemplateStreamFilter methods 89 def filter_stream(self, req, method, filename, stream, formdata): 90 """Adds BatchModify form to the query page""" 91 if filename != 'query.html' or not req.perm.has_permission('TICKET_BATCH_MODIFY'): 92 return stream 105 93 106 def _add_ticket_fields(self, req): 94 return stream | Transformer('//div[@id="help"]').before(self._generate_form(req, formdata) ) 95 96 97 def _generate_form(self, req, data): 98 batchFormData = dict(data) 99 batchFormData['actionUri']= req.session['query_href'] or req.href.query() 100 101 fields = [] 107 102 for field in TicketSystem(self.env).get_ticket_fields(): 108 name = field['name'] 109 del field['name'] 110 if name in ('summary', 'reporter', 'description', 'type', 'status', 111 'resolution', 'owner'): 112 field['skip'] = True 113 req.hdf['ticket.fields.' + name] = field 103 if field['name'] not in ('summary', 'reporter', 'description'): 104 fields.append(field) 105 batchFormData['fields']=fields 114 106 115 116 class TicketQueryMacro(WikiMacroBase): 117 __doc__ = Macro.__doc__ 118 119 def render_macro(self, req, name, content): 120 return Macro(self.env).render_macro(req, name, content) 107 stream = Chrome(self.env).render_template(req, 'batchmod.html', 108 batchFormData, fragment=True) 109 return stream.select('//form[@id="batchmod-form"]') batchmodifyplugin/0.11/setup.py
r1356 r2772 1 1 #!/usr/bin/env python 2 2 # -*- coding: utf-8 -*- 3 # Copyright (C) 2006 Ashwin Phatak 3 # Copyright (C) 2006 Ashwin Phatak 4 # Copyright (C) 2007 Dave Gynn (dgynn@optaros.com) 4 5 5 6 from setuptools import setup, find_packages 6 7 7 8 PACKAGE = 'BatchModify' 8 VERSION = '0. 1.0'9 VERSION = '0.2.0' 9 10 10 11 setup( … … 13 14 author="Ashwin Phatak", author_email="ashwinpphatak@gmail.com", 14 15 license='BSD', url='http://trac-hacks.org/wiki/BatchModifyPlugin', 15 packages =find_packages(exclude=['ez_setup', '*.tests*']),16 packages = ['batchmod'], 16 17 package_data={ 17 18 'batchmod': [ 18 'templates/*. cs'19 'templates/*.html' 19 20 ] 20 21 },
