Commit | Line | Data |
---|---|---|
427beb08 E |
1 | # GNU MediaGoblin -- federated, autonomous media hosting |
2 | # Copyright (C) 2013 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 logging | |
398d3841 | 18 | import re |
c732f422 JW |
19 | from os.path import splitext |
20 | import shutil | |
427beb08 | 21 | |
90d7de25 | 22 | from werkzeug.exceptions import MethodNotAllowed, BadRequest, NotImplemented |
e4e5948c | 23 | from werkzeug.wrappers import BaseResponse |
427beb08 E |
24 | |
25 | from mediagoblin.meddleware.csrf import csrf_exempt | |
7fb419dd | 26 | from mediagoblin.auth.lib import fake_login_attempt |
c732f422 JW |
27 | from mediagoblin.media_types import sniff_media |
28 | from mediagoblin.submit.lib import check_file_field, prepare_queue_task, \ | |
29 | run_process_media | |
30 | ||
7fb419dd E |
31 | from .tools import CmdTable, PwgNamedArray, response_xml, check_form, \ |
32 | PWGSession | |
c1df8d19 | 33 | from .forms import AddSimpleForm, AddForm |
427beb08 E |
34 | |
35 | ||
36 | _log = logging.getLogger(__name__) | |
37 | ||
38 | ||
427beb08 E |
39 | @CmdTable("pwg.session.login", True) |
40 | def pwg_login(request): | |
41 | username = request.form.get("username") | |
42 | password = request.form.get("password") | |
f035ec3d | 43 | _log.debug("Login for %r/%r...", username, password) |
7fb419dd E |
44 | user = request.db.User.query.filter_by(username=username).first() |
45 | if not user: | |
f035ec3d | 46 | _log.info("User %r not found", username) |
7fb419dd E |
47 | fake_login_attempt() |
48 | return False | |
49 | if not user.check_login(password): | |
f035ec3d | 50 | _log.warn("Wrong password for %r", username) |
7fb419dd | 51 | return False |
f035ec3d | 52 | _log.info("Logging %r in", username) |
7fb419dd E |
53 | request.session["user_id"] = user.id |
54 | request.session.save() | |
e4e5948c | 55 | return True |
bd3bc044 E |
56 | |
57 | ||
58 | @CmdTable("pwg.session.logout") | |
59 | def pwg_logout(request): | |
60 | _log.info("Logout") | |
7fb419dd | 61 | request.session.delete() |
e4e5948c | 62 | return True |
bd3bc044 E |
63 | |
64 | ||
65 | @CmdTable("pwg.getVersion") | |
66 | def pwg_getversion(request): | |
9924cd0f | 67 | return "2.5.0 (MediaGoblin)" |
cf0816c1 E |
68 | |
69 | ||
70 | @CmdTable("pwg.session.getStatus") | |
71 | def pwg_session_getStatus(request): | |
66594603 E |
72 | if request.user: |
73 | username = request.user.username | |
74 | else: | |
75 | username = "guest" | |
76 | return {'username': username} | |
e4e5948c E |
77 | |
78 | ||
79 | @CmdTable("pwg.categories.getList") | |
80 | def pwg_categories_getList(request): | |
cf0816c1 E |
81 | catlist = ({'id': -29711, |
82 | 'uppercats': "-29711", | |
83 | 'name': "All my images"},) | |
e4e5948c E |
84 | return { |
85 | 'categories': PwgNamedArray( | |
86 | catlist, | |
87 | 'category', | |
88 | ( | |
89 | 'id', | |
90 | 'url', | |
91 | 'nb_images', | |
92 | 'total_nb_images', | |
93 | 'nb_categories', | |
94 | 'date_last', | |
95 | 'max_date_last', | |
96 | ) | |
97 | ) | |
98 | } | |
427beb08 E |
99 | |
100 | ||
398d3841 E |
101 | @CmdTable("pwg.images.exist") |
102 | def pwg_images_exist(request): | |
103 | return {} | |
104 | ||
105 | ||
79f87b97 E |
106 | @CmdTable("pwg.images.addSimple", True) |
107 | def pwg_images_addSimple(request): | |
108 | form = AddSimpleForm(request.form) | |
109 | if not form.validate(): | |
110 | _log.error("addSimple: form failed") | |
111 | raise BadRequest() | |
112 | dump = [] | |
113 | for f in form: | |
114 | dump.append("%s=%r" % (f.name, f.data)) | |
115 | _log.info("addimple: %r %s %r", request.form, " ".join(dump), request.files) | |
116 | ||
f6f55769 E |
117 | if not check_file_field(request, 'image'): |
118 | raise BadRequest() | |
119 | ||
c732f422 JW |
120 | filename = request.files['image'].filename |
121 | ||
122 | # Sniff the submitted media to determine which | |
123 | # media plugin should handle processing | |
124 | media_type, media_manager = sniff_media( | |
125 | request.files['image']) | |
126 | ||
127 | # create entry and save in database | |
128 | entry = request.db.MediaEntry() | |
129 | entry.media_type = unicode(media_type) | |
130 | entry.title = ( | |
131 | unicode(form.name.data) | |
132 | or unicode(splitext(filename)[0])) | |
133 | ||
134 | entry.description = unicode(form.comment.data) | |
135 | ||
136 | # entry.license = unicode(form.license.data) or None | |
137 | ||
138 | entry.uploader = request.user.id | |
139 | ||
140 | ''' | |
141 | # Process the user's folksonomy "tags" | |
142 | entry.tags = convert_to_tag_list_of_dicts( | |
143 | form.tags.data) | |
144 | ''' | |
145 | ||
146 | # Generate a slug from the title | |
147 | entry.generate_slug() | |
148 | ||
149 | queue_file = prepare_queue_task(request.app, entry, filename) | |
150 | ||
151 | with queue_file: | |
152 | shutil.copyfileobj(request.files['image'].stream, | |
153 | queue_file, | |
154 | length=4 * 1048576) | |
155 | ||
156 | # Save now so we have this data before kicking off processing | |
157 | entry.save() | |
158 | ||
159 | # Pass off to processing | |
160 | # | |
161 | # (... don't change entry after this point to avoid race | |
162 | # conditions with changes to the document via processing code) | |
163 | feed_url = request.urlgen( | |
164 | 'mediagoblin.user_pages.atom_feed', | |
165 | qualified=True, user=request.user.username) | |
166 | run_process_media(entry, feed_url) | |
167 | ||
168 | return {'image_id': entry.id, 'url': entry.url_for_self(request.urlgen, | |
169 | qualified=True)} | |
170 | ||
79f87b97 | 171 | |
398d3841 E |
172 | md5sum_matcher = re.compile(r"^[0-9a-fA-F]{32}$") |
173 | ||
c732f422 | 174 | |
398d3841 E |
175 | def fetch_md5(request, parm_name, optional_parm=False): |
176 | val = request.form.get(parm_name) | |
177 | if (val is None) and (not optional_parm): | |
178 | _log.error("Parameter %s missing", parm_name) | |
179 | raise BadRequest("Parameter %s missing" % parm_name) | |
180 | if not md5sum_matcher.match(val): | |
181 | _log.error("Parameter %s=%r has no valid md5 value", parm_name, val) | |
182 | raise BadRequest("Parameter %s is not md5" % parm_name) | |
183 | return val | |
184 | ||
185 | ||
186 | @CmdTable("pwg.images.addChunk", True) | |
187 | def pwg_images_addChunk(request): | |
188 | o_sum = fetch_md5(request, 'original_sum') | |
189 | typ = request.form.get('type') | |
190 | pos = request.form.get('position') | |
191 | data = request.form.get('data') | |
192 | ||
193 | # Validate params: | |
194 | pos = int(pos) | |
195 | if not typ in ("file", "thumb"): | |
196 | _log.error("type %r not allowed for now", typ) | |
197 | return False | |
198 | ||
199 | _log.info("addChunk for %r, type %r, position %d, len: %d", | |
200 | o_sum, typ, pos, len(data)) | |
201 | if typ == "thumb": | |
202 | _log.info("addChunk: Ignoring thumb, because we create our own") | |
203 | return True | |
204 | ||
205 | return True | |
206 | ||
207 | ||
c1df8d19 E |
208 | @CmdTable("pwg.images.add", True) |
209 | def pwg_images_add(request): | |
210 | _log.info("add: %r", request.form) | |
211 | form = AddForm(request.form) | |
212 | check_form(form) | |
213 | ||
214 | return {'image_id': 123456, 'url': ''} | |
215 | ||
216 | ||
427beb08 E |
217 | @csrf_exempt |
218 | def ws_php(request): | |
219 | if request.method not in ("GET", "POST"): | |
220 | _log.error("Method %r not supported", request.method) | |
221 | raise MethodNotAllowed() | |
222 | ||
223 | func = CmdTable.find_func(request) | |
224 | if not func: | |
225 | _log.warn("wsphp: Unhandled %s %r %r", request.method, | |
226 | request.args, request.form) | |
90d7de25 | 227 | raise NotImplemented() |
427beb08 | 228 | |
7fb419dd E |
229 | with PWGSession(request) as session: |
230 | result = func(request) | |
427beb08 | 231 | |
7fb419dd E |
232 | if isinstance(result, BaseResponse): |
233 | return result | |
e4e5948c | 234 | |
7fb419dd E |
235 | response = response_xml(result) |
236 | session.save_to_cookie(response) | |
dc7c26f3 | 237 | |
7fb419dd | 238 | return response |