Ticket #2141: trac.multifile.patch
| File trac.multifile.patch, 8.2 KB (added by slavazanko@…, 13 months ago) |
|---|
-
trac/attachment.py
177 177 self.author = row[4] 178 178 self.ipnr = row[5] 179 179 180 def _get_dirPath(self): 181 return os.path.normpath(os.path.join(self.env.path, 'attachments', self.parent_realm, 182 unicode_quote(self.parent_id))) 183 180 184 def _get_path(self): 181 185 path = os.path.join(self.env.path, 'attachments', self.parent_realm, 182 186 unicode_quote(self.parent_id)) … … 485 489 def get_context_classes(self): 486 490 yield AttachmentContext 487 491 488 # Internal methods 489 490 def _do_save(self, context): 492 def _do_save_one(self, context, upload, description): 491 493 req, attachment = context.req, context.resource 492 req.perm.require('ATTACHMENT_CREATE', context)493 494 if 'cancel' in req.args:495 req.redirect(context.parent.resource_href())496 497 upload = req.args['attachment']498 494 if not hasattr(upload, 'filename') or not upload.filename: 499 495 raise TracError(_('No file uploaded')) 500 496 if hasattr(upload.file, 'fileno'): … … 523 519 # Now the filename is known, update the attachment context 524 520 context.id = filename 525 521 526 attachment.description = req.args.get('description', '')522 attachment.description = description 527 523 attachment.author = get_reporter_id(req, 'author') 528 524 attachment.ipnr = req.remote_addr 529 525 … … 538 534 else: 539 535 raise InvalidAttachment(_('Invalid attachment: %(message)s', 540 536 message=message)) 541 542 537 if req.args.get('replace'): 543 538 try: 544 539 old_attachment = Attachment(self.env, attachment.parent_realm, … … 552 547 attachment.filename = None 553 548 attachment.insert(filename, upload.file, size) 554 549 555 # Redirect the user to list of attachments (must add a trailing '/')556 req.redirect(context.resource_href('..') + '/')557 550 551 def _do_save_many(self, context): 552 req = context.req 553 curr_attach = 0 554 555 while curr_attach < int(req.args['multiple_attachments']): 556 upload=req.args['attachment-%d' % curr_attach] 557 if hasattr(upload, 'filename') and upload.filename: 558 self._do_save_one(context, upload, req.args.get('description-%d' % curr_attach, '')) 559 curr_attach=curr_attach+1 560 # Internal methods 561 562 def _do_save(self, context): 563 req, attachment = context.req, context.resource 564 req.perm.require('ATTACHMENT_CREATE', context) 565 566 if 'cancel' in req.args: 567 req.redirect(context.parent.resource_href()) 568 569 if 'multiple_attachments' in req.args: 570 self._do_save_many(context) 571 req.redirect(context.parent.resource_href()) 572 else: 573 self._do_save_one(context, req.args['attachment'], req.args.get('description', '')) 574 # Redirect the user to list of attachments (must add a trailing '/') 575 req.redirect(context.resource_href('..') + '/') 576 558 577 def _do_delete(self, context): 559 578 req, attachment = context.req, context.resource 560 579 req.perm.require('ATTACHMENT_DELETE', context) -
trac/templates/attachment.html
13 13 <body py:with="parent = attachments and attachments.parent or context.parent; 14 14 parent_name = parent.name(); 15 15 parent_href = parent.get_href(href)"> 16 17 <div id="ctxtnav" class="nav"> 18 <h2>Attachment Navigation</h2> 19 <ul> 20 <li class="first"> 21 <a href="${chrome.links.up[0].href}">${_("Back to %(parent)s", parent=parent_name)}</a> 22 </li> 23 </ul> 24 </div> 25 26 <div py:choose="mode" id="content" class="attachment"> 27 <py:when test="'new'"> 28 <h1>Add Attachment to <a href="$parent_href">$parent_name</a></h1> 16 <py:def function="attach_file_origForm()"> 17 <!--Old form placed here--> 29 18 <form id="attachment" method="post" enctype="multipart/form-data" action=""> 30 19 <div class="field"> 31 20 <label>File:<br /><input type="file" name="attachment" /></label> … … 58 47 <input type="submit" name="cancel" value="Cancel" /> 59 48 </div> 60 49 </form> 50 </py:def> 51 <py:def function="attach_multiFile_form()"> 52 <script type="text/javascript"> 53 function multipleAttach_manageFields(_obj){ 54 var count = document.getElementById("multiAttach_count"); 55 var tbody = document.getElementById("multiAttach_tbody"); 56 if(tbody.rows.length == 1) return; 57 if (_obj.value == '') { 58 tbody.deleteRow(_obj.getAttribute("attachNum")*1+1); 59 var loop; 60 for (loop=0;loop != tbody.rows.length; loop ++){ 61 tbody.rows[loop].setAttribute("id","multiAttach_tr-"+loop); 62 } 63 var loop1=0, inp; 64 for (loop=0; loop != count.value*1; loop ++){ 65 inp = document.getElementById("multiAttach_attachment-"+loop); 66 if (inp == null) continue; 67 inp.setAttribute("attachnum",loop1); 68 inp.name="attachment-"+loop1; 69 inp.setAttribute("name","attachment-"+loop1); 70 inp.setAttribute("id","multiAttach_attachment"+loop1); 71 inp = document.getElementById("multiAttach_description-"+loop); 72 inp.name="description-"+loop1; 73 inp.setAttribute("name","description-"+loop1); 74 inp.setAttribute("id","multiAttach_description"+loop1); 75 loop1++; 76 } 77 count.value = count.value*1-1; 78 } else { 79 if (_obj.getAttribute("attachnum") != count.value-1) return; 80 var tr = tbody.insertRow(-1); 81 tr.setAttribute("id","multiAttach_tr-"+count.value); 82 var td = tr.insertCell(-1); 83 td.innerHTML='<input type="file" id="multiAttach_attachment-'+count.value+'" attachnum="'+count.value+'" name="attachment-'+count.value+'" onchange="multipleAttach_manageFields(this);"/>'; 84 var td = tr.insertCell(-1); 85 td.innerHTML='<input type="text" id="multiAttach_description-'+count.value+'" name="description-'+count.value+'" size="60" />'; 86 count.value = count.value*1+1; 87 } 88 } 89 </script> 90 <form id="attachment" method="post" enctype="multipart/form-data" action="${ attachments and attachments.attach_href() or None}"> 91 <table><thead> 92 <tr py:if="authname == 'anonymous'"><td colspan="2"> 93 <label>Your email or username:<br /> 94 <input type="text" name="author" size="30" value="$author" /> 95 </label> 96 </td></tr> 97 <tr><td colspan="2"> 98 <label> 99 <input type="checkbox" name="replace" /> 100 Replace existing attachments of the same name 101 </label> 102 </td></tr> 103 </thead> 104 <tbody id="multiAttach_tbody"> 105 <tr><th align="left">File</th><th align="left">Description</th></tr> 106 <tr id="multiAttach_tr-0"> 107 <td><input type="file" id="multiAttach_attachment-0" attachnum="0" name="attachment-0" onchange="multipleAttach_manageFields(this);"/></td> 108 <td><input type="text" id="multiAttach_description-0" name="description-0" size="60" /></td> 109 </tr> 110 </tbody> 111 </table> 112 <div class="buttons"> 113 <input type="hidden" name="action" value="new" /> 114 <input type="hidden" id="multiAttach_count" name="multiple_attachments" value="1" /> 115 <input type="hidden" name="realm" value="$context.parent.realm" /> 116 <input type="hidden" name="id" value="$context.parent.id" /> 117 <input type="submit" value="Attach files" /> 118 <input type="button" name="cancel" value="Cancel" onclick="showAttachmentPanel();"/> 119 </div> 120 </form> 121 </py:def> 122 <div id="ctxtnav" class="nav"> 123 <h2>Attachment Navigation</h2> 124 <ul> 125 <li class="first"> 126 <a href="${chrome.links.up[0].href}">${_("Back to %(parent)s", parent=parent_name)}</a> 127 </li> 128 </ul> 129 </div> 130 131 <div py:choose="mode" id="content" class="attachment"> 132 <py:when test="'new'"> 133 <h1>Add Attachment to <a href="$parent_href">$parent_name</a></h1> 134 <!-- ${attach_file_origForm()} --> 135 ${attach_multiFile_form()} 61 136 </py:when> 62 137 63 138 <py:when test="'delete'">
