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 2018/10/05 21:26:06 UTC
[3/5] allura git commit: [#6299] support attachments on blog posts
[#6299] support attachments on blog posts
Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/b57b458f
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/b57b458f
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/b57b458f
Branch: refs/heads/db/6299
Commit: b57b458f990b0991bf913ac987ed5f6a00020b90
Parents: 4c5c9f9
Author: Dave Brondsema <da...@brondsema.net>
Authored: Fri Oct 5 13:26:21 2018 -0400
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Fri Oct 5 17:25:54 2018 -0400
----------------------------------------------------------------------
ForgeBlog/forgeblog/main.py | 27 ++++++++++----
ForgeBlog/forgeblog/model/__init__.py | 2 +-
ForgeBlog/forgeblog/model/blog.py | 8 +++-
.../forgeblog/templates/blog/edit_posts.html | 31 ----------------
ForgeBlog/forgeblog/templates/blog/post.html | 4 +-
.../templates/blog_widgets/post_form.html | 8 +++-
.../forgeblog/tests/functional/test_root.py | 39 ++++++++++++++------
ForgeBlog/forgeblog/widgets.py | 3 ++
8 files changed, 67 insertions(+), 55 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/allura/blob/b57b458f/ForgeBlog/forgeblog/main.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/main.py b/ForgeBlog/forgeblog/main.py
index 653400f..bf4c3ec 100644
--- a/ForgeBlog/forgeblog/main.py
+++ b/ForgeBlog/forgeblog/main.py
@@ -49,6 +49,7 @@ from allura.lib.widgets import form_fields as ffw
from allura.lib.widgets.search import SearchResults, SearchHelp
from allura import model as M
from allura.controllers import BaseController, AppDiscussionController, AppDiscussionRestController
+from allura.controllers.attachments import AttachmentController, AttachmentsController
from allura.controllers.rest import AppRestControllerMixin
from allura.controllers.feed import FeedArgs, FeedController
@@ -68,8 +69,6 @@ class W:
new_post_form = widgets.NewPostForm()
edit_post_form = widgets.EditPostForm()
view_post_form = widgets.ViewPostForm()
- label_edit = ffw.LabelEdit()
- attachment_add = ffw.AttachmentAdd()
attachment_list = ffw.AttachmentList()
preview_post_form = widgets.PreviewPostForm()
subscribe_form = SubscribeForm(thing='post')
@@ -207,7 +206,7 @@ class ForgeBlogApp(Application):
def uninstall(self, project):
"Remove all the tool's artifacts from the database"
- BM.Attachment.query.remove(dict(app_config_id=c.app.config._id))
+ BM.BlogAttachment.query.remove(dict(app_config_id=c.app.config._id))
BM.BlogPost.query.remove(dict(app_config_id=c.app.config._id))
BM.BlogPostSnapshot.query.remove(dict(app_config_id=c.app.config._id))
super(ForgeBlogApp, self).uninstall(project)
@@ -304,9 +303,12 @@ class RootController(BaseController, FeedController):
def save(self, **kw):
require_access(c.app, 'write')
self.rate_limit(BM.BlogPost, 'Create/edit', c.app.config.url())
+ attachment = kw.pop('attachment', None)
post = BM.BlogPost.new(**kw)
g.spam_checker.check(kw['title'] + u'\n' + kw['text'], artifact=post,
user=c.user, content_type='blog-post')
+ if attachment is not None:
+ post.add_multiple_attachments(attachment)
redirect(h.really_unicode(post.url()).encode('utf-8'))
@with_trailing_slash
@@ -338,22 +340,32 @@ class RootController(BaseController, FeedController):
app.url)
+class BlogAttachmentController(AttachmentController):
+ AttachmentClass = BM.BlogAttachment
+
+
+class BlogAttachmentsController(AttachmentsController):
+ AttachmentControllerClass = BlogAttachmentController
+
+
class PostController(BaseController, FeedController):
def __init__(self, post):
self.post = post
+ self.attachment = BlogAttachmentsController(self.post)
def _check_security(self):
require_access(self.post, 'read')
+ if self.post.state == 'draft':
+ require_access(self.post, 'write')
@expose('jinja:forgeblog:templates/blog/post.html')
@with_trailing_slash
@validate(dict(page=validators.Int(if_empty=0, if_invalid=0),
limit=validators.Int(if_empty=None, if_invalid=None)))
def index(self, page=0, limit=None, **kw):
- if self.post.state == 'draft':
- require_access(self.post, 'write')
c.form = W.view_post_form
+ c.attachment_list = W.attachment_list
c.subscribe_form = W.subscribe_form
c.thread = W.thread
post_count = self.post.discussion_thread.post_count
@@ -373,9 +385,7 @@ class PostController(BaseController, FeedController):
require_access(self.post, 'write')
self.rate_limit(BM.BlogPost, 'Create/edit', c.app.config.url())
c.form = W.edit_post_form
- c.attachment_add = W.attachment_add
c.attachment_list = W.attachment_list
- c.label_edit = W.label_edit
return dict(post=self.post)
@without_trailing_slash
@@ -407,6 +417,9 @@ class PostController(BaseController, FeedController):
else:
g.spam_checker.check(kw['title'] + u'\n' + kw['text'], artifact=self.post,
user=c.user, content_type='blog-post')
+ attachment = kw.pop('attachment', None)
+ if attachment is not None:
+ self.post.add_multiple_attachments(attachment)
for k, v in kw.iteritems():
setattr(self.post, k, v)
self.post.commit()
http://git-wip-us.apache.org/repos/asf/allura/blob/b57b458f/ForgeBlog/forgeblog/model/__init__.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/model/__init__.py b/ForgeBlog/forgeblog/model/__init__.py
index 7c17d5c..e1b5fcc 100644
--- a/ForgeBlog/forgeblog/model/__init__.py
+++ b/ForgeBlog/forgeblog/model/__init__.py
@@ -15,4 +15,4 @@
# specific language governing permissions and limitations
# under the License.
-from blog import Globals, BlogPost, Attachment, BlogPostSnapshot
+from blog import Globals, BlogPost, BlogAttachment, BlogPostSnapshot
http://git-wip-us.apache.org/repos/asf/allura/blob/b57b458f/ForgeBlog/forgeblog/model/blog.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/model/blog.py b/ForgeBlog/forgeblog/model/blog.py
index 67b45b6..baa4520 100644
--- a/ForgeBlog/forgeblog/model/blog.py
+++ b/ForgeBlog/forgeblog/model/blog.py
@@ -321,9 +321,13 @@ class BlogPost(M.VersionedArtifact, ActivityObject):
feed_item.delete()
super(BlogPost, self).delete()
+ @classmethod
+ def attachment_class(cls):
+ return BlogAttachment
+
-class Attachment(M.BaseAttachment):
- ArtifactClass = BlogPost
+class BlogAttachment(M.BaseAttachment):
+ ArtifactType = BlogPost
class __mongometa__:
polymorphic_identity = 'BlogAttachment'
http://git-wip-us.apache.org/repos/asf/allura/blob/b57b458f/ForgeBlog/forgeblog/templates/blog/edit_posts.html
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/templates/blog/edit_posts.html b/ForgeBlog/forgeblog/templates/blog/edit_posts.html
deleted file mode 100644
index 5c87a3c..0000000
--- a/ForgeBlog/forgeblog/templates/blog/edit_posts.html
+++ /dev/null
@@ -1,31 +0,0 @@
-{#-
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
--#}
-{% extends g.theme.master %}
-
-{% block title %}{{c.project.name}} / {{c.app.config.options.mount_label}}{% endblock %}
-
-{% block header %}{{c.project.name}} / {{c.app.config.options.mount_label}}: Recent posts{% endblock %}
-
-{% block content %}
- <div class="content">
- {% for post in posts %}
- {{c.form.display(value=post)}}
- {% endfor %}
- </div>
-{% endblock %}
http://git-wip-us.apache.org/repos/asf/allura/blob/b57b458f/ForgeBlog/forgeblog/templates/blog/post.html
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/templates/blog/post.html b/ForgeBlog/forgeblog/templates/blog/post.html
index 979b1f6..1b91176 100644
--- a/ForgeBlog/forgeblog/templates/blog/post.html
+++ b/ForgeBlog/forgeblog/templates/blog/post.html
@@ -35,7 +35,9 @@
{% block content %}
{{c.form.display(value=post, base_post=base_post)}}
- <div style="clear:both;"></div>
+ <div class="grid-19">
+ {{c.attachment_list.display(attachments=post.attachments, edit_mode=h.has_access(post, 'edit')())}}
+ </div>
{% if post.discussion_thread and c.app.show_discussion %}
<div style="margin-top: 10px">
{{c.thread.display(value=post.discussion_thread,page=page,limit=limit,count=count)}}
http://git-wip-us.apache.org/repos/asf/allura/blob/b57b458f/ForgeBlog/forgeblog/templates/blog_widgets/post_form.html
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/templates/blog_widgets/post_form.html b/ForgeBlog/forgeblog/templates/blog_widgets/post_form.html
index 5ec530f..b8216b0 100644
--- a/ForgeBlog/forgeblog/templates/blog_widgets/post_form.html
+++ b/ForgeBlog/forgeblog/templates/blog_widgets/post_form.html
@@ -28,14 +28,18 @@
<div class="grid-19">
{{widget.display_field(widget.fields.text)}}
</div>
- <div class="grid-6">
+ <div class="grid-5">
<label class="cr">State:</label>
{{widget.display_field(widget.fields.state)}}
</div>
- <div class="grid-13">
+ <div class="grid-6">
<label class="cr">Labels:</label>
{{widget.display_field(widget.fields.labels)}}
</div>
+ <div class="grid-8">
+ <label class="cr">Add attachments:</label>
+ {{widget.display_field(widget.fields.attachment)}}
+ </div>
{% for field in widget.fields %}
{% if field.field_type == 'hidden' %}
{% set ctx=widget.context_for(field) %}
http://git-wip-us.apache.org/repos/asf/allura/blob/b57b458f/ForgeBlog/forgeblog/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/tests/functional/test_root.py b/ForgeBlog/forgeblog/tests/functional/test_root.py
index 22a8fa3..4085744 100644
--- a/ForgeBlog/forgeblog/tests/functional/test_root.py
+++ b/ForgeBlog/forgeblog/tests/functional/test_root.py
@@ -19,31 +19,23 @@ import datetime
import json
import tg
-from nose.tools import assert_equal, assert_in
+from nose.tools import assert_equal
from mock import patch
from allura.lib import helpers as h
from alluratest.controller import TestController
-#---------x---------x---------x---------x---------x---------x---------x
-# RootController methods exposed:
-# index, new_page, search
-# PageController methods exposed:
-# index, edit, history, diff, raw, revert, update
-# CommentController methods exposed:
-# reply, delete
-
class Test(TestController):
- def _post(self, slug='', **kw):
+ def _post(self, slug='', extra_app_post_params={}, **kw):
d = {
'title': 'My Post',
'text': 'Nothing to see here',
'labels': '',
'state': 'published'}
d.update(kw)
- r = self.app.post('/blog%s/save' % slug, params=d)
+ r = self.app.post('/blog%s/save' % slug, params=d, **extra_app_post_params)
return r
def _blog_date(self):
@@ -169,6 +161,31 @@ class Test(TestController):
extra_environ=dict(username='*anonymous'))
assert 'Nothing' not in response
+ def test_post_attachments(self):
+ # create
+ upload = ('attachment', 'nums.txt', '123412341234')
+ self._post(extra_app_post_params=dict(upload_files=[upload]))
+
+ # check it is listed
+ d = self._blog_date()
+ r = self.app.get('/blog/%s/my-post/' % d)
+ assert 'nums.txt' in r
+
+ # edit
+ slug = '/%s/my-post' % d
+ upload = ('attachment', 'letters.txt', 'abcdefghij')
+ self._post(slug=slug,
+ extra_app_post_params=dict(upload_files=[upload]))
+
+ # check both are there
+ r = self.app.get('/blog/%s/my-post/' % d)
+ assert 'nums.txt' in r
+ assert 'letters.txt' in r
+
+ # check attachment is accessible
+ r = self.app.get('/blog/%s/my-post/attachment/letters.txt' % d)
+ assert 'abcdefghij' in r
+
def test_post_history(self):
self._post()
d = self._blog_date()
http://git-wip-us.apache.org/repos/asf/allura/blob/b57b458f/ForgeBlog/forgeblog/widgets.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/widgets.py b/ForgeBlog/forgeblog/widgets.py
index 9d54903..6b055fc 100644
--- a/ForgeBlog/forgeblog/widgets.py
+++ b/ForgeBlog/forgeblog/widgets.py
@@ -31,6 +31,7 @@ class BlogPager(ffw.PageList):
class NewPostForm(forms.ForgeForm):
template = 'jinja:forgeblog:templates/blog_widgets/post_form.html'
+ enctype = 'multipart/form-data'
class fields(ew_core.NameList):
title = ew.TextField(validator=fev.UnicodeString(not_empty=True,
@@ -48,6 +49,8 @@ class NewPostForm(forms.ForgeForm):
ew.Option(py_value='published', label='Published')])
labels = ffw.LabelEdit(placeholder='Add labels here',
title='Add labels here')
+ attachment = ew.InputField(label='Attachment', field_type='file', attrs={'multiple': 'True'},
+ validator=fev.FieldStorageUploadConverter(if_missing=None))
def resources(self):
for r in super(NewPostForm, self).resources():