]> git.mxchange.org Git - fba.git/commitdiff
Continued:
authorRoland Häder <roland@mxchange.org>
Thu, 29 Jun 2023 09:47:03 +0000 (11:47 +0200)
committerRoland Häder <roland@mxchange.org>
Thu, 29 Jun 2023 10:09:57 +0000 (12:09 +0200)
- introduced new view "/infos"
- changed indexed row array to associative e.g. row[0] had become row['domain']

13 files changed:
daemon.py
fba/commands.py
fba/database.py
fba/helpers/cache.py
fba/http/network.py
fba/utils.py
static/css/light.css
templates/base.html
templates/views/index.html
templates/views/infos.html [new file with mode: 0644]
templates/views/scoreboard.html
templates/views/top.html
templates/widgets/links.html

index 7ec401f2b89fa55354356675e974445b14be5065..d46d4e087b145b7d9966c7735a36603af21d785a 100755 (executable)
--- a/daemon.py
+++ b/daemon.py
@@ -316,6 +316,38 @@ def top(request: Request, mode: str, value: str, amount: int = config.get("api_l
         "theme"    : config.get("theme"),
     })
 
+@router.get(config.get("base_url") + "/infos")
+def rss(request: Request, domain: str):
+    # Tidy up domain name
+    domain = tidyup.domain(domain)
+
+    if not utils.is_domain_wanted(domain):
+        raise HTTPException(status_code=500, detail=f"domain='{domain}' is not wanted")
+
+    # Fetch domain data
+    database.cursor.execute("SELECT * FROM instances WHERE domain = ? LIMIT 1", [domain])
+    domain_data = database.cursor.fetchone()
+
+    # Format timestamps
+    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"]:
+            # Timestamps
+            instance[key] = datetime.utcfromtimestamp(domain_data[key]).strftime(format) if isinstance(domain_data[key], float) else "-"
+        else:
+            # Generic
+            instance[key] = domain_data[key]
+
+    print(domain_data.keys())
+    return templates.TemplateResponse("views/infos.html", {
+        "request" : request,
+        "domain"  : domain,
+        "instance": instance,
+        "theme"   : config.get("theme"),
+        "slogan"  : config.get("slogan"),
+    })
+
 @router.get(config.get("base_url") + "/rss")
 def rss(request: Request, domain: str = None):
     if domain is not None:
index 0b5715ef3a50f01da9ada3ed19a4de0a03dc2dbd..309a6b159251a96ccf156792960eac59f36ac77a 100644 (file)
@@ -307,9 +307,9 @@ def fetch_blocks(args: argparse.Namespace) -> int:
                     instances.set_has_obfuscation(blocker, True)
                     continue
 
-                block["blocked"] = row[0]
-                origin           = row[1]
-                nodeinfo_url     = row[2]
+                block["blocked"] = row["domain"]
+                origin           = row["origin"]
+                nodeinfo_url     = row["nodeinfo_url"]
             elif block["blocked"].find("?") >= 0:
                 logger.debug("blocker='%s' uses obfuscated domains", blocker)
 
@@ -322,9 +322,9 @@ def fetch_blocks(args: argparse.Namespace) -> int:
                     instances.set_has_obfuscation(blocker, True)
                     continue
 
-                block["blocked"] = row[0]
-                origin           = row[1]
-                nodeinfo_url     = row[2]
+                block["blocked"] = row["domain"]
+                origin           = row["origin"]
+                nodeinfo_url     = row["nodeinfo_url"]
 
             logger.debug("Looking up instance by domainm, blocked='%s'", block["blocked"])
             if not utils.is_domain_wanted(block["blocked"]):
@@ -726,17 +726,17 @@ def fetch_instances(args: argparse.Namespace) -> int:
     rows = database.cursor.fetchall()
     logger.info("Checking %d entries ...", len(rows))
     for row in rows:
