Commit | Line | Data |
---|---|---|
a062149e JW |
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 | |
4504dbba | 18 | import logging |
4504dbba JW |
19 | |
20 | from os.path import splitext | |
74af60bb | 21 | from werkzeug.datastructures import FileStorage |
62d14bf5 | 22 | from werkzeug.exceptions import BadRequest, Forbidden |
74af60bb | 23 | from werkzeug.wrappers import Response |
a062149e | 24 | |
4504dbba | 25 | from mediagoblin.decorators import require_active_login |
4504dbba | 26 | from mediagoblin.meddleware.csrf import csrf_exempt |
111a609d | 27 | from mediagoblin.media_types import sniff_media |
42c83752 JW |
28 | from mediagoblin.plugins.api.tools import api_auth, get_entry_serializable, \ |
29 | json_response | |
b228d897 | 30 | from mediagoblin.submit.lib import prepare_queue_task, run_process_media |
a062149e | 31 | |
4504dbba JW |
32 | _log = logging.getLogger(__name__) |
33 | ||
34 | ||
35 | @csrf_exempt | |
36 | @api_auth | |
37 | @require_active_login | |
38 | def post_entry(request): | |
39 | _log.debug('Posting entry') | |
09e528ac JW |
40 | |
41 | if request.method == 'OPTIONS': | |
42 | return json_response({'status': 200}) | |
43 | ||
4504dbba | 44 | if request.method != 'POST': |
09e528ac | 45 | _log.debug('Must POST against post_entry') |
cfa92229 | 46 | raise BadRequest() |
4504dbba | 47 | |
111a609d JW |
48 | if not 'file' in request.files \ |
49 | or not isinstance(request.files['file'], FileStorage) \ | |
50 | or not request.files['file'].stream: | |
09e528ac | 51 | _log.debug('File field not found') |
cfa92229 | 52 | raise BadRequest() |
4504dbba | 53 | |
111a609d | 54 | media_file = request.files['file'] |
4504dbba JW |
55 | |
56 | media_type, media_manager = sniff_media(media_file) | |
57 | ||
58 | entry = request.db.MediaEntry() | |
4504dbba | 59 | entry.media_type = unicode(media_type) |
111a609d | 60 | entry.title = unicode(request.form.get('title') |
4504dbba JW |
61 | or splitext(media_file.filename)[0]) |
62 | ||
111a609d JW |
63 | entry.description = unicode(request.form.get('description')) |
64 | entry.license = unicode(request.form.get('license', '')) | |
4504dbba JW |
65 | |
66 | entry.uploader = request.user.id | |
67 | ||
68 | entry.generate_slug() | |
69 | ||
4504dbba | 70 | # queue appropriately |
b228d897 | 71 | queue_file = prepare_queue_task(request.app, entry, media_file.filename) |
4504dbba JW |
72 | |
73 | with queue_file: | |
111a609d | 74 | queue_file.write(request.files['file'].stream.read()) |
4504dbba | 75 | |
4504dbba | 76 | # Save now so we have this data before kicking off processing |
b39d1f23 | 77 | entry.save() |
4504dbba | 78 | |
111a609d | 79 | if request.form.get('callback_url'): |
5354f954 JW |
80 | metadata = request.db.ProcessingMetaData() |
81 | metadata.media_entry = entry | |
111a609d | 82 | metadata.callback_url = unicode(request.form['callback_url']) |
5354f954 JW |
83 | metadata.save() |
84 | ||
4504dbba JW |
85 | # Pass off to processing |
86 | # | |
87 | # (... don't change entry after this point to avoid race | |
88 | # conditions with changes to the document via processing code) | |
37f90b43 | 89 | run_process_media(entry) |
4504dbba JW |
90 | |
91 | return json_response(get_entry_serializable(entry, request.urlgen)) | |
92 | ||
a062149e JW |
93 | |
94 | @api_auth | |
78fa73bc | 95 | @require_active_login |
a062149e | 96 | def api_test(request): |
a062149e JW |
97 | user_data = { |
98 | 'username': request.user.username, | |
99 | 'email': request.user.email} | |
100 | ||
74af60bb SS |
101 | # TODO: This is the *only* thing using Response() here, should that |
102 | # not simply use json_response()? | |
a062149e | 103 | return Response(json.dumps(user_data)) |
42c83752 JW |
104 | |
105 | ||
106 | def get_entries(request): | |
107 | entries = request.db.MediaEntry.query | |
108 | ||
c92aa0d0 | 109 | # TODO: Make it possible to fetch unprocessed media, or media in-processing |
42c83752 JW |
110 | entries = entries.filter_by(state=u'processed') |
111 | ||
c92aa0d0 JW |
112 | # TODO: Add sort order customization |
113 | entries = entries.order_by(request.db.MediaEntry.created.desc()) | |
114 | ||
115 | # TODO: Fetch default and upper limit from config | |
116 | entries = entries.limit(int(request.GET.get('limit') or 10)) | |
117 | ||
42c83752 JW |
118 | entries_serializable = [] |
119 | ||
120 | for entry in entries: | |
85726f73 | 121 | entries_serializable.append(get_entry_serializable(entry, request.urlgen)) |
42c83752 JW |
122 | |
123 | return json_response(entries_serializable) |