]> git.mxchange.org Git - fba.git/blobdiff - fba/networks/lemmy.py
Continued:
[fba.git] / fba / networks / lemmy.py
index a48b3c0a8422d86b646a51e3d4f212c8746d64fc..88e18e0acd56b78dcf319b8319d39f732d7005a4 100644 (file)
 # 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 inspect
 import logging
 
 import bs4
 
 from fba import csrf
-from fba import database
 from fba import utils
 
 from fba.helpers import config
@@ -30,14 +28,14 @@ from fba.helpers import tidyup
 from fba.http import federation
 from fba.http import network
 
-from fba.models import blocks
 from fba.models import instances
 
 logging.basicConfig(level=logging.INFO)
 logger = logging.getLogger(__name__)
+#logger.setLevel(logging.DEBUG)
 
-def fetch_peers(domain: str) -> list:
-    logger.debug("domain(%d)='%s' - CALLED!", len(domain), domain)
+def fetch_peers(domain: str, origin: str) -> list:
+    logger.debug("domain='%s',origin='%s' - CALLED!", domain, origin)
     domain_helper.raise_on(domain)
 
     peers = list()
@@ -51,7 +49,7 @@ def fetch_peers(domain: str) -> list:
     except network.exceptions as exception:
         logger.warning("Exception '%s' during checking CSRF (fetch_peers,%s) - EXIT!", type(exception), __name__)
         instances.set_last_error(domain, exception)
-        return peers
+        return list()
 
     try:
         logger.debug("Fetching '/api/v3/site' from domain='%s' ...", domain)
@@ -69,18 +67,18 @@ def fetch_peers(domain: str) -> list:
         elif "federated_instances" in data["json"] and isinstance(data["json"]["federated_instances"], dict):
             logger.debug("Found federated_instances for domain='%s'", domain)
             peers = peers + federation.add_peers(data["json"]["federated_instances"])
-            logger.debug("Added instance(s) to peers")
-        else:
-            logger.warning("JSON response does not contain 'federated_instances', domain='%s'", domain)
-            instances.set_last_error(domain, data)
+
+            logger.debug("Marking domain='%s' as successfully handled ...", domain)
+            instances.set_success(domain)
+
+        if len(peers) == 0:
+            logger.warning("Fetching instances for domain='%s' from /instances ...", domain)
+            peers = fetch_instances(domain, origin)
 
     except network.exceptions as exception:
         logger.warning("Exception during fetching JSON: domain='%s',exception[%s]:'%s'", domain, type(exception), str(exception))
         instances.set_last_error(domain, exception)
 
-    logger.debug("Adding %d for domain='%s'", len(peers), domain)
-    instances.set_total_peers(domain, peers)
-
     logger.debug("peers()=%d - EXIT!", len(peers))
     return peers
 
@@ -94,36 +92,36 @@ def fetch_blocks(domain: str, nodeinfo_url: str) -> list:
         raise ValueError("Parameter 'nodeinfo_url' is empty")
 
     translations = [
-        "Blocked Instances",
-        "Instàncies bloquejades",
-        "Blocáilte Ásc",
-        "封锁实例",
-        "Blokované instance",
-        "Geblokkeerde instanties",
-        "Blockerade instanser",
-        "Instàncias blocadas",
-        "Istanze bloccate",
-        "Instances bloquées",
-        "Letiltott példányok",
-        "Instancias bloqueadas",
-        "Blokeatuta dauden instantziak",
-        "차단된 인스턴스",
-        "Peladen Yang Diblokir",
-        "Blokerede servere",
-        "Blokitaj nodoj",
-        "Блокирани Инстанции",
-        "Blockierte Instanzen",
-        "Estetyt instanssit",
-        "Instâncias bloqueadas",
-        "Zablokowane instancje",
-        "Blokované inštancie",
-        "المثلاء المحجوبون",
-        "Užblokuoti serveriai",
-        "ブロックしたインスタンス",
-        "Блокированные Инстансы",
-        "Αποκλεισμένοι διακομιστές",
-        "封鎖站台",
-        "Instâncias bloqueadas",
+        "Blocked Instances".lower(),
+        "Instàncies bloquejades".lower(),
+        "Blocáilte Ásc".lower(),
+        "封锁实例".lower(),
+        "Blokované instance".lower(),
+        "Geblokkeerde instanties".lower(),
+        "Blockerade instanser".lower(),
+        "Instàncias blocadas".lower(),
+        "Istanze bloccate".lower(),
+        "Instances bloquées".lower(),
+        "Letiltott példányok".lower(),
+        "Instancias bloqueadas".lower(),
+        "Blokeatuta dauden instantziak".lower(),
+        "차단된 인스턴스".lower(),
+        "Peladen Yang Diblokir".lower(),
+        "Blokerede servere".lower(),
+        "Blokitaj nodoj".lower(),
+        "Блокирани Инстанции".lower(),
+        "Blockierte Instanzen".lower(),
+        "Estetyt instanssit".lower(),
+        "Instâncias bloqueadas".lower(),
+        "Zablokowane instancje".lower(),
+        "Blokované inštancie".lower(),
+        "المثلاء المحجوبون".lower(),
+        "Užblokuoti serveriai".lower(),
+        "ブロックしたインスタンス".lower(),
+        "Блокированные Инстансы".lower(),
+        "Αποκλεισμένοι διακομιστές".lower(),
+        "封鎖站台".lower(),
+        "Instâncias bloqueadas".lower(),
     ]
 
     blocklist = list()