-        logger.debug("domain='%s'", row[0])
-        if not utils.is_domain_wanted(row[0]):
-            logger.debug("Domain row[0]='%s' is not wanted - SKIPPED!", row[0])
+        logger.debug("domain='%s'", row["domain"])
+        if not utils.is_domain_wanted(row["domain"]):
+            logger.debug("Domain row[domain]='%s' is not wanted - SKIPPED!", row["domain"])
             continue
 
         try:
-            logger.info("Fetching instances for domain='%s',origin='%s',software='%s',nodeinfo_url='%s'", row[0], row[1], row[2], row[3])
-            federation.fetch_instances(row[0], row[1], row[2], inspect.currentframe().f_code.co_name, row[3])
+            logger.info("Fetching instances for domain='%s',origin='%s',software='%s',nodeinfo_url='%s'", row["domain"], row["origin"], row["software"], row["nodeinfo_url"])
+            federation.fetch_instances(row["domain"], row["origin"], row["software"], inspect.currentframe().f_code.co_name, row["nodeinfo_url"])
         except network.exceptions as exception:
-            logger.warning("Exception '%s' during fetching instances (fetch_instances) from row[0]='%s'", type(exception), row[0])
-            instances.set_last_error(row[0], exception)
+            logger.warning("Exception '%s' during fetching instances (fetch_instances) from row[domain]='%s'", type(exception), row["domain"])
+            instances.set_last_error(row["domain"], exception)
 
     logger.debug("Success - EXIT!")
     return 0
@@ -1117,9 +1117,9 @@ def recheck_obfuscation(args: argparse.Namespace) -> int:
 
     locking.acquire()
 
-    if args.domain != "" and utils.is_domain_wanted(args.domain):
+    if isinstance(args.domain, str) and args.domain != "" and utils.is_domain_wanted(args.domain):
         database.cursor.execute("SELECT domain, software, nodeinfo_url FROM instances WHERE has_obfuscation = 1 AND domain = ?", [args.domain])
-    elif args.domain != "" and validators.domain(args.software) == args.software:
+    elif isinstance(args.software, str) and args.software != "" and validators.domain(args.software) == args.software:
         database.cursor.execute("SELECT domain, software, nodeinfo_url FROM instances WHERE has_obfuscation = 1 AND software = ?", [args.software])
     else:
         database.cursor.execute("SELECT domain, software, nodeinfo_url FROM instances WHERE has_obfuscation = 1")
@@ -1127,28 +1127,28 @@ def recheck_obfuscation(args: argparse.Namespace) -> int:
     rows = database.cursor.fetchall()
     logger.info("Checking %d domains ...", len(rows))
     for row in rows:
-        logger.debug("Fetching peers from domain='%s',software='%s',nodeinfo_url='%s' ...", row[0], row[1], row[2])
+        logger.debug("Fetching peers from domain='%s',software='%s',nodeinfo_url='%s' ...", row["domain"], row["software"], row["nodeinfo_url"])
 
         blocking = list()
-        if row[1] == "pleroma":
-            logger.debug("domain='%s',software='%s'", row[0], row[1])
-            blocking = pleroma.fetch_blocks(row[0], row[2])
-        elif row[1] == "mastodon":
-            logger.debug("domain='%s',software='%s'", row[0], row[1])
-            blocking = mastodon.fetch_blocks(row[0], row[2])
-        elif row[1] == "lemmy":
-            logger.debug("domain='%s',software='%s'", row[0], row[1])
-            blocking = lemmy.fetch_blocks(row[0], row[2])
-        elif row[1] == "friendica":
-            logger.debug("domain='%s',software='%s'", row[0], row[1])
-            blocking = friendica.fetch_blocks(row[0])
-        elif row[1] == "misskey":
-            logger.debug("domain='%s',software='%s'", row[0], row[1])
-            blocking = misskey.fetch_blocks(row[0])
+        if row["software"] == "pleroma":
+            logger.debug("domain='%s',software='%s'", row["domain"], row["software"])
+            blocking = pleroma.fetch_blocks(row["domain"], row["nodeinfo_url"])
+        elif row["software"] == "mastodon":
+            logger.debug("domain='%s',software='%s'", row["domain"], row["software"])
+            blocking = mastodon.fetch_blocks(row["domain"], row["nodeinfo_url"])
+        elif row["software"] == "lemmy":
+            logger.debug("domain='%s',software='%s'", row["domain"], row["software"])
+            blocking = lemmy.fetch_blocks(row["domain"], row["nodeinfo_url"])
+        elif row["software"] == "friendica":
+            logger.debug("domain='%s',software='%s'", row["domain"], row["software"])
+            blocking = friendica.fetch_blocks(row["domain"])
+        elif row["software"] == "misskey":
+            logger.debug("domain='%s',software='%s'", row["domain"], row["software"])
+            blocking = misskey.fetch_blocks(row["domain"])
         else:
