diff --git a/.gitignore b/.gitignore index ffcf069..f70dd3a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +histogram.svg cache bans thumbs diff --git a/chanbans/__main__.py b/chanbans/__main__.py index 9f9c778..9661357 100644 --- a/chanbans/__main__.py +++ b/chanbans/__main__.py @@ -4,6 +4,7 @@ import logging from .pull import pull from .http import run_app +from .hist import generate_histogram_svg def parse_args(): @@ -30,6 +31,14 @@ def parse_args(): "pull", help="Pull bans from 4chan, save thumbnails, update the database, and exit", ) + + _histogram_parser = add_subcommand( + "hist", + help="Generate histogram file.", + # This doesn't work as expected for some reason. Doesn't get parsed correctly + #aliases=["histogram"], + ) + _serve_parser = add_subcommand("serve", help="Start HTTP server") _help_parser = add_subcommand("help", help="Show this help message") @@ -57,6 +66,8 @@ def main(): asyncio.run(pull()) case "serve": run_app() + case "hist": + generate_histogram_svg() case command: assert ( False diff --git a/chanbans/config.py b/chanbans/config.py index d202b11..af16db1 100644 --- a/chanbans/config.py +++ b/chanbans/config.py @@ -47,3 +47,5 @@ STATIC_LOCAL_FOLLOW_SYMLINKS = one_of_default( "STATIC_LOCAL_FOLLOW_SYMLINKS", ("yes", "true", "1", "no", "false", "0"), "true" ) in ("yes", "true", "1") STATIC_ROOT = default("STATIC_ROOT", "/static") + +HISTOGRAM_PATH = Path(default("HISTOGRAM_PATH", "static/histogram.svg")) diff --git a/chanbans/hist.py b/chanbans/hist.py new file mode 100644 index 0000000..98a526f --- /dev/null +++ b/chanbans/hist.py @@ -0,0 +1,35 @@ +from .db import get_db +from .config import HISTOGRAM_PATH +from pathlib import Path + + +def histogram_svg(): + db = get_db() + cursor = db.cursor() + + cursor.execute("SELECT board, COUNT(*) AS count FROM bans GROUP BY board") + data = list(cursor.fetchall()) + + max_count = max(data, key=lambda x: x["count"])["count"] + scale_factor = 200 / max_count + + bar_width = 30 + bar_padding = 5 + svg_width = (bar_width + bar_padding) * len(data) + + svg = f'' + for i, row in enumerate(data): + board = row["board"] + count = row["count"] + x = i * (bar_width + bar_padding) + y = 250 - (count * scale_factor) + svg += f'' + svg += f'{board}' + svg += f'{count}' + svg += "" + return svg + + +def generate_histogram_svg(path: Path = HISTOGRAM_PATH): + svg = histogram_svg() + path = path.write_text(svg)