1 # GNU MediaGoblin -- federated, autonomous media hosting
2 # Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
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.
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.
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/>.
17 from functools
import wraps
19 from urlparse
import urljoin
20 from werkzeug
.exceptions
import Forbidden
, NotFound
21 from werkzeug
.urls
import url_quote
23 from mediagoblin
import mg_globals
as mgg
24 from mediagoblin
.db
.models
import MediaEntry
, User
25 from mediagoblin
.tools
.response
import redirect
, render_404
28 def require_active_login(controller
):
30 Require an active login from the user.
33 def new_controller_func(request
, *args
, **kwargs
):
35 request
.user
.status
== u
'needs_email_verification':
37 request
, 'mediagoblin.user_pages.user_home',
38 user
=request
.user
.username
)
39 elif not request
.user
or request
.user
.status
!= u
'active':
41 request
.urlgen('mediagoblin.auth.login',
45 return redirect(request
, 'mediagoblin.auth.login',
46 next
=url_quote(next_url
))
48 return controller(request
, *args
, **kwargs
)
50 return new_controller_func
52 def active_user_from_url(controller
):
53 """Retrieve User() from <user> URL pattern and pass in as url_user=...
55 Returns a 404 if no such active user has been found"""
57 def wrapper(request
, *args
, **kwargs
):
58 user
= User
.query
.filter_by(username
=request
.matchdict
['user']).first()
60 return render_404(request
)
62 return controller(request
, *args
, url_user
=user
, **kwargs
)
67 def user_may_delete_media(controller
):
69 Require user ownership of the MediaEntry to delete.
72 def wrapper(request
, *args
, **kwargs
):
73 uploader_id
= kwargs
['media'].uploader
74 if not (request
.user
.is_admin
or
75 request
.user
.id == uploader_id
):
78 return controller(request
, *args
, **kwargs
)
83 def user_may_alter_collection(controller
):
85 Require user ownership of the Collection to modify.
88 def wrapper(request
, *args
, **kwargs
):
89 creator_id
= request
.db
.User
.find_one(
90 {'username': request
.matchdict
['user']}).id
91 if not (request
.user
.is_admin
or
92 request
.user
.id == creator_id
):
95 return controller(request
, *args
, **kwargs
)
100 def uses_pagination(controller
):
102 Check request GET 'page' key for wrong values
105 def wrapper(request
, *args
, **kwargs
):
107 page
= int(request
.GET
.get('page', 1))
109 return render_404(request
)
111 return render_404(request
)
113 return controller(request
, page
=page
, *args
, **kwargs
)
118 def get_user_media_entry(controller
):
120 Pass in a MediaEntry based off of a url component
123 def wrapper(request
, *args
, **kwargs
):
124 user
= User
.query
.filter_by(username
=request
.matchdict
['user']).first()
128 media
= MediaEntry
.query
.filter_by(
129 slug
= request
.matchdict
['media'],
130 state
= u
'processed',
131 uploader
= user
.id).first()
134 # no media via slug? Grab it via object id
136 media
= MediaEntry
.query
.filter_by(
137 id = int(request
.matchdict
['media']),
138 state
= u
'processed',
139 uploader
= user
.id).first()
141 # media "id" was no int
145 # no media by that id? Okay, 404.
148 return controller(request
, media
=media
, *args
, **kwargs
)
153 def get_user_collection(controller
):
155 Pass in a Collection based off of a url component
158 def wrapper(request
, *args
, **kwargs
):
159 user
= request
.db
.User
.find_one(
160 {'username': request
.matchdict
['user']})
163 return render_404(request
)
165 collection
= request
.db
.Collection
.find_one(
166 {'slug': request
.matchdict
['collection'],
169 # Still no collection? Okay, 404.
171 return render_404(request
)
173 return controller(request
, collection
=collection
, *args
, **kwargs
)
178 def get_user_collection_item(controller
):
180 Pass in a CollectionItem based off of a url component
183 def wrapper(request
, *args
, **kwargs
):
184 user
= request
.db
.User
.find_one(
185 {'username': request
.matchdict
['user']})
188 return render_404(request
)
190 collection
= request
.db
.Collection
.find_one(
191 {'slug': request
.matchdict
['collection'],
194 collection_item
= request
.db
.CollectionItem
.find_one(
195 {'id': request
.matchdict
['collection_item'] })
197 # Still no collection item? Okay, 404.
198 if not collection_item
:
199 return render_404(request
)
201 return controller(request
, collection_item
=collection_item
, *args
, **kwargs
)
206 def get_media_entry_by_id(controller
):
208 Pass in a MediaEntry based off of a url component
211 def wrapper(request
, *args
, **kwargs
):
212 media
= MediaEntry
.query
.filter_by(
213 id=request
.matchdict
['media_id'],
214 state
=u
'processed').first()
215 # Still no media? Okay, 404.
217 return render_404(request
)
219 given_username
= request
.matchdict
.get('user')
220 if given_username
and (given_username
!= media
.get_uploader
.username
):
221 return render_404(request
)
223 return controller(request
, media
=media
, *args
, **kwargs
)
228 def get_workbench(func
):
229 """Decorator, passing in a workbench as kwarg which is cleaned up afterwards"""
232 def new_func(*args
, **kwargs
):
233 with mgg
.workbench_manager
.create() as workbench
:
234 return func(*args
, workbench
=workbench
, **kwargs
)