forked from readthedocs/readthedocs.org
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdecorators.py
91 lines (76 loc) · 3.03 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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
from functools import wraps
import structlog
from readthedocs.projects.models import Project, ProjectRelationship
from readthedocs.proxito.exceptions import (
ProxitoProjectHttp404,
ProxitoSubProjectHttp404,
)
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'],
alias=subproject_slug,
).first()
if rel:
subproject = rel.child
else:
rel = ProjectRelationship.objects.filter(
parent=kwargs['project'],
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 ProxitoSubProjectHttp404(
"Invalid subproject slug", subproject_slug=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 a slug from the request if it can't be found in the URL
if not project_slug:
project_slug = getattr(request, 'host_project_slug', None)
log.debug(
'Inserting project slug from request.',
project_slug=project_slug,
)
try:
project = Project.objects.get(slug=project_slug)
except Project.DoesNotExist:
log.debug(
"Project not found.",
project_slug=project_slug,
)
raise ProxitoProjectHttp404(
"Project does not exist.", project_slug=project_slug
)
return view_func(request, project=project, *args, **kwargs)
return inner_view