]> git.mxchange.org Git - fba.git/commitdiff
Major frontend & API rehaul
authorMint <>
Tue, 29 Nov 2022 23:36:35 +0000 (02:36 +0300)
committerMint <>
Tue, 29 Nov 2022 23:36:35 +0000 (02:36 +0300)
api.py
index.html

diff --git a/api.py b/api.py
index 051fca76c4ddc24d65f53d05815f74953e7a2434..f2742ed6cea32e0d2b96f2e877ef897fa64d897c 100644 (file)
--- a/api.py
+++ b/api.py
@@ -6,6 +6,7 @@ from fastapi.templating import Jinja2Templates
 from requests import get
 from json import loads
 from re import sub
+from datetime import datetime
 
 with open("config.json") as f:
     config = loads(f.read())
@@ -30,9 +31,33 @@ def info():
         "blocks_recorded": blocks
     }
 
+@app.get(base_url+"/top")
+def top(blocked: int = None, blockers: int = None):
+    conn = sqlite3.connect("blocks.db")
+    c = conn.cursor()
+    if blocked == None and blockers == None:
+        raise HTTPException(status_code=400, detail="No filter specified")
+    elif blocked != None:
+        if blocked > 500:
+            raise HTTPException(status_code=400, detail="Too many results")
+        c.execute("select blocked, count(blocked) from blocks where block_level = 'reject' group by blocked order by count(blocked) desc limit ?", (blocked,))
+    elif blockers != None:
+        if blockers > 500:
+            raise HTTPException(status_code=400, detail="Too many results")
+        c.execute("select blocker, count(blocker) from blocks where block_level = 'reject' group by blocker order by count(blocker) desc limit ?", (blockers,))
+    scores = c.fetchall()
+    c.close()
+
+    scoreboard = []
+    print(scores)
+    for domain, highscore in scores:
+        scoreboard.append({"domain": domain, "highscore": highscore})
+
+    return scoreboard
+
 @app.get(base_url+"/api")
-def blocked(domain: str = None, reason: str = None):
-    if domain == None and reason == None:
+def blocked(domain: str = None, reason: str = None, reverse: str = None):
+    if domain == None and reason == None and reverse == None:
         raise HTTPException(status_code=400, detail="No filter specified")
     if reason != None:
         reason = sub("(%|_)", "", reason)
@@ -43,45 +68,46 @@ def blocked(domain: str = None, reason: str = None):
     if domain != None:
         wildchar = "*." + ".".join(domain.split(".")[-domain.count("."):])
         punycode = domain.encode('idna').decode('utf-8')