@@ -153,7 +151,13 @@ def fetch_blocks(domain: str, nodeinfo_url: str) -> list:
                 content = header.contents[0]
 
                 logger.debug("content[%s]='%s'", type(content), content)
-                if content in translations:
+                if content is None:
+                    logger.debug("domain='%s' has returned empty header='%s' - SKIPPED!", domain, header)
+                    continue
+                elif not isinstance(content, str):
+                    logger.debug("content[]='%s' is not supported/wanted type 'str' - SKIPPED!", type(content))
+                    continue
+                elif content.lower() in translations:
                     logger.debug("Found header with blocked instances - BREAK!")
                     found = header
                     break
@@ -163,18 +167,21 @@ def fetch_blocks(domain: str, nodeinfo_url: str) -> list:
                 logger.debug("domain='%s' is not blocking any instances - EXIT!", domain)
                 return blocklist
 
-            blocking = found.find_next("ul").findAll("a")
+            blocking = found.find_next(["ul","table"]).findAll("a")
             logger.debug("Found %d blocked instance(s) ...", len(blocking))
             for tag in blocking:
                 logger.debug("tag[]='%s'", type(tag))
                 blocked = tidyup.domain(tag.contents[0])
                 logger.debug("blocked='%s'", blocked)
 
-                if not utils.is_domain_wanted(blocked):
+                if blocked == "":
+                    logger.warning("blocked='%s' is empty after tidyup.domain() - SKIPPED!", tag.contents[0])
+                    continue
+                elif not utils.is_domain_wanted(blocked):
                     logger.debug("blocked='%s' is not wanted - SKIPPED!", blocked)
                     continue
 
-                logger.debug("Appending blocker='%s',blocked='%s',block_level='reject'", domain, blocked)
+                logger.debug("Appending blocker='%s',blocked='%s',block_level='reject' ...", domain, blocked)
                 blocklist.append({
                     "blocker"    : domain,
                     "blocked"    : blocked,
@@ -188,3 +195,62 @@ def fetch_blocks(domain: str, nodeinfo_url: str) -> list:
 
     logger.debug("blocklist()=%d - EXIT!", len(blocklist))
     return blocklist
+
+def fetch_instances(domain: str, origin: str) -> list:
+    logger.debug("domain='%s',origin='%s' - CALLED!", domain, origin)
+    domain_helper.raise_on(domain)
+
+    peers = list()
+
+    try:
+        # json endpoint for newer mastodongs
+        logger.debug("Fetching /instances from domain='%s'", domain)
+        response = network.fetch_response(
+            domain,
+            "/instances",
+            network.web_headers,
+            (config.get("connection_timeout"), config.get("read_timeout"))
+        )
+
+        logger.debug("response.ok='%s',response.status_code=%d,response.text()=%d", response.ok, response.status_code, len(response.text))
+        if response.ok and response.status_code < 300 and response.text != "":
+            logger.debug("Parsing %s Bytes ...", len(response.text))
+
+            doc = bs4.BeautifulSoup(response.text, "html.parser")
+            logger.debug("doc[]='%s'", type(doc))
+
+            headers = doc.findAll("h5")
+            logger.debug("Checking %d headers ...", len(headers))
+            for header in headers:
+                logger.debug("header[%s]='%s'", type(header), header)
+
+                rows = header.find_next(["ul","table"]).findAll("a")
+                logger.debug("Found %d blocked instance(s) ...", len(rows))
+                for tag in rows:
+                    logger.debug("tag[]='%s'", type(tag))
+                    text = tag.contents[0] if isinstance(tag.contents[0], str) else tag.contents[0].text
+                    peer = tidyup.domain(text)
+                    logger.debug("peer='%s'", peer)
+
+                    if peer == "":
+                        logger.debug("peer is empty - SKIPPED!")
+                        continue
+                    elif not utils.is_domain_wanted(peer):
+                        logger.debug("peer='%s' is not wanted - SKIPPED!", peer)
+                        continue
+                    elif peer in peers:
+                        logger.debug("peer='%s' already added - SKIPPED!", peer)
+                        continue
+
+                    logger.debug("Appending peer='%s' ...", peer)
+                    peers.append(peer)
+
+        logger.debug("Marking domain='%s' as successfully handled ...", domain)
+        instances.set_success(domain)
+
+    except network.exceptions as exception:
+        logger.warning("domain='%s',exception[%s]:'%s'", domain, type(exception), str(exception))
+        instances.set_last_error(domain, exception)
+
+    logger.debug("peers()=%d - EXIT!", len(peers))
+    return peers