Coverage for webapp/template_utils.py: 97%
67 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-28 22:05 +0000
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-28 22:05 +0000
1# Core
2import hashlib
3import os
5from dateutil import parser
7from emoji import replace_emoji
10# generator functions for templates
11def generate_slug(path):
12 """
13 Generate a slug for each page
14 """
15 if path.endswith(
16 (
17 "/snaps",
18 "/listing",
19 "/releases",
20 "/metrics",
21 "/publicise",
22 "/publicise/badges",
23 "/publicise/cards",
24 "/settings",
25 "/account/details",
26 )
27 ):
28 return "account"
30 if path == "/" or path.startswith("/first-snap"):
31 return "home"
33 if path.startswith("/build"):
34 return "build"
36 if path.startswith("/blog"):
37 return "blog"
39 if path.startswith("/iot"):
40 return "iot"
42 if path.startswith("/docs/snap-tutorials"):
43 return "tutorials"
45 if path.startswith("/docs"):
46 return "docs"
48 return "store"
51# template filters
52def contains(arr, contents):
53 """
54 Template helper for detecting if an array contains an item
55 """
57 return contents in arr
60def join(arr, separator=""):
61 """
62 Template helper for joining array items into a string, using a separator
63 """
65 return separator.join(arr)
68def static_url(filename):
69 """
70 Template function for generating URLs to static assets:
71 Given the path for a static file, output a url path
72 with a hex hash as a query string for versioning
73 """
75 filepath = os.path.join("static", filename)
76 url = "/" + filepath
78 if not os.path.isfile(filepath):
79 # Could not find static file
80 return url
82 # Use MD5 as we care about speed a lot
83 # and not security in this case
84 file_hash = hashlib.md5()
85 with open(filepath, "rb") as file_contents:
86 for chunk in iter(lambda: file_contents.read(4096), b""):
87 file_hash.update(chunk)
89 return url + "?v=" + file_hash.hexdigest()[:7]
92def install_snippet(
93 package_name, default_track, lowest_risk_available, confinement
94):
95 """
96 Template function that returns the snippet value to
97 install a snap to be used in distro pages and/or snap
98 detail pages
99 """
101 snippet_value = "sudo snap install " + package_name
103 if lowest_risk_available != "stable":
104 snippet_value += f" --{lowest_risk_available}"
106 if confinement == "classic":
107 snippet_value += " --classic"
109 return snippet_value
112def format_number(number: int):
113 """
114 Template function that transforms a int into a string
115 with a comma between every thousands
116 """
117 return "{:,}".format(number)
120def format_display_name(display_name):
121 """Template function that formats the displayed name
122 primarily to remove emoji
123 """
124 return replace_emoji(display_name, replace="")
127def display_name(display_name, username):
128 """Template function that returns the displayed name if the username
129 is the same, or the dispayed name and the username if differents
130 """
131 display_name = format_display_name(display_name)
132 if display_name.lower() == username.lower():
133 return display_name
134 else:
135 return f"{display_name} ({username})"
138def format_date(timestamp, format):
139 """Template function that returns a formatted date
140 based on the given timestamp
141 """
142 datestring = parser.parse(timestamp)
144 return datestring.strftime(format)
147def format_member_role(role):
148 """Template function that returns the
149 correct label for a members role
150 """
151 roles = {
152 "admin": "admin",
153 "review": "reviewer",
154 "view": "viewer",
155 "access": "publisher",
156 }
158 return roles[role]
161def format_link(url):
162 """
163 Template function that removes protocol, path and query string from links
164 """
165 url_parts = url.split(":")
167 if url_parts[0] == "mailto":
168 return url_parts[1]
170 if url_parts[0] == "http" or url_parts[0] == "https":
171 url_parts_no_slashes = url_parts[1].split("//")[1]
172 url_parts_no_query = url_parts_no_slashes.split("?")[0]
173 url_parts_no_path = url_parts_no_query.split("/")[0]
175 if url_parts_no_path in [
176 "github.com",
177 "gitlab.com",
178 "bitbucket.org",
179 "launchpad.net",
180 "sourceforge.net",
181 ]:
182 return url_parts_no_query
184 return url_parts_no_path