-            logger.warning("Unknown sofware: domain='%s',software='%s'", row[0], row[1])
+            logger.warning("Unknown sofware: domain='%s',software='%s'", row["domain"], row["software"])
 
-        logger.info("Checking %d block(s) from domain='%s' ...", len(blocking), row[0])
+        logger.info("Checking %d block(s) from domain='%s' ...", len(blocking), row["domain"])
         obfuscated = 0
         blockdict = list()
         for block in blocking:
@@ -1167,11 +1167,11 @@ def recheck_obfuscation(args: argparse.Namespace) -> int:
             elif block["blocked"].find("*") >= 0 or block["blocked"].find("?") >= 0:
                 logger.debug("block='%s' is obfuscated.", block["blocked"])
                 obfuscated = obfuscated + 1
-                blocked = utils.deobfuscate_domain(block["blocked"], row[0], block["hash"] if "hash" in block else None)
+                blocked = utils.deobfuscate_domain(block["blocked"], row["domain"], block["hash"] if "hash" in block else None)
             elif not utils.is_domain_wanted(block["blocked"]):
                 logger.debug("blocked='%s' is not wanted - SKIPPED!", block["blocked"])
                 continue
-            elif blocks.is_instance_blocked(row[0], block["blocked"]):
+            elif blocks.is_instance_blocked(row["domain"], block["blocked"]):
                 logger.debug("blocked='%s' is already blocked - SKIPPED!", block["blocked"])
                 continue
 
@@ -1179,35 +1179,35 @@ def recheck_obfuscation(args: argparse.Namespace) -> int:
             if blocked is not None and blocked != block["blocked"]:
                 logger.debug("blocked='%s' was deobfuscated to blocked='%s'", block["blocked"], blocked)
                 obfuscated = obfuscated - 1
-                if blocks.is_instance_blocked(row[0], blocked):
-                    logger.debug("blocked='%s' is already blocked by domain='%s' - SKIPPED!", blocked, row[0])
+                if blocks.is_instance_blocked(row["domain"], blocked):
+                    logger.debug("blocked='%s' is already blocked by domain='%s' - SKIPPED!", blocked, row["domain"])
                     continue
 
                 block["block_level"] = utils.alias_block_level(block["block_level"])
 
                 logger.info("blocked='%s' has been deobfuscated to blocked='%s', adding ...", block["blocked"], blocked)
-                if utils.process_block(row[0], blocked, block["reason"], block["block_level"]) and block["block_level"] == "reject" and config.get("bot_enabled"):
-                    logger.debug("Appending blocked='%s',reason='%s' for blocker='%s' ...", block["blocked"], block["block_level"], row[0])
+                if utils.process_block(row["domain"], blocked, block["reason"], block["block_level"]) and block["block_level"] == "reject" and config.get("bot_enabled"):
+                    logger.debug("Appending blocked='%s',reason='%s' for blocker='%s' ...", block["blocked"], block["block_level"], row["domain"])
                     blockdict.append({
                         "blocked": blocked,
                         "reason" : block["reason"],
                     })
 
-        logger.info("domain='%s' has %d obfuscated domain(s)", row[0], obfuscated)
+        logger.info("domain='%s' has %d obfuscated domain(s)", row["domain"], obfuscated)
         if obfuscated == 0 and len(blocking) > 0:
