| 1 | # GNU MediaGoblin -- federated, autonomous media hosting |
| 2 | # Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. |
| 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 | |
| 17 | import json |
| 18 | import logging |
| 19 | |
| 20 | import six |
| 21 | |
| 22 | from werkzeug.exceptions import BadRequest |
| 23 | from werkzeug.wrappers import Response |
| 24 | |
| 25 | from mediagoblin.tools.translate import pass_to_ugettext as _ |
| 26 | from mediagoblin.tools.response import json_response |
| 27 | from mediagoblin.decorators import require_active_login |
| 28 | from mediagoblin.meddleware.csrf import csrf_exempt |
| 29 | from mediagoblin.media_types import FileTypeNotSupported |
| 30 | from mediagoblin.plugins.api.tools import api_auth, get_entry_serializable |
| 31 | from mediagoblin.submit.lib import \ |
| 32 | check_file_field, submit_media, get_upload_file_limits, \ |
| 33 | FileUploadLimit, UserUploadLimit, UserPastUploadLimit |
| 34 | |
| 35 | _log = logging.getLogger(__name__) |
| 36 | |
| 37 | |
| 38 | @csrf_exempt |
| 39 | @api_auth |
| 40 | @require_active_login |
| 41 | def post_entry(request): |
| 42 | _log.debug('Posting entry') |
| 43 | |
| 44 | if request.method == 'OPTIONS': |
| 45 | return json_response({'status': 200}) |
| 46 | |
| 47 | if request.method != 'POST': |
| 48 | _log.debug('Must POST against post_entry') |
| 49 | raise BadRequest() |
| 50 | |
| 51 | if not check_file_field(request, 'file'): |
| 52 | _log.debug('File field not found') |
| 53 | raise BadRequest() |
| 54 | |
| 55 | callback_url = request.form.get('callback_url') |
| 56 | if callback_url: |
| 57 | callback_url = six.text_type(callback_url) |
| 58 | try: |
| 59 | entry = submit_media( |
| 60 | mg_app=request.app, user=request.user, |
| 61 | submitted_file=request.files['file'], |
| 62 | filename=request.files['file'].filename, |
| 63 | title=six.text_type(request.form.get('title')), |
| 64 | description=six.text_type(request.form.get('description')), |
| 65 | license=six.text_type(request.form.get('license', '')), |
| 66 | tags_string=six.text_type(request.form.get('tags', '')), |
| 67 | callback_url=callback_url) |
| 68 | |
| 69 | return json_response(get_entry_serializable(entry, request.urlgen)) |
| 70 | |
| 71 | # Handle upload limit issues |
| 72 | except FileUploadLimit: |
| 73 | raise BadRequest( |
| 74 | _(u'Sorry, the file size is too big.')) |
| 75 | except UserUploadLimit: |
| 76 | raise BadRequest( |
| 77 | _('Sorry, uploading this file will put you over your' |
| 78 | ' upload limit.')) |
| 79 | except UserPastUploadLimit: |
| 80 | raise BadRequest( |
| 81 | _('Sorry, you have reached your upload limit.')) |
| 82 | except FileTypeNotSupported as e: |
| 83 | raise BadRequest(e) |
| 84 | |
| 85 | |
| 86 | @api_auth |
| 87 | @require_active_login |
| 88 | def api_test(request): |
| 89 | user_data = { |
| 90 | 'username': request.user.username, |
| 91 | 'email': request.user.email} |
| 92 | |
| 93 | # TODO: This is the *only* thing using Response() here, should that |
| 94 | # not simply use json_response()? |
| 95 | return Response(json.dumps(user_data, sort_keys=True)) |
| 96 | |
| 97 | |
| 98 | def get_entries(request): |
| 99 | entries = request.db.MediaEntry.query |
| 100 | |
| 101 | # TODO: Make it possible to fetch unprocessed media, or media in-processing |
| 102 | entries = entries.filter_by(state=u'processed') |
| 103 | |
| 104 | # TODO: Add sort order customization |
| 105 | entries = entries.order_by(request.db.MediaEntry.created.desc()) |
| 106 | |
| 107 | # TODO: Fetch default and upper limit from config |
| 108 | entries = entries.limit(int(request.GET.get('limit') or 10)) |
| 109 | |
| 110 | entries_serializable = [] |
| 111 | |
| 112 | for entry in entries: |
| 113 | entries_serializable.append(get_entry_serializable(entry, request.urlgen)) |
| 114 | |
| 115 | return json_response(entries_serializable) |