elif blacklist.is_blacklisted(args.domain):
print(f"WARNING: args.domain='{args.domain}' is blacklisted")
status = 101
- elif fba.is_instance_registered(args.domain):
+ elif instances.is_registered(args.domain):
print(f"WARNING: args.domain='{args.domain}' is already registered")
status = 102
else:
elif blacklist.is_blacklisted(entry["domain"]):
# DEBUG: print(f"DEBUG: domain='{entry['domain']}' is blacklisted - SKIPPED!")
continue
- elif fba.is_instance_registered(entry["domain"]):
+ elif instances.is_registered(entry["domain"]):
# DEBUG: print(f"DEBUG: domain='{entry['domain']}' is already registered - SKIPPED!")
continue
elif blacklist.is_blacklisted(args.domain):
print(f"WARNING: domain='{args.domain}' is blacklisted, won't check it!")
return
- elif not fba.is_instance_registered(args.domain):
+ elif not instances.is_registered(args.domain):
print(f"WARNING: domain='{args.domain}' is not registered, please run ./fba.py fetch_instances {args.domain} first.")
return
if not validators.domain(blocked):
print(f"WARNING: blocked='{blocked}',software='{software}' is not a valid domain name - skipped!")
continue
- elif not fba.is_instance_registered(blocked):
+ elif not instances.is_registered(blocked):
# DEBUG: print("DEBUG: Hash wasn't found, adding:", blocked, blocker)
instances.add(blocked, blocker, inspect.currentframe().f_code.co_name, nodeinfo_url)
for row in domains[block_level]:
# DEBUG: print(f"DEBUG: row='{row}'")
- if not fba.is_instance_registered(row["domain"]):
+ if not instances.is_registered(row["domain"]):
print(f"INFO: Fetching instances from domain='{row['domain']}' ...")
fba.fetch_instances(row["domain"], None, None, inspect.currentframe().f_code.co_name)
elif domain in domains:
# DEBUG: print(f"DEBUG: domain='{domain}' is already added - SKIPPED!")
continue
- elif fba.is_instance_registered(domain):
+ elif instances.is_registered(domain):
# DEBUG: print(f"DEBUG: domain='{domain}' is already registered - SKIPPED!")
continue
elif domain in domains:
# DEBUG: print(f"DEBUG: domain='{domain}' is already added - SKIPPED!")
continue
- elif fba.is_instance_registered(domain):
+ elif instances.is_registered(domain):
# DEBUG: print(f"DEBUG: domain='{domain}' is already registered - SKIPPED!")
continue
elif domain == "":
raise ValueError(f"Parameter 'domain' is empty")
- if not is_instance_registered(domain):
+ if not instances.is_registered(domain):
# DEBUG: print("DEBUG: Adding new domain:", domain, origin)
instances.add(domain, origin, script, path)
return
elif instances.has_pending_instance_data(domain):
# DEBUG: print(f"DEBUG: domain='{domain}' has pending nodeinfo data, flushing ...")
- instances.update_instance_data(domain)
+ instances.update_data(domain)
print(f"INFO: Checking {len(peerlist)} instances from {domain} ...")
for instance in peerlist:
# DEBUG: print("DEBUG: Handling instance:", instance)
try:
- if not is_instance_registered(instance):
+ if not instances.is_registered(instance):
# DEBUG: print("DEBUG: Adding new instance:", instance, domain)
instances.add(instance, domain, script)
except BaseException as e:
# DEBUG: print("DEBUG: EXIT!")
-def update_last_error(domain: str, response: requests.models.Response):
- # DEBUG: print("DEBUG: domain,response[]:", domain, type(response))
- if type(domain) != str:
- raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'")
- elif domain == "":
- raise ValueError(f"Parameter 'domain' is empty")
-
- # DEBUG: print("DEBUG: BEFORE response[]:", type(response))
- if isinstance(response, BaseException) or isinstance(response, json.decoder.JSONDecodeError):
- response = f"{type}:str(response)"
-
- # DEBUG: print("DEBUG: AFTER response[]:", type(response))
- if type(response) is str:
- # DEBUG: print(f"DEBUG: Setting last_error_details='{response}'");
- instances.set("last_status_code" , domain, 999)
- instances.set("last_error_details", domain, response)
- else:
- # DEBUG: print(f"DEBUG: Setting last_error_details='{response.reason}'");
- instances.set("last_status_code" , domain, response.status_code)
- instances.set("last_error_details", domain, response.reason)
-
- # Running pending updated
- # DEBUG: print(f"DEBUG: Invoking instances.update_instance_data({domain}) ...")
- instances.update_instance_data(domain)
-
- log_error(domain, response)
-
- # DEBUG: print("DEBUG: EXIT!")
-
-def update_last_nodeinfo(domain: str):
- # DEBUG: print(f"DEBUG: domain='{domain}' - CALLED!")
- if type(domain) != str:
- raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'")
- elif domain == "":
- raise ValueError(f"Parameter 'domain' is empty")
-
- # DEBUG: print("DEBUG: Updating last_nodeinfo for domain:", domain)
- instances.set("last_nodeinfo", domain, time.time())
- instances.set("last_updated" , domain, time.time())
-
- # Running pending updated
- # DEBUG: print(f"DEBUG: Invoking instances.update_instance_data({domain}) ...")
- instances.update_instance_data(domain)
-
- # DEBUG: print("DEBUG: EXIT!")
-
def get_peers(domain: str, software: str) -> list:
# DEBUG: print(f"DEBUG: domain({len(domain)})={domain},software={software} - CALLED!")
if type(domain) != str:
# DEBUG: print(f"DEBUG: response.ok={response.ok},response.status_code={response.status_code},data[]='{type(data)}'")
if not response.ok or response.status_code >= 400:
print("WARNING: Could not reach any JSON API:", domain)
- update_last_error(domain, response)
+ instances.update_last_error(domain, response)
elif response.ok and isinstance(data, list):
# DEBUG: print(f"DEBUG: domain='{domain}' returned a list: '{data}'")
sys.exit(255)
# DEBUG: print("DEBUG: Added instance(s) to peers")
else:
print("WARNING: JSON response does not contain 'federated_instances':", domain)
- update_last_error(domain, response)
+ instances.update_last_error(domain, response)
else:
# DEBUG: print("DEBUG: Querying API was successful:", domain, len(data))
peers = data
except BaseException as e:
print("WARNING: Some error during get():", domain, e)
- update_last_error(domain, e)
+ instances.update_last_error(domain, e)
# DEBUG: print(f"DEBUG: Adding '{len(peers)}' for domain='{domain}'")
instances.set("total_peers", domain, len(peers))
# DEBUG: print(f"DEBUG: response.ok={response.ok},response.status_code={response.status_code},data[]='{type(data)}'")
if not response.ok or response.status_code >= 400:
print(f"WARNING: Cannot query JSON API: domain='{domain}',path='{path}',parameter()={len(parameter)},response.status_code='{response.status_code}',data[]='{type(data)}'")
- update_last_error(domain, response)
+ instances.update_last_error(domain, response)
except BaseException as e:
print(f"WARNING: Some error during post(): domain='{domain}',path='{path}',parameter()={len(parameter)},exception[{type(e)}]:'{str(e)}'")
sys.exit(255)
elif not response.ok or response.status_code >= 400:
print("WARNING: Failed fetching nodeinfo from domain:", domain)
- update_last_error(domain, response)
+ instances.update_last_error(domain, response)
continue
except BaseException as e:
# DEBUG: print("DEBUG: Cannot fetch API request:", request)
- update_last_error(domain, e)
+ instances.update_last_error(domain, e)
pass
# DEBUG: print(f"DEBUG: data()={len(data)} - EXIT!")
except BaseException as e:
print("WARNING: Failed fetching .well-known info:", domain)
- update_last_error(domain, e)
+ instances.update_last_error(domain, e)
pass
# DEBUG: print("DEBUG: Returning data[]:", type(data))
except BaseException as e:
# DEBUG: print(f"DEBUG: Cannot fetch / from '{domain}':", e)
- update_last_error(domain, e)
+ instances.update_last_error(domain, e)
pass
# DEBUG: print(f"DEBUG: software[]={type(software)}")
# DEBUG: print("DEBUG: data():", len(data), data)
if "status" in data and data["status"] == "error" and "message" in data:
print("WARNING: JSON response is an error:", data["message"])
- update_last_error(domain, data["message"])
+ instances.update_last_error(domain, data["message"])
return fetch_generator_from_path(domain)
elif "message" in data:
print("WARNING: JSON response contains only a message:", data["message"])
- update_last_error(domain, data["message"])
+ instances.update_last_error(domain, data["message"])
return fetch_generator_from_path(domain)
elif "software" not in data or "name" not in data["software"]:
# DEBUG: print(f"DEBUG: JSON response from domain='{domain}' does not include [software][name], fetching / ...")
# DEBUG: print("DEBUG: Returning domain,software:", domain, software)
return software
-def is_instance_registered(domain: str) -> bool:
- # DEBUG: print(f"DEBUG: domain='{domain}' - CALLED!")
- if type(domain) != str:
- raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'")
- elif domain == "":
- raise ValueError(f"Parameter 'domain' is empty")
-
- # DEBUG: print(f"DEBUG: domain='{domain}' - CALLED!")
- if not cache.key_exists("is_registered"):
- # DEBUG: print(f"DEBUG: Cache for 'is_registered' not initialized, fetching all rows ...")
- try:
- cursor.execute("SELECT domain FROM instances")
-
- # Check Set all
- cache.set_all("is_registered", cursor.fetchall(), True)
- except BaseException as e:
- print(f"ERROR: failed SQL query: domain='{domain}',exception[{type(e)}]:'{str(e)}'")
- sys.exit(255)
-
- # Is cache found?
- registered = cache.sub_key_exists("is_registered", domain)
-
- # DEBUG: print(f"DEBUG: registered='{registered}' - EXIT!")
- return registered
-
def send_bot_post(instance: str, blocklist: dict):
# DEBUG: print(f"DEBUG: instance={instance},blocklist()={len(blocklist)} - CALLED!")
if type(domain) != str:
)
except BaseException as e:
print("WARNING: Failed to fetch /friendica from domain:", domain, e)
- update_last_error(domain, e)
+ instances.update_last_error(domain, e)
return {}
blocklist = doc.find(id="about_blocklist")
except BaseException as e:
print("WARNING: Caught error, exiting loop:", domain, e)
- update_last_error(domain, e)
+ instances.update_last_error(domain, e)
offset = 0
break
except BaseException as e:
print("ERROR: Exception during POST:", domain, e)
- update_last_error(domain, e)
+ instances.update_last_error(domain, e)
offset = 0
break
# No individual users in block lists
domain = re.sub("(.+)\@", "", domain)
+ if domain.find("/profile/"):
+ domain = domain.split("/profile/")[0]
+ elif domain.find("/users/"):
+ domain = domain.split("/users/")[0]
# DEBUG: print(f"DEBUG: domain='{domain}' - EXIT!")
return domain
);
except requests.exceptions.ConnectionError as e:
# DEBUG: print(f"DEBUG: Fetching '{path}' from '{domain}' failed. exception[{type(e)}]='{str(e)}'")
- update_last_error(domain, e)
+ instances.update_last_error(domain, e)
raise e
# DEBUG: print(f"DEBUG: response[]='{type(response)}' - EXXIT!")
from fba import blocks
from fba import config
from fba import fba
+from fba import instances
def fetch_blocks(domain: str, origin: str, nodeinfo_url: str):
print(f"DEBUG: domain='{domain}',origin='{origin}',nodeinfo_url='{nodeinfo_url}' - CALLED!")
if not validators.domain(blocked):
print(f"WARNING: blocked='{blocked}',software='gotosocial' is not a valid domain name - skipped!")
continue
- elif not fba.is_instance_registered(blocked):
+ elif not instances.is_registered(blocked):
# DEBUG: print(f"DEBUG: Domain blocked='{blocked}' wasn't found, adding ..., domain='{domain}',origin='{origin}',nodeinfo_url='{nodeinfo_url}'")
instances.add(blocked, domain, inspect.currentframe().f_code.co_name, nodeinfo_url)
from fba import blocks
from fba import config
from fba import fba
+from fba import instances
language_mapping = {
# English -> English
if not validators.domain(blocked):
print(f"WARNING: blocked='{blocked}',software='mastodon' is not a valid domain name - skipped!")
continue
- elif not fba.is_instance_registered(blocked):
+ elif not instances.is_registered(blocked):
# DEBUG: print(f"DEBUG: Domain blocked='{blocked}' wasn't found, adding ..., domain='{domain}',origin='{origin}',nodeinfo_url='{nodeinfo_url}'")
instances.add(blocked, domain, inspect.currentframe().f_code.co_name, nodeinfo_url)
elif not validators.domain(blocked):
if not validators.domain(blocked):
print(f"WARNING: blocked='{blocked}',software='mastodon' is not a valid domain name - skipped!")
continue
- elif not fba.is_instance_registered(blocked):
+ elif not instances.is_registered(blocked):
# DEBUG: print("DEBUG: Hash wasn't found, adding:", blocked, domain)
instances.add(blocked, domain, inspect.currentframe().f_code.co_name, nodeinfo_url)
from fba import blacklist
from fba import blocks
from fba import fba
+from fba import instances
def fetch_blocks(domain: str, origin: str, nodeinfo_url: str):
print(f"DEBUG: domain='{domain}',origin='{origin}',nodeinfo_url='{nodeinfo_url}' - CALLED!")
return
# DEBUG: print("DEBUG: Updating nodeinfo:", domain)
- fba.update_last_nodeinfo(domain)
+ instances.update_last_nodeinfo(domain)
federation = json["metadata"]["federation"]
if not validators.domain(blocked):
print(f"WARNING: blocked='{blocked}',software='pleroma' is not a valid domain name - skipped!")
continue
- elif not fba.is_instance_registered(blocked):
+ elif not instances.is_registered(blocked):
# DEBUG: print(f"DEBUG: Domain blocked='{blocked}' wasn't found, adding ..., domain='{domain}',origin='{origin}',nodeinfo_url='{nodeinfo_url}'")
instances.add(blocked, domain, inspect.currentframe().f_code.co_name, nodeinfo_url)
if not validators.domain(blocked):
print(f"WARNING: blocked='{blocked}',software='pleroma' is not a valid domain name - skipped!")
continue
- elif not fba.is_instance_registered(blocked):
+ elif not instances.is_registered(blocked):
# DEBUG: print(f"DEBUG: Domain blocked='{blocked}' wasn't found, adding ..., domain='{domain}',origin='{origin}',nodeinfo_url='{nodeinfo_url}'")
instances.add(blocked, domain, inspect.currentframe().f_code.co_name, nodeinfo_url)
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
+import json
+import requests
import sys
import time
+import validators
+from fba import blacklist
+from fba import cache
from fba import fba
# Found info from node, such as nodeinfo URL, detection mode that needs to be
# written to database. Both arrays must be filled at the same time or else
-# update_instance_data() will fail
+# update_data() will fail
_pending = {
# Detection mode: 'AUTO_DISCOVERY', 'STATIC_CHECKS' or 'GENERATOR'
# NULL means all detection methods have failed (maybe still reachable instance)
# DEBUG: print(f"DEBUG: has_pending='{has_pending}' - EXIT!")
return has_pending
-def update_instance_data(domain: str):
+def update_data(domain: str):
# DEBUG: print(f"DEBUG: domain='{domain}' - CALLED!")
if type(domain) != str:
raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'")
set("last_instance_fetch", domain, time.time())
# Running pending updated
- # DEBUG: print(f"DEBUG: Invoking update_instance_data({domain}) ...")
- update_instance_data(domain)
+ # DEBUG: print(f"DEBUG: Invoking update_data({domain}) ...")
+ update_data(domain)
# DEBUG: print("DEBUG: EXIT!")
set("last_blocked", domain, time.time())
# Running pending updated
- # DEBUG: print(f"DEBUG: Invoking update_instance_data({domain}) ...")
- update_instance_data(domain)
+ # DEBUG: print(f"DEBUG: Invoking update_data({domain}) ...")
+ update_data(domain)
# DEBUG: print("DEBUG: EXIT!")
raise ValueError(f"Bad origin name='{origin}'")
elif blacklist.is_blacklisted(domain):
raise Exception(f"domain='{domain}' is blacklisted, but method invoked")
+ elif domain.find("/profile/") > 0 or domain.find("/users/") > 0:
+ raise Exception(f"domain='{domain}' is a single user")
# DEBUG: print("DEBUG: domain,origin,originator,path:", domain, origin, originator, path)
- if domain.find("/profile") > 0:
- # Need to cut off /profile/* part
- domain = domain.split("/profile/")[0]
- if instances.is_registered(domain):
- raise Exception(f"WARNING: After removing /profile/ domain='{domain}' is already registered - EXIT!")
-
- software = determine_software(domain, path)
+ software = fba.determine_software(domain, path)
# DEBUG: print("DEBUG: Determined software:", software)
+ if domain.find("/c/") > 0 and software == "lemmy":
+ domain = domain.split("/c/")[0]
+ if is_registered(domain):
+ print(f"WARNING: domain='{domain}' already registered after cutting off user part. - EXIT!")
+ return
print(f"INFO: Adding instance domain='{domain}' (origin='{origin}',software='{software}')")
try:
- cursor.execute(
+ fba.cursor.execute(
"INSERT INTO instances (domain, origin, originator, hash, software, first_seen) VALUES (?, ?, ?, ?, ?, ?)",
(
domain,
origin,
originator,
- get_hash(domain),
+ fba.get_hash(domain),
software,
time.time()
),
cache.set_sub_key("is_registered", domain, True)
- if instances.has_pending_instance_data(domain):
+ if has_pending_instance_data(domain):
# DEBUG: print(f"DEBUG: domain='{domain}' has pending nodeinfo being updated ...")
- instances.set("last_status_code" , domain, None)
- instances.set("last_error_details", domain, None)
- instances.update_instance_data(domain)
- remove_pending_error(domain)
+ set("last_status_code" , domain, None)
+ set("last_error_details", domain, None)
+ update_data(domain)
+ fba.remove_pending_error(domain)
- if domain in pending_errors:
+ if domain in fba.pending_errors:
# DEBUG: print("DEBUG: domain has pending error being updated:", domain)
- update_last_error(domain, pending_errors[domain])
- remove_pending_error(domain)
+ update_last_error(domain, fba.pending_errors[domain])
+ fba.remove_pending_error(domain)
except BaseException as e:
print(f"ERROR: failed SQL query: domain='{domain}',exception[{type(e)}]:'{str(e)}'")
update_last_nodeinfo(domain)
# DEBUG: print("DEBUG: EXIT!")
+
+def update_last_nodeinfo(domain: str):
+ # DEBUG: print(f"DEBUG: domain='{domain}' - CALLED!")
+ if type(domain) != str:
+ raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'")
+ elif domain == "":
+ raise ValueError(f"Parameter 'domain' is empty")
+
+ # DEBUG: print("DEBUG: Updating last_nodeinfo for domain:", domain)
+ set("last_nodeinfo", domain, time.time())
+ set("last_updated" , domain, time.time())
+
+ # Running pending updated
+ # DEBUG: print(f"DEBUG: Invoking update_data({domain}) ...")
+ update_data(domain)
+
+ # DEBUG: print("DEBUG: EXIT!")
+
+def update_last_error(domain: str, response: requests.models.Response):
+ # DEBUG: print("DEBUG: domain,response[]:", domain, type(response))
+ if type(domain) != str:
+ raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'")
+ elif domain == "":
+ raise ValueError(f"Parameter 'domain' is empty")
+
+ # DEBUG: print("DEBUG: BEFORE response[]:", type(response))
+ if isinstance(response, BaseException) or isinstance(response, json.decoder.JSONDecodeError):
+ response = f"{type}:str(response)"
+
+ # DEBUG: print("DEBUG: AFTER response[]:", type(response))
+ if type(response) is str:
+ # DEBUG: print(f"DEBUG: Setting last_error_details='{response}'");
+ set("last_status_code" , domain, 999)
+ set("last_error_details", domain, response)
+ else:
+ # DEBUG: print(f"DEBUG: Setting last_error_details='{response.reason}'");
+ set("last_status_code" , domain, response.status_code)
+ set("last_error_details", domain, response.reason)
+
+ # Running pending updated
+ # DEBUG: print(f"DEBUG: Invoking update_data({domain}) ...")
+ update_data(domain)
+
+ fba.log_error(domain, response)
+
+ # DEBUG: print("DEBUG: EXIT!")
+
+def is_registered(domain: str) -> bool:
+ # DEBUG: print(f"DEBUG: domain='{domain}' - CALLED!")
+ if type(domain) != str:
+ raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'")
+ elif domain == "":
+ raise ValueError(f"Parameter 'domain' is empty")
+
+ # DEBUG: print(f"DEBUG: domain='{domain}' - CALLED!")
+ if not cache.key_exists("is_registered"):
+ # DEBUG: print(f"DEBUG: Cache for 'is_registered' not initialized, fetching all rows ...")
+ try:
+ fba.cursor.execute("SELECT domain FROM instances")
+
+ # Check Set all
+ cache.set_all("is_registered", fba.cursor.fetchall(), True)
+ except BaseException as e:
+ print(f"ERROR: failed SQL query: domain='{domain}',exception[{type(e)}]:'{str(e)}'")
+ sys.exit(255)
+
+ # Is cache found?
+ registered = cache.sub_key_exists("is_registered", domain)
+
+ # DEBUG: print(f"DEBUG: registered='{registered}' - EXIT!")
+ return registered