-            logger.info("Block list from domain='%s' has been fully deobfuscated.", row[0])
-            instances.set_has_obfuscation(row[0], False)
+            logger.info("Block list from domain='%s' has been fully deobfuscated.", row["domain"])
+            instances.set_has_obfuscation(row["domain"], False)
 
-        if instances.has_pending(row[0]):
-            logger.debug("Flushing updates for blocker='%s' ...", row[0])
-            instances.update_data(row[0])
+        if instances.has_pending(row["domain"]):
+            logger.debug("Flushing updates for blocker='%s' ...", row["domain"])
+            instances.update_data(row["domain"])
 
         logger.debug("Invoking commit() ...")
         database.connection.commit()
 
         if config.get("bot_enabled") and len(blockdict) > 0:
-            logger.info("Sending bot POST for blocker='%s,blockdict()=%d ...", row[0], len(blockdict))
-            network.send_bot_post(row[0], blockdict)
+            logger.info("Sending bot POST for blocker='%s,blockdict()=%d ...", row["domain"], len(blockdict))
+            network.send_bot_post(row["domain"], blockdict)
 
     logger.debug("Success! - EXIT!")
     return 0
index 53b33bcc8b91dd8b71658265e10fdda3e62c6ffc..b87d94d68ac81172ceb7f44fd04ec253391fee10 100644 (file)
@@ -21,4 +21,9 @@ logger = logging.getLogger(__name__)
 
 # Connect to database
 connection = sqlite3.connect("blocks.db")
+
+# Init row factory
+connection.row_factory = sqlite3.Row
+
+# Get cursor
 cursor = connection.cursor()
index 05d3a809a64cb94666149e7390b3e6b30810e940..7a20a41f1447d04db6e96835b62d1f4232de96ed 100644 (file)
@@ -15,6 +15,7 @@
 # along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 import logging
+import sqlite3
 
 logging.basicConfig(level=logging.INFO)
 logger = logging.getLogger(__name__)
@@ -37,7 +38,7 @@ def set_all(key: str, rows: list, value: any):
 
     for sub in rows:
         logger.debug("Setting key='%s',sub[%s]='%s'", key, type(sub), sub)
-        if isinstance(sub, tuple):
+        if isinstance(sub, sqlite3.Row):
             logger.debug("Setting key='%s',sub[%s]='%s',value[]='%s'", key, type(sub), sub, type(value))
             _cache[key][sub[0]] = value
         else:
index e3233006aea37a6e9c2daec4f4c5cc7a98a7acaa..20ae9ee9694a854dc124399bc589c656416543a0 100644 (file)
@@ -82,6 +82,7 @@ def post_json_api(domain: str, path: str, data: str = "", headers: dict = dict()
             cookies=cookies.get_all(domain) if cookies.has(domain) else dict()
         )
 
+        logger.info("Parsing JSON response from domain='%s',path='%s' ...", domain, path)
         json_reply["json"] = json_from_response(response)
 
         logger.debug("response.ok='%s',response.status_code=%d,json_reply[]='%s'", response.ok, response.status_code, type(json_reply))