-        c.execute("select blocker, blocked, block_level, reason from blocks where blocked = ? or blocked = ? or blocked = ? or blocked = ? or blocked = ? or blocked = ?",
+        c.execute("select blocker, blocked, block_level, reason, first_added, last_seen from blocks where blocked = ? or blocked = ? or blocked = ? or blocked = ? or blocked = ? or blocked = ? order by first_added asc",
                   (domain, "*." + domain, wildchar, get_hash(domain), punycode, "*." + punycode))
+    elif reverse != None:
+        c.execute("select blocker, blocked, block_level, reason, first_added, last_seen from blocks where blocker = ? order by first_added asc", (reverse,))
     else:
-        c.execute("select blocker, blocked, reason, block_level from blocks where reason like ? and reason != ''", ("%"+reason+"%",))
+        c.execute("select blocker, blocked, block_level, reason, first_added, last_seen from blocks where reason like ? and reason != '' order by first_added asc", ("%"+reason+"%",))
     blocks = c.fetchall()
-    conn.close()
+    c.close()
 
     result = {}
-    reasons = {}
-    wildcards = []
-    if domain != None:
-        for domain, blocked, block_level, reason in blocks:
-            if block_level in result:
-                result[block_level].append(domain)
-            else:
-                result[block_level] = [domain]
-            if blocked == "*." + ".".join(blocked.split(".")[-blocked.count("."):]):
-                wildcards.append(domain)
-            if reason != "":
-                if block_level in reasons:
-                    reasons[block_level][domain] = reason
-                else:
-                    reasons[block_level] = {domain: reason}
-        return {"blocks": result, "reasons": reasons, "wildcards": wildcards}
-
-    for blocker, blocked, reason, block_level in blocks:
+    for blocker, blocked, block_level, reason, first_added, last_seen in blocks:
+        entry = {"blocker": blocker, "blocked": blocked, "reason": reason, "first_added": first_added, "last_seen": last_seen}
         if block_level in result:
-            result[block_level].append({"blocker": blocker, "blocked": blocked, "reason": reason})
+            result[block_level].append(entry)
         else:
-            result[block_level] = [{"blocker": blocker, "blocked": blocked, "reason": reason}]
-    return {"blocks": result}
+            result[block_level] = [entry]
+
+    return result
+
+@app.get(base_url+"/scoreboard")
+def index(request: Request, blockers: int = None, blocked: int = None):
+    if blockers == None and blocked == None:
+        raise HTTPException(status_code=400, detail="No filter specified")
+    elif blockers != None:
+        scores = get(f"http://127.0.0.1:{port}{base_url}/top?blockers={blockers}")
+    elif blocked != None:
+        scores = get(f"http://127.0.0.1:{port}{base_url}/top?blocked={blocked}")
+    if scores != None:
+        if not scores.ok:
+            raise HTTPException(status_code=blocks.status_code, detail=blocks.text)
+        scores = scores.json()
+    return templates.TemplateResponse("index.html", {"request": request, "scoreboard": True, "blockers": blockers, "blocked": blocked, "scores": scores})
 
 @app.get(base_url+"/")
-def index(request: Request, domain: str = None, reason: str = None):
-    if domain == "" or reason == "":
+def index(request: Request, domain: str = None, reason: str = None, reverse: str = None):
+    if domain == "" or reason == "" or reverse == "":
         return responses.RedirectResponse("/")
     info = None
     blocks = None
-    if domain == None and reason == None:
+    if domain == None and reason == None and reverse == None:
         info = get(f"http://127.0.0.1:{port}{base_url}/info")
         if not info.ok:
             raise HTTPException(status_code=info.status_code, detail=info.text)
@@ -90,11 +116,18 @@ def index(request: Request, domain: str = None, reason: str = None):
         blocks = get(f"http://127.0.0.1:{port}{base_url}/api?domain={domain}")
     elif reason != None:
         blocks = get(f"http://127.0.0.1:{port}{base_url}/api?reason={reason}")
+    elif reverse != None:
+        blocks = get(f"http://127.0.0.1:{port}{base_url}/api?reverse={reverse}")
     if blocks != None:
         if not blocks.ok:
             raise HTTPException(status_code=blocks.status_code, detail=blocks.text)
         blocks = blocks.json()
-    return templates.TemplateResponse("index.html", {"request": request, "domain": domain, "blocks": blocks, "reason": reason, "info": info})
+        for block_level in blocks:
+            for block in blocks[block_level]:
+                block["first_added"] = datetime.utcfromtimestamp(block["first_added"]).strftime('%Y-%m-%d %H:%M')
+                block["last_seen"] = datetime.utcfromtimestamp(block["last_seen"]).strftime('%Y-%m-%d %H:%M')
+
+    return templates.TemplateResponse("index.html", {"request": request, "domain": domain, "blocks": blocks, "reason": reason, "reverse": reverse, "info": info})
 
 if __name__ == "__main__":
     uvicorn.run("api:app", host="127.0.0.1", port=port, log_level="info")
index 644bf1d24c22ac7e99f50034de1a938e8f3a31cf..65afe7f9fa2f7b2217aaad8e4e9364fd94d8fb03 100644 (file)
         }
         .block_level {
             background-color: #1c1c3c;
-            width: 750px;
+            width: 80em;
             padding: 5px;
             margin: auto;
             margin-top: 10px;
         }
