]> git.mxchange.org Git - fba.git/blob - fba/networks/friendica.py
Continued:
[fba.git] / fba / networks / friendica.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 bs4
18 import validators
19
20 from fba import network
21
22 from fba.helpers import blacklist
23 from fba.helpers import config
24 from fba.helpers import tidyup
25
26 from fba.models import instances
27
28 def fetch_blocks(domain: str) -> dict:
29     # DEBUG: print(f"DEBUG: domain='{domain}' - CALLED!")
30     if not isinstance(domain, str):
31         raise ValueError(f"Parameter domain[]='{type(domain)}' is not 'str'")
32     elif domain == "":
33         raise ValueError("Parameter 'domain' is empty")
34
35     blocked = list()
36     blocklist = None
37
38     try:
39         # DEBUG: print("DEBUG: Fetching friendica blocks from domain:", domain)
40         doc = bs4.BeautifulSoup(
41             network.fetch_response(
42                 domain,
43                 "/friendica",
44                 network.web_headers,
45                 (config.get("connection_timeout"), config.get("read_timeout"))
46             ).text,
47             "html.parser",
48         )
49         # DEBUG: print(f"DEBUG: doc[]='{type(doc)}'")
50
51         blocklist = doc.find(id="about_blocklist")
52     except network.exceptions as exception:
53         print(f"WARNING: Exception '{type(exception)}' during fetching instances (friendica) from domain='{domain}'")
54         instances.set_last_error(domain, exception)
55         return dict()
56
57     # Prevents exceptions:
58     if blocklist is None:
59         # DEBUG: print("DEBUG: Instance has no block list:", domain)
60         return dict()
61
62     table = blocklist.find("table")
63
64     # DEBUG: print(f"DEBUG: table[]='{type(table)}'")
65     if table.find("tbody"):
66         rows = table.find("tbody").find_all("tr")
67     else:
68         rows = table.find_all("tr")
69
70     # DEBUG: print(f"DEBUG: Found rows()={len(rows)}")
71     for line in rows:
72         # DEBUG: print(f"DEBUG: line='{line}'")
73         blocked = tidyup.domain(line.find_all("td")[0].text)
74         print(f"DEBUG: blocked='{blocked}'")
75
76         if not validators.domain(blocked):
77             print(f"WARNING: blocked='{blocked}' is not a valid domain - SKIPPED!")
78             continue
79         elif blocked.endswith(".arpa"):
80             print(f"WARNING: blocked='{blocked}' is a reversed .arpa domain and should not be used generally.")
81             continue
82         elif blocked.endswith(".tld"):
83             print(f"WARNING: blocked='{blocked}' is a fake domain, please don't crawl them!")
84             continue
85         elif blacklist.is_blacklisted(blocked):
86             # DEBUG: print(f"DEBUG: blocked='{blocked}' is blacklisted - SKIPPED!")
87             continue
88
89         blocked.append({
90             "domain": tidyup.domain(blocked),
91             "reason": tidyup.reason(line.find_all("td")[1].text)
92         })
93         # DEBUG: print("DEBUG: Next!")
94
95     # DEBUG: print("DEBUG: Returning blocklist() for domain:", domain, len(blocklist))
96     return {
97         "reject": blocked
98     }