You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by tv...@apache.org on 2013/07/11 22:20:05 UTC

[1/5] git commit: [#4659] ticket:381 upload multiple attachments

Updated Branches:
  refs/heads/master 8fd2f6fc7 -> c2ac01666


[#4659]  ticket:381 upload multiple attachments


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/087b9ec5
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/087b9ec5
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/087b9ec5

Branch: refs/heads/master
Commit: 087b9ec58400c9ebe7ab4c41cd8581ff12195820
Parents: 8fd2f6f
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Fri Jul 5 15:44:48 2013 +0400
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Thu Jul 11 14:35:12 2013 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/discuss.py            | 20 ++++++++++++++++----
 Allura/allura/lib/widgets/discuss.py            |  2 +-
 Allura/allura/lib/widgets/form_fields.py        |  3 ++-
 Allura/allura/model/notification.py             | 16 ++++++++++++----
 .../templates/widgets/attachment_add.html       |  4 ++--
 Allura/allura/templates/widgets/edit_post.html  |  4 ++--
 Allura/allura/tests/model/test_discussion.py    | 18 ++++++++++++++++++
 .../tests/functional/test_forum.py              |  5 +++++
 ForgeTracker/forgetracker/model/ticket.py       | 10 +++++++---
 .../templates/tracker_widgets/ticket_form.html  |  4 ++--
 .../forgetracker/tests/functional/test_root.py  | 12 ++++++++++++
 ForgeTracker/forgetracker/tracker_main.py       | 10 +++++++---
 .../forgetracker/widgets/ticket_form.py         |  5 +++--
 .../forgewiki/tests/functional/test_root.py     | 14 ++++++++++++++
 ForgeWiki/forgewiki/wiki_main.py                |  9 +++++++--
 15 files changed, 110 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/087b9ec5/Allura/allura/controllers/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index 9ff5e6c..97a08e5 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -202,7 +202,10 @@ class ThreadController(BaseController, FeedController):
 
         file_info = kw.get('file_info', None)
         p = self.thread.add_post(**kw)
-        p.add_attachment(file_info)
+        if isinstance(file_info, list):
+            map(p.add_attachment, file_info)
+        else:
+            p.add_attachment(file_info)
         if self.thread.artifact:
             self.thread.artifact.mod_date = datetime.utcnow()
         flash('Message posted')
@@ -275,7 +278,10 @@ class PostController(BaseController):
             require_access(self.post, 'moderate')
             post_fields = self.W.edit_post.to_python(kw, None)
             file_info = post_fields.pop('file_info', None)
-            self.post.add_attachment(file_info)
+            if isinstance(file_info, list):
+                map(self.post.add_attachment, file_info)
+            else:
+                self.post.add_attachment(file_info)
             for k,v in post_fields.iteritems():
                 try:
                     setattr(self.post, k, v)
@@ -320,7 +326,10 @@ class PostController(BaseController):
         require_access(self.thread, 'post')
         kw = self.W.edit_post.to_python(kw, None)
         p = self.thread.add_post(parent_id=self.post._id, **kw)
-        p.add_attachment(file_info)
+        if isinstance(file_info, list):
+            map(p.add_attachment, file_info)
+        else:
+            p.add_attachment(file_info)
         redirect(request.referer)
 
     @h.vardec
@@ -355,7 +364,10 @@ class PostController(BaseController):
     @require_post()
     def attach(self, file_info=None):
         require_access(self.post, 'moderate')
-        self.post.add_attachment(file_info)
+        if isinstance(file_info, list):
+            map(self.post.add_attachment, file_info)
+        else:
+            self.post.add_attachment(file_info)
         redirect(request.referer)
 
     @expose()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/087b9ec5/Allura/allura/lib/widgets/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/discuss.py b/Allura/allura/lib/widgets/discuss.py
index e62a993..96a48b3 100644
--- a/Allura/allura/lib/widgets/discuss.py
+++ b/Allura/allura/lib/widgets/discuss.py
@@ -160,9 +160,9 @@ class EditPost(ff.ForgeForm):
         for r in ffw.MarkdownEdit(name='text').resources(): yield r
         yield ew.JSScript('''$(document).ready(function () {
             $("a.attachment_form_add_button").click(function(evt){
+                evt.preventDefault();
                 $(this).hide();
                 $(".attachment_form_fields", this.parentNode).show();
-                evt.preventDefault();
             });
             $("a.cancel_edit_post").click(function(evt){
                 $("textarea", this.parentNode).val($("input.original_value", this.parentNode).val());

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/087b9ec5/Allura/allura/lib/widgets/form_fields.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/form_fields.py b/Allura/allura/lib/widgets/form_fields.py
index 1accf93..221e0fc 100644
--- a/Allura/allura/lib/widgets/form_fields.py
+++ b/Allura/allura/lib/widgets/form_fields.py
@@ -191,9 +191,10 @@ class AttachmentAdd(ew_core.Widget):
     def resources(self):
         for r in super(AttachmentAdd, self).resources(): yield r
         yield onready('''
-            $("input.attachment_form_add_button").click(function () {
+            $(".attachment_form_add_button").click(function (evt) {
                 $(this).hide();
                 $(".attachment_form_fields", this.parentNode).show();
+                evt.preventDefault();
             });
          ''')
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/087b9ec5/Allura/allura/model/notification.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/notification.py b/Allura/allura/model/notification.py
index eced9d8..1d03eef 100644
--- a/Allura/allura/model/notification.py
+++ b/Allura/allura/model/notification.py
@@ -147,10 +147,18 @@ class Notification(MappedClass):
             text = post.text
             file_info = kwargs.pop('file_info', None)
             if file_info is not None:
-                file_info.file.seek(0, 2)
-                bytecount = file_info.file.tell()
-                file_info.file.seek(0)
-                text = "%s\n\n\nAttachment: %s (%s; %s)" % (text, file_info.filename, h.do_filesizeformat(bytecount), file_info.type)
+                text = "%s\n\n\nAttachment:" % text
+                if isinstance(file_info, list):
+                    for attach in file_info:
+                        attach.file.seek(0, 2)
+                        bytecount = attach.file.tell()
+                        attach.file.seek(0)
+                        text = "%s %s (%s; %s) " % (text, attach.filename, h.do_filesizeformat(bytecount), attach.type)
+                else:
+                    file_info.file.seek(0, 2)
+                    bytecount = file_info.file.tell()
+                    file_info.file.seek(0)
+                    text = "%s %s (%s; %s) " % (text, file_info.filename, h.do_filesizeformat(bytecount), file_info.type)
 
             subject = post.subject or ''
             if post.parent_id and not subject.lower().startswith('re:'):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/087b9ec5/Allura/allura/templates/widgets/attachment_add.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/attachment_add.html b/Allura/allura/templates/widgets/attachment_add.html
index 8ed2ab5..3af2ce7 100644
--- a/Allura/allura/templates/widgets/attachment_add.html
+++ b/Allura/allura/templates/widgets/attachment_add.html
@@ -19,11 +19,11 @@
 <form method="post"
       action="{{action}}"
       enctype="multipart/form-data">
-      <input type="button" value="Add attachment" class="attachment_form_add_button"/>
+      <a href="#" class="btn link attachment_form_add_button">Add attachments</a>
       <ol class="attachment_form_fields" style="display:none">
         <li>
           <label for="{{name}}">File to upload</label>
-          <input type="file" class="text" name="{{name}}" id="{{name}}"/>
+          <input type="file" class="text" name="{{name}}" multiple="True" id="{{name}}"/>
         </li>
         <li>
           <label>&nbsp;</label>

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/087b9ec5/Allura/allura/templates/widgets/edit_post.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/edit_post.html b/Allura/allura/templates/widgets/edit_post.html
index 65762f3..0fe22a7 100644
--- a/Allura/allura/templates/widgets/edit_post.html
+++ b/Allura/allura/templates/widgets/edit_post.html
@@ -27,12 +27,12 @@
     <input type="hidden" class="original_value" value="{{value.text}}">
     <span class="arw"><span></span></span><br/>
     <div class="attachment_form_fields" style="display:none; padding: 5px 0;">
-      <input type="file" class="text" name="{{att_name}}" {% if att_id %}id="{{att_id}}"{% endif %}/>
+      <input type="file" class="text" multiple="True" name="{{att_name}}" {% if att_id %}id="{{att_id}}"{% endif %}/>
     </div>
     <div style="clear:both"></div>
     <input type="submit" value="{{submit_text}}"/>
     <a href="#" class="btn link cancel_edit_post">Cancel</a> &nbsp;
-    <a href="#" class="btn link attachment_form_add_button">Add attachment</a>
+    <a href="#" class="btn link attachment_form_add_button">Add attachments</a>
   {% if widget.antispam %}{% for fld in g.antispam.extra_fields() %}
   {{fld}}{% endfor %}{% endif %}
   </form>

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/087b9ec5/Allura/allura/tests/model/test_discussion.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/model/test_discussion.py b/Allura/allura/tests/model/test_discussion.py
index ec23e3b..72920e6 100644
--- a/Allura/allura/tests/model/test_discussion.py
+++ b/Allura/allura/tests/model/test_discussion.py
@@ -223,6 +223,24 @@ def test_add_attachment():
     assert attach.filename == 'test.txt', attach.filename
     assert attach.content_type == 'text/plain', attach.content_type
 
+def test_notification_two_attaches():
+    d = M.Discussion(shortname='test', name='test')
+    t = M.Thread.new(discussion_id=d._id, subject='Test comment notification')
+    fs1 = FieldStorage()
+    fs1.name = 'file_info'
+    fs1.filename = 'fake.txt'
+    fs1.type = 'text/plain'
+    fs1.file = StringIO('this is the content of the fake file\n')
+    fs2 = FieldStorage()
+    fs2.name = 'file_info'
+    fs2.filename = 'fake2.txt'
+    fs2.type = 'text/plain'
+    fs2.file = StringIO('this is the content of the fake file\n')
+    t.post(text=u'test message', forum=None, subject='', file_info=[fs1, fs2])
+    ThreadLocalORMSession.flush_all()
+    n = M.Notification.query.get(subject=u'[test:wiki] Test comment notification')
+    assert '\nAttachment: fake.txt (37 Bytes; text/plain)  fake2.txt (37 Bytes; text/plain)' in n.text
+
 @with_setup(setUp, tearDown)
 def test_discussion_delete():
     d = M.Discussion(shortname='test', name='test')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/087b9ec5/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
index a9288c8..c319263 100644
--- a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
+++ b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
@@ -226,7 +226,12 @@ class TestForumAsync(TestController):
         r = self.app.post(url + 'attach',
                           upload_files=[('file_info', 'test.asdfasdtxt',
                                          'This is a textfile')])
+        r = self.app.post(url + 'attach',
+                          upload_files=[('file_info', 'test1.txt','This is a textfile'),
+                                        ('file_info', 'test2.txt','This is a textfile')])
         r = self.app.get(url)
+        assert "test1.txt" in r
+        assert "test2.txt" in r
         for link in r.html.findAll('a'):
             if 'attachment' in link.get('href', ''):
                 self.app.get(str(link['href']))

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/087b9ec5/ForgeTracker/forgetracker/model/ticket.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/model/ticket.py b/ForgeTracker/forgetracker/model/ticket.py
index 175c660..6679e2a 100644
--- a/ForgeTracker/forgetracker/model/ticket.py
+++ b/ForgeTracker/forgetracker/model/ticket.py
@@ -833,9 +833,13 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
                     self.custom_fields[k] = v
         self.commit()
         if attachment is not None:
-            self.attach(
-                attachment.filename, attachment.file,
-                content_type=attachment.type)
+            if isinstance(attachment, list):
+                for attach in attachment:
+                    self.attach(attach.filename, attach.file, content_type=attach.type)
+            else:
+                self.attach(
+                    attachment.filename, attachment.file,
+                    content_type=attachment.type)
 
     def _move_attach(self, attachments, attach_metadata, app_config):
         for attach in attachments:

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/087b9ec5/ForgeTracker/forgetracker/templates/tracker_widgets/ticket_form.html
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/templates/tracker_widgets/ticket_form.html b/ForgeTracker/forgetracker/templates/tracker_widgets/ticket_form.html
index d9c5743..5741603 100644
--- a/ForgeTracker/forgetracker/templates/tracker_widgets/ticket_form.html
+++ b/ForgeTracker/forgetracker/templates/tracker_widgets/ticket_form.html
@@ -99,8 +99,8 @@
       </div>
       <div style="clear:both">&nbsp;</div>
     {% endif %}
-    <div id="show_attach">
-      <input type="checkbox"> I would like to add an attachment
+    <div>
+      <a href="#" id="show_attach">Add attachments</a>
     </div>
     <div style="clear:both">&nbsp;</div>
     <div id="view_attach" style="display:none">

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/087b9ec5/ForgeTracker/forgetracker/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/functional/test_root.py b/ForgeTracker/forgetracker/tests/functional/test_root.py
index 77e0dc7..a78abd9 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_root.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_root.py
@@ -537,6 +537,18 @@ class TestFunctionalController(TrackerTestController):
         download = self.app.get(str(ticket_editor.html.findAll('form')[1].findAll('a')[7]['href']))
         assert_equal(download.body, file_data)
 
+    def test_two_attachments(self):
+        file_name1 = 'test_root1.py'
+        file_name2 = 'test_root2.py'
+        file_data = file(__file__).read()
+        self.new_ticket(summary='test new attachment')
+        ticket_editor = self.app.post('/bugs/1/update_ticket',{
+            'summary':'zzz'
+        }, upload_files=[('attachment', file_name1, file_data), ('attachment', file_name2, file_data)]).follow()
+
+        assert 'test_root1.py' in ticket_editor
+        assert 'test_root2.py' in ticket_editor
+
     def test_new_image_attachment_content(self):
         h.set_context('test', 'bugs', neighborhood='Projects')
         file_name = 'neo-icon-set-454545-256x350.png'

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/087b9ec5/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index 5476596..3d2d02d 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -1293,9 +1293,13 @@ class TicketController(BaseController, FeedController):
 
         if 'attachment' in post_data:
             attachment = post_data['attachment']
-            if hasattr(attachment, 'file'):
-                self.ticket.attach(
-                    attachment.filename, attachment.file, content_type=attachment.type)
+            if isinstance(attachment, list):
+                for attach in attachment:
+                    self.ticket.attach(attach.filename, attach.file, content_type=attach.type)
+            else:
+                if hasattr(attachment, 'file'):
+                    self.ticket.attach(
+                        attachment.filename, attachment.file, content_type=attachment.type)
         for cf in c.app.globals.custom_fields or []:
             if 'custom_fields.' + cf.name in post_data:
                 value = post_data['custom_fields.' + cf.name]

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/087b9ec5/ForgeTracker/forgetracker/widgets/ticket_form.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/widgets/ticket_form.py b/ForgeTracker/forgetracker/widgets/ticket_form.py
index cb05085..edee7e5 100644
--- a/ForgeTracker/forgetracker/widgets/ticket_form.py
+++ b/ForgeTracker/forgetracker/widgets/ticket_form.py
@@ -106,7 +106,7 @@ class GenericTicketForm(ew.SimpleForm):
             ffw.ProjectUserCombo(name='assigned_to', label='Owner'),
             ffw.LabelEdit(label='Labels',name='labels', className='ticket_form_tags'),
             ew.Checkbox(name='private', label='Mark as Private', attrs={'class':'unlabeled'}),
-            ew.InputField(name='attachment', label='Attachment', field_type='file', validator=fev.FieldStorageUploadConverter(if_missing=None)),
+            ew.InputField(name='attachment', label='Attachment', field_type='file', attrs={'multiple': 'True'}, validator=fev.FieldStorageUploadConverter(if_missing=None)),
             ffw.MarkdownEdit(name='comment', label='Comment',
                         attrs={'style':'min-height:7em; width:97%'}),
             ew.SubmitButton(label=self.submit_text,name='submit',
@@ -135,7 +135,8 @@ class TicketForm(GenericTicketForm):
         for r in super(TicketForm, self).resources(): yield r
         yield ew.JSScript('''
         $(function(){
-            $('#show_attach input').click(function(){
+            $('#show_attach').click(function(evt) {
+                evt.preventDefault();
                 $('#view_attach').show();
                 $('#show_attach').hide();
             });

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/087b9ec5/ForgeWiki/forgewiki/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/tests/functional/test_root.py b/ForgeWiki/forgewiki/tests/functional/test_root.py
index f3570b2..05c0dd1 100644
--- a/ForgeWiki/forgewiki/tests/functional/test_root.py
+++ b/ForgeWiki/forgewiki/tests/functional/test_root.py
@@ -348,6 +348,20 @@ class TestRootController(TestController):
         response = self.app.get('/wiki/tést/')
         assert 'test_root.py' in response
 
+    def test_attach_two_fiels(self):
+        self.app.post(
+            '/wiki/tést/update',
+            params={
+                'title':'tést',
+                'text':'sometext',
+                'labels':'',
+                'viewable_by-0.id':'all'})
+        content = file(__file__).read()
+        self.app.post('/wiki/tést/attach', upload_files=[('file_info', 'test1.py', content),('file_info', 'test2.py', content)])
+        response = self.app.get('/wiki/tést/')
+        assert 'test1.py' in response
+        assert 'test2.py' in response
+
     def test_new_text_attachment_content(self):
         self.app.post(
             '/wiki/tést/update',

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/087b9ec5/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index 9cc0ffc..88f1102 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -649,8 +649,13 @@ class PageController(BaseController, FeedController):
         if not self.page:
             raise exc.HTTPNotFound
         require_access(self.page, 'edit')
-        if hasattr(file_info, 'file'):
-            self.page.attach(file_info.filename, file_info.file, content_type=file_info.type)
+        if isinstance(file_info, list):
+            for attach in file_info:
+                if hasattr(attach, 'file'):
+                    self.page.attach(attach.filename, attach.file, content_type=attach.type)
+        else:
+            if hasattr(file_info, 'file'):
+                self.page.attach(file_info.filename, file_info.file, content_type=file_info.type)
         redirect(request.referer)
 
     @expose()


[5/5] git commit: [#4659] Cleanup layout for attachment widget

Posted by tv...@apache.org.
[#4659] Cleanup layout for attachment widget

Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/c2ac0166
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/c2ac0166
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/c2ac0166

Branch: refs/heads/master
Commit: c2ac016668cda5c17226d4cb79974cfa1b3dfcc0
Parents: 779e794
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Thu Jul 11 20:19:34 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Thu Jul 11 20:19:34 2013 +0000

----------------------------------------------------------------------
 Allura/allura/templates/widgets/attachment_add.html | 14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c2ac0166/Allura/allura/templates/widgets/attachment_add.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/attachment_add.html b/Allura/allura/templates/widgets/attachment_add.html
index 3af2ce7..51f4d5b 100644
--- a/Allura/allura/templates/widgets/attachment_add.html
+++ b/Allura/allura/templates/widgets/attachment_add.html
@@ -20,14 +20,8 @@
       action="{{action}}"
       enctype="multipart/form-data">
       <a href="#" class="btn link attachment_form_add_button">Add attachments</a>
-      <ol class="attachment_form_fields" style="display:none">
-        <li>
-          <label for="{{name}}">File to upload</label>
-          <input type="file" class="text" name="{{name}}" multiple="True" id="{{name}}"/>
-        </li>
-        <li>
-          <label>&nbsp;</label>
-          <input type="submit" value="Attach file"/>
-        </li>
-      </ol>
+      <div class="attachment_form_fields" style="display:none">
+          <input type="file" class="text" name="{{name}}" multiple="True" id="{{name}}" style="margin-left:0"/><br/>
+          <input type="submit" value="Attach files"/>
+      </div>
 </form>


[2/5] git commit: [#4659] ticket:381 test for multiple attachments

Posted by tv...@apache.org.
[#4659]  ticket:381 test for multiple attachments


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/94026f29
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/94026f29
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/94026f29

Branch: refs/heads/master
Commit: 94026f295048ff34325d51ea420ebdc5d71f567a
Parents: 870f5aa
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Mon Jul 8 08:47:11 2013 +0400
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Thu Jul 11 14:35:13 2013 +0000

----------------------------------------------------------------------
 Allura/allura/tests/model/test_discussion.py | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/94026f29/Allura/allura/tests/model/test_discussion.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/model/test_discussion.py b/Allura/allura/tests/model/test_discussion.py
index 72920e6..4ac1e37 100644
--- a/Allura/allura/tests/model/test_discussion.py
+++ b/Allura/allura/tests/model/test_discussion.py
@@ -206,6 +206,28 @@ def test_attachment_methods():
     n = M.Notification.query.get(subject=u'[test:wiki] Test comment notification')
     assert '\nAttachment: fake.txt (37 Bytes; text/plain)' in n.text
 
+@with_setup(setUp, tearDown())
+def test_multiple_attach():
+    test_file1 = FieldStorage()
+    test_file1.name = 'file_info'
+    test_file1.filename = 'test1.txt'
+    test_file1.type = 'text/plain'
+    test_file1.file=StringIO('test file1\n')
+    test_file2 = FieldStorage()
+    test_file2.name = 'file_info'
+    test_file2.filename = 'test2.txt'
+    test_file2.type = 'text/plain'
+    test_file2.file=StringIO('test file2\n')
+    d = M.Discussion(shortname='test', name='test')
+    t = M.Thread.new(discussion_id=d._id, subject='Test Thread')
+    test_post = t.post('test post')
+    test_post.add_multiple_attach([test_file1, test_file2])
+    ThreadLocalORMSession.flush_all()
+    assert test_post.attachments.count() == 2, test_post.attachments.count()
+    attaches = test_post.attachments.all()
+    assert 'test1.txt' in [attaches[0].filename, attaches[1].filename]
+    assert 'test2.txt' in [attaches[0].filename, attaches[1].filename]
+
 @with_setup(setUp, tearDown)
 def test_add_attachment():
     test_file = FieldStorage()


[3/5] git commit: [#4659] ticket:381 refactored multiple attachments

Posted by tv...@apache.org.
[#4659]  ticket:381 refactored multiple attachments


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/870f5aad
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/870f5aad
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/870f5aad

Branch: refs/heads/master
Commit: 870f5aad4b4c2c5680429d6f649df47a6bb7adc1
Parents: 087b9ec
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Fri Jul 5 21:03:24 2013 +0400
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Thu Jul 11 14:35:13 2013 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/discuss.py            | 20 ++++----------------
 Allura/allura/lib/widgets/discuss.py            |  2 +-
 Allura/allura/model/artifact.py                 |  7 +++++++
 Allura/allura/model/discuss.py                  |  6 ++++++
 Allura/allura/model/notification.py             | 18 +++++++-----------
 Allura/allura/templates/widgets/edit_post.html  |  4 +---
 ForgeTracker/forgetracker/tracker_main.py       |  8 +-------
 .../forgetracker/widgets/ticket_form.py         |  2 +-
 .../forgewiki/tests/functional/test_root.py     |  2 +-
 ForgeWiki/forgewiki/wiki_main.py                |  8 +-------
 10 files changed, 30 insertions(+), 47 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/870f5aad/Allura/allura/controllers/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index 97a08e5..45b0124 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -202,10 +202,7 @@ class ThreadController(BaseController, FeedController):
 
         file_info = kw.get('file_info', None)
         p = self.thread.add_post(**kw)
-        if isinstance(file_info, list):
-            map(p.add_attachment, file_info)
-        else:
-            p.add_attachment(file_info)
+        p.add_multiple_attach(file_info)
         if self.thread.artifact:
             self.thread.artifact.mod_date = datetime.utcnow()
         flash('Message posted')
@@ -278,10 +275,7 @@ class PostController(BaseController):
             require_access(self.post, 'moderate')
             post_fields = self.W.edit_post.to_python(kw, None)
             file_info = post_fields.pop('file_info', None)
-            if isinstance(file_info, list):
-                map(self.post.add_attachment, file_info)
-            else:
-                self.post.add_attachment(file_info)
+            self.post.add_multiple_attach(file_info)
             for k,v in post_fields.iteritems():
                 try:
                     setattr(self.post, k, v)
@@ -326,10 +320,7 @@ class PostController(BaseController):
         require_access(self.thread, 'post')
         kw = self.W.edit_post.to_python(kw, None)
         p = self.thread.add_post(parent_id=self.post._id, **kw)
-        if isinstance(file_info, list):
-            map(p.add_attachment, file_info)
-        else:
-            p.add_attachment(file_info)
+        p.add_multiple_attach(file_info)
         redirect(request.referer)
 
     @h.vardec
@@ -364,10 +355,7 @@ class PostController(BaseController):
     @require_post()
     def attach(self, file_info=None):
         require_access(self.post, 'moderate')
-        if isinstance(file_info, list):
-            map(self.post.add_attachment, file_info)
-        else:
-            self.post.add_attachment(file_info)
+        self.post.add_multiple_attach(file_info)
         redirect(request.referer)
 
     @expose()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/870f5aad/Allura/allura/lib/widgets/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/discuss.py b/Allura/allura/lib/widgets/discuss.py
index 96a48b3..e62a993 100644
--- a/Allura/allura/lib/widgets/discuss.py
+++ b/Allura/allura/lib/widgets/discuss.py
@@ -160,9 +160,9 @@ class EditPost(ff.ForgeForm):
         for r in ffw.MarkdownEdit(name='text').resources(): yield r
         yield ew.JSScript('''$(document).ready(function () {
             $("a.attachment_form_add_button").click(function(evt){
-                evt.preventDefault();
                 $(this).hide();
                 $(".attachment_form_fields", this.parentNode).show();
+                evt.preventDefault();
             });
             $("a.cancel_edit_post").click(function(evt){
                 $("textarea", this.parentNode).val($("input.original_value", this.parentNode).val());

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/870f5aad/Allura/allura/model/artifact.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/artifact.py b/Allura/allura/model/artifact.py
index 05d7c14..6fbe0f5 100644
--- a/Allura/allura/model/artifact.py
+++ b/Allura/allura/model/artifact.py
@@ -386,6 +386,13 @@ class Artifact(MappedClass):
         """
         return self.get_discussion_thread()[0]
 
+    def add_multiple_attach(self, file_info):
+        if not isinstance(file_info, list):
+            file_info = [file_info]
+        for attach in file_info:
+            if hasattr(attach, 'file'):
+                self.attach(attach.filename, attach.file, content_type=attach.type)
+
     def attach(self, filename, fp, **kw):
         """Attach a file to this Artifact.
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/870f5aad/Allura/allura/model/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/discuss.py b/Allura/allura/model/discuss.py
index 7699d33..b15d03d 100644
--- a/Allura/allura/model/discuss.py
+++ b/Allura/allura/model/discuss.py
@@ -527,6 +527,12 @@ class Post(Message, VersionedArtifact, ActivityObject):
         return self.attachment_class().query.find(dict(
             post_id=self._id, type='attachment'))
 
+    def add_multiple_attach(self, file_info):
+        if isinstance(file_info, list):
+            map(self.add_attachment, file_info)
+        else:
+            self.add_attachment(file_info)
+
     def add_attachment(self, file_info):
         if hasattr(file_info, 'file'):
             mime_type = file_info.type

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/870f5aad/Allura/allura/model/notification.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/notification.py b/Allura/allura/model/notification.py
index 1d03eef..d4b0755 100644
--- a/Allura/allura/model/notification.py
+++ b/Allura/allura/model/notification.py
@@ -148,17 +148,13 @@ class Notification(MappedClass):
             file_info = kwargs.pop('file_info', None)
             if file_info is not None:
                 text = "%s\n\n\nAttachment:" % text
-                if isinstance(file_info, list):
-                    for attach in file_info:
-                        attach.file.seek(0, 2)
-                        bytecount = attach.file.tell()
-                        attach.file.seek(0)
-                        text = "%s %s (%s; %s) " % (text, attach.filename, h.do_filesizeformat(bytecount), attach.type)
-                else:
-                    file_info.file.seek(0, 2)
-                    bytecount = file_info.file.tell()
-                    file_info.file.seek(0)
-                    text = "%s %s (%s; %s) " % (text, file_info.filename, h.do_filesizeformat(bytecount), file_info.type)
+                if not isinstance(file_info, list):
+                    file_info = [file_info]
+                for attach in file_info:
+                    attach.file.seek(0, 2)
+                    bytecount = attach.file.tell()
+                    attach.file.seek(0)
+                    text = "%s %s (%s; %s) " % (text, attach.filename, h.do_filesizeformat(bytecount), attach.type)
 
             subject = post.subject or ''
             if post.parent_id and not subject.lower().startswith('re:'):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/870f5aad/Allura/allura/templates/widgets/edit_post.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/edit_post.html b/Allura/allura/templates/widgets/edit_post.html
index 0fe22a7..38ad0b3 100644
--- a/Allura/allura/templates/widgets/edit_post.html
+++ b/Allura/allura/templates/widgets/edit_post.html
@@ -26,13 +26,11 @@
     {{widget.display_field(widget.fields.text)}}
     <input type="hidden" class="original_value" value="{{value.text}}">
     <span class="arw"><span></span></span><br/>
-    <div class="attachment_form_fields" style="display:none; padding: 5px 0;">
-      <input type="file" class="text" multiple="True" name="{{att_name}}" {% if att_id %}id="{{att_id}}"{% endif %}/>
-    </div>
     <div style="clear:both"></div>
     <input type="submit" value="{{submit_text}}"/>
     <a href="#" class="btn link cancel_edit_post">Cancel</a> &nbsp;
     <a href="#" class="btn link attachment_form_add_button">Add attachments</a>
+    <input type="file" class="text attachment_form_fields" style="display:none" multiple="True" name="{{att_name}}" {% if att_id %}id="{{att_id}}"{% endif %}/>
   {% if widget.antispam %}{% for fld in g.antispam.extra_fields() %}
   {{fld}}{% endfor %}{% endif %}
   </form>

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/870f5aad/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index 3d2d02d..9037c4d 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -1293,13 +1293,7 @@ class TicketController(BaseController, FeedController):
 
         if 'attachment' in post_data:
             attachment = post_data['attachment']
-            if isinstance(attachment, list):
-                for attach in attachment:
-                    self.ticket.attach(attach.filename, attach.file, content_type=attach.type)
-            else:
-                if hasattr(attachment, 'file'):
-                    self.ticket.attach(
-                        attachment.filename, attachment.file, content_type=attachment.type)
+            self.ticket.add_multiple_attach(attachment)
         for cf in c.app.globals.custom_fields or []:
             if 'custom_fields.' + cf.name in post_data:
                 value = post_data['custom_fields.' + cf.name]

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/870f5aad/ForgeTracker/forgetracker/widgets/ticket_form.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/widgets/ticket_form.py b/ForgeTracker/forgetracker/widgets/ticket_form.py
index edee7e5..f022177 100644
--- a/ForgeTracker/forgetracker/widgets/ticket_form.py
+++ b/ForgeTracker/forgetracker/widgets/ticket_form.py
@@ -136,9 +136,9 @@ class TicketForm(GenericTicketForm):
         yield ew.JSScript('''
         $(function(){
             $('#show_attach').click(function(evt) {
-                evt.preventDefault();
                 $('#view_attach').show();
                 $('#show_attach').hide();
+                evt.preventDefault();
             });
             $('form').submit(function() {
                 var value = $('div.tagsinput div input').val();

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/870f5aad/ForgeWiki/forgewiki/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/tests/functional/test_root.py b/ForgeWiki/forgewiki/tests/functional/test_root.py
index 05c0dd1..3312ed7 100644
--- a/ForgeWiki/forgewiki/tests/functional/test_root.py
+++ b/ForgeWiki/forgewiki/tests/functional/test_root.py
@@ -348,7 +348,7 @@ class TestRootController(TestController):
         response = self.app.get('/wiki/tést/')
         assert 'test_root.py' in response
 
-    def test_attach_two_fiels(self):
+    def test_attach_two_files(self):
         self.app.post(
             '/wiki/tést/update',
             params={

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/870f5aad/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index 88f1102..76f66f6 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -649,13 +649,7 @@ class PageController(BaseController, FeedController):
         if not self.page:
             raise exc.HTTPNotFound
         require_access(self.page, 'edit')
-        if isinstance(file_info, list):
-            for attach in file_info:
-                if hasattr(attach, 'file'):
-                    self.page.attach(attach.filename, attach.file, content_type=attach.type)
-        else:
-            if hasattr(file_info, 'file'):
-                self.page.attach(file_info.filename, file_info.file, content_type=file_info.type)
+        self.page.add_multiple_attach(file_info)
         redirect(request.referer)
 
     @expose()


[4/5] git commit: [#4659] ticket:381 refactored multiple attachments

Posted by tv...@apache.org.
[#4659]  ticket:381 refactored multiple attachments


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/779e7947
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/779e7947
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/779e7947

Branch: refs/heads/master
Commit: 779e7947e8a34d26e404ee93fd5a9eb0ff8f3074
Parents: 94026f2
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Tue Jul 9 18:28:30 2013 +0400
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Thu Jul 11 14:35:13 2013 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/discuss.py         | 8 ++++----
 Allura/allura/model/artifact.py              | 2 +-
 Allura/allura/model/discuss.py               | 2 +-
 Allura/allura/tests/model/test_discussion.py | 4 ++--
 ForgeTracker/forgetracker/model/ticket.py    | 8 +-------
 ForgeTracker/forgetracker/tracker_main.py    | 2 +-
 ForgeWiki/forgewiki/wiki_main.py             | 2 +-
 7 files changed, 11 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/779e7947/Allura/allura/controllers/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index 45b0124..9f745a3 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -202,7 +202,7 @@ class ThreadController(BaseController, FeedController):
 
         file_info = kw.get('file_info', None)
         p = self.thread.add_post(**kw)
-        p.add_multiple_attach(file_info)
+        p.add_multiple_attachments(file_info)
         if self.thread.artifact:
             self.thread.artifact.mod_date = datetime.utcnow()
         flash('Message posted')
@@ -275,7 +275,7 @@ class PostController(BaseController):
             require_access(self.post, 'moderate')
             post_fields = self.W.edit_post.to_python(kw, None)
             file_info = post_fields.pop('file_info', None)
-            self.post.add_multiple_attach(file_info)
+            self.post.add_multiple_attachments(file_info)
             for k,v in post_fields.iteritems():
                 try:
                     setattr(self.post, k, v)
@@ -320,7 +320,7 @@ class PostController(BaseController):
         require_access(self.thread, 'post')
         kw = self.W.edit_post.to_python(kw, None)
         p = self.thread.add_post(parent_id=self.post._id, **kw)
-        p.add_multiple_attach(file_info)
+        p.add_multiple_attachments(file_info)
         redirect(request.referer)
 
     @h.vardec
@@ -355,7 +355,7 @@ class PostController(BaseController):
     @require_post()
     def attach(self, file_info=None):
         require_access(self.post, 'moderate')
-        self.post.add_multiple_attach(file_info)
+        self.post.add_multiple_attachments(file_info)
         redirect(request.referer)
 
     @expose()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/779e7947/Allura/allura/model/artifact.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/artifact.py b/Allura/allura/model/artifact.py
index 6fbe0f5..b41b103 100644
--- a/Allura/allura/model/artifact.py
+++ b/Allura/allura/model/artifact.py
@@ -386,7 +386,7 @@ class Artifact(MappedClass):
         """
         return self.get_discussion_thread()[0]
 
-    def add_multiple_attach(self, file_info):
+    def add_multiple_attachments(self, file_info):
         if not isinstance(file_info, list):
             file_info = [file_info]
         for attach in file_info:

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/779e7947/Allura/allura/model/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/discuss.py b/Allura/allura/model/discuss.py
index b15d03d..76cf615 100644
--- a/Allura/allura/model/discuss.py
+++ b/Allura/allura/model/discuss.py
@@ -527,7 +527,7 @@ class Post(Message, VersionedArtifact, ActivityObject):
         return self.attachment_class().query.find(dict(
             post_id=self._id, type='attachment'))
 
-    def add_multiple_attach(self, file_info):
+    def add_multiple_attachments(self, file_info):
         if isinstance(file_info, list):
             map(self.add_attachment, file_info)
         else:

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/779e7947/Allura/allura/tests/model/test_discussion.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/model/test_discussion.py b/Allura/allura/tests/model/test_discussion.py
index 4ac1e37..34e550a 100644
--- a/Allura/allura/tests/model/test_discussion.py
+++ b/Allura/allura/tests/model/test_discussion.py
@@ -207,7 +207,7 @@ def test_attachment_methods():
     assert '\nAttachment: fake.txt (37 Bytes; text/plain)' in n.text
 
 @with_setup(setUp, tearDown())
-def test_multiple_attach():
+def test_multiple_attachments():
     test_file1 = FieldStorage()
     test_file1.name = 'file_info'
     test_file1.filename = 'test1.txt'
@@ -221,7 +221,7 @@ def test_multiple_attach():
     d = M.Discussion(shortname='test', name='test')
     t = M.Thread.new(discussion_id=d._id, subject='Test Thread')
     test_post = t.post('test post')
-    test_post.add_multiple_attach([test_file1, test_file2])
+    test_post.add_multiple_attachments([test_file1, test_file2])
     ThreadLocalORMSession.flush_all()
     assert test_post.attachments.count() == 2, test_post.attachments.count()
     attaches = test_post.attachments.all()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/779e7947/ForgeTracker/forgetracker/model/ticket.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/model/ticket.py b/ForgeTracker/forgetracker/model/ticket.py
index 6679e2a..80ce102 100644
--- a/ForgeTracker/forgetracker/model/ticket.py
+++ b/ForgeTracker/forgetracker/model/ticket.py
@@ -833,13 +833,7 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
                     self.custom_fields[k] = v
         self.commit()
         if attachment is not None:
-            if isinstance(attachment, list):
-                for attach in attachment:
-                    self.attach(attach.filename, attach.file, content_type=attach.type)
-            else:
-                self.attach(
-                    attachment.filename, attachment.file,
-                    content_type=attachment.type)
+            self.add_multiple_attachments(attachment)
 
     def _move_attach(self, attachments, attach_metadata, app_config):
         for attach in attachments:

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/779e7947/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index 9037c4d..b6af2ee 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -1293,7 +1293,7 @@ class TicketController(BaseController, FeedController):
 
         if 'attachment' in post_data:
             attachment = post_data['attachment']
-            self.ticket.add_multiple_attach(attachment)
+            self.ticket.add_multiple_attachments(attachment)
         for cf in c.app.globals.custom_fields or []:
             if 'custom_fields.' + cf.name in post_data:
                 value = post_data['custom_fields.' + cf.name]

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/779e7947/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index 76f66f6..57e2bff 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -649,7 +649,7 @@ class PageController(BaseController, FeedController):
         if not self.page:
             raise exc.HTTPNotFound
         require_access(self.page, 'edit')
-        self.page.add_multiple_attach(file_info)
+        self.page.add_multiple_attachments(file_info)
         redirect(request.referer)
 
     @expose()