Ticket #1749: ticketdelete-trac0.11.patch
| File ticketdelete-trac0.11.patch, 13.3 kB (added by phpxcache, 1 year ago) |
|---|
-
ticketdelete/web_ui.py
old new 1 1 # Ticket deleting plugins 2 2 3 3 from trac import __version__ as TRAC_VERSION 4 from trac import ticket5 4 from trac.core import * 5 from trac.ticket.model import Ticket 6 6 from trac.web.api import IRequestFilter 7 7 from trac.web.chrome import ITemplateProvider, add_script, add_stylesheet 8 from webadmin.web_ui import IAdminPageProvider8 from trac.admin.web_ui import IAdminPanelProvider 9 9 import re, traceback, pprint 10 10 from time import strftime, localtime 11 11 … … 14 14 class TicketDeletePlugin(Component): 15 15 """A small ticket deletion plugin.""" 16 16 17 implements(ITemplateProvider, IAdminPa geProvider, IRequestFilter)17 implements(ITemplateProvider, IAdminPanelProvider, IRequestFilter) 18 18 19 19 # IRequestFilter methods 20 20 def pre_process_request(self, req, handler): 21 21 return handler 22 22 23 def post_process_request(self, req, template, content_type): 24 if template == 'ticket.cs' and req.perm.has_permission('TICKET_ADMIN'): 25 add_script(req, 'ticketdelete/jquery.js') 23 def post_process_request(self, req, template, data, content_type): 24 if template == 'ticket.html' and req.perm.has_permission('TICKET_ADMIN'): 25 major, minor = self._get_trac_version() 26 if major <= 0 and minor < 11: 27 add_script(req, 'ticketdelete/jquery.js') 26 28 add_script(req, 'ticketdelete/ticketdelete.js') 27 29 add_stylesheet(req, 'ticketdelete/ticketdelete.css') 28 return template, content_type30 return template, data, content_type 29 31 30 # IAdminPa geProvider methods31 def get_admin_pa ges(self, req):32 # IAdminPanelProvider methods 33 def get_admin_panels(self, req): 32 34 if req.perm.has_permission('TICKET_ADMIN'): 33 35 yield ('ticket', 'Ticket System', 'delete', 'Delete') 34 36 yield ('ticket', 'Ticket System', 'comments', 'Delete Changes') 35 37 36 def process_admin_request(self, req, cat, page, path_info):38 def render_admin_panel(self, req, cat, page, path_info): 37 39 req.perm.assert_permission('TICKET_ADMIN') 38 40 39 data = {} 41 ticketdelete = {} 42 ticketdelete['href'] = req.href('admin', cat, page) 43 ticketdelete['page'] = page 44 ticketdelete['redir'] = 1 40 45 41 data['ticketdelete.href'] = req.href('admin', cat, page)42 data['ticketdelete.page'] = page43 data['ticketdelete.redir'] = 144 45 46 if req.method == 'POST': 46 47 if page == 'delete': 47 48 if 'ticketid' in req.args and 'ticketid2' in req.args: 48 49 if req.args.get('ticketid') == req.args.get('ticketid2'): 49 t = self._validate(req, req.args.get('ticketid'))50 t, ticketdelete = self._validate(req, req.args.get('ticketid'), ata) 50 51 if t: 51 52 self._delete_ticket(t.id) 52 data['ticketdelete.message'] = "Ticket #%s has been deleted." % t.id53 ticketdelete['message'] = "Ticket #%s has been deleted." % t.id 53 54 54 55 else: 55 data['ticketdelete.message'] = "The two IDs did not match. Please try again."56 ticketdelete['message'] = "The two IDs did not match. Please try again." 56 57 elif page == 'comments': 57 58 if 'ticketid' in req.args: 58 59 req.redirect(req.href.admin(cat, page, req.args.get('ticketid'))) 59 60 else: 60 t = self._validate(req, path_info)61 t, ticketdelete = self._validate(req, path_info, ticketdelete) 61 62 if t: 62 data['ticketdelete.href'] = req.href('admin', cat, page, path_info)63 ticketdelete['href'] = req.href('admin', cat, page, path_info) 63 64 try: 64 65 deletions = None 65 66 if "multidelete" in req.args: … … 74 75 ts = int(ts) 75 76 self.log.debug('TicketDelete: Deleting change to ticket %s at %s (%s)'%(t.id,ts,field)) 76 77 self._delete_change(t.id, ts, field) 77 data['ticketdelete.message'] = "Change to ticket #%s at %s has been modified" % (t.id, strftime('%a, %d %b %Y %H:%M:%S',localtime(ts)))78 data['ticketdelete.redir'] = 078 ticketdelete['message'] = "Change to ticket #%s at %s has been modified" % (t.id, strftime('%a, %d %b %Y %H:%M:%S',localtime(ts))) 79 ticketdelete['redir'] = 0 79 80 except ValueError, e: 80 81 self.log.debug("TicketDelete: Error is %s"%e) 81 82 self.log.debug("TicketDelete: args = '%s'"%req.args.items()) 82 data['ticketdelete.message'] = "Timestamp '%s' not valid" % req.args.get('ts')83 ticketdelete['message'] = "Timestamp '%s' not valid" % req.args.get('ts') 83 84 84 85 85 86 if path_info: 86 t = self._validate(req, path_info)87 t, ticketdelete = self._validate(req, path_info, ticketdelete) 87 88 if t: 88 89 if page == 'comments': 89 90 try: … … 96 97 data = ticket_data.setdefault(str(time), {}) 97 98 data.setdefault('fields', {})[field] = {'old': oldvalue, 'new': newvalue} 98 99 data['author'] = author 99 data['prettytime'] = strftime('%a, %d %b %Y %H:%M:%S',localtime(time))100 #data['prettytime'] = strftime('%a, %d %b %Y %H:%M:%S',localtime(0.10)) 100 101 101 102 # Remove all attachment changes 102 103 for k, v in ticket_data.items(): … … 107 108 time_list = list(sorted(ticket_data.iterkeys())) 108 109 if selected is not None and selected < len(time_list): 109 110 ticket_data[time_list[selected]]['checked'] = True 110 data['ticketdelete.changes'] = ticket_data 111 ticketdelete['changes'] = [] 112 for time in time_list: 113 ticketdelete['changes'].append(ticket_data[time]) 111 114 elif page == 'delete': 112 data['ticketdelete.id'] = t.id115 ticketdelete['id'] = t.id 113 116 114 return 'ticketdelete_admin.html', data, None117 data = {'ticketdelete': ticketdelete} 115 118 119 return 'ticketdelete_admin.html', data 120 116 121 # ITemplateProvider methods 117 122 def get_templates_dirs(self): 118 123 """ … … 145 150 else: 146 151 return (0,0) 147 152 148 def _validate(self, req, arg ):153 def _validate(self, req, arg, ticketdelete): 149 154 """Validate that arg is a string containing a valid ticket ID.""" 150 155 try: 151 156 id = int(arg) 152 157 t = Ticket(self.env, id) 153 return t 158 return t, ticketdelete 154 159 except TracError: 155 data['ticketdelete.message'] = "Ticket #%s not found. Please try again." % id160 ticketdelete['message'] = "Ticket #%s not found. Please try again." % id 156 161 except ValueError: 157 data['ticketdelete.message'] = "Ticket ID '%s' is not valid. Please try again." % arg158 return False 162 ticketdelete['message'] = "Ticket ID '%s' is not valid. Please try again." % arg 163 return False, ticketdelete 159 164 160 165 161 166 def _delete_ticket(self, id): -
ticketdelete/htdocs/ticketdelete.js
old new 7 7 } else { 8 8 $('#ticket table.properties').after('<div class="description"><h3><span class="inlinebuttons">'+delete_link+'</span> </h3></div>'); 9 9 } 10 $('#changelog h3').each(function() { 10 $('#changelog form').each(function() { 11 if (!/#comment$/.test(this.action)) { 12 return; 13 } 11 14 var comment = $('input[@name=replyto]', this)[0]; 12 15 if (comment) { 13 16 comment = comment.value; -
ticketdelete/templates/ticketdelete_admin.html
old new 1 <div xmlns="http://www.w3.org/1999/xhtml" 2 xmlns:py="http://genshi.edgewall.org/" 3 id="page"> 4 <h2>Delete Ticket<py:if ticketdelete.page="comments"> Changes</py:if></h2> 1 <!DOCTYPE html 2 PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 4 <html xmlns="http://www.w3.org/1999/xhtml" 5 xmlns:xi="http://www.w3.org/2001/XInclude" 6 xmlns:py="http://genshi.edgewall.org/"> 7 <xi:include href="admin.html" /> 8 <head> 9 <title>Delete</title> 10 </head> 11 <body> 5 12 13 <h2>Delete Ticket<py:if test="ticketdelete.page == 'comments'"> Changes</py:if></h2> 14 6 15 <py:choose> 7 16 <py:when test="ticketdelete.message and ticketdelete.redir"> 8 17 <b>${ticketdelete.message}</b><br /> … … 22 31 </form> 23 32 </py:when> 24 33 <py:when test="ticketdelete.page == 'comments'"> 25 <py:choose has_tickets="len(ticketdelete.changes)">26 <py:when has_tickets="True">34 <py:choose test="len(ticketdelete.changes)"> 35 <py:when test="True"> 27 36 <py:if test="ticketdelete.message"> 28 37 <p><b>${ticketdelete.message}</b></p> 29 38 </py:if> … … 34 43 <tbody> 35 44 <py:for each="change in ticketdelete.changes"> 36 45 <tr> 37 <td><input type="checkbox" name="dontcare" value="dontcare" id="checkbox_${change}" checked="${change.checked or None}" /></td>46 <td><input type="checkbox" name="dontcare" value="dontcare" id="checkbox_${change}" checked="${change.checked or None}" onchange="syncchecks(this)" /></td> 38 47 <td colspan="3"><b>Change at ${change.prettytime} by ${change.author}</b></td> 39 48 <td><input type="submit" name="delete_${change}" value="Delete change" /></td> 40 49 <tr> 41 50 <py:for each="field in change.fields"> 42 51 <tr> 43 <td><input type="checkbox" id="checkbox${field}_${change}" name="mdelete" value="${field}_${change}" checked="${change.checked or None}" /></td> 52 <td><input type="checkbox" id="checkbox_${change}_${field}" name="mdelete" value="${field}_${change}" checked="${change.checked or None}" onchange="if(this.checked) { $('#checkbox_${change}').checked = 0; }" /></td> 53 44 54 <td>${field}</td> 45 <py:choose test=" name(field)">55 <py:choose test="str(field)"> 46 56 <td py:when="comment" colspan="2">${field.new}</td> 47 57 48 58 <py:otherwise> … … 61 71 62 72 <script type="text/javascript"> 63 73 <!-- 64 function toggleboxen(me, boxen)74 function syncchecks(me) 65 75 { 66 status = document.getElementById("checkbox_" + me).checked; 67 boxen.pop() // Remove the last (blank) entry. 68 for (box in boxen) { 69 //alert("Changing checkbox"+boxen[box]+"_"+me); 70 document.getElementById("checkbox"+boxen[box]+"_"+me).checked = status; 76 var checked = me.checked; 77 var checks = document.getElementsByTagName("input"); 78 var re = new RegExp("^" + me.id + "_"); 79 for (var i = 0, l = checks.length; i < l; i ++) { 80 var check = checks[i]; 81 if (check.type == "checkbox" && re.test(check.id)) { 82 check.checked = checked; 83 } 71 84 } 72 85 } 73 74 <py:for each="change in ticketdelete.changes">75 addEvent(document.getElementById("checkbox_${change}"), "change", function() {76 var boxen = Array(${py:for each="field in change.fields"${field}",</py:for>"");77 toggleboxen("${change}", boxen); //Array(<py:for each="field in change.fields">"${field}",</py:for>));78 });79 <py:for each="field in change.fields">80 addEvent(document.getElementById("checkbox${field}_${change}"),"change", function() {81 if(!document.getElementById("checkbox${field}_${change}").checked) {82 document.getElementById("checkbox${change}").checked = 0;83 }84 });85 </py:for>86 </py:for>87 88 89 86 //--> 90 87 </script> 91 88 … … 104 101 </py:choose> 105 102 </py:when> 106 103 </py:choose> 107 </div> 104 </body> 105 106 </html>
