-
-with open("config.json") as f:
- config = json.loads(f.read())
-
-domain = sys.argv[1]
-
-blacklist = [
- "activitypub-troll.cf",
- "gab.best",
- "4chan.icu",
- "social.shrimpcam.pw",
- "mastotroll.netz.org"
-]
-
-headers = {
- "user-agent": config["useragent"]
-}
-
-
-def get_hash(domain: str) -> str:
- return sha256(domain.encode("utf-8")).hexdigest()
-
-
-def get_peers(domain: str) -> str:
- try:
- res = get(f"https://{domain}/api/v1/instance/peers", headers=headers, timeout=5)
- return res.json()
- except:
- return None
-
-peerlist = get_peers(domain)
-
-def get_type(instdomain: str) -> str:
- try:
- res = get(f"https://{instdomain}/nodeinfo/2.1.json", headers=headers, timeout=5)
- if res.status_code == 404:
- res = get(f"https://{instdomain}/nodeinfo/2.0", headers=headers, timeout=5)
- if res.status_code == 404:
- res = get(f"https://{instdomain}/nodeinfo/2.0.json", headers=headers, timeout=5)
- if res.ok and "text/html" in res.headers["content-type"]:
- res = get(f"https://{instdomain}/nodeinfo/2.1", headers=headers, timeout=5)
- if res.ok:
- if res.json()["software"]["name"] in ["akkoma", "rebased"]:
- return "pleroma"
- elif res.json()["software"]["name"] in ["hometown", "ecko"]:
- return "mastodon"
- elif res.json()["software"]["name"] in ["calckey", "groundpolis", "foundkey", "cherrypick"]:
- return "misskey"
- else:
- return res.json()["software"]["name"]
- elif res.status_code == 404:
- res = get(f"https://{instdomain}/api/v1/instance", headers=headers, timeout=5)
- if res.ok:
- return "mastodon"
- except:
- return None
-
-
-conn = sqlite3.connect("blocks.db")
-c = conn.cursor()
-
-c.execute(
- "SELECT domain FROM instances WHERE 1"
+import time
+import validators
+import fba
+
+def fetch_instances(domain: str, origin: str, software: str, path: str = None):
+ # NOISY-DEBUG: print("DEBUG: domain,origin,software,path:", domain, origin, software, path)
+ if not fba.is_instance_registered(domain):
+ # NOISY-DEBUG: print("DEBUG: Adding new domain:", domain, origin)
+ fba.add_instance(domain, origin, sys.argv[0], path)
+
+ # NOISY-DEBUG: print("DEBUG: Fetching instances for domain:", domain, software)
+ peerlist = fba.get_peers(domain, software)
+
+ if (peerlist is None):
+ print("ERROR: Cannot fetch peers:", domain)
+ return
+ elif fba.has_pending_nodeinfos(domain):
+ # NOISY-DEBUG: print(f"DEBUG: domain='{domain}' has pending nodeinfo data, flushing ...")
+ fba.update_nodeinfos(domain)
+
+ print(f"INFO: Checking {len(peerlist)} instances from {domain} ...")
+ for instance in peerlist:
+ # NOISY-DEBUG: print("DEBUG: BEFORE instance:", instance)
+ instance = fba.tidyup(instance)
+ # NOISY-DEBUG: print("DEBUG: AFTER instance:", instance)
+
+ if instance == "":
+ print("WARNING: Empty instance after tidyup(), domain:", domain)
+ continue
+ elif not validators.domain(instance.split("/")[0]):
+ print(f"WARNING: Bad instance='{instance}' from domain='{domain}',origin='{origin}',software='{software}'")
+ continue
+ elif fba.is_blacklisted(instance):
+ # NOISY-DEBUG: print("DEBUG: instance is blacklisted:", instance)
+ continue
+
+ # NOISY-DEBUG: print("DEBUG: Handling instance:", instance)
+ try:
+ if not fba.is_instance_registered(instance):
+ # NOISY-DEBUG: print("DEBUG: Adding new instance:", instance, domain)
+ fba.add_instance(instance, domain, sys.argv[0])
+ except BaseException as e:
+ print(f"ERROR: instance='{instance}',exception:'{str(e)}'")
+ continue
+
+instance = sys.argv[1]
+
+# Initial fetch
+fetch_instances(instance, None, None)
+
+# Loop through some instances
+fba.cursor.execute(
+ "SELECT domain, origin, software, nodeinfo_url FROM instances WHERE software IN ('pleroma', 'mastodon', 'friendica', 'misskey', 'gotosocial', 'bookwyrm', 'takahe', 'lemmy') AND (last_instance_fetch IS NULL OR last_instance_fetch < ?) ORDER BY rowid DESC", [time.time() - fba.config["recheck_instance"]]