Commit | Line | Data |
---|---|---|
7f4ebeed | 1 | # GNU MediaGoblin -- federated, autonomous media hosting |
cf29e8a8 | 2 | # Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. |
9a16e16f SS |
3 | # |
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. | |
8 | # | |
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. | |
13 | # | |
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/>. | |
16 | ||
1c63ad5d | 17 | from webob import exc |
fb2fbe2c | 18 | import logging |
64712915 | 19 | import datetime |
52359e91 | 20 | |
3a8c3a38 | 21 | from mediagoblin import messages, mg_globals |
9074ee7c | 22 | from mediagoblin.db.util import DESCENDING, ObjectId |
152a3bfa | 23 | from mediagoblin.tools.response import render_to_response, render_404, redirect |
ae3bc7fa | 24 | from mediagoblin.tools.translate import pass_to_ugettext as _ |
152a3bfa AW |
25 | from mediagoblin.tools.pagination import Pagination |
26 | from mediagoblin.tools.files import delete_media_files | |
9074ee7c | 27 | from mediagoblin.user_pages import forms as user_forms |
252eaf21 | 28 | from mediagoblin.user_pages.lib import send_comment_email |
f6249408 | 29 | |
50854db0 | 30 | from mediagoblin.decorators import (uses_pagination, get_user_media_entry, |
be5be115 AW |
31 | require_active_login, user_may_delete_media, user_may_alter_collection, |
32 | get_user_collection, get_user_collection_item) | |
9a16e16f | 33 | |
00c39256 | 34 | from werkzeug.contrib.atom import AtomFeed |
1301a8ad | 35 | |
93bdab9d | 36 | from mediagoblin.media_types import get_media_manager |
be5be115 | 37 | from sqlalchemy.exc import IntegrityError |
9074ee7c | 38 | |
fb2fbe2c JAN |
39 | _log = logging.getLogger(__name__) |
40 | _log.setLevel(logging.DEBUG) | |
41 | ||
64712915 | 42 | |
3eb6fc4f | 43 | @uses_pagination |
1301a8ad | 44 | def user_home(request, page): |
9a16e16f | 45 | """'Homepage' of a User()""" |
7acdbfd3 | 46 | user = request.db.User.find_one({ |
990d3b69 | 47 | 'username': request.matchdict['user']}) |
7acdbfd3 | 48 | if not user: |
de12b4e7 | 49 | return render_404(request) |
7a3d00ec | 50 | elif user.status != u'active': |
990d3b69 CAW |
51 | return render_to_response( |
52 | request, | |
53 | 'mediagoblin/user_pages/user.html', | |
54 | {'user': user}) | |
9a16e16f | 55 | |
434b3221 | 56 | cursor = request.db.MediaEntry.find( |
eabe6b67 | 57 | {'uploader': user._id, |
5bd0adeb | 58 | 'state': u'processed'}).sort('created', DESCENDING) |
9a16e16f | 59 | |
1301a8ad | 60 | pagination = Pagination(page, cursor) |
ca3ca51c | 61 | media_entries = pagination() |
44e3e917 | 62 | |
ae85ed0f BK |
63 | #if no data is available, return NotFound |
64 | if media_entries == None: | |
de12b4e7 | 65 | return render_404(request) |
243c3843 | 66 | |
5949be9a CAW |
67 | user_gallery_url = request.urlgen( |
68 | 'mediagoblin.user_pages.user_gallery', | |
5a4e3ff1 | 69 | user=user.username) |
5949be9a | 70 | |
9038c9f9 CAW |
71 | return render_to_response( |
72 | request, | |
c9c24934 E |
73 | 'mediagoblin/user_pages/user.html', |
74 | {'user': user, | |
5949be9a | 75 | 'user_gallery_url': user_gallery_url, |
c9c24934 E |
76 | 'media_entries': media_entries, |
77 | 'pagination': pagination}) | |
f6249408 | 78 | |
243c3843 | 79 | |
184f2240 | 80 | @uses_pagination |
81 | def user_gallery(request, page): | |
82 | """'Gallery' of a User()""" | |
83 | user = request.db.User.find_one({ | |
84 | 'username': request.matchdict['user'], | |
5bd0adeb | 85 | 'status': u'active'}) |
184f2240 | 86 | if not user: |
de12b4e7 | 87 | return render_404(request) |
184f2240 | 88 | |
89 | cursor = request.db.MediaEntry.find( | |
eabe6b67 | 90 | {'uploader': user._id, |
5bd0adeb | 91 | 'state': u'processed'}).sort('created', DESCENDING) |
184f2240 | 92 | |
93 | pagination = Pagination(page, cursor) | |
94 | media_entries = pagination() | |
95 | ||
96 | #if no data is available, return NotFound | |
97 | if media_entries == None: | |
de12b4e7 | 98 | return render_404(request) |
243c3843 | 99 | |
4b5f5a08 | 100 | return render_to_response( |
101 | request, | |
102 | 'mediagoblin/user_pages/gallery.html', | |
103 | {'user': user, | |
104 | 'media_entries': media_entries, | |
105 | 'pagination': pagination}) | |
184f2240 | 106 | |
6f59a3a3 | 107 | MEDIA_COMMENTS_PER_PAGE = 50 |
434b3221 | 108 | |
243c3843 | 109 | |
01674e10 | 110 | @get_user_media_entry |
9074ee7c | 111 | @uses_pagination |
6f59a3a3 | 112 | def media_home(request, media, page, **kwargs): |
9074ee7c JW |
113 | """ |
114 | 'Homepage' of a MediaEntry() | |
115 | """ | |
af2fcba5 JW |
116 | if ObjectId(request.matchdict.get('comment')): |
117 | pagination = Pagination( | |
7c378f2c CAW |
118 | page, media.get_comments( |
119 | mg_globals.app_config['comments_ascending']), | |
120 | MEDIA_COMMENTS_PER_PAGE, | |
af2fcba5 JW |
121 | ObjectId(request.matchdict.get('comment'))) |
122 | else: | |
123 | pagination = Pagination( | |
7c378f2c CAW |
124 | page, media.get_comments( |
125 | mg_globals.app_config['comments_ascending']), | |
126 | MEDIA_COMMENTS_PER_PAGE) | |
9074ee7c | 127 | |
6f59a3a3 | 128 | comments = pagination() |
9074ee7c | 129 | |
6f59a3a3 | 130 | comment_form = user_forms.MediaCommentForm(request.POST) |
9074ee7c | 131 | |
f4ee8399 | 132 | media_template_name = get_media_manager(media.media_type)['display_template'] |
93bdab9d | 133 | |
9038c9f9 CAW |
134 | return render_to_response( |
135 | request, | |
93bdab9d | 136 | media_template_name, |
9074ee7c JW |
137 | {'media': media, |
138 | 'comments': comments, | |
139 | 'pagination': pagination, | |
3a8c3a38 JW |
140 | 'comment_form': comment_form, |
141 | 'app_config': mg_globals.app_config}) | |
9074ee7c | 142 | |
95e6da02 | 143 | |
95e12bf2 | 144 | @get_user_media_entry |
9074ee7c | 145 | @require_active_login |
95e12bf2 | 146 | def media_post_comment(request, media): |
9074ee7c JW |
147 | """ |
148 | recieves POST from a MediaEntry() comment form, saves the comment. | |
149 | """ | |
95e12bf2 CAW |
150 | assert request.method == 'POST' |
151 | ||
9074ee7c | 152 | comment = request.db.MediaComment() |
8efcd405 E |
153 | comment.media_entry = media.id |
154 | comment.author = request.user.id | |
155 | comment.content = unicode(request.POST['comment_content']) | |
9074ee7c | 156 | |
8efcd405 | 157 | if not comment.content.strip(): |
7298ffa1 AW |
158 | messages.add_message( |
159 | request, | |
160 | messages.ERROR, | |
eae7d058 | 161 | _("Oops, your comment was empty.")) |
7298ffa1 AW |
162 | else: |
163 | comment.save() | |
b5d3aec6 | 164 | |
7298ffa1 AW |
165 | messages.add_message( |
166 | request, messages.SUCCESS, | |
eae7d058 | 167 | _('Your comment has been posted!')) |
52359e91 | 168 | |
252eaf21 DM |
169 | media_uploader = media.get_uploader |
170 | #don't send email if you comment on your own post | |
171 | if (comment.author != media_uploader and | |
00722c99 | 172 | media_uploader.wants_comment_notification): |
252eaf21 DM |
173 | send_comment_email(media_uploader, comment, media, request) |
174 | ||
95e12bf2 CAW |
175 | return exc.HTTPFound( |
176 | location=media.url_for_self(request.urlgen)) | |
00c39256 | 177 | |
95e6da02 | 178 | |
be5be115 AW |
179 | @get_user_media_entry |
180 | @require_active_login | |
181 | def media_collect(request, media): | |
182 | ||
183 | form = user_forms.MediaCollectForm(request.POST) | |
184 | filt = (request.db.Collection.creator == request.user.id) | |
185 | form.collection.query = request.db.Collection.query.filter(filt).order_by(request.db.Collection.title) | |
186 | ||
187 | if request.method == 'POST': | |
188 | if form.validate(): | |
189 | ||
190 | collection = None | |
191 | collection_item = request.db.CollectionItem() | |
192 | ||
193 | # If the user is adding a new collection, use that | |
194 | if request.POST['collection_title']: | |
195 | collection = request.db.Collection() | |
196 | collection.id = ObjectId() | |
197 | ||
198 | collection.title = ( | |
199 | unicode(request.POST['collection_title']) | |
200 | or unicode(splitext(filename)[0])) | |
201 | ||
202 | collection.description = unicode(request.POST.get('collection_description')) | |
203 | collection.creator = request.user._id | |
204 | collection.generate_slug() | |
205 | ||
206 | # Make sure this user isn't duplicating an existing collection | |
207 | existing_collection = request.db.Collection.find_one({ | |
208 | 'creator': request.user._id, | |
209 | 'title':collection.title}) | |
210 | ||
211 | if existing_collection: | |
212 | messages.add_message( | |
213 | request, messages.ERROR, _('You already have a collection called "%s"!' % collection.title)) | |
214 | ||
215 | return redirect(request, "mediagoblin.user_pages.media_home", | |
216 | user=request.user.username, | |
217 | media=media.id) | |
218 | ||
219 | collection.save(validate=True) | |
220 | ||
221 | collection_item.collection = collection.id | |
222 | # Otherwise, use the collection selected from the drop-down | |
223 | else: | |
224 | collection = request.db.Collection.find_one({'_id': request.POST.get('collection')}) | |
225 | collection_item.collection = collection.id | |
226 | ||
227 | # Make sure the user actually selected a collection | |
228 | if not collection: | |
229 | messages.add_message( | |
230 | request, messages.ERROR, _('You have to select or add a collection')) | |
231 | # Check whether media already exists in collection | |
232 | elif request.db.CollectionItem.find_one({'media_entry': media.id, 'collection': collection_item.collection}): | |
233 | messages.add_message( | |
234 | request, messages.ERROR, _('"%s" already in collection "%s"' % (media.title, collection.title))) | |
235 | else: | |
236 | collection_item.media_entry = media.id | |
237 | collection_item.author = request.user.id | |
238 | collection_item.note = unicode(request.POST['note']) | |
239 | collection_item.save(validate=True) | |
240 | ||
241 | collection.items = collection.items + 1 | |
242 | collection.save(validate=True) | |
243 | ||
244 | media.collected = media.collected + 1 | |
245 | media.save() | |
246 | ||
247 | messages.add_message( | |
248 | request, messages.SUCCESS, _('"%s" added to collection "%s"' % (media.title, collection.title))) | |
249 | ||
250 | return redirect(request, "mediagoblin.user_pages.media_home", | |
251 | user=request.user.username, | |
252 | media=media.id) | |
253 | else: | |
254 | messages.add_message( | |
255 | request, messages.ERROR, _('Please check your entries and try again.')) | |
256 | ||
257 | return render_to_response( | |
258 | request, | |
259 | 'mediagoblin/user_pages/media_collect.html', | |
260 | {'media': media, | |
261 | 'form': form}) | |
262 | ||
263 | ||
502073f2 JW |
264 | @get_user_media_entry |
265 | @require_active_login | |
266 | @user_may_delete_media | |
267 | def media_confirm_delete(request, media): | |
268 | ||
269 | form = user_forms.ConfirmDeleteForm(request.POST) | |
270 | ||
271 | if request.method == 'POST' and form.validate(): | |
8daef28d | 272 | if form.confirm.data is True: |
05751758 | 273 | username = media.get_uploader.username |
502073f2 | 274 | |
a0a7f87f BS |
275 | # Delete all the associated comments |
276 | for comment in media.get_comments(): | |
277 | comment.delete() | |
278 | ||
502073f2 | 279 | # Delete all files on the public storage |
fb2fbe2c JAN |
280 | try: |
281 | delete_media_files(media) | |
282 | except OSError, error: | |
283 | _log.error('No such files from the user "{1}"' | |
284 | ' to delete: {0}'.format(str(error), username)) | |
285 | messages.add_message(request, messages.ERROR, | |
286 | _('Some of the files with this entry seem' | |
287 | ' to be missing. Deleting anyway.')) | |
502073f2 JW |
288 | |
289 | media.delete() | |
ea33f636 E |
290 | messages.add_message( |
291 | request, messages.SUCCESS, _('You deleted the media.')) | |
502073f2 JW |
292 | |
293 | return redirect(request, "mediagoblin.user_pages.user_home", | |
294 | user=username) | |
295 | else: | |
d0ba62e2 PUS |
296 | messages.add_message( |
297 | request, messages.ERROR, | |
56bfd91a | 298 | _("The media was not deleted because you didn't check that you were sure.")) |
8d7b549b E |
299 | return exc.HTTPFound( |
300 | location=media.url_for_self(request.urlgen)) | |
502073f2 | 301 | |
bec591d8 | 302 | if ((request.user.is_admin and |
4deda94a | 303 | request.user._id != media.uploader)): |
7a4c0126 CAW |
304 | messages.add_message( |
305 | request, messages.WARNING, | |
306 | _("You are about to delete another user's media. " | |
307 | "Proceed with caution.")) | |
308 | ||
502073f2 JW |
309 | return render_to_response( |
310 | request, | |
311 | 'mediagoblin/user_pages/media_confirm_delete.html', | |
312 | {'media': media, | |
313 | 'form': form}) | |
314 | ||
315 | ||
be5be115 AW |
316 | @uses_pagination |
317 | def user_collection(request, page): | |
318 | """A User-defined Collection""" | |
319 | user = request.db.User.find_one({ | |
320 | 'username': request.matchdict['user'], | |
321 | 'status': u'active'}) | |
322 | if not user: | |
323 | return render_404(request) | |
324 | ||
325 | collection = request.db.Collection.find_one( | |
326 | {'slug': request.matchdict['collection'] }) | |
327 | ||
328 | cursor = request.db.CollectionItem.find( | |
329 | {'collection': collection.id }) | |
330 | ||
331 | pagination = Pagination(page, cursor) | |
332 | collection_items = pagination() | |
333 | ||
334 | #if no data is available, return NotFound | |
335 | if collection_items == None: | |
336 | return render_404(request) | |
337 | ||
338 | return render_to_response( | |
339 | request, | |
340 | 'mediagoblin/user_pages/collection.html', | |
341 | {'user': user, | |
342 | 'collection': collection, | |
343 | 'collection_items': collection_items, | |
344 | 'pagination': pagination}) | |
345 | ||
346 | ||
347 | @get_user_collection_item | |
348 | @require_active_login | |
349 | @user_may_alter_collection | |
350 | def collection_item_confirm_remove(request, collection_item): | |
351 | ||
352 | form = user_forms.ConfirmCollectionItemRemoveForm(request.POST) | |
353 | ||
354 | if request.method == 'POST' and form.validate(): | |
355 | username = collection_item.in_collection.get_creator.username | |
356 | collection = collection_item.in_collection | |
357 | ||
358 | if form.confirm.data is True: | |
359 | entry = collection_item.get_media_entry | |
360 | entry.collected = entry.collected - 1 | |
361 | entry.save() | |
362 | ||
363 | collection_item.delete() | |
364 | collection.items = collection.items - 1; | |
365 | collection.save() | |
366 | ||
367 | messages.add_message( | |
368 | request, messages.SUCCESS, _('You deleted the item from the collection.')) | |
369 | else: | |
370 | messages.add_message( | |
371 | request, messages.ERROR, | |
372 | _("The item was not removed because you didn't check that you were sure.")) | |
373 | ||
374 | return redirect(request, "mediagoblin.user_pages.user_collection", | |
375 | user=username, | |
376 | collection=collection.slug) | |
377 | ||
378 | if ((request.user.is_admin and | |
cdb35b97 | 379 | request.user._id != collection_item.in_collection.creator)): |
be5be115 AW |
380 | messages.add_message( |
381 | request, messages.WARNING, | |
382 | _("You are about to delete an item from another user's collection. " | |
383 | "Proceed with caution.")) | |
384 | ||
385 | return render_to_response( | |
386 | request, | |
387 | 'mediagoblin/user_pages/collection_item_confirm_remove.html', | |
388 | {'collection_item': collection_item, | |
389 | 'form': form}) | |
390 | ||
391 | ||
392 | @get_user_collection | |
393 | @require_active_login | |
394 | @user_may_alter_collection | |
395 | def collection_confirm_delete(request, collection): | |
396 | ||
397 | form = user_forms.ConfirmDeleteForm(request.POST) | |
398 | ||
399 | if request.method == 'POST' and form.validate(): | |
400 | ||
401 | username = collection.get_creator.username | |
402 | ||
403 | if form.confirm.data is True: | |
404 | collection_title = collection.title | |
405 | ||
406 | # Delete all the associated collection items | |
407 | for item in collection.get_collection_items(): | |
408 | entry = item.get_media_entry | |
409 | entry.collected = entry.collected - 1 | |
410 | entry.save() | |
411 | item.delete() | |
412 | ||
413 | collection.delete() | |
414 | messages.add_message( | |
415 | request, messages.SUCCESS, _('You deleted the collection "%s"' % collection_title)) | |
416 | ||
417 | return redirect(request, "mediagoblin.user_pages.user_home", | |
418 | user=username) | |
419 | else: | |
420 | messages.add_message( | |
421 | request, messages.ERROR, | |
422 | _("The collection was not deleted because you didn't check that you were sure.")) | |
423 | ||
424 | return redirect(request, "mediagoblin.user_pages.user_collection", | |
425 | user=username, | |
426 | collection=collection.slug) | |
427 | ||
428 | if ((request.user.is_admin and | |
429 | request.user._id != collection.creator)): | |
430 | messages.add_message( | |
431 | request, messages.WARNING, | |
432 | _("You are about to delete another user's collection. " | |
433 | "Proceed with caution.")) | |
434 | ||
435 | return render_to_response( | |
436 | request, | |
437 | 'mediagoblin/user_pages/collection_confirm_delete.html', | |
438 | {'collection': collection, | |
439 | 'form': form}) | |
440 | ||
441 | ||
a5303e47 | 442 | ATOM_DEFAULT_NR_OF_UPDATED_ITEMS = 15 |
00c39256 | 443 | |
243c3843 | 444 | |
00c39256 BK |
445 | def atom_feed(request): |
446 | """ | |
447 | generates the atom feed with the newest images | |
448 | """ | |
449 | ||
450 | user = request.db.User.find_one({ | |
451 | 'username': request.matchdict['user'], | |
5bd0adeb | 452 | 'status': u'active'}) |
00c39256 | 453 | if not user: |
de12b4e7 | 454 | return render_404(request) |
00c39256 BK |
455 | |
456 | cursor = request.db.MediaEntry.find({ | |
eabe6b67 | 457 | 'uploader': user._id, |
5bd0adeb | 458 | 'state': u'processed'}) \ |
00c39256 BK |
459 | .sort('created', DESCENDING) \ |
460 | .limit(ATOM_DEFAULT_NR_OF_UPDATED_ITEMS) | |
461 | ||
1df68a35 MA |
462 | """ |
463 | ATOM feed id is a tag URI (see http://en.wikipedia.org/wiki/Tag_URI) | |
464 | """ | |
5b1a7bae MA |
465 | atomlinks = [{ |
466 | 'href': request.urlgen( | |
467 | 'mediagoblin.user_pages.user_home', | |
64712915 | 468 | qualified=True, user=request.matchdict['user']), |
5b1a7bae MA |
469 | 'rel': 'alternate', |
470 | 'type': 'text/html' | |
64712915 JW |
471 | }] |
472 | ||
bb025ebd MA |
473 | if mg_globals.app_config["push_urls"]: |
474 | for push_url in mg_globals.app_config["push_urls"]: | |
475 | atomlinks.append({ | |
476 | 'rel': 'hub', | |
477 | 'href': push_url}) | |
5b1a7bae | 478 | |
1df68a35 MA |
479 | feed = AtomFeed( |
480 | "MediaGoblin: Feed for user '%s'" % request.matchdict['user'], | |
00c39256 | 481 | feed_url=request.url, |
64712915 JW |
482 | id='tag:{host},{year}:gallery.user-{user}'.format( |
483 | host=request.host, | |
484 | year=datetime.datetime.today().strftime('%Y'), | |
485 | user=request.matchdict['user']), | |
5b1a7bae MA |
486 | links=atomlinks) |
487 | ||
00c39256 BK |
488 | for entry in cursor: |
489 | feed.add(entry.get('title'), | |
1e72e075 | 490 | entry.description_html, |
64712915 | 491 | id=entry.url_for_self(request.urlgen, qualified=True), |
00c39256 | 492 | content_type='html', |
1df68a35 MA |
493 | author={ |
494 | 'name': entry.get_uploader.username, | |
495 | 'uri': request.urlgen( | |
496 | 'mediagoblin.user_pages.user_home', | |
497 | qualified=True, user=entry.get_uploader.username)}, | |
00c39256 | 498 | updated=entry.get('created'), |
1df68a35 MA |
499 | links=[{ |
500 | 'href': entry.url_for_self( | |
501 | request.urlgen, | |
be5be115 AW |
502 | qualified=True), |
503 | 'rel': 'alternate', | |
504 | 'type': 'text/html'}]) | |
505 | ||
506 | return feed.get_response() | |
507 | ||
508 | def collection_atom_feed(request): | |
509 | """ | |
510 | generates the atom feed with the newest images from a collection | |
511 | """ | |
512 | ||
513 | user = request.db.User.find_one({ | |
514 | 'username': request.matchdict['user'], | |
515 | 'status': u'active'}) | |
516 | if not user: | |
517 | return render_404(request) | |
518 | ||
519 | collection = request.db.Collection.find_one({ | |
520 | 'creator': user.id, | |
521 | 'slug': request.matchdict['collection']}) | |
522 | ||
523 | cursor = request.db.CollectionItem.find({ | |
524 | 'collection': collection._id}) \ | |
525 | .sort('added', DESCENDING) \ | |
526 | .limit(ATOM_DEFAULT_NR_OF_UPDATED_ITEMS) | |
527 | ||
528 | """ | |
529 | ATOM feed id is a tag URI (see http://en.wikipedia.org/wiki/Tag_URI) | |
530 | """ | |
531 | atomlinks = [{ | |
532 | 'href': request.urlgen( | |
533 | 'mediagoblin.user_pages.user_collection', | |
534 | qualified=True, user=request.matchdict['user'], collection=collection.slug), | |
535 | 'rel': 'alternate', | |
536 | 'type': 'text/html' | |
537 | }] | |
538 | ||
539 | if mg_globals.app_config["push_urls"]: | |
540 | for push_url in mg_globals.app_config["push_urls"]: | |
541 | atomlinks.append({ | |
542 | 'rel': 'hub', | |
543 | 'href': push_url}) | |
544 | ||
545 | feed = AtomFeed( | |
546 | "MediaGoblin: Feed for %s's collection %s" % (request.matchdict['user'], collection.title), | |
547 | feed_url=request.url, | |
548 | id='tag:{host},{year}:collection.user-{user}.title-{title}'.format( | |
549 | host=request.host, | |
550 | year=datetime.datetime.today().strftime('%Y'), | |
551 | user=request.matchdict['user'], | |
552 | title=collection.title), | |
553 | links=atomlinks) | |
554 | ||
555 | for item in cursor: | |
556 | entry = item.get_media_entry | |
557 | feed.add(entry.get('title'), | |
558 | item.note_html, | |
559 | id=entry.url_for_self(request.urlgen, qualified=True), | |
560 | content_type='html', | |
561 | author={ | |
562 | 'name': entry.get_uploader.username, | |
563 | 'uri': request.urlgen( | |
564 | 'mediagoblin.user_pages.user_home', | |
565 | qualified=True, user=entry.get_uploader.username)}, | |
566 | updated=item.get('added'), | |
567 | links=[{ | |
568 | 'href': entry.url_for_self( | |
569 | request.urlgen, | |
1df68a35 MA |
570 | qualified=True), |
571 | 'rel': 'alternate', | |
572 | 'type': 'text/html'}]) | |
00c39256 | 573 | |
9074ee7c | 574 | return feed.get_response() |
01c75c7e CAW |
575 | |
576 | ||
577 | @require_active_login | |
578 | def processing_panel(request): | |
579 | """ | |
580 | Show to the user what media is still in conversion/processing... | |
581 | and what failed, and why! | |
582 | """ | |
583 | # Get the user | |
584 | user = request.db.User.find_one( | |
585 | {'username': request.matchdict['user'], | |
5bd0adeb | 586 | 'status': u'active'}) |
01c75c7e CAW |
587 | |
588 | # Make sure the user exists and is active | |
589 | if not user: | |
de12b4e7 | 590 | return render_404(request) |
7a3d00ec | 591 | elif user.status != u'active': |
01c75c7e CAW |
592 | return render_to_response( |
593 | request, | |
594 | 'mediagoblin/user_pages/user.html', | |
595 | {'user': user}) | |
596 | ||
597 | # XXX: Should this be a decorator? | |
598 | # | |
599 | # Make sure we have permission to access this user's panel. Only | |
600 | # admins and this user herself should be able to do so. | |
eabe6b67 | 601 | if not (user._id == request.user._id |
01c75c7e CAW |
602 | or request.user.is_admin): |
603 | # No? Let's simply redirect to this user's homepage then. | |
604 | return redirect( | |
605 | request, 'mediagoblin.user_pages.user_home', | |
606 | user=request.matchdict['user']) | |
607 | ||
608 | # Get media entries which are in-processing | |
609 | processing_entries = request.db.MediaEntry.find( | |
eabe6b67 | 610 | {'uploader': user._id, |
64712915 | 611 | 'state': u'processing'}).sort('created', DESCENDING) |
01c75c7e CAW |
612 | |
613 | # Get media entries which have failed to process | |
614 | failed_entries = request.db.MediaEntry.find( | |
eabe6b67 | 615 | {'uploader': user._id, |
5bd0adeb | 616 | 'state': u'failed'}).sort('created', DESCENDING) |
01c75c7e | 617 | |
64712915 JW |
618 | processed_entries = request.db.MediaEntry.find( |
619 | {'uploader': user._id, | |
620 | 'state': u'processed'}).sort('created', DESCENDING).limit(10) | |
621 | ||
01c75c7e CAW |
622 | # Render to response |
623 | return render_to_response( | |
624 | request, | |
625 | 'mediagoblin/user_pages/processing_panel.html', | |
626 | {'user': user, | |
627 | 'processing_entries': processing_entries, | |
64712915 JW |
628 | 'failed_entries': failed_entries, |
629 | 'processed_entries': processed_entries}) |