Coverage for app/venv/lib/python3.14/site-packages/weblate/trans/filter.py: 53%

49 statements  

« 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 

4 

5from __future__ import annotations 

6 

7from typing import TYPE_CHECKING 

8 

9from django.utils.functional import cached_property 

10from django.utils.text import format_lazy 

11from django.utils.translation import gettext, gettext_lazy 

12 

13from weblate.checks.models import CHECKS 

14 

15if TYPE_CHECKING: 15 ↛ 16line 15 didn't jump to line 16 because the condition on line 15 was never true

16 from django_stubs_ext import StrOrPromise 

17 

18 

19class FilterRegistry: 

20 @cached_property 

21 def full_list(self): 

22 result: list[tuple[str, StrOrPromise, str]] = [ 

23 ("all", gettext_lazy("All strings"), ""), 

24 ("readonly", gettext_lazy("Read-only strings"), "state:read-only"), 

25 ("nottranslated", gettext_lazy("Untranslated strings"), "state:empty"), 

26 ("todo", gettext_lazy("Unfinished strings"), "state:<translated"), 

27 ("translated", gettext_lazy("Translated strings"), "state:>=translated"), 

28 ("fuzzy", gettext_lazy("Strings marked for edit"), "state:needs-editing"), 

29 ("suggestions", gettext_lazy("Strings with suggestions"), "has:suggestion"), 

30 ("variants", gettext_lazy("Strings with variants"), "has:variant"), 

31 ("screenshots", gettext_lazy("Strings with screenshots"), "has:screenshot"), 

32 ("labels", gettext_lazy("Strings with labels"), "has:label"), 

33 ("context", gettext_lazy("Strings with context"), "has:context"), 

34 ( 

35 "nosuggestions", 

36 gettext_lazy("Unfinished strings without suggestions"), 

37 "state:<translated AND NOT has:suggestion", 

38 ), 

39 ("comments", gettext_lazy("Strings with comments"), "has:comment"), 

40 ("allchecks", gettext_lazy("Strings with any failing checks"), "has:check"), 

41 ( 

42 "translated_checks", 

43 gettext_lazy("Translated strings with any failing checks"), 

44 "has:check AND state:>=translated", 

45 ), 

46 ( 

47 "dismissed_checks", 

48 gettext_lazy("Translated strings with dismissed checks"), 

49 "has:dismissed-check", 

50 ), 

51 ("approved", gettext_lazy("Approved strings"), "state:approved"), 

52 ( 

53 "approved_suggestions", 

54 gettext_lazy("Approved strings with suggestions"), 

55 "state:approved AND has:suggestion", 

56 ), 

57 ( 

58 "unapproved", 

59 gettext_lazy("Strings waiting for review"), 

60 "state:translated", 

61 ), 

62 ( 

63 "noscreenshot", 

64 gettext_lazy("Strings without screenshots"), 

65 "NOT has:screenshot", 

66 ), 

67 ("unlabeled", gettext_lazy("Strings without a label"), "NOT has:label"), 

68 ("pluralized", gettext_lazy("Pluralized string"), "has:plural"), 

69 ] 

70 result.extend( 

71 ( 

72 CHECKS[check].url_id, 

73 format_lazy(gettext_lazy("Failing check: {}"), CHECKS[check].name), 

74 f"check:{check}", 

75 ) 

76 for check in CHECKS 

77 ) 

78 return result 

79 

80 @cached_property 

81 def search_name(self): 

82 return {x[2]: x[1] for x in self.full_list} 

83 

84 def get_search_name(self, query): 

85 try: 

86 return self.search_name[query.strip()] 

87 except KeyError: 

88 return gettext("Custom search") 

89 

90 @cached_property 

91 def id_name(self): 

92 return {x[0]: x[1] for x in self.full_list} 

93 

94 def get_filter_name(self, name): 

95 try: 

96 return self.id_name[name] 

97 except KeyError: 

98 if name.startswith("label:"): 

99 return gettext("Labeled: {}").format(gettext(name[6:])) 

100 raise 

101 

102 @cached_property 

103 def id_query(self): 

104 return {x[0]: x[2] for x in self.full_list} 

105 

106 def get_filter_query(self, name): 

107 try: 

108 return self.id_query[name] 

109 except KeyError: 

110 if name.startswith("label:"): 

111 return f'label:"{name[6:]}"' 

112 raise 

113 

114 

115FILTERS = FilterRegistry() 

116 

117 

118def get_filter_choice(project=None): 

119 """Return all filtering choices.""" 

120 result: list[tuple[str, StrOrPromise]] = [ 

121 ("all", gettext("All strings")), 

122 ("nottranslated", gettext("Untranslated strings")), 

123 ("todo", gettext("Unfinished strings")), 

124 ("translated", gettext("Translated strings")), 

125 ("fuzzy", gettext("Strings marked for edit")), 

126 ("suggestions", gettext("Strings with suggestions")), 

127 ("nosuggestions", gettext("Unfinished strings without suggestions")), 

128 ("comments", gettext("Strings with comments")), 

129 ("allchecks", gettext("Strings with any failing checks")), 

130 ("approved", gettext("Approved strings")), 

131 ("approved_suggestions", gettext("Approved strings with suggestions")), 

132 ("unapproved", gettext("Strings waiting for review")), 

133 ] 

134 result.extend( 

135 ( 

136 CHECKS[check].url_id, 

137 format_lazy(gettext("Failing check: {}"), CHECKS[check].name), 

138 ) 

139 for check in CHECKS 

140 ) 

141 if project is not None: 141 ↛ 142line 141 didn't jump to line 142 because the condition on line 141 was never true

142 result.extend( 

143 (f"label:{label}", format_lazy(gettext("Labeled: {}"), gettext(label))) 

144 for label in project.label_set.values_list("name", flat=True) 

145 ) 

146 return result