forked from readthedocs/readthedocs.org
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdecorators.py
77 lines (62 loc) · 2.57 KB
/
decorators.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
from functools import wraps
import structlog
from django.db.models import Q
from django.http import Http404
from readthedocs.projects.models import Project, ProjectRelationship
log = structlog.get_logger(__name__) # noqa
def map_subproject_slug(view_func):
"""
A decorator that maps a ``subproject_slug`` URL param into a Project.
:raises: Http404 if the Project doesn't exist
.. warning:: Does not take into account any kind of privacy settings.
"""
@wraps(view_func)
def inner_view( # noqa
request, subproject=None, subproject_slug=None, *args, **kwargs
):
if subproject is None and subproject_slug:
# Try to fetch by subproject alias first, otherwise we might end up
# redirected to an unrelated project.
# Depends on a project passed into kwargs
rel = (
ProjectRelationship.objects.filter(parent=kwargs["project"])
.filter(Q(alias=subproject_slug) | Q(child__slug=subproject_slug))
.first()
)
if rel:
subproject = rel.child
else:
log.warning(
"The slug is not subproject of project.",
subproject_slug=subproject_slug,
project_slug=kwargs["project"].slug,
)
raise Http404("Invalid subproject slug")
return view_func(request, subproject=subproject, *args, **kwargs)
return inner_view
def map_project_slug(view_func):
"""
A decorator that maps a ``project_slug`` URL param into a Project.
:raises: Http404 if the Project doesn't exist
.. warning:: Does not take into account any kind of privacy settings.
"""
@wraps(view_func)
def inner_view( # noqa
request, project=None, project_slug=None, *args, **kwargs
):
if project is None:
# Get the project from the request if it can't be found in the URL
unresolved_domain = request.unresolved_domain
if unresolved_domain and not project_slug:
log.debug(
'Inserting project slug from request.',
project_slug=project_slug,
)
project = unresolved_domain.project
elif project_slug:
try:
project = Project.objects.get(slug=project_slug)
except Project.DoesNotExist:
raise Http404("Project does not exist.")
return view_func(request, project=project, *args, **kwargs)
return inner_view