@@ -89,8 +90,8 @@ def post_json_api(domain: str, path: str, data: str = "", headers: dict = dict()
             logger.warning("Cannot query JSON API: domain='%s',path='%s',data()=%d,response.status_code=%d,json_reply[]='%s'", domain, path, len(data), response.status_code, type(json_reply))
             json_reply["status_code"]   = response.status_code
             json_reply["error_message"] = response.reason
-            del json_reply["json"]
             instances.set_last_error(domain, response)
+            del json_reply["json"]
 
     except exceptions as exception:
         logger.debug("Fetching path='%s' from domain='%s' failed. exception[%s]='%s'", path, domain, type(exception), str(exception))
@@ -120,6 +121,7 @@ def fetch_api_url(url: str, timeout: tuple) -> dict:
         logger.debug("Fetching url='%s' ...", url)
         response = utils.fetch_url(url, api_headers, timeout)
 
+        logger.info("Parsing JSON response from url='%s' ...", url)
         json_reply["json"] = json_from_response(response)
 
         logger.debug("response.ok='%s',response.status_code='%s',json_reply[]='%s'", response.ok, response.status_code, type(json_reply))
@@ -173,6 +175,7 @@ def get_json_api(domain: str, path: str, headers: dict, timeout: tuple) -> dict:
         instances.set_last_error(domain, exception)
         raise exception
 
+    logger.info("Parsing JSON response from domain='%s',path='%s' ...", domain, path)
     json_reply["json"] = json_from_response(response)
 
     logger.debug("response.ok='%s',response.status_code=%d,json_reply[]='%s'", response.ok, response.status_code, type(json_reply))
@@ -272,7 +275,7 @@ def json_from_response(response: requests.models.Response) -> list:
         try:
             data = response.json()
         except json.decoder.JSONDecodeError as exception:
-            logger.warning("Exception '%s' during decoding JSON", type(exception))
+            logger.warning("Exception '%s' during decoding JSON from response.url='%s'", type(exception), response.url)
 
     logger.debug("data[]='%s' - EXIT!", type(data))
     return data
index 2befee36a97ff4728027bfb1ec102cbdf3f6bc4f..f2ff076cfee671c72656f9ffd9e9d1fab788eeaa 100644 (file)
@@ -197,8 +197,8 @@ def deobfuscate_domain(domain: str, blocker: str, domain_hash: str = None) -> st
 
         logger.debug("row[]='%s'", type(row))
         if row is not None:
-            logger.debug("domain='%s' de-obscured to '%s'", domain, row[0])
-            domain = row[0]
+            logger.debug("domain='%s' de-obscured to '%s'", domain, row["domain"])
+            domain = row["domain"]
         else:
             logger.debug("blocker='%s' has domain that cannot be deobfuscated.", blocker)
             instances.set_has_obfuscation(blocker, True)
@@ -210,8 +210,8 @@ def deobfuscate_domain(domain: str, blocker: str, domain_hash: str = None) -> st
 
         logger.debug("row[]='%s'", type(row))
         if row is not None:
-            logger.debug("domain='%s' de-obscured to '%s'", domain, row[0])
-            domain = row[0]
+            logger.debug("domain='%s' de-obscured to '%s'", domain, row["domain"])
+            domain = row["domain"]
         else:
             logger.debug("blocker='%s' has domain that cannot be deobfuscated.", blocker)
             instances.set_has_obfuscation(blocker, True)
index 47aea43d913e6412259200cc42593fe173f8957e..e46a4a75021ceab1a7336dc264e36471f8f5a13c 100644 (file)
@@ -33,11 +33,26 @@ th {
     padding-bottom: 4px;
 }
 
-table.with-rows > tbody > tr:nth-of-type(2n),
-table.with-rows > thead {
+.index-table {
+    width: 700px;
+    margin-left: auto;
+    margin-right: auto;
+}
+
+.table-with-rows > tbody > tr:nth-of-type(2n),
+.table-with-rows > thead,
+.index-table > thead {
     background-color: #eaeaea;
 }
 
+.index-table h3 {
+    margin: 0px;
+}
+
+.index-table form {
+    padding: 2px;
+}
+
 table td {
     padding: 4px;
     text-align: left;
index 7191ba4c9eeffca7f17c1dae496c7996b55aa4fc..d67f14df43ab39e852619af004bde4e075c33a6a 100644 (file)
@@ -4,11 +4,12 @@
     <title>fedi-block-api - {% block title %}{% endblock %}</title>
 
     <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+    <base href="{{base_url}}" />
 
-    <link rel="alternate" type="application/rss+xml" title="RSS Feed for latest blocked instances" href="{{base_url}}/rss" />
+    <link rel="alternate" type="application/rss+xml" title="RSS Feed for latest blocked instances" href="rss" />
     {% block rss %}{% endblock %}
 
-    <link rel="stylesheet" type="text/css" href="{{ url_for('static', path='css/' + theme + '.css') }}" media="all" />
+    <link rel="stylesheet" type="text/css" href="{{ url_for('static', path='css/' + theme + '.css') }}?v=0.0.1" media="all" />
 </head>
 
 <body>
index 71c0e80d5c190edc757799bb3a38a87160b68edf..320c1c0575fda38be3a305541e548992d767fcc0 100644 (file)
@@ -5,40 +5,65 @@
 {% block header %}<h1>Welcome to FBA</h1>{% endblock %}
 
 {% block content %}
-    <h2>Enter a Domain</h2>
-    <form action="top">
-        <input type="hidden" name="mode" value="domain" />
-        <input type="text" name="value" placeholder="example.com" required="required" />
-        <input type="submit" value="Submit" />
-    </form>
+    <table class="index-table">
+    <thead>
+        <th colspan="2">
+            <h3>Choose an option</h3>
+        </th>
+    </thead>
 
-    <h2>Enter a Reason</h2>
-    <form action="top">
-        <input type="hidden" name="mode" value="reason" />
-        <input type="text" name="value" placeholder="free speech" required="required" />
-        <input type="submit" value="Submit" />
-    </form>
-
-    <h2>Reverse search</h2>
-    <form action="top">
-        <input type="hidden" name="mode" value="reverse" />
-        <input type="text" name="value" placeholder="example.com" required="required" />
-        <input type="submit" value="Submit" />
-    </form>
+    <tbody>
+    <tr>
+        <td>
+            <h3>Enter a domain:</h3>
+            <form action="top">
+                <input type="hidden" name="mode" value="domain" />
+                <input type="text" name="value" placeholder="example.com" required="required" />
+                <input type="submit" value="Submit" />
+            </form>
+        </td>
+        <td>
+            <h3>Enter a reason:</h3>
+            <form action="top">
+                <input type="hidden" name="mode" value="reason" />
+                <input type="text" name="value" placeholder="free speech" required="required" />
+                <input type="submit" value="Submit" />
+            </form>
+        </td>
+    </tr>
+    <tr>
+        <td>
+            <h3>Reverse search:</h3>
+            <form action="top">
+                <input type="hidden" name="mode" value="reverse" />
+                <input type="text" name="value" placeholder="example.com" required="required" />
+                <input type="submit" value="Submit" />
+            </form>
+        </td>
+        <td>
+            <h3>Info of a domain:</h3>
+            <form action="infos">
+                <input type="text" name="domain" placeholder="example.com" required="required" />
+                <input type="submit" value="Submit" />
+            </form>
+        </td>
+    </tr>
+    </tbody>
+    </table>
 
     <h2>Scoreboards:</h2>
     <ul class="nav">
-        <li><a href="{{base_url}}/scoreboard?mode=blocker&amp;amount=50">Defederating instances</a></li>
-        <li><a href="{{base_url}}/scoreboard?mode=blocked&amp;amount=50">Defederated instances</a></li>
-        <li><a href="{{base_url}}/scoreboard?mode=reference&amp;amount=50">Referencing instances</a></li>
-        <li><a href="{{base_url}}/scoreboard?mode=software&amp;amount=50">Used software</a></li>
-        <li><a href="{{base_url}}/scoreboard?mode=command&amp;amount=10">Commands</a></li>
-        <li><a href="{{base_url}}/scoreboard?mode=error_code&amp;amount=30">Error codes</a></li>
-        <li><a href="{{base_url}}/scoreboard?mode=detection_mode&amp;amount=10">Detection modes</a></li>
-        <li><a href="{{base_url}}/scoreboard?mode=avg_peers&amp;amount=30">Average peers</a></li>
-        <li><a href="{{base_url}}/scoreboard?mode=obfuscator&amp;amount=30">Obfuscating software</a></li>
-        <li><a href="{{base_url}}/scoreboard?mode=obfuscation&amp;amount=10">Obfuscation statistics</a></li>
-        <li><a href="{{base_url}}/scoreboard?mode=block_level&amp;amount=20">Block level statistics</a></li>
+        <li><a href="scoreboard?mode=blocker&amp;amount=50">Defederating instances</a></li>
+        <li><a href="scoreboard?mode=blocked&amp;amount=50">Defederated instances</a></li>
+        <li><a href="scoreboard?mode=reference&amp;amount=50">Referencing instances</a></li>
+        <li><a href="scoreboard?mode=software&amp;amount=50">Used software</a></li>
+        <li><a href="scoreboard?mode=command&amp;amount=10">Commands</a></li>
+        <li><a href="scoreboard?mode=error_code&amp;amount=30">Error codes</a></li>
+        <li><a href="scoreboard?mode=detection_mode&amp;amount=10">Detection modes</a></li>
+        <li><a href="scoreboard?mode=avg_peers&amp;amount=30">Average peers</a></li>
+        <li><a href="scoreboard?mode=obfuscator&amp;amount=30">Obfuscating software</a></li>
+        <li><a href="scoreboard?mode=obfuscation&amp;amount=10">Obfuscation statistics</a></li>
+        <li><a href="scoreboard?mode=block_level&amp;amount=20">Block level statistics</a></li>
     </ul>
 {% endblock %}
 {% block footer %}
diff --git a/templates/views/infos.html b/templates/views/infos.html
new file mode 100644 (file)
index 0000000..2764c72
--- /dev/null
@@ -0,0 +1,104 @@
+{% extends "base.html" %}
+
+{% block title %}Infos on domain {{domain}}{% endblock %}
+
+{% block header %}<h1>Infos on {{domain}}</h1>{% endblock %}
+
+{% block content %}
+<div class="infos">
+    <table class="table-with-rows">
+    <thead>
+        <th colspan="2">
+            <h3>Instance information</h3>
+        </th>
+    </thead>
+
+    <tbody>
+    <tr>
+        <td>Domain name:</td>
+        <td>{% with domain=instance['domain'] %}{% include "widgets/links.html" %}{% endwith %}</td>
+    </tr>
+
+    <tr>
+        <td>Domain hash:</td>
+        <td>{{instance['hash']}}</td>
+    </tr>
+
+    <tr>
+        <td>Software:</td>
+        <td>{{instance['software']}}</td>
+    </tr>
+
+    <tr>
+        <td>Originating instance:</td>
+        <td>{% if instance['origin'] != None %}{% with domain=instance['origin'] %}{% include "widgets/links.html" %}{% endwith %}{% else %}-{% endif %}</td>
+    </tr>
+
+    <tr>
+        <td>Command:</td>
+        <td><code>{{instance['command']}}</code></td>
+    </tr>
+
+    <tr>
+        <td>Detection mode:</td>
+        <td><em>{{instance['detection_mode']}}</em></td>
+    </tr>
+
+    <tr>
+        <td>NodeInfo URL:</td>
+        <td>{{instance['nodeinfo_url']}}</td>
+    </tr>
+
+    <tr>
+        <td>Total peers:</td>
+        <td>{{instance['total_peers']}}</td>
+    </tr>
+
+    <tr>
+        <td>Has obfuscated block list:</td>
+        <td>{% if instance['has_obfuscation']%}Yes{%elif not instance['has_obfuscation']%}No{%else%}-{%endif%}</td>
+    </tr>
+
+    <tr>
+        <td>First seen:</td>
+        <td>{{instance['first_seen']}}</td>
+    </tr>
+
+    <tr>
+        <td>Last updated:</td>
+        <td>{{instance['last_updated']}}</td>
+    </tr>
+
+    <tr>
+        <td>Last nodeinfo fetched:</td>
+        <td>{{instance['last_nodeinfo']}}</td>
+    </tr>
+
+    <tr>
+        <td>Last blocks fetched:</td>
+        <td>{{instance['last_blocked']}}</td>
+    </tr>
+
+    <tr>
+        <td>Last instances fetched:</td>
+        <td>{{instance['last_instance_fetch']}}</td>
+    </tr>
+
+    <tr>
+        <td>Last status code:</td>
+        <td>{{instance['last_status_code']}}</td>
+    </tr>
+
+    <tr>
+        <td>Last error details:</td>
+        <td>{{instance['last_error_details']}}</td>
+    </tr>
+    </tbody>
+    </table>
+</div>
+{% endblock %}
+
+{% block footer %}
+    <a href="{{base_url}}/">Index</a> /
+    {{ super() }}
+{% endblock %}
index 51a7f4fc0c235bffac729b073a245df223d2b53a..512e40967a578ca75e7332c4942f80abf8b0c9ac 100644 (file)
@@ -30,7 +30,7 @@
 
 {% block content %}
     <div class="scoreboard">
-        <table class="with-rows">
+        <table class="table-with-rows">
             <thead>
                 <th>№</th>
                 <th>{% if mode in ('software', 'avg_peers', 'obfuscator') %}Software{% elif mode == 'obfuscation' %}Obfuscation status{% elif mode == 'detection_mode' %}Detection mode{% elif mode == 'error_code' %}Error code{% else %}Instance{% endif %}</th>
@@ -47,7 +47,7 @@
                         {% elif entry['domain'] == None %}
                             -
                         {% elif mode == 'block_level' %}
-                            <a href="{{base_url}}/top?mode=block_level&amp;value={{entry['domain']}}&amp;amount=50">{{entry['domain']}}</a>
+                            <a href="top?mode=block_level&amp;value={{entry['domain']}}&amp;amount=50">{{entry['domain']}}</a>
                         {% else %}
                             {% with domain=entry['domain'] %}
                             {% include "widgets/links.html" %}
index 204db6e25e3eae5d68b14bf8449263d8b4d10ad9..9b0d1c3309afe77fcee8d9a6c4edc159a54a7ce7 100644 (file)
@@ -5,9 +5,9 @@
 {% block rss %}
     {{ super() }}
     {% if mode == 'domain' %}
-        <link rel="alternate" type="application/rss+xml" title="RSS Feed for blocked domain {{value}}" href="{{base_url}}/rss?domain={{value}}" />
+        <link rel="alternate" type="application/rss+xml" title="RSS Feed for blocked domain {{value}}" href="rss?domain={{value}}" />
     {% elif mode == 'reverse' %}
-        <link rel="alternate" type="application/rss+xml" title="RSS Feed for blocking domain {{value}}" href="{{base_url}}/rss?reverse={{value}}" />
+        <link rel="alternate" type="application/rss+xml" title="RSS Feed for blocking domain {{value}}" href="rss?reverse={{value}}" />
     {% endif %}
 {% endblock %}
 
@@ -35,7 +35,7 @@
     {% for block_level in blocklist %}
         <div class="block_level">
             <h2>{{block_level}} ({{blocklist[block_level]|length}})</h2>
-            <table class="with-rows">
+            <table class="table-with-rows">
                 <thead>
                     <th>Blocker</th>
                     <th>{% if block_level == 'accept' %}Accepted{% else %}Blocked{% endif %}</th>
index 46b435a701a5cb465472ac8e8c27b027851053ba..e058c2e5da212dd299790aa2ee2f3eb99997daee 100644 (file)
@@ -1,3 +1,4 @@
-[<a class="listlink" href="{{base_url}}/top?mode=domain&amp;value={{domain}}" title="Search {{domain}}">D</a>]
-[<a class="listlink" href="{{base_url}}/top?mode=reverse&amp;value={{domain}}" title="Reverse search {{domain}}">R</a>]
+[<a class="listlink" href="top?mode=domain&amp;value={{domain}}" title="Search {{domain}}">D</a>]
+[<a class="listlink" href="top?mode=reverse&amp;value={{domain}}" title="Reverse search {{domain}}">R</a>]
+[<a class="listlink" href="infos?domain={{domain}}" title="Information on domain {{domain}}">I</a>]
 <a href="https://{{domain}}" rel="nofollow noopener noreferrer">{{domain}}</a>