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
|
from urllib.parse import urlparse
from django.contrib.postgres.search import SearchVector
from django.db.models import TextChoices
from django.db.models.fields.json import KeyTextTransform
from django.test import Client
from django.utils.translation import gettext_lazy as _
# Imported from
# https://github.com/postgres/postgres/blob/REL_14_STABLE/src/bin/initdb/initdb.c#L659
TSEARCH_CONFIG_LANGUAGES = {
"ar": "arabic",
"ca": "catalan",
"da": "danish",
"de": "german",
"el": "greek",
"en": "english",
"es": "spanish",
"eu": "basque",
"fi": "finnish",
"fr": "french",
"ga": "irish",
"hi": "hindi",
"hu": "hungarian",
"hy": "armenian",
"id": "indonesian",
"it": "italian",
"lt": "lithuanian",
"ne": "nepali",
"nl": "dutch",
"no": "norwegian",
"pt": "portuguese",
"ro": "romanian",
"ru": "russian",
"sr": "serbian",
"sv": "swedish",
"ta": "tamil",
"tr": "turkish",
"yi": "yiddish",
}
# Imported from
# https://github.com/postgres/postgres/blob/REL_14_STABLE/src/bin/initdb/initdb.c#L2557
DEFAULT_TEXT_SEARCH_CONFIG = "simple"
def get_document_search_vector(lang=DEFAULT_TEXT_SEARCH_CONFIG):
"""Return the search vector with the proper language config."""
return (
SearchVector("title", weight="A", config=lang)
+ SearchVector(KeyTextTransform("slug", "metadata"), weight="A", config=lang)
+ SearchVector(KeyTextTransform("toc", "metadata"), weight="B", config=lang)
+ SearchVector(KeyTextTransform("body", "metadata"), weight="C", config=lang)
+ SearchVector(KeyTextTransform("parents", "metadata"), weight="D", config=lang)
)
START_SEL = "<mark>"
STOP_SEL = "</mark>"
class DocumentationCategory(TextChoices):
"""
Categories used to filter the documentation search.
The value must match a folder name within django/docs.
"""
# Diátaxis folders.
REFERENCE = "ref", _("API Reference")
TOPICS = "topics", _("Using Django")
HOWTO = "howto", _("How-to guides")
RELEASE_NOTES = "releases", _("Release notes")
WEBSITE = "website", _("Django Website")
@classmethod
def parse(cls, value, default=None):
try:
return cls(value)
except ValueError:
return None
def fetch_html(url):
parsed = urlparse(url)
headers = {"HOST": parsed.netloc} # Use netloc to include the port.
client = Client(headers=headers, raise_request_exception=False)
response = client.get(parsed.path)
content_type = response.headers.get("Content-Type", "")
if response.status_code == 200 and "text/html" in content_type:
return response.text
raise ValueError(
f"Failed to fetch {url}, "
f"status code: {response.status_code}, "
f"Content-Type: {content_type}"
)
|