1 # Copyright (C) 2023 Free Software Foundation
3 # This program is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU Affero General Public License as published
5 # by the Free Software Foundation, either version 3 of the License, or
6 # (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU Affero General Public License for more details.
13 # You should have received a copy of the GNU Affero General Public License
14 # along with this program. If not, see <https://www.gnu.org/licenses/>.
18 # Pattern instance for version numbers
20 # semantic version number (with v|V) prefix)
21 re.compile("^(?P<version>v|V{0,1})(\.{0,1})(?P<major>0|[1-9]\d*)\.(?P<minor>0+|[1-9]\d*)(\.(?P<patch>0+|[1-9]\d*)(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)?$"),
22 # non-sematic, e.g. 1.2.3.4
23 re.compile("^(?P<version>v|V{0,1})(\.{0,1})(?P<major>0|[1-9]\d*)\.(?P<minor>0+|[1-9]\d*)(\.(?P<patch>0+|[1-9]\d*)(\.(?P<subpatch>0|[1-9]\d*))?)$"),
24 # non-sematic, e.g. 2023-05[-dev]
25 re.compile("^(?P<year>[1-9]{1}[0-9]{3})\.(?P<month>[0-9]{2})(-dev){0,1}$"),
26 # non-semantic, e.g. abcdef0
27 re.compile("^[a-f0-9]{7}$"),
30 def remove(software: str) -> str:
31 # DEBUG: print(f"DEBUG: software='{software}' - CALLED!")
32 if not "." in software and " " not in software:
33 print(f"WARNING: software='{software}' does not contain a version number.")
38 temp = software.split(";")[0]
40 temp = software.split(",")[0]
41 elif " - " in software:
42 temp = software.split(" - ")[0]
44 # DEBUG: print(f"DEBUG: software='{software}'")
47 version = temp.split(" ")[-1]
49 version = temp.split("/")[-1]
51 version = temp.split("-")[-1]
53 # DEBUG: print(f"DEBUG: Was not able to find common seperator, returning untouched software='{software}'")
57 # DEBUG: print(f"DEBUG: Checking {len(patterns)} patterns ...")
58 for pattern in patterns:
60 match = pattern.match(version)
62 # DEBUG: print(f"DEBUG: match[]='{type(match)}'")
63 if isinstance(match, re.Match):
64 # DEBUG: print(f"DEBUG: version='{version}' is matching pattern='{pattern}'")
67 # DEBUG: print(f"DEBUG: version[{type(version)}]='{version}',match='{match}'")
68 if not isinstance(match, re.Match):
69 print(f"WARNING: version='{version}' does not match regex, leaving software='{software}' untouched.")
72 # DEBUG: print(f"DEBUG: Found valid version number: '{version}', removing it ...")
73 end = len(temp) - len(version) - 1
75 # DEBUG: print(f"DEBUG: end[{type(end)}]={end}")
76 software = temp[0:end].strip()
77 if " version" in software:
78 # DEBUG: print(f"DEBUG: software='{software}' contains word ' version'")
79 software = strip_until(software, " version")
81 # DEBUG: print(f"DEBUG: software='{software}' - EXIT!")
84 def strip_powered_by(software: str) -> str:
85 # DEBUG: print(f"DEBUG: software='{software}' - CALLED!")
86 if not isinstance(software, str):
87 raise ValueError(f"Parameter software[]='{type(software)}' is not 'str'")
89 raise ValueError("Parameter 'software' is empty")
90 elif "powered by" not in software:
91 print(f"WARNING: Cannot find 'powered by' in software='{software}'!")
94 start = software.find("powered by ")
95 # DEBUG: print(f"DEBUG: start[{type(start)}]='{start}'")
97 software = software[start + 11:].strip()
98 # DEBUG: print(f"DEBUG: software='{software}'")
100 software = strip_until(software, " - ")
102 # DEBUG: print(f"DEBUG: software='{software}' - EXIT!")
105 def strip_hosted_on(software: str) -> str:
106 # DEBUG: print(f"DEBUG: software='{software}' - CALLED!")
107 if not isinstance(software, str):
108 raise ValueError(f"Parameter software[]='{type(software)}' is not 'str'")
110 raise ValueError("Parameter 'software' is empty")
111 elif "hosted on" not in software:
112 print(f"WARNING: Cannot find 'hosted on' in '{software}'!")
115 end = software.find("hosted on ")
116 # DEBUG: print(f"DEBUG: end[{type(end)}]='{end}'")
118 software = software[0, end].strip()
119 # DEBUG: print(f"DEBUG: software='{software}'")
121 software = strip_until(software, " - ")
123 # DEBUG: print(f"DEBUG: software='{software}' - EXIT!")
126 def strip_until(software: str, until: str) -> str:
127 # DEBUG: print(f"DEBUG: software='{software}',until='{until}' - CALLED!")
128 if not isinstance(software, str):
129 raise ValueError(f"Parameter software[]='{type(software)}' is not 'str'")
131 raise ValueError("Parameter 'software' is empty")
132 elif not isinstance(until, str):
133 raise ValueError(f"Parameter until[]='{type(until)}' is not 'str'")
135 raise ValueError("Parameter 'until' is empty")
136 elif not until in software:
137 print(f"WARNING: Cannot find '{until}' in '{software}'!")
140 # Next, strip until part
141 end = software.find(until)
143 # DEBUG: print(f"DEBUG: end[{type(end)}]='{end}'")
145 software = software[0:end].strip()
147 # DEBUG: print(f"DEBUG: software='{software}' - EXIT!")