]> git.mxchange.org Git - fba.git/blobdiff - daemon.py
Continued:
[fba.git] / daemon.py
index 2f2e32837acd9fe68136ed00ec9e2221f3baff87..499ffc11602eb85eb54f51e603156e54305806fe 100755 (executable)
--- a/daemon.py
+++ b/daemon.py
@@ -30,8 +30,8 @@ from fastapi.responses import PlainTextResponse
 from fastapi.staticfiles import StaticFiles
 from fastapi.templating import Jinja2Templates
 
-import uvicorn
 import requests
+import uvicorn
 
 from fba import database
 from fba import utils
@@ -41,6 +41,7 @@ from fba.helpers import json as json_helper
 from fba.helpers import tidyup
 
 from fba.models import blocks
+from fba.models import instances
 
 router = fastapi.FastAPI(docs_url=config.get("base_url") + "/docs", redoc_url=config.get("base_url") + "/redoc")
 router.mount(
@@ -103,6 +104,28 @@ def api_scoreboard(mode: str, amount: int):
 
     return scores
 
+@router.get(config.get("base_url") + "/api/list.json", response_class=JSONResponse)
+def api_list(request: Request, mode: str, value: str, amount: int):
+    if mode is None or value is None or amount is None:
+        raise HTTPException(status_code=500, detail="No filter specified")
+    elif amount > config.get("api_limit"):
+        raise HTTPException(status_code=500, detail=f"amount={amount} is to big")
+
+    domain = wildchar = punycode = reason = None
+
+    if mode in ("detection_mode", "software", "command"):
+        database.cursor.execute(
+            f"SELECT domain, origin, software, detection_mode, command, total_peers, total_blocks, first_seen, last_updated \
+FROM instances \
+WHERE {mode} = ? \
+ORDER BY domain \
+LIMIT ?", [value, amount]
+        )
+
+    domainlist = database.cursor.fetchall()
+
+    return domainlist
+
 @router.get(config.get("base_url") + "/api/top.json", response_class=JSONResponse)
 def api_index(request: Request, mode: str, value: str, amount: int):
     if mode is None or value is None or amount is None:
@@ -290,36 +313,52 @@ def index(request: Request):
         "slogan" : config.get("slogan"),
     })
 
-@router.get(config.get("base_url") + "/top")
-def top(request: Request, mode: str, value: str, amount: int = config.get("api_limit")):
-    response = requests.get(f"http://{config.get('host')}:{config.get('port')}{config.get('base_url')}/api/info.json")
+@router.get(config.get("base_url") + "/list")
+def list_domains(request: Request, mode: str, value: str, amount: int = config.get("api_limit")):
+    if mode == "detection_mode" and not instances.valid(value, "detection_mode"):
+        raise HTTPException(status_code=500, detail="Invalid detection mode provided")
 
-    if not response.ok:
-        raise HTTPException(status_code=response.status_code, detail=response.text)
-    elif mode == "" or value == "" or amount == 0:
-        raise HTTPException(status_code=500, detail="Parameter mode, value and amount must always be set")
-    elif amount > config.get("api_limit"):
-        raise HTTPException(status_code=500, detail=f"amount='{amount}' is to big")
+    response = requests.get(f"http://{config.get('host')}:{config.get('port')}{config.get('base_url')}/api/list.json?mode={mode}&value={value}&amount={amount}")
 
-    info = response.json()
-    blocklist = list()
+    domainlist = list()
+    if response is not None and response.ok:
+        domainlist = response.json()
+        format = config.get("timestamp_format")
+        for row in domainlist:
+            row["first_seen"]   = datetime.utcfromtimestamp(row["first_seen"]).strftime(format)
+            row["last_updated"] = datetime.utcfromtimestamp(row["last_updated"]).strftime(format) if isinstance(row["last_updated"], float) else None
+
+    return templates.TemplateResponse("views/list.html", {
+        "request"   : request,
+        "mode"      : mode if response is not None else None,
+        "value"     : value if response is not None else None,
+        "amount"    : amount if response is not None else None,
+        "found"     : len(domainlist),
+        "domainlist": domainlist,
+        "slogan"    : config.get("slogan"),
+        "theme"     : config.get("theme"),
+    })
 
-    if mode == "block_level" and not blocks.is_valid_level(value):
+@router.get(config.get("base_url") + "/top")
+def top(request: Request, mode: str, value: str, amount: int = config.get("api_limit")):
+    if mode == "block_level" and not blocks.valid(value, "block_level"):
         raise HTTPException(status_code=500, detail="Invalid block level provided")
     elif mode in ["domain", "reverse"] and not utils.is_domain_wanted(value):
         raise HTTPException(status_code=500, detail="Invalid or blocked domain specified")
 
     response = requests.get(f"http://{config.get('host')}:{config.get('port')}{config.get('base_url')}/api/top.json?mode={mode}&value={value}&amount={amount}")
 
-    if response is not None and response.ok:
+    found = 0
+    blocklist = list()
+    if response.ok and response.status_code == 200 and len(response.text) > 0:
         blocklist = response.json()
 
-    found = 0
-    for block_level in blocklist:
-        for block in blocklist[block_level]:
-            block["first_seen"] = datetime.utcfromtimestamp(block["first_seen"]).strftime(config.get("timestamp_format"))
-            block["last_seen"]  = datetime.utcfromtimestamp(block["last_seen"]).strftime(config.get("timestamp_format"))
-            found = found + 1
+        format = config.get("timestamp_format")
+        for block_level in blocklist:
+            for row in blocklist[block_level]:
+                row["first_seen"] = datetime.utcfromtimestamp(row["first_seen"]).strftime(format)
+                row["last_seen"]  = datetime.utcfromtimestamp(row["last_seen"]).strftime(format) if isinstance(row["last_seen"], float) else None
+                found = found + 1
 
     return templates.TemplateResponse("views/top.html", {
         "request"  : request,
@@ -328,7 +367,7 @@ def top(request: Request, mode: str, value: str, amount: int = config.get("api_l
         "amount"   : amount if response is not None else None,
         "found"    : found,
         "blocklist": blocklist,
-        "info"     : info,
+        "slogan"   : config.get("slogan"),
         "theme"    : config.get("theme"),
     })
 
@@ -342,7 +381,7 @@ def rss(request: Request, domain: str):
 
     response = requests.get(f"http://{config.get('host')}:{config.get('port')}{config.get('base_url')}/api/domain.json?domain={domain}")
 
-    if not response.ok or response.status_code > 200 or response.text.strip() == "":
+    if not response.ok or response.status_code >= 300 or response.text.strip() == "":
         raise HTTPException(status_code=response.status_code, detail=response.reason)
 
     domain_data = response.json()
@@ -351,9 +390,9 @@ def rss(request: Request, domain: str):
     format = config.get("timestamp_format")
     instance = dict()
     for key in domain_data.keys():
-        if key in ["last_nodeinfo", "last_blocked", "first_seen", "last_updated", "last_instance_fetch"]:
+        if key in ["last_nodeinfo", "last_blocked", "first_seen", "last_updated", "last_instance_fetch"] and isinstance(domain_data[key], float):
             # Timestamps
-            instance[key] = datetime.utcfromtimestamp(domain_data[key]).strftime(format) if isinstance(domain_data[key], float) else "-"
+            instance[key] = datetime.utcfromtimestamp(domain_data[key]).strftime(format)
         else:
             # Generic
             instance[key] = domain_data[key]