Merge remote-tracking branch 'aleksej/632_config_spec_comment_typo'
[mediagoblin.git] / mediagoblin / plugins / api / views.py
CommitLineData
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
17import json
4504dbba 18import logging
4504dbba
JW
19
20from os.path import splitext
74af60bb 21from werkzeug.datastructures import FileStorage
62d14bf5 22from werkzeug.exceptions import BadRequest, Forbidden
74af60bb 23from werkzeug.wrappers import Response
a062149e 24
4504dbba 25from mediagoblin.decorators import require_active_login
4504dbba 26from mediagoblin.meddleware.csrf import csrf_exempt
111a609d 27from mediagoblin.media_types import sniff_media
42c83752
JW
28from mediagoblin.plugins.api.tools import api_auth, get_entry_serializable, \
29 json_response
b228d897 30from 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
38def 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)
c7b3d070
SS
89 feed_url = request.urlgen(
90 'mediagoblin.user_pages.atom_feed',
91 qualified=True, user=request.user.username)
92 run_process_media(entry, feed_url)
4504dbba
JW
93
94 return json_response(get_entry_serializable(entry, request.urlgen))
95
a062149e
JW
96
97@api_auth
78fa73bc 98@require_active_login
a062149e 99def api_test(request):
a062149e
JW
100 user_data = {
101 'username': request.user.username,
102 'email': request.user.email}
103
74af60bb
SS
104 # TODO: This is the *only* thing using Response() here, should that
105 # not simply use json_response()?
a062149e 106 return Response(json.dumps(user_data))
42c83752
JW
107
108
109def get_entries(request):
110 entries = request.db.MediaEntry.query
111
c92aa0d0 112 # TODO: Make it possible to fetch unprocessed media, or media in-processing
42c83752
JW
113 entries = entries.filter_by(state=u'processed')
114
c92aa0d0
JW
115 # TODO: Add sort order customization
116 entries = entries.order_by(request.db.MediaEntry.created.desc())
117
118 # TODO: Fetch default and upper limit from config
119 entries = entries.limit(int(request.GET.get('limit') or 10))
120
42c83752
JW
121 entries_serializable = []
122
123 for entry in entries:
85726f73 124 entries_serializable.append(get_entry_serializable(entry, request.urlgen))
42c83752
JW
125
126 return json_response(entries_serializable)