Merge remote-tracking branch 'refs/remotes/spaetz/WIP/user_tag_gallery'
[mediagoblin.git] / mediagoblin / plugins / api / views.py
... / ...
CommitLineData
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
18import logging
19
20from os.path import splitext
21from werkzeug.datastructures import FileStorage
22from werkzeug.exceptions import BadRequest, Forbidden
23from werkzeug.wrappers import Response
24
25from mediagoblin.decorators import require_active_login
26from mediagoblin.meddleware.csrf import csrf_exempt
27from mediagoblin.media_types import sniff_media
28from mediagoblin.plugins.api.tools import api_auth, get_entry_serializable, \
29 json_response
30from mediagoblin.submit.lib import prepare_queue_task, run_process_media
31
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')
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 'file' in request.files \
49 or not isinstance(request.files['file'], FileStorage) \
50 or not request.files['file'].stream:
51 _log.debug('File field not found')
52 raise BadRequest()
53
54 media_file = request.files['file']
55
56 media_type, media_manager = sniff_media(media_file)
57
58 entry = request.db.MediaEntry()
59 entry.media_type = unicode(media_type)
60 entry.title = unicode(request.form.get('title')
61 or splitext(media_file.filename)[0])
62
63 entry.description = unicode(request.form.get('description'))
64 entry.license = unicode(request.form.get('license', ''))
65
66 entry.uploader = request.user.id
67
68 entry.generate_slug()
69
70 # queue appropriately
71 queue_file = prepare_queue_task(request.app, entry, media_file.filename)
72
73 with queue_file:
74 queue_file.write(request.files['file'].stream.read())
75
76 # Save now so we have this data before kicking off processing
77 entry.save()
78
79 if request.form.get('callback_url'):
80 metadata = request.db.ProcessingMetaData()
81 metadata.media_entry = entry
82 metadata.callback_url = unicode(request.form['callback_url'])
83 metadata.save()
84
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)
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)
93
94 return json_response(get_entry_serializable(entry, request.urlgen))
95
96
97@api_auth
98@require_active_login
99def api_test(request):
100 user_data = {
101 'username': request.user.username,
102 'email': request.user.email}
103
104 # TODO: This is the *only* thing using Response() here, should that
105 # not simply use json_response()?
106 return Response(json.dumps(user_data))
107
108
109def get_entries(request):
110 entries = request.db.MediaEntry.query
111
112 # TODO: Make it possible to fetch unprocessed media, or media in-processing
113 entries = entries.filter_by(state=u'processed')
114
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
121 entries_serializable = []
122
123 for entry in entries:
124 entries_serializable.append(get_entry_serializable(entry, request.urlgen))
125
126 return json_response(entries_serializable)