1 # GNU MediaGoblin -- federated, autonomous media hosting
2 # Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Affero General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU Affero General Public License for more details.
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 _log
= logging
.getLogger(__name__
)
20 from datetime
import datetime
24 from werkzeug
.exceptions
import Forbidden
25 from mediagoblin
.tools
import pluginapi
27 from mediagoblin
import mg_globals
29 from mediagoblin
.media_types
.blog
import forms
as blog_forms
30 from mediagoblin
.media_types
.blog
.models
import Blog
, BlogPostData
31 from mediagoblin
.media_types
.blog
.lib
import (
32 may_edit_blogpost
, set_blogpost_state
, get_all_blogposts_of_blog
,
35 from mediagoblin
.decorators
import (require_active_login
, active_user_from_url
,
36 get_media_entry_by_id
, user_may_alter_collection
,
37 get_user_collection
, uses_pagination
)
38 from mediagoblin
.tools
.pagination
import Pagination
39 from mediagoblin
.tools
.response
import (render_to_response
,
41 from mediagoblin
.tools
.translate
import pass_to_ugettext
as _
42 from mediagoblin
.tools
.template
import render_template
43 from mediagoblin
.tools
.text
import (
44 convert_to_tag_list_of_dicts
, media_tags_as_string
, clean_html
,
45 cleaned_markdown_conversion
)
47 from mediagoblin
.db
.util
import check_media_slug_used
, check_collection_slug_used
48 from mediagoblin
.db
.models
import User
, Collection
, MediaEntry
, LocalUser
50 from mediagoblin
.notifications
import add_comment_subscription
54 def blog_edit(request
):
56 View for editing an existing blog or creating a new blog
57 if user have not exceeded maximum allowed acount of blogs.
59 url_user
= request
.matchdict
.get('user', None)
60 blog_slug
= request
.matchdict
.get('blog_slug', None)
62 config
= pluginapi
.get_config('mediagoblin.media_types.blog')
63 max_blog_count
= config
['max_blog_count']
64 form
= blog_forms
.BlogEditForm(request
.form
)
67 if Blog
.query
.filter_by(author
=request
.user
.id).count()<max_blog_count
:
68 if request
.method
=='GET':
69 return render_to_response(
71 'mediagoblin/blog/blog_edit_create.html',
73 'user' : request
.user
,
74 'app_config': mg_globals
.app_config
})
76 if request
.method
=='POST' and form
.validate():
78 blog
= request
.db
.Blog()
79 blog
.title
= six
.text_type(form
.title
.data
)
80 blog
.description
= six
.text_type(cleaned_markdown_conversion((form
.description
.data
)))
81 blog
.author
= request
.user
.id
85 return redirect(request
, "mediagoblin.media_types.blog.blog_admin_dashboard",
86 user
=request
.user
.username
92 "Welcome! You already have created maximum number of blogs.")
93 return redirect(request
, "mediagoblin.media_types.blog.blog_admin_dashboard",
94 user
=request
.user
.username
)
99 blog
= get_blog_by_slug(request
, blog_slug
)
101 return render_404(request
)
102 if request
.method
== 'GET':
105 description
= cleaned_markdown_conversion(blog
.description
),
106 author
= request
.user
.id)
108 form
= blog_forms
.BlogEditForm(**defaults
)
110 return render_to_response(
112 'mediagoblin/blog/blog_edit_create.html',
114 'user': request
.user
,
115 'app_config': mg_globals
.app_config
})
117 if request
.method
== 'POST' and form
.validate():
118 blog
.title
= six
.text_type(form
.title
.data
)
119 blog
.description
= six
.text_type(cleaned_markdown_conversion((form
.description
.data
)))
120 blog
.author
= request
.user
.id
124 messages
.add_message(
127 "Your blog is updated.")
128 return redirect(request
, "mediagoblin.media_types.blog.blog-dashboard",
129 user
=request
.user
.username
,
133 @require_active_login
134 def blogpost_create(request
):
136 form
= blog_forms
.BlogPostEditForm(request
.form
, license
=request
.user
.license_preference
)
138 if request
.method
== 'POST' and form
.validate():
139 blog_slug
= request
.matchdict
.get('blog_slug')
140 blog
= get_blog_by_slug(request
, blog_slug
, author
=request
.user
.id)
142 return render_404(request
)
144 blogpost
= request
.db
.MediaEntry()
145 blogpost
.media_type
= 'mediagoblin.media_types.blogpost'
146 blogpost
.title
= six
.text_type(form
.title
.data
)
147 blogpost
.description
= six
.text_type(cleaned_markdown_conversion((form
.description
.data
)))
148 blogpost
.tags
= convert_to_tag_list_of_dicts(form
.tags
.data
)
149 blogpost
.license
= six
.text_type(form
.license
.data
) or None
150 blogpost
.actor
= request
.user
.id
151 blogpost
.generate_slug()
153 set_blogpost_state(request
, blogpost
)
156 # connect this blogpost to its blog
157 blog_post_data
= request
.db
.BlogPostData()
158 blog_post_data
.blog
= blog
.id
159 blog_post_data
.media_entry
= blogpost
.id
160 blog_post_data
.save()
162 messages
.add_message(
165 _('Woohoo! Submitted!'))
166 add_comment_subscription(request
.user
, blogpost
)
167 return redirect(request
, "mediagoblin.media_types.blog.blog-dashboard",
168 user
=request
.user
.username
,
171 return render_to_response(
173 'mediagoblin/blog/blog_post_edit_create.html',
175 'app_config': mg_globals
.app_config
,
176 'user': request
.user
.username
})
179 @require_active_login
180 def blogpost_edit(request
):
182 blog_slug
= request
.matchdict
.get('blog_slug', None)
183 blog_post_slug
= request
.matchdict
.get('blog_post_slug', None)
185 blogpost
= request
.db
.MediaEntry
.query
.filter_by(slug
=blog_post_slug
, actor
=request
.user
.id).first()
186 blog
= get_blog_by_slug(request
, blog_slug
, author
=request
.user
.id)
188 if not blogpost
or not blog
:
189 return render_404(request
)
192 title
= blogpost
.title
,
193 description
= cleaned_markdown_conversion(blogpost
.description
),
194 tags
=media_tags_as_string(blogpost
.tags
),
195 license
=blogpost
.license
)
197 form
= blog_forms
.BlogPostEditForm(request
.form
, **defaults
)
198 if request
.method
== 'POST' and form
.validate():
199 blogpost
.title
= six
.text_type(form
.title
.data
)
200 blogpost
.description
= six
.text_type(cleaned_markdown_conversion((form
.description
.data
)))
201 blogpost
.tags
= convert_to_tag_list_of_dicts(form
.tags
.data
)
202 blogpost
.license
= six
.text_type(form
.license
.data
)
203 set_blogpost_state(request
, blogpost
)
204 blogpost
.generate_slug()
207 messages
.add_message(
210 _('Woohoo! edited blogpost is submitted'))
211 return redirect(request
, "mediagoblin.media_types.blog.blog-dashboard",
212 user
=request
.user
.username
,
215 return render_to_response(
217 'mediagoblin/blog/blog_post_edit_create.html',
219 'app_config': mg_globals
.app_config
,
220 'user': request
.user
.username
,
221 'blog_post_slug': blog_post_slug
225 @active_user_from_url
227 def blog_dashboard(request
, page
, url_user
=None):
229 Dashboard for a blog, only accessible to
230 the owner of the blog.
232 blog_slug
= request
.matchdict
.get('blog_slug', None)
233 blogs
= request
.db
.Blog
.query
.filter_by(author
=url_user
.id)
234 config
= pluginapi
.get_config('mediagoblin.media_types.blog')
235 max_blog_count
= config
['max_blog_count']
236 if request
.user
and (request
.user
.id == url_user
.id or request
.user
.has_privilege(u
'admin')):
238 blog
= get_blog_by_slug(request
, blog_slug
)
240 return render_404(request
)
242 blog_posts_list
= blog
.get_all_blog_posts().order_by(MediaEntry
.created
.desc())
243 pagination
= Pagination(page
, blog_posts_list
)
244 pagination
.per_page
= 15
245 blog_posts_on_a_page
= pagination()
246 if may_edit_blogpost(request
, blog
):
247 return render_to_response(
249 'mediagoblin/blog/blog_admin_dashboard.html',
250 {'blog_posts_list': blog_posts_on_a_page
,
251 'blog_slug':blog_slug
,
254 'pagination':pagination
256 if not request
.user
or request
.user
.id != url_user
.id or not blog_slug
:
258 return render_to_response(
260 'mediagoblin/blog/list_of_blogs.html',
264 'max_blog_count':max_blog_count
268 @active_user_from_url
270 def blog_post_listing(request
, page
, url_user
=None):
272 Page, listing all the blog posts of a particular blog.
274 blog_slug
= request
.matchdict
['blog_slug']
275 blog
= get_blog_by_slug(request
, blog_slug
, author
=url_user
.id)
277 return render_404(request
)
279 all_blog_posts
= blog
.get_all_blog_posts(u
'processed').order_by(MediaEntry
.created
.desc())
280 pagination
= Pagination(page
, all_blog_posts
)
281 pagination
.per_page
= 8
282 blog_posts_on_a_page
= pagination()
284 return render_to_response(
286 'mediagoblin/blog/blog_post_listing.html',
287 {'blog_posts': blog_posts_on_a_page
,
288 'pagination': pagination
,
289 'blog_owner': url_user
,
294 @require_active_login
295 def draft_view(request
):
296 blog_slug
= request
.matchdict
.get('blog_slug', None)
297 blog_post_slug
= request
.matchdict
.get('blog_post_slug', None)
298 user
= request
.matchdict
.get('user')
299 blog
= get_blog_by_slug(request
, blog_slug
, author
=request
.user
.id)
300 blogpost
= request
.db
.MediaEntry
.query
.filter_by(state
= u
'failed', actor
=request
.user
.id, slug
=blog_post_slug
).first()
302 if not blog
or not blogpost
:
303 return render_404(request
)
305 return render_to_response(
307 'mediagoblin/blog/blogpost_draft_view.html',
308 {'blogpost':blogpost
,
313 @require_active_login
314 def blog_delete(request
, **kwargs
):
316 Deletes a blog and media entries, tags associated with it.
318 url_user
= request
.matchdict
.get('user')
319 owner_user
= request
.db
.LocalUser
.query
.filter(
320 LocalUser
.username
==url_user
323 blog_slug
= request
.matchdict
.get('blog_slug', None)
324 blog
= get_blog_by_slug(request
, blog_slug
, author
=owner_user
.id)
326 return render_404(request
)
328 form
= blog_forms
.ConfirmDeleteForm(request
.form
)
329 if request
.user
.id == blog
.author
or request
.user
.has_privilege(u
'admin'):
330 if request
.method
== 'POST' and form
.validate():
331 if form
.confirm
.data
is True:
333 messages
.add_message(
336 _('You deleted the Blog.'))
337 return redirect(request
, "mediagoblin.media_types.blog.blog_admin_dashboard",
338 user
=request
.user
.username
)
340 messages
.add_message(
343 _("The media was not deleted because you didn't check "
344 "that you were sure."))
345 return redirect(request
, "mediagoblin.media_types.blog.blog_admin_dashboard",
346 user
=request
.user
.username
)
348 if request
.user
.has_privilege(u
'admin'):
349 messages
.add_message(
352 _("You are about to delete another user's Blog. "
353 "Proceed with caution."))
354 return render_to_response(
356 'mediagoblin/blog/blog_confirm_delete.html',
361 messages
.add_message(
364 _("The blog was not deleted because you have no rights."))
365 return redirect(request
, "mediagoblin.media_types.blog.blog_admin_dashboard",
366 user
=request
.user
.username
)
369 def blog_about_view(request
):
371 Page containing blog description and statistics
373 blog_slug
= request
.matchdict
.get('blog_slug', None)
374 url_user
= request
.matchdict
.get('user', None)
376 user
= request
.db
.LocalUser
.query
.filter(
377 LocalUser
.username
==url_user
379 blog
= get_blog_by_slug(request
, blog_slug
, author
=user
.id)
381 if not user
or not blog
:
382 return render_404(request
)
385 blog_posts_processed
= blog
.get_all_blog_posts(u
'processed').count()
386 return render_to_response(
388 'mediagoblin/blog/blog_about.html',
391 'blogpost_count': blog_posts_processed