Coverage for app/venv/lib/python3.14/site-packages/weblate/trans/views/js.py: 41%
62 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
6from typing import TYPE_CHECKING
8from django.contrib.auth.decorators import login_required
9from django.core.exceptions import PermissionDenied
10from django.db import transaction
11from django.http import HttpResponse, JsonResponse
12from django.shortcuts import get_object_or_404, render
13from django.utils.http import urlencode
14from django.views.decorators.cache import cache_control
15from django.views.decorators.http import require_POST
17from weblate.checks.flags import Flags
18from weblate.checks.models import Check
19from weblate.trans.models import Change, Component, Project, Translation, Unit
20from weblate.trans.util import sort_unicode
21from weblate.utils.views import parse_path
23if TYPE_CHECKING: 23 ↛ 24line 23 didn't jump to line 24 because the condition on line 23 was never true
24 from weblate.auth.models import AuthenticatedHttpRequest
27def get_unit_translations(request: AuthenticatedHttpRequest, unit_id):
28 """Return unit's other translations."""
29 unit = get_object_or_404(Unit, pk=int(unit_id))
30 user = request.user
31 user.check_access_component(unit.translation.component)
33 return render(
34 request,
35 "js/translations.html",
36 {
37 "units": sort_unicode(
38 unit.source_unit.unit_set.exclude(pk=unit.pk)
39 .prefetch()
40 .prefetch_full(),
41 user.profile.get_translation_orderer(request),
42 ),
43 "component": unit.translation.component,
44 },
45 )
48@require_POST
49@login_required
50@transaction.atomic
51def ignore_check(request: AuthenticatedHttpRequest, check_id):
52 obj = get_object_or_404(Check.objects.select_for_update(), pk=int(check_id))
54 if not request.user.has_perm("unit.check", obj):
55 raise PermissionDenied
57 # Mark check for ignoring
58 obj.set_dismiss(state="revert" not in request.GET)
59 # response for AJAX
60 return HttpResponse("ok")
63@require_POST
64@login_required
65@transaction.atomic
66def ignore_check_source(request: AuthenticatedHttpRequest, check_id):
67 obj = get_object_or_404(Check, pk=int(check_id))
68 unit = obj.unit.source_unit
70 if not request.user.has_perm("unit.check", obj) or not request.user.has_perm(
71 "source.edit", unit.translation.component
72 ):
73 raise PermissionDenied
75 # Mark check for ignoring
76 if obj.check_obj is None:
77 # Disabled check
78 ignore = f"ignore-{obj.name.replace('_', '-')}"
79 else:
80 ignore = obj.check_obj.ignore_string
81 flags = Flags(unit.extra_flags)
82 if ignore not in flags:
83 flags.merge(ignore)
84 unit.update_extra_flags(flags.format(), request.user)
86 # response for AJAX
87 return JsonResponse(
88 {
89 "extra_flags": unit.extra_flags,
90 "all_flags": obj.unit.all_flags.format(),
91 "ignore_check": ignore,
92 }
93 )
96@login_required
97def git_status(request: AuthenticatedHttpRequest, path):
98 obj = parse_path(request, path, (Project, Component, Translation))
99 if not request.user.has_perm("meta:vcs.status", obj):
100 raise PermissionDenied
102 repo_components = obj.all_repo_components
104 # Filter events from repository
105 changes = (
106 Change.objects.filter(
107 component__in=repo_components, action__in=Change.ACTIONS_REPOSITORY
108 )
109 .prefetch()
110 .recent()
111 )
113 # Get push label for the first component
114 try:
115 push_label = repo_components[0].repository_class.push_label
116 except IndexError:
117 push_label = ""
119 return render(
120 request,
121 "js/git-status.html",
122 {
123 "object": obj,
124 "changes": changes,
125 "changes_url_query": urlencode(
126 ("action", action) for action in Change.ACTIONS_REPOSITORY
127 ),
128 "repositories": repo_components,
129 "pending_units": obj.count_pending_units,
130 "outgoing_commits": sum(
131 repo.count_repo_outgoing for repo in repo_components
132 ),
133 "has_push_branch": any(repo.push_branch for repo in repo_components),
134 "push_branch_outgoing_commits": sum(
135 repo.count_push_branch_outgoing
136 for repo in repo_components
137 if repo.push_branch
138 ),
139 "missing_commits": sum(repo.count_repo_missing for repo in repo_components),
140 "supports_push": any(
141 repo.repository_class.supports_push for repo in repo_components
142 ),
143 "push_label": push_label,
144 },
145 )
148@cache_control(max_age=3600)
149def matomo(request: AuthenticatedHttpRequest):
150 return render(
151 request, "js/matomo.js", content_type='text/javascript; charset="utf-8"'
152 )