Skip to content

Commit 1e3f989

Browse files
committed
fixed: things
1 parent 3f994f0 commit 1e3f989

2 files changed

Lines changed: 46 additions & 55 deletions

File tree

main.py

Lines changed: 23 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,32 @@
11
# bello! dont bully my code im still learning gulp
22
# i appreciate any feedback or suggestions for improvement though! in fact im begging u to help me!
33
import os
4-
import magic # type: ignore
4+
import magic
55
import re
6-
import markdown # pyright: ignore[reportMissingModuleSource] GODDAMIT
6+
import markdown
7+
import httpx
78

8-
import httpx # pyright: ignore[reportMissingImports]
9-
10-
from fastapi import FastAPI, UploadFile, File, Form, Request, HTTPException # type: ignore
11-
from fastapi.middleware.cors import CORSMiddleware # pyright: ignore[reportMissingImports]
12-
from fastapi.responses import FileResponse, JSONResponse # pyright: ignore[reportMissingImports]
13-
from fastapi.staticfiles import StaticFiles # pyright: ignore[reportMissingImports]
14-
from fastapi.templating import Jinja2Templates # type: ignore
9+
from fastapi import FastAPI, UploadFile, File, Form, Request, HTTPException
10+
from fastapi.middleware.cors import CORSMiddleware
11+
from fastapi.responses import FileResponse, JSONResponse
12+
from fastapi.staticfiles import StaticFiles
13+
from fastapi.templating import Jinja2Templates
1514

1615
from google import genai
17-
from google.genai import types # pyright: ignore[reportMissingImports]
16+
from google.genai import types
1817

19-
from dotenv import load_dotenv # type: ignore
18+
from dotenv import load_dotenv
2019

21-
from slowapi import Limiter, _rate_limit_exceeded_handler # pyright: ignore[reportMissingImports]
22-
from slowapi.util import get_remote_address # pyright: ignore[reportMissingImports]
23-
from slowapi.errors import RateLimitExceeded # pyright: ignore[reportMissingImports]
20+
from slowapi import Limiter, _rate_limit_exceeded_handler
21+
from slowapi.util import get_remote_address
22+
from slowapi.errors import RateLimitExceeded
2423
from functools import wraps
2524
import time
2625

27-
# note: overkill? maybe! but i need the prac. also i wanna learn how to do this stuff cus im a chud
28-
from starlette.middleware.base import BaseHTTPMiddleware # pyright: ignore[reportMissingImports]
26+
from starlette.middleware.base import BaseHTTPMiddleware
2927
from pathlib import Path
30-
import bleach # pyright: ignore[reportMissingImports]
31-
from PIL import Image # pyright: ignore[reportMissingImports]
28+
import bleach
29+
from PIL import Image
3230
import io
3331

3432
load_dotenv()
@@ -61,7 +59,7 @@ async def dispatch(self, request: Request, call_next):
6159
"default-src 'self'; "
6260
"script-src 'self' 'unsafe-inline'; "
6361
"style-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com; "
64-
"img-src 'self' data: blob: https://*.google.com https://t1.gstatic.com https://*.gstatic.com; "
62+
"img-src 'self' data: blob: https://*.google.com https://t1.gstatic.com https://*.gstatic.com; " # for favicon fetching
6563
"font-src 'self' data: blob: https://cdnjs.cloudflare.com; "
6664
"connect-src 'self'; "
6765
"frame-ancestors 'none'; "
@@ -73,8 +71,8 @@ async def dispatch(self, request: Request, call_next):
7371
app.add_middleware(SecurityHeadersMiddleware)
7472
app.add_middleware(
7573
CORSMiddleware,
76-
allow_origins=["https://nousint.app"],
77-
allow_methods=["*"],
74+
allow_origins=["https://nousint-cd55bda4eead.herokuapp.com"], # updated: domain is actually noustint.app so using heroku now :(
75+
allow_methods=["GET", "POST", "OPTIONS"],
7876
allow_headers=["*"],
7977
)
8078

@@ -151,7 +149,7 @@ def replaceCallout(match):
151149
'span': ['class'],
152150
'p': ['class']
153151
}
154-
152+
# parsing markdown files for frontmatter metadata
155153
def parseMarkdownFile(filepath):
156154
try:
157155
with open(filepath, 'r', encoding='utf-8') as f:
@@ -165,7 +163,6 @@ def parseMarkdownFile(filepath):
165163
for line in parts[1].strip().split('\n'):
166164
if ':' in line:
167165
k, v = line.split(':', 1)
168-
# Sanitize metadata values
169166
metadata[k.strip()] = bleach.clean(v.strip())
170167
mdContent = parts[2].strip()
171168

