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
« 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
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
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
18if TYPE_CHECKING:
19 pass
21register = template.Library()
23logger = getLogger(__name__)
24tracer = get_tracer(__name__)
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))
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)
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})
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)
69@register.filter
70def get_impersonate_data(request: HttpRequest) -> ImpersonateData | None:
71 return ImpersonateData.from_session(request.session)
74@register.filter
75@stringfilter
76def filter_email(value):
77 new_value = re.sub(r"\(.*\@.*\)", "", value)
78 return new_value
81@register.filter
82def get_delay(date):
83 today = datetime.date.today()
85 # delta = date - today
86 delta = relativedelta(date, today)
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)
97 badge_class = "success"
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"
127 if days > 0 or months > 0 or years > 1:
128 value = "in " + value
129 else:
130 value = value + " ago"
131 badge_class = "error"
133 value = f'<span class="badge rounded-pill badge-{badge_class}">{value}</span>'
134 return value
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