You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by br...@apache.org on 2013/07/11 23:58:55 UTC
[35/50] [abbrv] git commit: [#4659] ticket:381 upload multiple
attachments
[#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/db/6277
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> </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>
- <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"> </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"> </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()