Coverage for app/venv/lib/python3.14/site-packages/weblate/trans/context_processors.py: 72%
78 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 07:15 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 07:15 +0000
1# Copyright © Michal Čihař <michal@weblate.org>
2#
3# SPDX-License-Identifier: GPL-3.0-or-later
4from __future__ import annotations
6import random
7from typing import TYPE_CHECKING
8from urllib.parse import urlparse
10from django.conf import settings
11from django.utils.html import format_html
12from django.utils.http import url_has_allowed_host_and_scheme
13from django.utils.translation import gettext
15import weblate.utils.version
16from weblate.configuration.views import CustomCSSView
17from weblate.utils.site import get_site_domain, get_site_url
18from weblate.wladmin.models import ConfigurationError, get_support_status
20if TYPE_CHECKING: 20 ↛ 21line 20 didn't jump to line 21 because the condition on line 20 was never true
21 from weblate.auth.models import AuthenticatedHttpRequest
23WEBLATE_URL = "https://weblate.org/"
24DONATE_URL = "https://weblate.org/donate/"
25SUPPORT_URL = "https://weblate.org/support/"
27CONTEXT_SETTINGS = [
28 "SITE_TITLE",
29 "SITE_DOMAIN",
30 "ENABLE_HTTPS",
31 "OFFER_HOSTING",
32 "ENABLE_AVATARS",
33 "ENABLE_SHARING",
34 "MATOMO_SITE_ID",
35 "MATOMO_URL",
36 "GOOGLE_ANALYTICS_ID",
37 "ENABLE_HOOKS",
38 "REGISTRATION_OPEN",
39 "GET_HELP_URL",
40 "STATUS_URL",
41 "LEGAL_URL",
42 "PRIVACY_URL",
43 "FONTS_CDN_URL",
44 "AVATAR_URL_PREFIX",
45 "HIDE_VERSION",
46 "EXTRA_HTML_HEAD",
47 "PRIVATE_COMMIT_EMAIL_OPT_IN",
48 # Hosted Weblate integration
49 "PAYMENT_ENABLED",
50 "IP_ADDRESSES",
51]
53CONTEXT_APPS = ["billing", "legal", "gitexport"]
56def add_settings_context(context) -> None:
57 for name in CONTEXT_SETTINGS:
58 context[name.lower()] = getattr(settings, name, None)
61def add_optional_context(context) -> None:
62 for name in CONTEXT_APPS:
63 appname = f"weblate.{name}"
64 context[f"has_{name}"] = appname in settings.INSTALLED_APPS
67def get_preconnect_list():
68 result = []
69 if settings.MATOMO_URL: 69 ↛ 70line 69 didn't jump to line 70 because the condition on line 69 was never true
70 result.append(urlparse(settings.MATOMO_URL).hostname)
71 if settings.GOOGLE_ANALYTICS_ID: 71 ↛ 72line 71 didn't jump to line 72 because the condition on line 71 was never true
72 result.append("www.google-analytics.com")
73 return result
76def get_bread_image(path) -> str:
77 if path == "/": 77 ↛ 78line 77 didn't jump to line 78 because the condition on line 77 was never true
78 return "dashboard.svg"
79 first = path.split("/", 2)[1]
80 if first in {"user", "accounts"}: 80 ↛ 81line 80 didn't jump to line 81 because the condition on line 80 was never true
81 return "account.svg"
82 if first == "checks": 82 ↛ 83line 82 didn't jump to line 83 because the condition on line 82 was never true
83 return "alert.svg"
84 if first == "languages": 84 ↛ 85line 84 didn't jump to line 85 because the condition on line 84 was never true
85 return "language.svg"
86 if first == "manage": 86 ↛ 87line 86 didn't jump to line 87 because the condition on line 86 was never true
87 return "wrench.svg"
88 if first in {"about", "stats", "keys", "legal", "donate"}: 88 ↛ 89line 88 didn't jump to line 89 because the condition on line 88 was never true
89 return "weblate.svg"
90 if first in { 90 ↛ 96line 90 didn't jump to line 96 because the condition on line 90 was never true
91 "glossaries",
92 "upload-glossaries",
93 "delete-glossaries",
94 "edit-glossaries",
95 }:
96 return "glossary.svg"
97 return "project.svg"
100def get_interledger_payment_pointer() -> str:
101 interledger_payment_pointers: list[str] = []
102 if settings.INTERLEDGER_PAYMENT_BUILTIN: 102 ↛ 106line 102 didn't jump to line 106 because the condition on line 102 was always true
103 # Weblate funding
104 interledger_payment_pointers.append("$ilp.uphold.com/ENU7fREdeZi9")
106 interledger_payment_pointers.extend(settings.INTERLEDGER_PAYMENT_POINTERS)
108 if not interledger_payment_pointers: 108 ↛ 109line 108 didn't jump to line 109 because the condition on line 108 was never true
109 return None
111 return random.choice(interledger_payment_pointers) # noqa: S311
114def weblate_context(request: AuthenticatedHttpRequest):
115 """Context processor to inject various useful variables into context."""
116 if url_has_allowed_host_and_scheme(request.GET.get("next", ""), allowed_hosts=None): 116 ↛ 117line 116 didn't jump to line 117 because the condition on line 116 was never true
117 login_redirect_url = request.GET["next"]
118 elif request.resolver_match is None or ( 118 ↛ 124line 118 didn't jump to line 124 because the condition on line 118 was always true
119 not request.resolver_match.view_name.startswith("social:")
120 and request.resolver_match.view_name != "logout"
121 ):
122 login_redirect_url = request.get_full_path()
123 else:
124 login_redirect_url = ""
126 # Load user translations if user is authenticated
127 watched_projects = None
128 theme = "auto"
129 if hasattr(request, "user"): 129 ↛ 134line 129 didn't jump to line 134 because the condition on line 129 was always true
130 if request.user.is_authenticated: 130 ↛ 131line 130 didn't jump to line 131 because the condition on line 130 was never true
131 watched_projects = request.user.watched_projects
132 theme = request.user.profile.theme
134 if settings.OFFER_HOSTING: 134 ↛ 135line 134 didn't jump to line 135 because the condition on line 134 was never true
135 description = gettext(
136 "Hosted Weblate, the place to localize your software project."
137 )
138 else:
139 description = gettext(
140 "This site runs Weblate for localizing various software projects."
141 )
143 support_status = get_support_status(request)
145 context = {
146 "support_status": support_status,
147 "cache_param": f"?v={weblate.utils.version.GIT_VERSION}"
148 if not settings.COMPRESS_ENABLED
149 else "",
150 "version": weblate.utils.version.VERSION,
151 "bread_image": get_bread_image(request.path),
152 "description": description,
153 "weblate_link": format_html('<a href="{}">weblate.org</a>', WEBLATE_URL),
154 "weblate_name_link": format_html('<a href="{}">Weblate</a>', WEBLATE_URL),
155 "weblate_version_link": format_html(
156 '<a href="{}">Weblate {}</a>',
157 WEBLATE_URL,
158 "" if settings.HIDE_VERSION else weblate.utils.version.VERSION,
159 ),
160 "donate_url": DONATE_URL,
161 "support_url": SUPPORT_URL,
162 "site_url": get_site_url(),
163 "site_domain": get_site_domain(),
164 "login_redirect_url": login_redirect_url,
165 "has_antispam": False, # Akismet integration removed
166 "has_sentry": bool(settings.SENTRY_DSN),
167 "watched_projects": watched_projects,
168 "allow_index": False,
169 "configuration_errors": ConfigurationError.objects.filter(
170 ignored=False
171 ).order_by("-timestamp"),
172 "preconnect_list": get_preconnect_list(),
173 "custom_css_hash": CustomCSSView.get_hash(request),
174 "interledger_payment_pointer": get_interledger_payment_pointer(),
175 "theme": theme,
176 }
178 add_settings_context(context)
179 add_optional_context(context)
181 return context