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!
This commit is contained in:
Christopher Allan Webber 2013-11-13 10:22:46 -06:00
parent 1779a0702f
commit 9e15c674ce
2 changed files with 84 additions and 116 deletions

View 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):

View File

@ -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
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)
# 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]
add_message(request, SUCCESS, _('Woohoo! Submitted!'))
# Sniff the submitted media to determine which
# media plugin should handle processing
media_type, media_manager = sniff_media(
request.files['file'])
return redirect(request, "mediagoblin.user_pages.user_home",
user=user.username)
# 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)
# 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)
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)
return redirect(request, "mediagoblin.user_pages.user_home",
user=user.username)
except Exception as e:
'''
This section is intended to catch exceptions raised in