]> git.mxchange.org Git - fba.git/blob - fba/helpers/domain.py
00bf9384aee437d3d9b2fc715fa0ba0968584369
[fba.git] / fba / helpers / domain.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 urllib.parse import urlparse
20
21 import validators
22
23 from fba.helpers import blacklist
24 from fba.helpers import config
25
26 from fba.models import instances
27
28 logging.basicConfig(level=logging.INFO)
29 logger = logging.getLogger(__name__)
30
31 def raise_on(domain: str):
32     logger.debug("domain='%s' - CALLED!", domain)
33
34     if not isinstance(domain, str):
35         raise ValueError(f"Parameter domain[]='{type(domain)}' is not of type 'str'")
36     elif domain == "":
37         raise ValueError("Parameter 'domain' is empty")
38     elif domain.lower() != domain:
39         raise ValueError(f"Parameter domain='{domain}' must be all lower-case")
40     elif not validators.domain(domain.split("/")[0]):
41         raise ValueError(f"domain='{domain}' is not a valid domain")
42     elif domain.endswith(".onion"):
43         raise ValueError(f"domain='{domain}' is a TOR, please don't crawl them!")
44     elif domain.endswith(".i2p") and config.get("allow_i2p_domain") == "true":
45         raise ValueError(f"domain='{domain}' is an I2P, please don't crawl them!")
46     elif domain.endswith(".arpa"):
47         raise ValueError(f"domain='{domain}' is a domain for reversed IP addresses, please don't crawl them!")
48     elif domain.endswith(".tld"):
49         raise ValueError(f"domain='{domain}' is a fake domain, please don't crawl them!")
50
51     logger.debug("EXIT!")
52
53 def is_in_url(domain: str, url: str) -> bool:
54     logger.debug("domain='%s',url='%s' - CALLED!", domain, url)
55     raise_on(domain)
56
57     if not isinstance(url, str):
58         raise ValueError(f"Parameter url[]='{type(url)}' is not of type 'str'")
59     elif url == "":
60         raise ValueError("Parameter 'url' is empty")
61
62     punycode = domain.encode("idna").decode("utf-8")
63
64     components = urlparse(url)
65     logger.debug("components[]='%s',punycode='%s'", type(components), punycode)
66
67     is_found = (punycode in [components.netloc, components.hostname])
68
69     logger.debug("is_found='%s' - EXIT!", is_found)
70     return is_found
71
72 def is_wanted(domain: str) -> bool:
73     logger.debug("domain='%s' - CALLED!", domain)
74
75     if not isinstance(domain, str):
76         raise ValueError(f"Parameter domain[]='{type(domain)}' is not of type 'str'")
77     elif domain == "":
78         raise ValueError("Parameter 'domain' is empty")
79
80     wanted = True
81     if domain.lower() != domain:
82         logger.debug("domain='%s' is not all-lowercase - setting False ...", domain)
83         wanted = False
84     elif not validators.domain(domain.split("/")[0]):
85         logger.debug("domain='%s' is not a valid domain name - setting False ...", domain)
86         wanted = False
87     elif domain.endswith(".arpa"):
88         logger.debug("domain='%s' is a domain for reversed IP addresses - setting False ...", domain)
89         wanted = False
90     elif domain.endswith(".onion"):
91         logger.debug("domain='%s' is a TOR .onion domain - setting False ...", domain)
92         wanted = False
93     elif domain.endswith(".i2p") and config.get("allow_i2p_domain") == "true":
94         logger.debug("domain='%s' is an I2P domain - setting False ...", domain)
95         wanted = False
96     elif domain.endswith(".tld"):
97         logger.debug("domain='%s' is a fake domain - setting False ...", domain)
98         wanted = False
99     elif blacklist.is_blacklisted(domain):
100         logger.debug("domain='%s' is blacklisted - setting False ...", domain)
101         wanted = False
102     elif domain.find("/profile/") > 0 or domain.find("/users/") > 0 or (instances.is_registered(domain.split("/")[0]) and domain.find("/c/") > 0):
103         logger.debug("domain='%s' is a single user", domain)
104         wanted = False
105     elif domain.find("/tag/") > 0:
106         logger.debug("domain='%s' is a tag", domain)
107         wanted = False
108
109     logger.debug("wanted='%s' - EXIT!", wanted)
110     return wanted