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