-
Notifications
You must be signed in to change notification settings - Fork 35
/
linklists.py
161 lines (122 loc) · 4.55 KB
/
linklists.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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
from __future__ import annotations
from typing import TYPE_CHECKING
from django.conf import settings
from django.db.models import Exists, OuterRef
from linkcheck import Linklist
from .models import (
Event,
EventTranslation,
ImprintPageTranslation,
LanguageTreeNode,
Organization,
Page,
PageTranslation,
POITranslation,
)
if TYPE_CHECKING:
from django.db.models.base import ModelBase
from django.db.models.query import QuerySet
class ActiveLanguageLinklist(Linklist):
"""
Base class for content translation link lists
"""
html_fields: list[str] = ["content"]
@classmethod
def filter_callable(cls, objects: QuerySet) -> QuerySet:
"""
Get only translations in active languages
:param objects: Objects to be filtered
:return: Objects that passed the filter
"""
# Because of large overhead, we only want this filter during the findlinks management command.
if settings.LINKCHECK_COMMAND_RUNNING:
# Exclude links in inactive languages
objects = objects.annotate(
active=Exists(
LanguageTreeNode.objects.filter(
region=OuterRef(f"{objects.model.foreign_field()}__region"),
language=OuterRef("language"),
active=True,
)
)
).filter(active=True)
return objects
class PageTranslationLinklist(ActiveLanguageLinklist):
"""
Class for selecting the PageTranslation model for link checks
"""
model: ModelBase = PageTranslation
@classmethod
def filter_callable(cls, objects: QuerySet) -> QuerySet:
"""
Get only latest versions for non-archived pages in active languages
:param objects: Objects to be filtered
:return: Objects that passed the filter
"""
# Apply filter of parent class
objects = super().filter_callable(objects)
# Because of large overhead, we only want this filter during the findlinks management command.
if settings.LINKCHECK_COMMAND_RUNNING:
# Exclude archived pages
pages = Page.objects.all().cache_tree(archived=False)
objects = objects.filter(page__in=pages)
return objects.distinct("page__pk", "language__pk")
class ImprintTranslationLinklist(ActiveLanguageLinklist):
"""
Class for selecting the ImprintPageTranslation model for linkchecks
"""
model: ModelBase = ImprintPageTranslation
class NonArchivedLinkList(ActiveLanguageLinklist):
"""
Class for excluding archived events and locations
"""
@classmethod
def filter_callable(cls, objects: QuerySet) -> QuerySet:
"""
Get only latest translations for non-archived events/locations in active languages
:param objects: Objects to be filtered
:return: Objects that passed the filter
"""
# Apply filter of parent class
objects = super().filter_callable(objects)
# Exclude archived events/locations
objects = objects.filter(
**{f"{objects.model.foreign_field()}__archived": False}
).distinct(f"{objects.model.foreign_field()}__pk", "language__pk")
return objects
class EventTranslationLinklist(NonArchivedLinkList):
"""
Class for selecting the EventTranslation model for link checks
"""
model: ModelBase = EventTranslation
@classmethod
def filter_callable(cls, objects: QuerySet) -> QuerySet:
"""
Get only translations of upcoming events in active languages
:param objects: Objects to be filtered
:return: Objects that passed the filter
"""
# Apply filter of parent class
objects = super().filter_callable(objects)
# Exclude past events
upcoming_events = Event.objects.filter_upcoming()
objects = objects.filter(event__in=upcoming_events)
return objects
class POITranslationLinklist(NonArchivedLinkList):
"""
Class for selecting the POITranslation model for link checks
"""
model: ModelBase = POITranslation
class OrganizationLinklist(Linklist):
"""
Class for selecting the Organization model for link checks
"""
model: ModelBase = Organization
url_fields = ["website"]
linklists = {
"PageTranslations": PageTranslationLinklist,
"EventTranslations": EventTranslationLinklist,
"POITranslations": POITranslationLinklist,
"ImprintPageTranslations": ImprintTranslationLinklist,
"Organizations": OrganizationLinklist,
}