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
.messages
import add_message
, SUCCESS
, ERROR
36 from mediagoblin
.decorators
import (require_active_login
, active_user_from_url
,
37 get_media_entry_by_id
, user_may_alter_collection
,
38 get_user_collection
, uses_pagination
)
39 from mediagoblin
.tools
.pagination
import Pagination
40 from mediagoblin
.tools
.response
import (render_to_response
,
42 from mediagoblin
.tools
.translate
import pass_to_ugettext
as _
43 from mediagoblin
.tools
.template
import render_template
44 from mediagoblin
.tools
.text
import (
45 convert_to_tag_list_of_dicts
, media_tags_as_string
, clean_html
,
46 cleaned_markdown_conversion
)
48 from mediagoblin
.db
.util
import check_media_slug_used
, check_collection_slug_used
49 from mediagoblin
.db
.models
import User
, Collection
, MediaEntry
, LocalUser
51 from mediagoblin
.notifications
import add_comment_subscription
55 def blog_edit(request
):
57 View for editing an existing blog or creating a new blog
58 if user have not exceeded maximum allowed acount of blogs.
60 url_user
= request
.matchdict
.get('user', None)
61 blog_slug
= request
.matchdict
.get('blog_slug', None)
63 config
= pluginapi
.get_config('mediagoblin.media_types.blog')
64 max_blog_count
= config
['max_blog_count']
65 form
= blog_forms
.BlogEditForm(request
.form
)
68 if Blog
.query
.filter_by(author
=request
.user
.id).count()<max_blog_count
:
69 if request
.method
=='GET':
70 return render_to_response(
72 'mediagoblin/blog/blog_edit_create.html',
74 'user' : request
.user
,
75 'app_config': mg_globals
.app_config
})
77 if request
.method
=='POST' and form
.validate():
79 blog
= request
.db
.Blog()
80 blog
.title
= six
.text_type(form
.title
.data
)
81 blog
.description
= six
.text_type(cleaned_markdown_conversion((form
.description
.data
)))
82 blog
.author
= request
.user
.id
86 return redirect(request
, "mediagoblin.media_types.blog.blog_admin_dashboard",
87 user
=request
.user
.username
90 add_message(request
, ERROR
, "Welcome! You already have created \
91 maximum number of blogs.")
92 return redirect(request
, "mediagoblin.media_types.blog.blog_admin_dashboard",
93 user
=request
.user
.username
)
98 blog
= get_blog_by_slug(request
, blog_slug
)
100 return render_404(request
)
101 if request
.method
== 'GET':
104 description
= cleaned_markdown_conversion(blog
.description
),
105 author
= request
.user
.id)
107 form
= blog_forms
.BlogEditForm(**defaults
)
109 return render_to_response(
111 'mediagoblin/blog/blog_edit_create.html',
113 'user': request
.user
,
114 'app_config': mg_globals
.app_config
})
116 if request
.method
== 'POST' and form
.validate():
117 blog
.title
= six
.text_type(form
.title
.data
)
118 blog
.description
= six
.text_type(cleaned_markdown_conversion((form
.description
.data
)))
119 blog
.author
= request
.user
.id
123 add_message(request
, SUCCESS
, "Your blog is updated.")
124 return redirect(request
, "mediagoblin.media_types.blog.blog-dashboard",
125 user
=request
.user
.username
,
129 @require_active_login
130 def blogpost_create(request
):
132 form
= blog_forms
.BlogPostEditForm(request
.form
, license
=request
.user
.license_preference
)
134 if request
.method
== 'POST' and form
.validate():
135 blog_slug
= request
.matchdict
.get('blog_slug')
136 blog
= get_blog_by_slug(request
, blog_slug
, author
=request
.user
.id)
138 return render_404(request
)
140 blogpost
= request
.db
.MediaEntry()
141 blogpost
.media_type
= 'mediagoblin.media_types.blogpost'
142 blogpost
.title
= six
.text_type(form
.title
.data
)
143 blogpost
.description
= six
.text_type(cleaned_markdown_conversion((form
.description
.data
)))
144 blogpost
.tags
= convert_to_tag_list_of_dicts(form
.tags
.data
)
145 blogpost
.license
= six
.text_type(form
.license
.data
) or None
146 blogpost
.uploader
= request
.user
.id
147 blogpost
.generate_slug()
149 set_blogpost_state(request
, blogpost
)
152 # connect this blogpost to its blog
153 blog_post_data
= request
.db
.BlogPostData()
154 blog_post_data
.blog
= blog
.id
155 blog_post_data
.media_entry
= blogpost
.id
156 blog_post_data
.save()
158 add_message(request
, SUCCESS
, _('Woohoo! Submitted!'))
159 add_comment_subscription(request
.user
, blogpost
)
160 return redirect(request
, "mediagoblin.media_types.blog.blog-dashboard",
161 user
=request
.user
.username
,
164 return render_to_response(
166 'mediagoblin/blog/blog_post_edit_create.html',
168 'app_config': mg_globals
.app_config
,
169 'user': request
.user
.username
})
172 @require_active_login
173 def blogpost_edit(request
):
175 blog_slug
= request
.matchdict
.get('blog_slug', None)
176 blog_post_slug
= request
.matchdict
.get('blog_post_slug', None)
178 blogpost
= request
.db
.MediaEntry
.query
.filter_by(slug
=blog_post_slug
, uploader
=request
.user
.id).first()
179 blog
= get_blog_by_slug(request
, blog_slug
, author
=request
.user
.id)
181 if not blogpost
or not blog
:
182 return render_404(request
)
185 title
= blogpost
.title
,
186 description
= cleaned_markdown_conversion(blogpost
.description
),
187 tags
=media_tags_as_string(blogpost
.tags
),
188 license
=blogpost
.license
)
190 form
= blog_forms
.BlogPostEditForm(request
.form
, **defaults
)
191 if request
.method
== 'POST' and form
.validate():
192 blogpost
.title
= six
.text_type(form
.title
.data
)
193 blogpost
.description
= six
.text_type(cleaned_markdown_conversion((form
.description
.data
)))
194 blogpost
.tags
= convert_to_tag_list_of_dicts(form
.tags
.data
)
195 blogpost
.license
= six
.text_type(form
.license
.data
)
196 set_blogpost_state(request
, blogpost
)
197 blogpost
.generate_slug()
200 add_message(request
, SUCCESS
, _('Woohoo! edited blogpost is submitted'))
201 return redirect(request
, "mediagoblin.media_types.blog.blog-dashboard",
202 user
=request
.user
.username
,
205 return render_to_response(
207 'mediagoblin/blog/blog_post_edit_create.html',
209 'app_config': mg_globals
.app_config
,
210 'user': request
.user
.username
,
211 'blog_post_slug': blog_post_slug
215 @active_user_from_url
217 def blog_dashboard(request
, page
, url_user
=None):
219 Dashboard for a blog, only accessible to
220 the owner of the blog.
222 blog_slug
= request
.matchdict
.get('blog_slug', None)
223 blogs
= request
.db
.Blog
.query
.filter_by(author
=url_user
.id)
224 config
= pluginapi
.get_config('mediagoblin.media_types.blog')
225 max_blog_count
= config
['max_blog_count']
226 if request
.user
and (request
.user
.id == url_user
.id or request
.user
.has_privilege(u
'admin')):
228 blog
= get_blog_by_slug(request
, blog_slug
)
230 return render_404(request
)
232 blog_posts_list
= blog
.get_all_blog_posts().order_by(MediaEntry
.created
.desc())
233 pagination
= Pagination(page
, blog_posts_list
)
234 pagination
.per_page
= 15
235 blog_posts_on_a_page
= pagination()
236 if may_edit_blogpost(request
, blog
):
237 return render_to_response(
239 'mediagoblin/blog/blog_admin_dashboard.html',
240 {'blog_posts_list': blog_posts_on_a_page
,
241 'blog_slug':blog_slug
,
244 'pagination':pagination
246 if not request
.user
or request
.user
.id != url_user
.id or not blog_slug
:
248 return render_to_response(
250 'mediagoblin/blog/list_of_blogs.html',
254 'max_blog_count':max_blog_count
258 @active_user_from_url
260 def blog_post_listing(request
, page
, url_user
=None):
262 Page, listing all the blog posts of a particular blog.
264 blog_slug
= request
.matchdict
['blog_slug']
265 blog
= get_blog_by_slug(request
, blog_slug
, author
=url_user
.id)
267 return render_404(request
)
269 all_blog_posts
= blog
.get_all_blog_posts(u
'processed').order_by(MediaEntry
.created
.desc())
270 pagination
= Pagination(page
, all_blog_posts
)
271 pagination
.per_page
= 8
272 blog_posts_on_a_page
= pagination()
274 return render_to_response(
276 'mediagoblin/blog/blog_post_listing.html',
277 {'blog_posts': blog_posts_on_a_page
,
278 'pagination': pagination
,
279 'blog_owner': url_user
,
284 @require_active_login
285 def draft_view(request
):
286 blog_slug
= request
.matchdict
.get('blog_slug', None)
287 blog_post_slug
= request
.matchdict
.get('blog_post_slug', None)
288 user
= request
.matchdict
.get('user')
289 blog
= get_blog_by_slug(request
, blog_slug
, author
=request
.user
.id)
290 blogpost
= request
.db
.MediaEntry
.query
.filter_by(state
= u
'failed', uploader
=request
.user
.id, slug
=blog_post_slug
).first()
292 if not blog
or not blogpost
:
293 return render_404(request
)
295 return render_to_response(
297 'mediagoblin/blog/blogpost_draft_view.html',
298 {'blogpost':blogpost
,
303 @require_active_login
304 def blog_delete(request
, **kwargs
):
306 Deletes a blog and media entries, tags associated with it.
308 url_user
= request
.matchdict
.get('user')
309 owner_user
= request
.db
.LocalUser
.query
.filter(
310 LocalUser
.username
==url_user
313 blog_slug
= request
.matchdict
.get('blog_slug', None)
314 blog
= get_blog_by_slug(request
, blog_slug
, author
=owner_user
.id)
316 return render_404(reequest
)
318 form
= blog_forms
.ConfirmDeleteForm(request
.form
)
319 if request
.user
.id == blog
.author
or request
.user
.has_privilege(u
'admin'):
320 if request
.method
== 'POST' and form
.validate():
321 if form
.confirm
.data
is True:
324 request
, SUCCESS
, _('You deleted the Blog.'))
325 return redirect(request
, "mediagoblin.media_types.blog.blog_admin_dashboard",
326 user
=request
.user
.username
)
330 _("The media was not deleted because you didn't check that you were sure."))
331 return redirect(request
, "mediagoblin.media_types.blog.blog_admin_dashboard",
332 user
=request
.user
.username
)
334 if request
.user
.has_privilege(u
'admin'):
337 _("You are about to delete another user's Blog. "
338 "Proceed with caution."))
339 return render_to_response(
341 'mediagoblin/blog/blog_confirm_delete.html',
348 _("The blog was not deleted because you have no rights."))
349 return redirect(request
, "mediagoblin.media_types.blog.blog_admin_dashboard",
350 user
=request
.user
.username
)
353 def blog_about_view(request
):
355 Page containing blog description and statistics
357 blog_slug
= request
.matchdict
.get('blog_slug', None)
358 url_user
= request
.matchdict
.get('user', None)
360 user
= request
.db
.User
.query
.filter(
361 LocalUser
.username
=url_user
363 blog
= get_blog_by_slug(request
, blog_slug
, author
=user
.id)
365 if not user
or not blog
:
366 return render_404(request
)
369 blog_posts_processed
= blog
.get_all_blog_posts(u
'processed').count()
370 return render_to_response(
372 'mediagoblin/blog/blog_about.html',
375 'blogpost_count': blog_posts_processed