Coverage for webapp/publisher/logic.py: 98%
41 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-27 22:07 +0000
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-27 22:07 +0000
1from typing import TypedDict, List, Union, Dict
2from collections import Counter
3from datetime import datetime
4from webapp.observability.utils import trace_function
5from webapp.store.logic import process_revision
7Error = TypedDict("Error", {"code": str, "message": str})
9Base = TypedDict("Base", {"architecture": str, "channel": str, "name": str})
11Revision = TypedDict(
12 "Revision",
13 {
14 "bases": List[Base],
15 "created-at": str,
16 "revision": int,
17 "sha3-384": str,
18 "size": int,
19 "status": str,
20 "version": str,
21 "errors": Union[List[Error], None],
22 },
23)
25Resource = TypedDict(
26 "Resource", {"name": str, "revision": Union[int, None], "type": str}
27)
29Release = TypedDict(
30 "Release", {"revision": Revision, "resources": List[Resource]}
31)
33ReleaseMap = TypedDict(
34 "ReleaseMap",
35 {
36 "track": str,
37 "risk": str,
38 "releases": List[Release],
39 },
40)
43@trace_function
44def process_releases(
45 channel_map, channels, revisions: List[Revision]
46) -> Dict[str, ReleaseMap]:
47 """
48 Process the releases and return a dictionary with the
49 channel name as key and a list of releases as value.
51 Args:
52 channel_map: Mapping of revisions to channels and resources
53 channels: List of channels
54 revisions: List of revisions
56 Returns:
57 Dictionary with channel name as key and a list of releases as value
58 """
60 res = {}
61 for channel in channels:
62 res[channel["name"]] = {}
63 res[channel["name"]]["track"] = channel["track"]
64 res[channel["name"]]["risk"] = channel["risk"]
65 res[channel["name"]]["releases"] = {}
67 revision_map = {}
69 for revision in revisions:
70 revision_map[revision["revision"]] = process_revision(revision)
72 for channel in channel_map:
73 revision = revision_map[channel["revision"]]
74 resources = channel["resources"]
75 res[channel["channel"]]["releases"][revision["revision"]] = {
76 "revision": revision,
77 "resources": resources,
78 }
80 for channel in list(res):
81 releases = list(res[channel]["releases"].values())
83 releases.sort(
84 key=lambda x: datetime.strptime(
85 x["revision"]["created-at"], "%Y-%m-%dT%H:%M:%SZ"
86 ),
87 reverse=True,
88 )
90 if len(releases) > 0:
91 res[channel]["releases"] = releases
92 else:
93 del res[channel]
95 return res
98@trace_function
99def get_all_architectures(releases: Dict[str, ReleaseMap]) -> List[str]:
100 """
101 Get all architectures from the releases
103 Args:
104 releases: Dictionary with channel name as key
105 and a list of releases as value
107 Returns:
108 List of architectures, sorted by frequency
110 """
111 architectures = Counter()
112 for channel in releases:
113 for release in releases[channel]["releases"]:
114 for base in release["revision"]["bases"]:
115 architectures.update([base["architecture"]])
117 return [arch for arch, _ in architectures.most_common()]