From: Christopher Allan Webber Date: Wed, 13 Nov 2013 16:22:46 +0000 (-0600) Subject: Refactoring submission utility to make it more generic! Reusable! X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=9e15c674ceaf708e5c44a79c6793ade695f11933;p=mediagoblin.git Refactoring submission utility to make it more generic! Reusable! This commit sponsored by Joar Wandborg. Joar, thanks for the many things you've done for MediaGoblin! --- diff --git a/mediagoblin/submit/lib.py b/mediagoblin/submit/lib.py index bea39b2a..9036c419 100644 --- a/mediagoblin/submit/lib.py +++ b/mediagoblin/submit/lib.py @@ -25,6 +25,7 @@ from mediagoblin.tools.text import convert_to_tag_list_of_dicts from mediagoblin.db.models import MediaEntry from mediagoblin.processing import mark_entry_failed from mediagoblin.processing.task import ProcessMedia +from mediagoblin.notifications import add_comment_subscription from mediagoblin.media_types import sniff_media, \ InvalidFileType, FileTypeNotSupported @@ -52,9 +53,44 @@ def new_upload_entry(user): return entry +class UploadLimitError(Exception): + """ + General exception for when an upload will be over some upload limit + """ + pass + + +class FileUploadLimit(UploadLimitError): + """ + This file is over the site upload limit + """ + pass + + +class UserUploadLimit(UploadLimitError): + """ + This file is over the user's particular upload limit + """ + pass + + +class UserPastUploadLimit(UploadLimitError): + """ + The user is *already* past their upload limit! + """ + pass + + + def submit_media(mg_app, user, submitted_file, filename, title=None, description=None, - license=None, tags_string=u""): + license=None, tags_string=u"", + upload_limit=None, max_file_size=None, + # If provided we'll do the feed_url update, otherwise ignore + urlgen=None): + if upload_limit and user.uploaded >= upload_limit: + raise UserPastUploadLimit() + # If the filename contains non ascii generate a unique name if not all(ord(c) < 128 for c in filename): filename = unicode(uuid.uuid4()) + splitext(filename)[-1] @@ -88,45 +124,36 @@ def submit_media(mg_app, user, submitted_file, filename, entry.queued_media_file) / (1024.0 * 1024) file_size = float('{0:.2f}'.format(file_size)) - #### We should be throwing an exception here instead... - error = False # Check if file size is over the limit if max_file_size and file_size >= max_file_size: - submit_form.file.errors.append( - _(u'Sorry, the file size is too big.')) - error = True + raise FileUploadLimit() # Check if user is over upload limit if upload_limit and (user.uploaded + file_size) >= upload_limit: - submit_form.file.errors.append( - _('Sorry, uploading this file will put you over your' - ' upload limit.')) - error = True + raise UserUploadLimit() - if not error: - ####################################################3 - user.uploaded = user.uploaded + file_size - user.save() + user.uploaded = user.uploaded + file_size + user.save() - entry.file_size = file_size + entry.file_size = file_size - # Save now so we have this data before kicking off processing - entry.save() + # Save now so we have this data before kicking off processing + entry.save() - # Pass off to processing - # - # (... don't change entry after this point to avoid race - # conditions with changes to the document via processing code) - feed_url = request.urlgen( + if urlgen: + feed_url = urlgen( 'mediagoblin.user_pages.atom_feed', - qualified=True, user=request.user.username) - run_process_media(entry, feed_url) - add_message(request, SUCCESS, _('Woohoo! Submitted!')) + qualified=True, user=user.username) + else: + feed_url = None - add_comment_subscription(request.user, entry) + # Pass off to processing + # + # (... don't change entry after this point to avoid race + # conditions with changes to the document via processing code) + run_process_media(entry, feed_url) - return redirect(request, "mediagoblin.user_pages.user_home", - user=user.username) + add_comment_subscription(user, entry) def prepare_queue_task(app, entry, filename): diff --git a/mediagoblin/submit/views.py b/mediagoblin/submit/views.py index e0e2f1a5..dc618861 100644 --- a/mediagoblin/submit/views.py +++ b/mediagoblin/submit/views.py @@ -16,26 +16,21 @@ from mediagoblin import messages import mediagoblin.mg_globals as mg_globals -from os.path import splitext import logging -import uuid _log = logging.getLogger(__name__) -from mediagoblin.tools.text import convert_to_tag_list_of_dicts from mediagoblin.tools.translate import pass_to_ugettext as _ from mediagoblin.tools.response import render_to_response, redirect from mediagoblin.decorators import require_active_login, user_has_privilege from mediagoblin.submit import forms as submit_forms from mediagoblin.messages import add_message, SUCCESS -from mediagoblin.media_types import sniff_media, \ +from mediagoblin.media_types import \ InvalidFileType, FileTypeNotSupported -from mediagoblin.submit.lib import check_file_field, prepare_queue_task, \ - run_process_media, new_upload_entry - -from mediagoblin.notifications import add_comment_subscription +from mediagoblin.submit.lib import check_file_field, submit_media, \ + FileUploadLimit, UserUploadLimit, UserPastUploadLimit @require_active_login @@ -50,14 +45,6 @@ def submit_start(request): else: upload_limit = mg_globals.app_config.get('upload_limit', None) - if upload_limit and user.uploaded >= upload_limit: - messages.add_message( - request, - messages.WARNING, - _('Sorry, you have reached your upload limit.')) - return redirect(request, "mediagoblin.user_pages.user_home", - user=request.user.username) - max_file_size = mg_globals.app_config.get('max_file_size', None) submit_form = submit_forms.get_submit_start_form( @@ -73,83 +60,37 @@ def submit_start(request): _(u'You must provide a file.')) else: try: - filename = request.files['file'].filename - - # If the filename contains non ascii generate a unique name - if not all(ord(c) < 128 for c in filename): - filename = unicode(uuid.uuid4()) + splitext(filename)[-1] - - # Sniff the submitted media to determine which - # media plugin should handle processing - media_type, media_manager = sniff_media( - request.files['file']) - - # create entry and save in database - entry = new_upload_entry(request.user) - entry.media_type = unicode(media_type) - entry.title = ( - unicode(submit_form.title.data) - or unicode(splitext(request.files['file'].filename)[0])) - - entry.description = unicode(submit_form.description.data) - - entry.license = unicode(submit_form.license.data) or None - - # Process the user's folksonomy "tags" - entry.tags = convert_to_tag_list_of_dicts( - submit_form.tags.data) - - # Generate a slug from the title - entry.generate_slug() - - queue_file = prepare_queue_task(request.app, entry, filename) - - with queue_file: - queue_file.write(request.files['file'].stream.read()) - - # Get file size and round to 2 decimal places - file_size = request.app.queue_store.get_file_size( - entry.queued_media_file) / (1024.0 * 1024) - file_size = float('{0:.2f}'.format(file_size)) - - error = False - - # Check if file size is over the limit - if max_file_size and file_size >= max_file_size: - submit_form.file.errors.append( - _(u'Sorry, the file size is too big.')) - error = True - - # Check if user is over upload limit - if upload_limit and (user.uploaded + file_size) >= upload_limit: - submit_form.file.errors.append( - _('Sorry, uploading this file will put you over your' - ' upload limit.')) - error = True - - if not error: - user.uploaded = user.uploaded + file_size - user.save() - - entry.file_size = file_size - - # Save now so we have this data before kicking off processing - entry.save() - - # Pass off to processing - # - # (... don't change entry after this point to avoid race - # conditions with changes to the document via processing code) - feed_url = request.urlgen( - 'mediagoblin.user_pages.atom_feed', - qualified=True, user=request.user.username) - run_process_media(entry, feed_url) - add_message(request, SUCCESS, _('Woohoo! Submitted!')) - - add_comment_subscription(request.user, entry) + submit_media( + request.app, request.user, + request.files['file'], request.files['file'].filename, + unicode(submit_form.title.data), + unicode(submit_form.description.data), + unicode(submit_form.license.data) or None, + submit_form.tags.data, + upload_limit, max_file_size) + + add_message(request, SUCCESS, _('Woohoo! Submitted!')) + + return redirect(request, "mediagoblin.user_pages.user_home", + user=user.username) + + + # Handle upload limit issues + except FileUploadLimit: + submit_form.file.errors.append( + _(u'Sorry, the file size is too big.')) + except UserUploadLimit: + submit_form.file.errors.append( + _('Sorry, uploading this file will put you over your' + ' upload limit.')) + except UserPastUploadLimit: + messages.add_message( + request, + messages.WARNING, + _('Sorry, you have reached your upload limit.')) + return redirect(request, "mediagoblin.user_pages.user_home", + user=request.user.username) - return redirect(request, "mediagoblin.user_pages.user_home", - user=user.username) except Exception as e: ''' This section is intended to catch exceptions raised in