@@ -194,19 +191,15 @@ def parseMarkdownFile(filepath):
194191

195192
def getAllArticles():
196193
articles = []
197-
if not os.path.exists("articles"):
198-
# print("ARTICLES DIRECTORY MISSING")
199-
return articles
200-
201194
for filename in os.listdir("articles"):
202195
if filename.endswith('.md'):
203196
parsed = parseMarkdownFile(f"articles/{filename}")
204197
if parsed:
205198
m = parsed['metadata']
206199
tags = []
207200
if m.get('tags'):
208-
for t in m.get('tags', '').split(','):
209-
tags.append(t.strip())
201+
for tag in m.get('tags', '').split(','):
202+
tags.append(tag.strip())
210203
articles.append({
211204
'id': filename[:-3],
212205
'title': m.get('title', filename[:-3]),
@@ -217,7 +210,7 @@ def getAllArticles():
217210
})
218211
return sorted(articles, key=lambda x: x.get('date', ''), reverse=True)
219212

220-
# no db, global cache!
213+
# no db, global cache
221214
ARTICLE_CACHE = getAllArticles()
222215

223216
@app.get("/articles")
@@ -333,7 +326,6 @@ async def scanPost(
333326
except Exception:
334327
raise HTTPException(status_code=400, detail="Invalid or corrupted image")
335328

336-
# TODO: find a way to make it more aggressive cus ts not very bueno at being a threat actor
337329
if toggleThreat:
338330
persona = "Act as an aggressive threat actor and OSINT expert by mapping out potential habits " \
339331
"from the user's behavior.Check for image metadata, and tell the user exactly what you find."

static/js/catalogscript.js

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ if (redBtnElement) {
1212

1313
var catalogState = {
1414
mode: "blue",
15-
nav: "categories",
15+
nav: "categories",
1616
cat: null,
1717
sub: null
1818
};
@@ -23,14 +23,13 @@ if (isRedPath || isRedBtn) {
2323
}
2424

2525
// Stats Counter Animation
26-
document.addEventListener("DOMContentLoaded", function() {
26+
document.addEventListener("DOMContentLoaded", function () {
2727
var statsContainer = document.getElementById('statsContainer');
2828
var blueCountEl = document.getElementById('blueCount');
2929
var redCountEl = document.getElementById('redCount');
3030

3131
if (!statsContainer || !blueCountEl || !redCountEl) return;
3232

33-
// Calculate totals
3433
var totalBlue = 0;
3534
var totalRed = 0;
3635

@@ -51,7 +50,7 @@ document.addEventListener("DOMContentLoaded", function() {
5150
for (var cat in db.red) {
5251
var categoryObj = db.red[cat];
5352
for (var sub in categoryObj) {
54-
if (sub !== 'meta' && categoryObj[sub].tools) {
53+
if (sub !== 'meta' && categoryObj[sub].tools) {
5554
totalRed += categoryObj[sub].tools.length;
5655
}
5756
}
@@ -60,8 +59,8 @@ document.addEventListener("DOMContentLoaded", function() {
6059
}
6160

6261
// Animation observer
63-
var observer = new IntersectionObserver(function(entries) {
64-
entries.forEach(function(entry) {
62+
var observer = new IntersectionObserver(function (entries) {
63+
entries.forEach(function (entry) {
6564
if (entry.isIntersecting) {
6665
statsContainer.classList.add('visible');
6766
animateValue(blueCountEl, 0, totalBlue, 1500);
@@ -75,7 +74,7 @@ document.addEventListener("DOMContentLoaded", function() {
7574

7675
function animateValue(obj, start, end, duration) {
7776
var startTimestamp = null;
78-
var step = function(timestamp) {
77+
var step = function (timestamp) {
7978
if (!startTimestamp) startTimestamp = timestamp;
8079
var progress = Math.min((timestamp - startTimestamp) / duration, 1);
8180
obj.innerHTML = Math.floor(progress * (end - start) + start);
@@ -87,7 +86,7 @@ document.addEventListener("DOMContentLoaded", function() {
8786
}
8887
});
8988

90-
// DONT REMOVE TS: formats keys
89+
// DONT REMOVE THIS: formats keys
9190
function formatName(str) {
9291
var words = str.split("-");
9392
var finalString = "";
@@ -124,7 +123,7 @@ function renderCatalog() {
124123
if (catalogState.sub != null) {
125124
breadcrumb += ` <span class="breadcrumb-separator">></span> <span class="breadcrumb-current">${formatName(catalogState.sub)}</span>`;
126125
}
127-
126+
128127
// legend: only when viewing tools
129128
var legend = '';
130129
if (catalogState.nav === 'tools') {
@@ -136,7 +135,7 @@ function renderCatalog() {
136135
<span class="tool-indicator download">(D)</span> Download
137136
</div>`;
138137
}
139-
138+
140139
// show breadcrumbs if not at root
141140
if (catalogState.nav !== "categories") {
142141
filterDiv.innerHTML = `<div class="breadcrumb-nav">${breadcrumb}</div>${legend}`;
@@ -153,7 +152,7 @@ function renderCatalog() {
153152
if (catData.meta && catData.meta.desc) {
154153
desc = catData.meta.desc;
155154
}
156-
155+
157156
gridHtml += `
158157
<div class="category-card" onclick="catalogState.cat='${cat}'; catalogState.nav='subcategories'; renderCatalog()">
159158
<div class="category-cover"><div class="logo-placeholder"></div></div>
@@ -165,7 +164,7 @@ function renderCatalog() {
165164
}
166165
gridHtml += '</div>';
167166

168-
}
167+
}
169168
else if (catalogState.nav === "subcategories") {
170169

171170
gridHtml = '<div class="subcategory-grid">';
@@ -192,25 +191,25 @@ function renderCatalog() {
192191
<div class="subcategory-card" onclick="catalogState.sub='${sub}'; catalogState.nav='tools'; renderCatalog()">
193192
<div class="subcategory-name">${formatName(sub)}</div>
194193
<div class="subcategory-count">${toolCount} tools</div>`;
195-
194+
196195
if (subDesc !== '') {
197196
subHtml += `<div class="subcategory-description">${subDesc}</div>`;
198197
}
199-
198+
200199
subHtml += `</div>`;
201200
gridHtml += subHtml;
202201
}
203-
202+
204203
if (hasSubs == false) {
205204
gridHtml = "<div class='selection-prompt'>No subcategories found.</div>";
206205
}
207206
gridHtml += '</div>';
208207

209-
}
208+
}
210209
else if (catalogState.nav === "tools") {
211210

212211
gridHtml = '<div class="tool-category-grid">';
213-
212+
214213
var subData = {};
215214
if (currentDb[catalogState.cat] && currentDb[catalogState.cat][catalogState.sub]) {
216215
subData = currentDb[catalogState.cat][catalogState.sub];
@@ -224,21 +223,21 @@ function renderCatalog() {
224223
} else {
225224
tools = [];
226225
}
227-
226+
228227
if (tools.length === 0) {
229228
gridHtml = gridHtml + "<div style='color:white; padding:20px;'>No tools found in this subcategory.</div>";
230229
}
231230

232231
for (const t of tools) {
233-
// fetch favicons
232+
// fetch favicons (care: can break with cosrm )
234233
let domain = 'google.com';
235234
try {
236235
if (t.url) {
237236
const urlObj = new URL(t.url);
238237
domain = urlObj.hostname;
239238
}
240-
}
241-
catch(e) {
239+
}
240+
catch (e) {
242241
console.error("Invalid URL for tool:", t.name, t.url);
243242
throw e;
244243
}
@@ -257,7 +256,7 @@ function renderCatalog() {
257256
indicators += "<span class='tool-indicator download' title='Download only'>(D)</span>";
258257
}
259258
}
260-
259+
261260
let tName = t.name;
262261
if (indicators) {
263262
tName = tName + ' ' + indicators;
@@ -288,12 +287,12 @@ function renderCatalog() {
288287
gridDiv.innerHTML = '<div class="tools-scroll-container">' + gridHtml + '</div>';
289288
}
290289

291-
document.addEventListener("DOMContentLoaded", function() {
290+
document.addEventListener("DOMContentLoaded", function () {
292291
var hasCatalog = document.querySelector(".catalog-preview");
293292
if (!hasCatalog) {
294293
hasCatalog = document.querySelector(".catalog-fullscreen");
295294
}
296-
295+
297296
if (hasCatalog) {
298297
renderCatalog();
299298
}

0 commit comments

Comments
 (0)