From cea457ff94113b8ce0f20904dc6bf854118d20fd Mon Sep 17 00:00:00 2001 From: Azalea <22280294+hykilpikonna@users.noreply.github.com> Date: Fri, 13 Mar 2026 21:13:23 -0400 Subject: [PATCH] [+] Bubble graph --- .gitignore | 2 +- public/bubble.html | 205 +++++++++++++++++++++++++++++++++++++++++++++ src/bot.py | 36 ++++++++ uv.lock | 14 ++++ 4 files changed, 256 insertions(+), 1 deletion(-) create mode 100644 public/bubble.html diff --git a/.gitignore b/.gitignore index 570bf9d..acdd999 100644 --- a/.gitignore +++ b/.gitignore @@ -161,5 +161,5 @@ cython_debug/ *.iml config.toml public/index.html -admin +admin.html user_states.json \ No newline at end of file diff --git a/public/bubble.html b/public/bubble.html new file mode 100644 index 0000000..6c9b3a3 --- /dev/null +++ b/public/bubble.html @@ -0,0 +1,205 @@ + + + + + + + + + + +
+ + +
+ +
+ + + + diff --git a/src/bot.py b/src/bot.py index 9338fa0..6ab24ca 100644 --- a/src/bot.py +++ b/src/bot.py @@ -586,6 +586,42 @@ def api_tree(): return tree_to_dict("azaneko") +@app.get("/api/graph_data") +def api_graph_data(): + nodes = [] + links = [] + + r_chan = re.compile(r"([\d ]+) subscribers") + r_grp = re.compile(r"([\d ]+) members") + + for entity in db.Channel.select().where(db.Channel.hidden == False): + html_t = channel_html(entity.username) + + subs = 0 + if m1 := r_chan.search(html_t): + subs = int(m1.group(1).replace(" ", "")) + elif m2 := r_grp.search(html_t): + subs = int(m2.group(1).replace(" ", "")) + + waters = db.get_votes(entity.username) + + nodes.append({ + "id": entity.username, + "name": entity.name, + "subscribers": subs, + "waters": waters, + "height": entity.height + }) + + if entity.parent_id: + links.append({ + "source": entity.parent_id, + "target": entity.username + }) + + return {"nodes": nodes, "links": links} + + @app.get("/api/admin/channels") def api_admin_channels(x_admin_password: str = Header(None)): if x_admin_password not in CONFIG.get("admin-passwords", [CONFIG.get("init-password")]): diff --git a/uv.lock b/uv.lock index 00e3370..8050c9f 100644 --- a/uv.lock +++ b/uv.lock @@ -58,6 +58,7 @@ dependencies = [ { name = "python-telegram-bot" }, { name = "requests" }, { name = "starlette" }, + { name = "tqdm" }, { name = "uvicorn" }, ] @@ -71,6 +72,7 @@ requires-dist = [ { name = "python-telegram-bot", specifier = ">=22.6" }, { name = "requests", specifier = ">=2.32.5" }, { name = "starlette", specifier = ">=0.52.1" }, + { name = "tqdm", specifier = ">=4.67.3" }, { name = "uvicorn", specifier = ">=0.41.0" }, ] @@ -343,6 +345,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/81/0d/13d1d239a25cbfb19e740db83143e95c772a1fe10202dda4b76792b114dd/starlette-0.52.1-py3-none-any.whl", hash = "sha256:0029d43eb3d273bc4f83a08720b4912ea4b071087a3b48db01b7c839f7954d74", size = 74272, upload-time = "2026-01-18T13:34:09.188Z" }, ] +[[package]] +name = "tqdm" +version = "4.67.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/09/a9/6ba95a270c6f1fbcd8dac228323f2777d886cb206987444e4bce66338dd4/tqdm-4.67.3.tar.gz", hash = "sha256:7d825f03f89244ef73f1d4ce193cb1774a8179fd96f31d7e1dcde62092b960bb", size = 169598, upload-time = "2026-02-03T17:35:53.048Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/16/e1/3079a9ff9b8e11b846c6ac5c8b5bfb7ff225eee721825310c91b3b50304f/tqdm-4.67.3-py3-none-any.whl", hash = "sha256:ee1e4c0e59148062281c49d80b25b67771a127c85fc9676d3be5f243206826bf", size = 78374, upload-time = "2026-02-03T17:35:50.982Z" }, +] + [[package]] name = "typing-extensions" version = "4.15.0"