Coverage for src / mesh / templatetags / mesh_tags.py: 73%

98 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-08-11 09:47 +0000

1import datetime 

2import re 

3from logging import getLogger 

4from typing import TYPE_CHECKING 

5 

6from dateutil.relativedelta import relativedelta 

7from django import template 

8from django.http import HttpRequest 

9from django.template.defaultfilters import stringfilter 

10from django.utils.html import mark_safe 

11from opentelemetry.trace import get_tracer 

12 

13from mesh.models.file_helpers import file_name as original_file_name 

14from mesh.models.orm.submission_models import SUBMISSION_STATE_CHOICES 

15from mesh.models.user.user_interfaces import ImpersonateData 

16from mesh.views.forms.role_forms import RoleSwitchForm 

17 

18if TYPE_CHECKING: 

19 pass 

20 

21register = template.Library() 

22 

23logger = getLogger(__name__) 

24tracer = get_tracer(__name__) 

25 

26 

27@register.filter 

28def render_attrs(attrs): 

29 """Render a Dict[str, List[str]] as HTML attributes.""" 

30 parts = [] 

31 for attr, values in attrs.items(): 

32 value = " ".join(str(v) for v in values) 

33 parts.append(f'{attr}="{value}"') 

34 return mark_safe(" ".join(parts)) 

35 

36 

37@register.filter 

38@stringfilter 

39def file_name(file_path: str) -> str: 

40 """ 

41 Returns the base name of a file from its path. 

42 """ 

43 return original_file_name(file_path) 

44 

45 

46@register.filter 

47@stringfilter 

48def role_switch_form(role_code: str) -> RoleSwitchForm: 

49 """ 

50 Returns a RoleSwitchForm whose POST switches the user current role to 

51 the provided role code. 

52 """ 

53 return RoleSwitchForm(initial={"role_code": role_code}) 

54 

55 

56@register.simple_tag(takes_context=True) 

57def check_rights(context, function_name: str, *args, **kwargs) -> bool: 

58 """ 

59 Wrapper around `RoleHandler.check_rights` method for use in template. 

60 """ 

61 role = context["request"].current_role 

62 fct = getattr(role, function_name, None) 

63 if not fct: 

64 logger.error(f"function {function_name} not found for role {role}") 

65 return False 

66 return fct(*args, **kwargs) 

67 

68 

69@register.filter 

70def get_impersonate_data(request: HttpRequest) -> ImpersonateData | None: 

71 return ImpersonateData.from_session(request.session) 

72 

73 

74@register.filter 

75@stringfilter 

76def filter_email(value): 

77 new_value = re.sub(r"\(.*\@.*\)", "", value) 

78 return new_value 

79 

80 

81@register.filter 

82def get_delay(date): 

83 today = datetime.date.today() 

84 

85 # delta = date - today 

86 delta = relativedelta(date, today) 

87 

88 days = delta.days 

89 weeks = delta.weeks 

90 months = delta.months 

91 years = delta.years 

92 abs_days = abs(days) 

93 abs_weeks = abs(weeks) 

94 abs_months = abs(months) 

95 abs_years = abs(years) 

96 

97 badge_class = "success" 

98 

99 if date == today: 

100 value = "today" 

101 badge_class = "warning" 

102 elif days == 1 and months == 0: 

103 value = "tomorrow" 

104 badge_class = "warning" 

105 elif days == -1 and months == 0: 

106 value = "yesterday" 

107 badge_class = "error" 

108 else: 

109 if abs_years == 1: 

110 value = "1 year" 

111 elif abs_years > 1: 

112 value = f"{abs_years} years" 

113 elif abs_months == 1: 

114 value = "1 month" 

115 elif abs_months > 1: 

116 value = f"{abs_months} months" 

117 elif days % 7 == 0: 

118 if abs_weeks == 1: 

119 value = "1 week" 

120 else: 

121 value = f"{abs_weeks} weeks" 

122 else: 

123 value = f"{abs_days} days" 

124 if abs_days < 7: 

125 badge_class = "warning" 

126 

127 if days > 0 or months > 0 or years > 1: 

128 value = "in " + value 

129 else: 

130 value = value + " ago" 

131 badge_class = "error" 

132 

133 value = f'<span class="badge rounded-pill badge-{badge_class}">{value}</span>' 

134 return value 

135 

136 

137@register.filter 

138@stringfilter 

139def get_state_display(value): 

140 results = [s[1] for s in SUBMISSION_STATE_CHOICES if s[0] == value] 

141 if len(results) > 0: 

142 value = results[0] 

143 return value