Refactoring submission utility to make it more generic! Reusable!
authorChristopher Allan Webber <cwebber@dustycloud.org>
Wed, 13 Nov 2013 16:22:46 +0000 (10:22 -0600)
committerChristopher Allan Webber <cwebber@dustycloud.org>
Wed, 13 Nov 2013 16:22:46 +0000 (10:22 -0600)
This commit sponsored by Joar Wandborg.  Joar, thanks for the many
things you've done for MediaGoblin!

mediagoblin/submit/lib.py
mediagoblin/submit/views.py

index bea39b2a3cab17cbe683e784558a0cbe44d78e5d..9036c4195366562e03b388d07036c4fbc7233a59 100644 (file)
@@ -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):
index e0e2f1a52fd1fe7772aa893f87970d886be3e88a..dc618861589cfd7331e705f67ebe97c4e56832de 100644 (file)
 
 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