X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=fba%2Fmodels%2Finstances.py;h=320a24f69d90d639dc7fb29c5a99b85329aad928;hb=323bc106bb37febb52eeb87c2eaca720d3dc1d53;hp=cb08eb5bd0f15c20a40bdc6f1df2143fec0806d7;hpb=1ca249f8108a3bccc1b9bcb56602f712937f02a4;p=fba.git diff --git a/fba/models/instances.py b/fba/models/instances.py index cb08eb5..320a24f 100644 --- a/fba/models/instances.py +++ b/fba/models/instances.py @@ -14,28 +14,34 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +import logging import json -import sys import time import requests import validators -from fba import blacklist -from fba import config -from fba import fba -from fba import federation -from fba import network +from fba import database +from fba import utils +from fba.helpers import blacklist from fba.helpers import cache +from fba.helpers import config +from fba.helpers import domain as domain_helper + +from fba.http import federation +from fba.http import network from fba.models import error_log +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + # 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_data() will fail _pending = { - # Detection mode: 'AUTO_DISCOVERY', 'STATIC_CHECKS' or 'GENERATOR' + # Detection mode # NULL means all detection methods have failed (maybe still reachable instance) "detection_mode" : {}, # Found nodeinfo URL @@ -54,67 +60,60 @@ _pending = { "last_status_code" : {}, # Last error details "last_error_details" : {}, + # Wether obfuscation has been used + "has_obfuscation" : {}, } def _set_data(key: str, domain: str, value: any): - # DEBUG: print(f"DEBUG: key='{key}',domain='{domain}',value[]='{type(value)}' - CALLED!") + logger.debug("key='%s',domain='%s',value[]='%s' - CALLED!", key, domain, type(value)) + domain_helper.raise_on(domain) if not isinstance(key, str): raise ValueError("Parameter key[]='{type(key)}' is not 'str'") elif key == "": raise ValueError("Parameter 'key' is empty") - elif not isinstance(domain, str): - raise ValueError(f"Parameter domain[]='{type(domain)}' is not 'str'") - elif domain == "": - raise ValueError("Parameter 'domain' is empty") elif not key in _pending: raise ValueError(f"key='{key}' not found in _pending") - elif not fba.is_primitive(value): + elif not utils.is_primitive(value): raise ValueError(f"value[]='{type(value)}' is not a primitive type") # Set it _pending[key][domain] = value - # DEBUG: print("DEBUG: EXIT!") + logger.debug("EXIT!") def has_pending(domain: str) -> bool: - # DEBUG: print(f"DEBUG: domain='{domain}' - CALLED!") - if not isinstance(domain, str): - raise ValueError(f"Parameter domain[]='{type(domain)}' is not 'str'") - elif domain == "": - raise ValueError("Parameter 'domain' is empty") + logger.debug("domain='%s' - CALLED!", domain) + domain_helper.raise_on(domain) has = False for key in _pending: - # DEBUG: print(f"DEBUG: key='{key}',domain='{domain}',_pending[key]()='{len(_pending[key])}'") + logger.debug("key='%s',domain='%s',_pending[key]()=%d", key, domain, len(_pending[key])) if domain in _pending[key]: has = True break - # DEBUG: print(f"DEBUG: has='{has}' - EXIT!") + logger.debug("has='%s' - EXIT!", has) return has def update_data(domain: str): - # DEBUG: print(f"DEBUG: domain='{domain}' - CALLED!") - if not isinstance(domain, str): - raise ValueError(f"Parameter domain[]='{type(domain)}' is not 'str'") - elif domain == "": - raise ValueError("Parameter 'domain' is empty") - elif not has_pending(domain): + logger.debug("domain='%s' - CALLED!", domain) + domain_helper.raise_on(domain) + if not has_pending(domain): raise Exception(f"domain='{domain}' has no pending instance data, but function invoked") elif not is_registered(domain): raise Exception(f"domain='{domain}' cannot be updated while not being registered") - # DEBUG: print(f"DEBUG: Updating instance data for domain='{domain}' ...") + logger.debug("Updating instance data for domain='%s' ...", domain) sql_string = "" fields = list() for key in _pending: - # DEBUG: print("DEBUG: key:", key) + logger.debug("Checking key='%s',domain='%s'", key, domain) if domain in _pending[key]: - # DEBUG: print(f"DEBUG: Adding '{_pending[key][domain]}' for key='{key}' ...") + logger.debug("Adding '%s' for key='%s' ...", _pending[key][domain], key) fields.append(_pending[key][domain]) sql_string += f" {key} = ?," - # DEBUG: print(f"DEBUG: sql_string()={len(sql_string)}") + logger.debug("sql_string()=%d", len(sql_string)) if sql_string == "": raise ValueError(f"No fields have been set, but method invoked, domain='{domain}'") @@ -124,35 +123,33 @@ def update_data(domain: str): # For WHERE statement fields.append(domain) - # DEBUG: print(f"DEBUG: sql_string='{sql_string}',fields()={len(fields)}") + logger.debug("sql_string='%s',fields()=%d", sql_string, len(fields)) sql_string = "UPDATE instances SET" + sql_string + " last_updated = ? WHERE domain = ? LIMIT 1" - # DEBUG: print("DEBUG: sql_string:", sql_string) - # DEBUG: print("DEBUG: Executing SQL:", sql_string) - fba.cursor.execute(sql_string, fields) + logger.debug("Executing SQL: '%s'", sql_string) + database.cursor.execute(sql_string, fields) - # DEBUG: print(f"DEBUG: Success! (rowcount={fba.cursor.rowcount })") - if fba.cursor.rowcount == 0: + logger.debug("rowcount=%d", database.cursor.rowcount) + if database.cursor.rowcount == 0: raise Exception(f"Did not update any rows: domain='{domain}',fields()={len(fields)}") - # DEBUG: print("DEBUG: Committing changes ...") - fba.connection.commit() + logger.debug("Invoking commit() ...") + database.connection.commit() - # DEBUG: print(f"DEBUG: Deleting _pending for domain='{domain}'") + logger.debug("Deleting _pending for domain='%s'", domain) for key in _pending: - # DEBUG: print(f"DEBUG: domain='{domain}',key='{key}'") + logger.debug("domain='%s',key='%s'", domain, key) if domain in _pending[key]: + logger.debug("Deleting key='%s',domain='%s' ...", key, domain) del _pending[key][domain] - # DEBUG: print("DEBUG: EXIT!") + logger.debug("EXIT!") def add(domain: str, origin: str, command: str, path: str = None, software: str = None): - # DEBUG: print(f"DEBUG: domain='{domain}',origin='{origin}',command='{command}',path='{path}',software='{software}' - CALLED!") - if not isinstance(domain, str): - raise ValueError(f"Parameter domain[]='{type(domain)}' is not 'str'") - elif domain == "": - raise ValueError("Parameter 'domain' is empty") - elif not isinstance(origin, str) and origin is not None: + logger.debug("domain='%s',origin='%s',command='%s',path='%s',software='%s' - CALLED!", domain, origin, command, path, software) + domain_helper.raise_on(domain) + + if not isinstance(origin, str) and origin is not None: raise ValueError(f"origin[]='{type(origin)}' is not 'str'") elif origin == "": raise ValueError("Parameter 'origin' is empty") @@ -160,8 +157,6 @@ def add(domain: str, origin: str, command: str, path: str = None, software: str raise ValueError(f"command[]='{type(command)}' is not 'str'") elif command == "": raise ValueError("Parameter 'command' is empty") - elif not validators.domain(domain.split("/")[0]): - raise ValueError(f"Bad domain name='{domain}'") elif not isinstance(path, str) and path is not None: raise ValueError(f"path[]='{type(path)}' is not 'str'") elif path == "": @@ -170,274 +165,254 @@ def add(domain: str, origin: str, command: str, path: str = None, software: str raise ValueError(f"software[]='{type(software)}' is not 'str'") elif software == "": raise ValueError("Parameter 'software' is empty") - elif domain.endswith(".arpa"): - raise ValueError(f"Please don't crawl .arpa domains: domain='{domain}'") elif origin is not None and not validators.domain(origin.split("/")[0]): 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 or (software == "lemmy" and domain.find("/c/") > 0): + elif domain.find("/profile/") > 0 or domain.find("/users/") > 0 or (is_registered(domain.split("/")[0]) and domain.find("/c/") > 0): raise Exception(f"domain='{domain}' is a single user") + elif domain.find("/tag/") > 0: + raise Exception(f"domain='{domain}' is a tag") if software is None: try: - # DEBUG: print("DEBUG: domain,origin,command,path:", domain, origin, command, path) + logger.debug("domain='%s',origin='%s',command='%s',path='%s'", domain, origin, command, path) software = federation.determine_software(domain, path) except network.exceptions as exception: - print(f"WARNING: Exception '{type(exception)}' during determining software type") + logger.warning("Exception '%s' during determining software type, domain='%s'", type(exception), domain) set_last_error(domain, exception) - # DEBUG: print("DEBUG: Determined software:", software) + logger.debug("Determined software='%s'", software) if software == "lemmy" and domain.find("/c/") > 0: domain = domain.split("/c/")[0] if is_registered(domain): - print(f"WARNING: domain='{domain}' already registered after cutting off user part. - EXIT!") + logger.warning("domain='%s' already registered after cutting off user part. - EXIT!", domain) return - print(f"INFO: Adding instance domain='{domain}' (origin='{origin}',software='{software}')") - fba.cursor.execute( + logger.info("Adding instance domain='%s',origin='%s',software='%s',command='%s'", domain, origin, software, command) + database.cursor.execute( "INSERT INTO instances (domain, origin, command, hash, software, first_seen) VALUES (?, ?, ?, ?, ?, ?)", ( domain, origin, command, - fba.get_hash(domain), + utils.get_hash(domain), software, time.time() ), ) - # DEBUG: print(f"DEBUG: Marking domain='{domain}' as registered.") + logger.debug("Marking domain='%s' as registered.", domain) cache.set_sub_key("is_registered", domain, True) + logger.debug("Checking if domain='%s' has pending updates ...", domain) if has_pending(domain): - # DEBUG: print(f"DEBUG: domain='{domain}' has pending nodeinfo being updated ...") + logger.debug("Flushing updates for domain='%s' ...", domain) update_data(domain) - # DEBUG: print("DEBUG: EXIT!") + logger.debug("EXIT!") def set_last_nodeinfo(domain: str): - # DEBUG: print(f"DEBUG: domain='{domain}' - CALLED!") - if not isinstance(domain, str): - raise ValueError(f"Parameter domain[]='{type(domain)}' is not 'str'") - elif domain == "": - raise ValueError("Parameter 'domain' is empty") + logger.debug("domain='%s' - CALLED!", domain) + domain_helper.raise_on(domain) - # DEBUG: print("DEBUG: Updating last_nodeinfo for domain:", domain) + logger.debug("Updating last_nodeinfo for domain='%s'", domain) _set_data("last_nodeinfo", domain, time.time()) - # Running pending updated - # DEBUG: print(f"DEBUG: Invoking update_data({domain}) ...") - update_data(domain) - - # DEBUG: print("DEBUG: EXIT!") + logger.debug("EXIT!") def set_last_error(domain: str, error: dict): - # DEBUG: print("DEBUG: domain,error[]:", domain, type(error)) - if not isinstance(domain, str): - raise ValueError(f"Parameter domain[]='{type(domain)}' is not 'str'") - elif domain == "": - raise ValueError("Parameter 'domain' is empty") + logger.debug("domain='%s',error[]='%s' - CALLED!", domain, type(error)) + domain_helper.raise_on(domain) - # DEBUG: print("DEBUG: BEFORE error[]:", type(error)) + logger.debug("error[]='%s' - BEFORE!", type(error)) if isinstance(error, (BaseException, json.decoder.JSONDecodeError)): error = f"error[{type(error)}]='{str(error)}'" - # DEBUG: print("DEBUG: AFTER error[]:", type(error)) + logger.debug("error[]='%s' - AFTER!", type(error)) if isinstance(error, str): - # DEBUG: print(f"DEBUG: Setting last_error_details='{error}'") + logger.debug("Setting last_error_details='%s' (str)", error) _set_data("last_status_code" , domain, 999) _set_data("last_error_details", domain, error if error != "" else None) elif isinstance(error, requests.models.Response): - # DEBUG: print(f"DEBUG: Setting last_error_details='{error.reason}'") + logger.debug("Setting last_error_details='%s' (Response)", error.reason) _set_data("last_status_code" , domain, error.status_code) _set_data("last_error_details", domain, error.reason if error.reason != "" else None) elif not isinstance(error, dict): raise KeyError(f"Cannot handle keys in error[{type(error)}]='{error}'") elif "status_code" in error and "error_message" in error: - # DEBUG: print(f"DEBUG: Setting last_error_details='{error['error_message']}'") + logger.debug("Setting last_error_details='%s' (error_message)", error['error_message']) _set_data("last_status_code" , domain, error["status_code"]) _set_data("last_error_details", domain, error["error_message"] if error["error_message"] != "" else None) elif "json" in error and "error" in error["json"]: + logger.debug("Setting last_error_details='%s' (json,error)", error["json"]["error"]) _set_data("last_status_code" , domain, error["status_code"]) _set_data("last_error_details", domain, error["json"]["error"] if error["json"]["error"] != "" else None) - # DEBUG: print(f"DEBUG: Invoking error_log.add(domain='{domain}',error[]='{type(error)}'") + logger.debug("Invoking error_log.add(domain='%s',error[]='%s'", domain, type(error)) error_log.add(domain, error) - # DEBUG: print("DEBUG: EXIT!") + logger.debug("EXIT!") + +def set_success(domain: str): + logger.debug("domain='%s' - CALLED!", domain) + domain_helper.raise_on(domain) + + # Set both to success + _set_data("last_status_code" , domain, 200) + _set_data("last_error_details", domain, None) + + logger.debug("EXIT!") def is_registered(domain: str) -> bool: - # DEBUG: print(f"DEBUG: domain='{domain}' - CALLED!") - if not isinstance(domain, str): - raise ValueError(f"Parameter domain[]='{type(domain)}' is not 'str'") - elif domain == "": - raise ValueError("Parameter 'domain' is empty") + logger.debug("domain='%s' - CALLED!", domain) + domain_helper.raise_on(domain) - # DEBUG: print(f"DEBUG: domain='{domain}' - CALLED!") + logger.debug("domain='%s' - CALLED!", domain) if not cache.key_exists("is_registered"): - # DEBUG: print("DEBUG: Cache for 'is_registered' not initialized, fetching all rows ...") - fba.cursor.execute("SELECT domain FROM instances") + logger.debug("Cache for 'is_registered' not initialized, fetching all rows ...") + database.cursor.execute("SELECT domain FROM instances") # Check Set all - cache.set_all("is_registered", fba.cursor.fetchall(), True) + cache.set_all("is_registered", database.cursor.fetchall(), True) # Is cache found? registered = cache.sub_key_exists("is_registered", domain) - # DEBUG: print(f"DEBUG: registered='{registered}' - EXIT!") + logger.debug("registered='%s' - EXIT!", registered) return registered -def is_recent(domain: str) -> bool: - # DEBUG: print(f"DEBUG: domain='{domain}' - CALLED!") - if not isinstance(domain, str): - raise ValueError(f"Parameter domain[]='{type(domain)}' is not 'str'") - elif domain == "": - raise ValueError("Parameter 'domain' is empty") +def is_recent(domain: str, column: str = "last_instance_fetch") -> bool: + logger.debug("domain='%s',column='%s' - CALLED!", domain) + domain_helper.raise_on(domain) + + if not isinstance(column, str): + raise ValueError(f"Parameter column[]='{type(column)}' is not 'str'") + elif column not in ["last_instance_fetch", "last_blocked"]: + raise ValueError(f"Parameter column='{column}' is not expected") elif not is_registered(domain): - # DEBUG: print(f"DEBUG: domain='{domain}' is not registered, returning False - EXIT!") + logger.debug("domain='%s' is not registered, returning False - EXIT!", domain) return False # Query database - fba.cursor.execute("SELECT last_instance_fetch FROM instances WHERE domain = ? LIMIT 1", [domain]) + database.cursor.execute(f"SELECT {column} FROM instances WHERE domain = ? LIMIT 1", [domain]) # Fetch row - fetched = fba.cursor.fetchone()[0] + fetched = database.cursor.fetchone()[0] - # DEBUG: print(f"DEBUG: fetched[{type(fetched)}]='{fetched}'") + logger.debug("fetched[%s]='%s'", type(fetched), fetched) recently = isinstance(fetched, float) and time.time() - fetched <= config.get("recheck_instance") - # DEBUG: print(f"DEBUG: recently='{recently}' - EXIT!") + logger.debug("recently='%s' - EXIT!", recently) return recently -def deobscure(char: str, domain: str, blocked_hash: str = None) -> tuple: - # DEBUG: print(f"DEBUG: char='{char}',domain='{domain}',blocked_hash='{blocked_hash}' - CALLED!") - if not isinstance(char, str): - raise ValueError(f"Parameter char[]='{type(char)}' is not 'str'") - elif char == "": - raise ValueError("Parameter 'char' is empty") - elif not isinstance(domain, str): +def deobfuscate(char: str, domain: str, blocked_hash: str = None) -> tuple: + logger.debug("char='%s',domain='%s',blocked_hash='%s' - CALLED!", char, domain, blocked_hash) + + if not isinstance(domain, str): raise ValueError(f"Parameter domain[]='{type(domain)}' is not 'str'") elif domain == "": raise ValueError("Parameter 'domain' is empty") + elif domain.lower() != domain: + raise ValueError(f"Parameter domain='{domain}' must be all lower-case") + elif domain.endswith(".arpa"): + raise ValueError(f"domain='{domain}' is a domain for reversed IP addresses, please don't crawl them!") + elif domain.endswith(".tld"): + raise ValueError(f"domain='{domain}' is a fake domain, please don't crawl them!") + elif not isinstance(char, str): + raise ValueError(f"Parameter char[]='{type(char)}' is not 'str'") + elif char == "": + raise ValueError("Parameter 'char' is empty") + elif not char in domain: + raise ValueError(f"char='{char}' not found in domain='{domain}' but function invoked") elif not isinstance(blocked_hash, str) and blocked_hash is not None: raise ValueError(f"Parameter blocked_hash[]='{type(blocked_hash)}' is not 'str'") + logger.debug("blocked_hash[]='%s'", type(blocked_hash)) if isinstance(blocked_hash, str): - # DEBUG: print(f"DEBUG: Looking up blocked_hash='{blocked_hash}' ...") - fba.cursor.execute( - "SELECT domain, origin, nodeinfo_url FROM instances WHERE hash = ? LIMIT 1", [blocked_hash] + logger.debug("Looking up blocked_hash='%s',domain='%s' ...", blocked_hash, domain) + database.cursor.execute( + "SELECT domain, origin, nodeinfo_url FROM instances WHERE hash = ? OR domain LIKE ? LIMIT 1", [blocked_hash, domain.replace(char, "_")] ) - row = fba.cursor.fetchone() - # DEBUG: print(f"DEBUG: row[]='{type(row)}'") + row = database.cursor.fetchone() + logger.debug("row[]='%s'", type(row)) if row is None: - # DEBUG: print(f"DEBUG: blocked_hash='{blocked_hash}' not found, trying domain='{domain}' ...") - return deobscure(char, domain) + logger.debug("blocked_hash='%s' not found, trying domain='%s' ...", blocked_hash, domain) + return deobfuscate(char, domain) else: - # DEBUG: print(f"DEBUG: Looking up domain='{domain}' ...") - fba.cursor.execute( + logger.debug("Looking up domain='%s' ...", domain) + database.cursor.execute( "SELECT domain, origin, nodeinfo_url FROM instances WHERE domain LIKE ? ORDER BY rowid LIMIT 1", [domain.replace(char, "_")] ) - row = fba.cursor.fetchone() - # DEBUG: print(f"DEBUG: row[]='{type(row)}'") + row = database.cursor.fetchone() + logger.debug("row[]='%s'", type(row)) - # DEBUG: print(f"DEBUG: row[]='{type(row)}' - EXIT!") + logger.debug("row[]='%s' - EXIT!", type(row)) return row -def set_last_blocked (domain: str): - # DEBUG: print(f"DEBUG: domain='{domain}' - CALLED!") - if not isinstance(domain, str): - raise ValueError(f"Parameter domain[]='{type(domain)}' is not 'str'") - elif domain == "": - raise ValueError("Parameter 'domain' is empty") +def set_last_blocked(domain: str): + logger.debug("domain='%s' - CALLED!", domain) + domain_helper.raise_on(domain) # Set timestamp _set_data("last_blocked", domain, time.time()) - # DEBUG: print("DEBUG: EXIT!") + logger.debug("EXIT!") -def set_last_instance_fetch (domain: str): - # DEBUG: print(f"DEBUG: domain='{domain}' - CALLED!") - if not isinstance(domain, str): - raise ValueError(f"Parameter domain[]='{type(domain)}' is not 'str'") - elif domain == "": - raise ValueError("Parameter 'domain' is empty") +def set_last_instance_fetch(domain: str): + logger.debug("domain='%s' - CALLED!", domain) + domain_helper.raise_on(domain) # Set timestamp _set_data("last_instance_fetch", domain, time.time()) - # DEBUG: print("DEBUG: EXIT!") + logger.debug("EXIT!") -def set_total_peers (domain: str, peers: list): - # DEBUG: print(f"DEBUG: domain='{domain}',peers()={len(peers)} - CALLED!") - if not isinstance(domain, str): - raise ValueError(f"Parameter domain[]='{type(domain)}' is not 'str'") - elif domain == "": - raise ValueError("Parameter 'domain' is empty") - elif not isinstance(peers, list): - raise ValueError("Parameter peers[]='{type(peers)}' is not 'list'") +def set_total_peers(domain: str, peers: list): + logger.debug("domain='%s',peers()=%d - CALLED!", domain, len(peers)) + domain_helper.raise_on(domain) + + if not isinstance(peers, list): + raise ValueError(f"Parameter peers[]='{type(peers)}' is not 'list': '%s'") # Set timestamp _set_data("total_peers", domain, len(peers)) - # DEBUG: print("DEBUG: EXIT!") + logger.debug("EXIT!") -def set_nodeinfo_url (domain: str, url: list): - # DEBUG: print(f"DEBUG: domain='{domain}',url='{url}' - CALLED!") - if not isinstance(domain, str): - raise ValueError(f"Parameter domain[]='{type(domain)}' is not 'str'") - elif domain == "": - raise ValueError("Parameter 'domain' is empty") - elif not isinstance(url, str): - raise ValueError("Parameter url[]='{type(url)}' is not 'list'") - elif url == "": - raise ValueError("Parameter 'url' is empty") - - # Set timestamp - _set_data("nodeinfo_url", domain, url) - # DEBUG: print("DEBUG: EXIT!") +def set_nodeinfo_url(domain: str, url: str): + logger.debug("domain='%s',url='%s' - CALLED!", domain, url) + domain_helper.raise_on(domain) -def set_detection_mode (domain: str, url: list): - # DEBUG: print(f"DEBUG: domain='{domain}',url='{url}' - CALLED!") - if not isinstance(domain, str): - raise ValueError(f"Parameter domain[]='{type(domain)}' is not 'str'") - elif domain == "": - raise ValueError("Parameter 'domain' is empty") - elif not isinstance(url, str): + if not isinstance(url, str): raise ValueError("Parameter url[]='{type(url)}' is not 'list'") elif url == "": raise ValueError("Parameter 'url' is empty") # Set timestamp - _set_data("detection_mode", domain, url) - # DEBUG: print("DEBUG: EXIT!") - -def set_detection_mode (domain: str, url: list): - # DEBUG: print(f"DEBUG: domain='{domain}',url='{url}' - CALLED!") - if not isinstance(domain, str): - raise ValueError(f"Parameter domain[]='{type(domain)}' is not 'str'") - elif domain == "": - raise ValueError("Parameter 'domain' is empty") - elif not isinstance(url, str): - raise ValueError("Parameter url[]='{type(url)}' is not 'list'") - elif url == "": - raise ValueError("Parameter 'url' is empty") + _set_data("nodeinfo_url", domain, url) + logger.debug("EXIT!") - # Set timestamp - _set_data("detection_mode", domain, url) - # DEBUG: print("DEBUG: EXIT!") +def set_detection_mode(domain: str, mode: str): + logger.debug("domain='%s',mode='%s' - CALLED!", domain, mode) + domain_helper.raise_on(domain) -def set_detection_mode (domain: str, mode: list): - # DEBUG: print(f"DEBUG: domain='{domain}',mode='{mode}' - CALLED!") - if not isinstance(domain, str): - raise ValueError(f"Parameter domain[]='{type(domain)}' is not 'str'") - elif domain == "": - raise ValueError("Parameter 'domain' is empty") - elif not isinstance(mode, str): + if not isinstance(mode, str): raise ValueError("Parameter mode[]='{type(mode)}' is not 'list'") elif mode == "": raise ValueError("Parameter 'mode' is empty") # Set timestamp _set_data("detection_mode", domain, mode) - # DEBUG: print("DEBUG: EXIT!") + logger.debug("EXIT!") + +def set_has_obfuscation(domain: str, status: bool): + logger.debug("domain(%d)='%s',status='%s' - CALLED!", len(domain), domain, status) + domain_helper.raise_on(domain) + + if not isinstance(status, bool): + raise ValueError(f"Parameter status[]='{type(status)}' is not 'bool'") + + # Set timestamp + _set_data("has_obfuscation", domain, status) + logger.debug("EXIT!")