]> git.mxchange.org Git - fba.git/blob - fba/helpers/software.py
7389c9ca4af0449dfe896106c8b17f8628833c30
[fba.git] / fba / helpers / software.py
1 # Fedi API Block - An aggregator for fetching blocking data from fediverse nodes
2 # Copyright (C) 2023 Free Software Foundation
3 #
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Affero General Public License as published
6 # by the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU Affero General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program.  If not, see <https://www.gnu.org/licenses/>.
16
17 import logging
18
19 from functools import lru_cache
20
21 from fba.helpers import tidyup
22
23 logging.basicConfig(level=logging.INFO)
24 logger = logging.getLogger(__name__)
25
26 # A list of relay software
27 relays = [
28     "activityrelay",
29     "aoderelay",
30     "selective-relay",
31     "pub-relay"
32 ]
33
34 # Aliases for mastodon
35 _mastodon_aliases = [
36     "hometown",
37     "ecko",
38     "fedibird",
39     "glitchcafe",
40     "kmyblue",
41     "nagitodon"
42 ]
43
44 # Aliases for misskey
45 _misskey_aliases = [
46     "slipfox calckey",
47     "calckey",
48     "groundpolis",
49     "foundkey",
50     "cherrypick",
51     "meisskey",
52     "magnetar",
53     "keybump",
54     "dolphin",
55     "calckey social",
56     "azk.sns",
57     "firefish",
58     "qtmmsky",
59     "iceshrimp",
60     "owohub",
61     "re+",
62     "russkey",
63     "loverskey",
64     "hajkey",
65     "sharkey",
66     "renekey",
67     "renekey-lite",
68     "yoiyami",
69     "catnip",
70     "cyberskey",
71     "catodon",
72     "lycheebridge",
73     "goblin",
74     "miraiskey",
75     "lovers",
76     "rosekey",
77     "hijikey",
78     "shrimpkey"
79 ]
80
81 # Aliases for pleroma
82 _pleroma_aliases = [
83     "akkoma",
84     "rebased",
85     "akkounfucked",
86     "ched",
87     "incestoma",
88     "revolver",
89     "menzoberranzan",
90     "moon-eyed"
91 ]
92
93 @lru_cache
94 def alias(software: str) -> str:
95     logger.debug("software='%s'- CALLED!", software)
96
97     if not isinstance(software, str) and software is not None:
98         raise ValueError(f"software[]='{type(software)}' is not type 'str'")
99     elif software == "":
100         raise ValueError("Parameter 'software' is empty")
101     elif software.startswith("re:"):
102         logger.debug("Cutting prefix 're:' from software='%s' ...", software)
103         software = software.split(":")[1]
104
105     logger.debug("software='%s'- BEFORE!", software)
106     cleared = tidyup.domain(software)
107     logger.debug("cleared='%s'- AFTER!", cleared)
108
109     if cleared in _pleroma_aliases or "pleroma" in cleared:
110         logger.debug("Setting pleroma: cleared='%s'", cleared)
111         cleared = "pleroma"
112     elif "radiant" in cleared:
113         logger.debug("Setting radiant: cleared='%s'", cleared)
114         cleared = "radiant"
115     elif cleared in _mastodon_aliases or "되는 마스토돈" in cleared or "mastodon" in cleared:
116         logger.debug("Setting mastodon: cleared='%s'", cleared)
117         cleared = "mastodon"
118     elif cleared in _misskey_aliases or "shumihub" in cleared or "мисскей" in cleared or "milkey" in cleared or "misskey" in cleared:
119         logger.debug("Setting misskey: cleared='%s'", cleared)
120         cleared = "misskey"
121     elif cleared in ["runtube.re", "islameye"]:
122         logger.debug("Setting peertube: cleared='%s'", cleared)
123         cleared = "peertube"
124     elif cleared in ["nextcloud social", "nextcloudpi", "storage share", "nube"] or "nextcloud" in cleared:
125         logger.debug("Setting nextcloud: cleared='%s'", cleared)
126         cleared = "nextcloud"
127     elif "discourse" in cleared:
128         logger.debug("Setting discourse: cleared='%s'", cleared)
129         cleared = "discourse"
130     elif cleared == "activity-relay":
131         logger.debug("Setting activityrelay: cleared='%s'", cleared)
132         cleared = "activityrelay"
133     elif "owncast" in cleared:
134         logger.debug("Setting owncast: cleared='%s'", cleared)
135         cleared = "owncast"
136     elif cleared in ["streams-hubzilla-social", "streams13"]:
137         logger.debug("Setting streams: cleared='%s'", cleared)
138         cleared = "streams"
139     elif cleared == "roadhouse":
140         logger.debug("Setting hubzilla: cleared='%s'", cleared)
141         cleared = "hubzilla"
142     elif cleared == "takahē":
143         logger.debug("Setting takahe: cleared='%s'", cleared)
144         cleared = "takahe"
145     elif cleared == "diaspora* social network":
146         logger.debug("Setting diaspora: cleared='%s'", cleared)
147         cleared = "diaspora"
148     elif cleared == "tkz relay":
149         logger.debug("Setting aoderelay: cleared='%s'", cleared)
150         cleared = "aoderelay"
151     elif cleared == "gitdab":
152         logger.debug("Setting forgejo: cleared='%s'", cleared)
153         cleared = "forgejo"
154     elif cleared == "mbin":
155         logger.debug("Setting kbin: cleared='%s'", cleared)
156         cleared = "kbin"
157     elif cleared == "write.as":
158         logger.debug("Setting writefreely: cleared='%s'", cleared)
159         cleared = "writefreely"
160     elif "gnu social" in cleared:
161         logger.debug("Setting gnusocial: cleared='%s'", cleared)
162         cleared = "gnusocial"
163     elif cleared.find("/") > 0:
164         logger.warning("Spliting of slash: cleared='%s'", cleared)
165         cleared = cleared.split("/")[-1]
166     elif cleared.find("|") > 0:
167         logger.warning("Spliting of pipe: cleared='%s'", cleared)
168         cleared = cleared.split("|")[0]
169     elif "powered by" in cleared:
170         logger.debug("cleared='%s' has 'powered by' in it", cleared)
171         cleared = strip_powered_by(cleared)
172     elif cleared.endswith(" experimental"):
173         logger.debug("cleared='%s' ends with 'experimental", cleared)
174         cleared = strip_until(cleared, "experimental")
175
176     if isinstance(cleared, str) and " by " in cleared:
177         logger.debug("cleared='%s' has ' by ' in it", cleared)
178         cleared = strip_until(cleared, " by ")
179     elif isinstance(cleared, str) and " - " in cleared:
180         logger.debug("cleared='%s' has ' - ' in it", cleared)
181         cleared = strip_until(cleared, " - ")
182     elif isinstance(cleared, str) and " see " in cleared:
183         logger.debug("cleared='%s' has ' see ' in it", cleared)
184         cleared = strip_until(cleared, " see ")
185
186     logger.debug("cleared['%s']='%s'", type(cleared), cleared)
187     if cleared == "":
188         logger.warning("tidyup.domain() left no cleared name behind: cleared='%s'", cleared)
189         cleared = None
190     else:
191         logger.debug("cleared='%s' is being cleaned up further ...", cleared)
192         cleared = cleared.rstrip("!").strip()
193
194     logger.debug("cleared[%s]='%s' - EXIT!", type(cleared), cleared)
195     return cleared
196
197 def strip_hosted_on(software: str) -> str:
198     logger.debug("software='%s' - CALLED!", software)
199
200     if not isinstance(software, str):
201         raise ValueError(f"Parameter software[]='{type(software)}' is not of type 'str'")
202     elif software == "":
203         raise ValueError("Parameter 'software' is empty")
204     elif "hosted on" not in software:
205         logger.warning("Cannot find 'hosted on' in software='%s'!", software)
206         return software
207
208     end = software.find("hosted on ")
209     logger.debug("end[%s]=%d", type(end), end)
210
211     software = software[0:end].strip()
212     logger.debug("software[%s]='%s'", type(software), software)
213
214     if " - " in software:
215         logger.debug("Stripping ' - ' of from software='%s' ...", software)
216         software = strip_until(software, " - ").strip()
217
218     logger.debug("software='%s' - EXIT!", software)
219     return software
220
221 def strip_powered_by(software: str) -> str:
222     logger.debug("software='%s' - CALLED!", software)
223
224     if not isinstance(software, str):
225         raise ValueError(f"Parameter software[]='{type(software)}' is not of type 'str'")
226     elif software == "":
227         raise ValueError("Parameter 'software' is empty")
228     elif "powered by" not in software:
229         logger.warning("Cannot find 'powered by' in software='%s'!", software)
230         return software
231
232     start = software.find("powered by ")
233     logger.debug("start[%s]=%d", type(start), start)
234
235     software = software[start + 11:].strip()
236     logger.debug("software='%s'", software)
237
238     if " - " in software:
239         logger.debug("Stripping ' - ' of from software='%s' ...", software)
240         software = strip_until(software, " - ").strip()
241
242     logger.debug("software='%s' - EXIT!", software)
243     return software
244
245 def strip_until(software: str, until: str) -> str:
246     logger.debug("software='%s',until='%s' - CALLED!", software, until)
247
248     if not isinstance(software, str):
249         raise ValueError(f"Parameter software[]='{type(software)}' is not of type 'str'")
250     elif software == "":
251         raise ValueError("Parameter 'software' is empty")
252     elif not isinstance(until, str):
253         raise ValueError(f"Parameter until[]='{type(until)}' is not of type 'str'")
254     elif until == "":
255         raise ValueError("Parameter 'until' is empty")
256     elif not until in software:
257         logger.warning("Cannot find until='%s' in software='%s'!", until, software)
258         return software
259
260     # Next, strip until part
261     end = software.strip().find(until)
262
263     logger.debug("end[%s]=%d", type(end), end)
264     if end > 0:
265         software = software[0:end].strip()
266
267     logger.debug("software='%s' - EXIT!", software)
268     return software
269
270 def is_relay(software: str) -> bool:
271     logger.debug("software='%s'- CALLED!", software)
272
273     if not isinstance(software, str):
274         raise ValueError(f"software[]='{type(software)}' is not type 'str'")
275     elif software == "":
276         raise ValueError("Parameter 'software' is empty")
277
278     found = software in relays
279
280     logger.debug("found='%s' - EXIT!", found)
281     return found