+        .scoreboard {
+            background-color: #1c1c3c;
+            width: 40em;
+            padding: 5px;
+            margin: auto;
+            margin-top: 10px;
+        }
+        table {
+            width: 100%;
+            background-color: #2d2d4d;
+            border-spacing: 0px;
+        }
+        table tr:nth-of-type(2n) {
+            background-color: #1c1c3c;
+        }
+        table td {
+            padding: 4px;
+        }
+        .block_level table td:nth-of-type(1), .block_level table td:nth-of-type(2),
+        .block_level table td:nth-of-type(4), .block_level table td:nth-of-type(5) {
+            white-space: nowrap;
+        }
         .block {
             background-color: #2d2d4d;
             padding: 5px;
     </style>
 </head>
 <body>
-    {% if reason %}
-        <h1>Instances that use "{{reason}}" in their Reason</h1>
-        {% for block_level in blocks.blocks %}
-            <div class="block_level">
-                <h2>{{block_level}} ({{blocks.blocks[block_level]|length}})</h2>
-                {% for block in blocks.blocks[block_level] %}
-                    <div class="block">
-                        <img src="https://proxy.duckduckgo.com/ip3/{{block.blocker}}.ico" width=16/>
-                        <b><a href="https://{{block.blocker}}" rel="nofollow noopener noreferrer">{{block.blocker}}</a></b> ->
-                        <img src="https://proxy.duckduckgo.com/ip3/{{block.blocked}}.ico" width=16/>
-                        <b><a href="https://{{block.blocked}}" rel="nofollow noopener noreferrer">{{block.blocked}}</a></b><br/>
-                        {{block.reason}}
-                    </div>
+    {% if scoreboard %}
+        {% if blockers %}
+            <h1>Top {{blockers}} defederating instances</h1>
+        {% elif blocked %}
+            <h1>Top {{blocked}} defederated instances</h1>
+        {% endif %}
+        <div class="scoreboard">
+            <table>
+                <th>Instance</th>
+                <th>Defederations</th>
+                {% for entry in scores %}
+                    <tr>
+                        <td>
+                            <img src="https://proxy.duckduckgo.com/ip3/{{entry['domain']}}.ico" width=16/>
+                            <b><a href="https://{{entry['domain']}}" rel="nofollow noopener noreferrer">{{entry['domain']}}</a></b>
+                        </td>
+                        <td>{{entry['highscore']}}</td>
+                    </tr>
                 {% endfor %}
-            </div>
-        {% endfor %}
-    {% elif blocks %}
-        <h1>Instances that block {{domain}}</h1>
-        {% for block_level in blocks.blocks %}
+            </table>
+        </div>
+    {% elif reason or blocks or reverse %}
+        {% if reason %}
+            <h1>Instances that use "{{reason}}" in their reason</h1>
+        {% elif reverse %}
+            <h1>Instances that are blocked by {{reverse}}</h1>
+        {% elif blocks %}
+            <h1>Instances that block {{domain}}</h1>
+        {% endif %}
+        {% for block_level in blocks %}
             <div class="block_level" id="{{block_level}}">
-                <h2>{{block_level}} ({{blocks.blocks[block_level]|length}})</h2>
-                {% for block in blocks.blocks[block_level] %}
-                    <div class="block">
-                        <img src="https://proxy.duckduckgo.com/ip3/{{block}}.ico" width=16/>
-                        <b><a href="https://{{block}}" rel="nofollow noopener noreferrer">{{block}}</a></b>
-                        {% if block in blocks.wildcards %}
-                            (<span title="wildcard block">&lowast;</span>)
-                        {% endif %}
-                        <br/>
-                        {% if block_level in blocks.reasons %}
-                            {{blocks.reasons[block_level][block]}}
-                        {% endif %}
-                    </div>
-                {% endfor %}
+                <h2>{{block_level}} ({{blocks[block_level]|length}})</h2>
+                <table>
+                    <th>Blocker</th>
+                    <th>{% if block_level == 'accept' %}Accepted{% else %}Blocked{% endif %}</th>
+                    <th>Reason</th>
+                    <th>First added</th>
+                    <th>Last seen</th>
+                    {% for block in blocks[block_level] %}
+                        <tr>
+                            <td>
+                                <img src="https://proxy.duckduckgo.com/ip3/{{block['blocker']}}.ico" width=16/>
+                                <b><a href="https://{{block['blocker']}}" rel="nofollow noopener noreferrer">{{block['blocker']}}</a></b>
+                            </td>
+                            <td>
+                                <img src="https://proxy.duckduckgo.com/ip3/{{domain or block['blocked']}}.ico" width=16/>
+                                <b><a href="https://{{domain or block['blocked']}}" rel="nofollow noopener noreferrer">{{block['blocked']}}</a></b>
+                            </td>
+                            <td>{{block['reason']}}</td>
+                            <td>{{block['first_added']}}</td>
+                            <td>{{block['last_seen']}}</td>
+                        </tr>
+                    {% endfor %}
+                </table>
             </div>
         {% endfor %}
     {% else %}
             <input type="text" name="reason" placeholder="free speech" />
             <input type="submit" value="Submit" />
         </form>
+        <h1>Reverse search</h1>
+        <form>
+            <input type="text" name="reverse" placeholder="example.com" />
+            <input type="submit" value="Submit" />
+        </form>
+        <p>
+            <a href="./scoreboard?blockers=50">top 50 defederating</a> / <a href="./scoreboard?blocked=50">defederated instances</a>
+        </p>
         <div class="info">
             known instances: {{info.known_instances}}<br/>
             indexed instances: {{info.indexed_instances}}<br/>
             blocks recorded: {{info.blocks_recorded}}<br/>
-            source code: <a href="https://git.kiwifarms.net/mint/fedi-block-api">git.kiwifarms.net/mint/fedi-block-api</a> (<a href="https://gitgud.io/mintplg/fedi-block-api">mirror</a>)
+            source code: <a href="https://git.kiwifarms.net/mint/fedi-block-api">git.kiwifarms.net/mint/fedi-block-api</a> (<a href="https://gitgud.io/mintplg/fedi-block-api">mirror</a>)<br/>
+            fuck jannies
         </div>
     {% endif %}
 </body>