Committing extracted and compiled translations
[mediagoblin.git] / mediagoblin / decorators.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 from functools import wraps
18
19 from urlparse import urljoin
20 from urllib import urlencode
21
22 from webob import exc
23
24 from mediagoblin.db.util import ObjectId, InvalidId
25 from mediagoblin.tools.response import redirect, render_404
26
27
28 def require_active_login(controller):
29 """
30 Require an active login from the user.
31 """
32 @wraps(controller)
33 def new_controller_func(request, *args, **kwargs):
34 if request.user and \
35 request.user.get('status') == u'needs_email_verification':
36 return redirect(
37 request, 'mediagoblin.user_pages.user_home',
38 user=request.user.username)
39 elif not request.user or request.user.get('status') != u'active':
40 next_url = urljoin(
41 request.urlgen('mediagoblin.auth.login',
42 qualified=True),
43 request.url)
44
45 return exc.HTTPFound(
46 location='?'.join([
47 request.urlgen('mediagoblin.auth.login'),
48 urlencode({
49 'next': next_url})]))
50
51 return controller(request, *args, **kwargs)
52
53 return new_controller_func
54
55
56 def user_may_delete_media(controller):
57 """
58 Require user ownership of the MediaEntry to delete.
59 """
60 @wraps(controller)
61 def wrapper(request, *args, **kwargs):
62 uploader_id = request.db.MediaEntry.find_one(
63 {'_id': ObjectId(request.matchdict['media'])}).uploader
64 if not (request.user.is_admin or
65 request.user._id == uploader_id):
66 return exc.HTTPForbidden()
67
68 return controller(request, *args, **kwargs)
69
70 return wrapper
71
72
73 def user_may_alter_collection(controller):
74 """
75 Require user ownership of the Collection to modify.
76 """
77 @wraps(controller)
78 def wrapper(request, *args, **kwargs):
79 creator_id = request.db.User.find_one(
80 {'username': request.matchdict['user']}).id
81 if not (request.user.is_admin or
82 request.user._id == creator_id):
83 return exc.HTTPForbidden()
84
85 return controller(request, *args, **kwargs)
86
87 return wrapper
88
89
90 def uses_pagination(controller):
91 """
92 Check request GET 'page' key for wrong values
93 """
94 @wraps(controller)
95 def wrapper(request, *args, **kwargs):
96 try:
97 page = int(request.GET.get('page', 1))
98 if page < 0:
99 return render_404(request)
100 except ValueError:
101 return render_404(request)
102
103 return controller(request, page=page, *args, **kwargs)
104
105 return wrapper
106
107
108 def get_user_media_entry(controller):
109 """
110 Pass in a MediaEntry based off of a url component
111 """
112 @wraps(controller)
113 def wrapper(request, *args, **kwargs):
114 user = request.db.User.find_one(
115 {'username': request.matchdict['user']})
116
117 if not user:
118 return render_404(request)
119 media = request.db.MediaEntry.find_one(
120 {'slug': request.matchdict['media'],
121 'state': u'processed',
122 'uploader': user._id})
123
124 # no media via slug? Grab it via ObjectId
125 if not media:
126 try:
127 media = request.db.MediaEntry.find_one(
128 {'_id': ObjectId(request.matchdict['media']),
129 'state': u'processed',
130 'uploader': user._id})
131 except InvalidId:
132 return render_404(request)
133
134 # Still no media? Okay, 404.
135 if not media:
136 return render_404(request)
137
138 return controller(request, media=media, *args, **kwargs)
139
140 return wrapper
141
142
143 def get_user_collection(controller):
144 """
145 Pass in a Collection based off of a url component
146 """
147 @wraps(controller)
148 def wrapper(request, *args, **kwargs):
149 user = request.db.User.find_one(
150 {'username': request.matchdict['user']})
151
152 if not user:
153 return render_404(request)
154
155 collection = request.db.Collection.find_one(
156 {'slug': request.matchdict['collection'],
157 'creator': user._id})
158
159 # Still no collection? Okay, 404.
160 if not collection:
161 return render_404(request)
162
163 return controller(request, collection=collection, *args, **kwargs)
164
165 return wrapper
166
167
168 def get_user_collection_item(controller):
169 """
170 Pass in a CollectionItem based off of a url component
171 """
172 @wraps(controller)
173 def wrapper(request, *args, **kwargs):
174 user = request.db.User.find_one(
175 {'username': request.matchdict['user']})
176
177 if not user:
178 return render_404(request)
179
180 collection = request.db.Collection.find_one(
181 {'slug': request.matchdict['collection'],
182 'creator': user._id})
183
184 collection_item = request.db.CollectionItem.find_one(
185 {'_id': request.matchdict['collection_item'] })
186
187 # Still no collection item? Okay, 404.
188 if not collection_item:
189 return render_404(request)
190
191 return controller(request, collection_item=collection_item, *args, **kwargs)
192
193 return wrapper
194
195
196 def get_media_entry_by_id(controller):
197 """
198 Pass in a MediaEntry based off of a url component
199 """
200 @wraps(controller)
201 def wrapper(request, *args, **kwargs):
202 try:
203 media = request.db.MediaEntry.find_one(
204 {'_id': ObjectId(request.matchdict['media']),
205 'state': u'processed'})
206 except InvalidId:
207 return render_404(request)
208
209 # Still no media? Okay, 404.
210 if not media:
211 return render_404(request)
212
213 return controller(request, media=media, *args, **kwargs)
214
215 return wrapper