From: Roland Häder Date: Thu, 8 Jun 2023 06:01:00 +0000 (+0200) Subject: Continued: X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=a1629661824c89b287117c53026660d8946f093f;p=fba.git Continued: - moved more instances-related functions to module fba.instances - also cut of /profile/ and /users/ from paths --- diff --git a/fba/commands.py b/fba/commands.py index 514da07..408eadd 100644 --- a/fba/commands.py +++ b/fba/commands.py @@ -44,7 +44,7 @@ def check_instance(args: argparse.Namespace) -> int: 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: @@ -80,7 +80,7 @@ def fetch_bkali(args: argparse.Namespace): 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 @@ -111,7 +111,7 @@ def fetch_blocks(args: argparse.Namespace): 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 @@ -218,7 +218,7 @@ def fetch_blocks(args: argparse.Namespace): 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) @@ -288,7 +288,7 @@ def fetch_cs(args: argparse.Namespace): 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) @@ -325,7 +325,7 @@ def fetch_fba_rss(args: argparse.Namespace): 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 @@ -378,7 +378,7 @@ def fetch_fbabot_atom(args: argparse.Namespace): 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 diff --git a/fba/fba.py b/fba/fba.py index 2d11a69..9a8b3d7 100644 --- a/fba/fba.py +++ b/fba/fba.py @@ -101,7 +101,7 @@ def fetch_instances(domain: str, origin: str, software: str, script: str, path: 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) @@ -113,7 +113,7 @@ def fetch_instances(domain: str, origin: str, software: str, script: str, 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: @@ -137,7 +137,7 @@ def fetch_instances(domain: str, origin: str, software: str, script: str, path: # 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: @@ -343,52 +343,6 @@ def log_error(domain: str, response: requests.models.Response): # 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: @@ -424,7 +378,7 @@ def get_peers(domain: str, software: str) -> list: # 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) @@ -434,14 +388,14 @@ def get_peers(domain: str, software: str) -> list: # 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)) @@ -479,7 +433,7 @@ def post_json_api(domain: str, path: str, parameter: str, extra_headers: dict = # 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)}'") @@ -535,12 +489,12 @@ def fetch_nodeinfo(domain: str, path: str = None) -> list: 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!") @@ -586,7 +540,7 @@ def fetch_wellknown_nodeinfo(domain: str) -> list: 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)) @@ -635,7 +589,7 @@ def fetch_generator_from_path(domain: str, path: str = "/") -> str: 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)}") @@ -686,11 +640,11 @@ def determine_software(domain: str, path: str = None) -> str: # 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 / ...") @@ -748,31 +702,6 @@ def determine_software(domain: str, path: str = None) -> str: # 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: @@ -835,7 +764,7 @@ def fetch_friendica_blocks(domain: str) -> dict: ) 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") @@ -941,7 +870,7 @@ def fetch_misskey_blocks(domain: str) -> dict: 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 @@ -998,7 +927,7 @@ def fetch_misskey_blocks(domain: str) -> dict: 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 @@ -1047,6 +976,10 @@ def tidyup_domain(domain: str) -> str: # 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 @@ -1087,7 +1020,7 @@ def get_response(domain: str, path: str, headers: dict, timeout: list) -> reques ); 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!") diff --git a/fba/federation/gotosocial.py b/fba/federation/gotosocial.py index 4008110..2ca6309 100644 --- a/fba/federation/gotosocial.py +++ b/fba/federation/gotosocial.py @@ -21,6 +21,7 @@ from fba import blacklist 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!") @@ -81,7 +82,7 @@ def fetch_blocks(domain: str, origin: str, nodeinfo_url: str): 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) diff --git a/fba/federation/mastodon.py b/fba/federation/mastodon.py index e0c180d..e03a7d7 100644 --- a/fba/federation/mastodon.py +++ b/fba/federation/mastodon.py @@ -21,6 +21,7 @@ from fba import blacklist from fba import blocks from fba import config from fba import fba +from fba import instances language_mapping = { # English -> English @@ -217,7 +218,7 @@ def fetch_blocks(domain: str, origin: str, nodeinfo_url: str): 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): @@ -228,7 +229,7 @@ def fetch_blocks(domain: str, origin: str, nodeinfo_url: str): 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) diff --git a/fba/federation/pleroma.py b/fba/federation/pleroma.py index 52c0f00..3e47c01 100644 --- a/fba/federation/pleroma.py +++ b/fba/federation/pleroma.py @@ -20,6 +20,7 @@ import validators 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!") @@ -52,7 +53,7 @@ def fetch_blocks(domain: str, origin: str, nodeinfo_url: str): return # DEBUG: print("DEBUG: Updating nodeinfo:", domain) - fba.update_last_nodeinfo(domain) + instances.update_last_nodeinfo(domain) federation = json["metadata"]["federation"] @@ -108,7 +109,7 @@ def fetch_blocks(domain: str, origin: str, nodeinfo_url: str): 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) @@ -181,7 +182,7 @@ def fetch_blocks(domain: str, origin: str, nodeinfo_url: str): 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) diff --git a/fba/instances.py b/fba/instances.py index 8818920..76a1a80 100644 --- a/fba/instances.py +++ b/fba/instances.py @@ -14,14 +14,19 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +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) @@ -81,7 +86,7 @@ def has_pending_instance_data(domain: str) -> bool: # 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'") @@ -147,8 +152,8 @@ def update_last_instance_fetch(domain: 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!") @@ -162,8 +167,8 @@ def update_last_blocked(domain: str): 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!") @@ -185,26 +190,27 @@ def add(domain: str, origin: str, originator: str, path: str = None): 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() ), @@ -212,17 +218,17 @@ def add(domain: str, origin: str, originator: str, path: str = None): 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)}'") @@ -232,3 +238,74 @@ def add(domain: str, origin: str, originator: str, path: str = None): 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