From cba9cb1e189328d375e2ec43f2396f6013a9a85f Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Tue, 25 Feb 2025 18:20:04 +0100 Subject: [PATCH 01/23] refactor: rename all jinja files to html for autoescaping --- senju/main.py | 4 ++-- senju/templates/{base.jinja => base.html} | 0 senju/templates/{haiku.jinja => haiku.html} | 0 senju/templates/{index.jinja => index.html} | 0 4 files changed, 2 insertions(+), 2 deletions(-) rename senju/templates/{base.jinja => base.html} (100%) rename senju/templates/{haiku.jinja => haiku.html} (100%) rename senju/templates/{index.jinja => index.html} (100%) diff --git a/senju/main.py b/senju/main.py index 034f4b7..e963f1b 100644 --- a/senju/main.py +++ b/senju/main.py @@ -5,12 +5,12 @@ app = Flask(__name__) @app.route("/") def index_view(): - return render_template("index.jinja", title="Senju") + return render_template("index.html", title="Senju") @app.route("/haiku") def haiku_view(): return render_template( - "haiku.jinja", + "haiku.html", title="Haiku of the Day") diff --git a/senju/templates/base.jinja b/senju/templates/base.html similarity index 100% rename from senju/templates/base.jinja rename to senju/templates/base.html diff --git a/senju/templates/haiku.jinja b/senju/templates/haiku.html similarity index 100% rename from senju/templates/haiku.jinja rename to senju/templates/haiku.html diff --git a/senju/templates/index.jinja b/senju/templates/index.html similarity index 100% rename from senju/templates/index.jinja rename to senju/templates/index.html From 554f3bfffc22397accc78946b383150ba8c1f0b2 Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Tue, 25 Feb 2025 18:21:52 +0100 Subject: [PATCH 02/23] refactor: rename jinja files in extends --- senju/templates/haiku.html | 2 +- senju/templates/index.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/senju/templates/haiku.html b/senju/templates/haiku.html index fa1db07..39feb77 100644 --- a/senju/templates/haiku.html +++ b/senju/templates/haiku.html @@ -1,4 +1,4 @@ -{% extends "base.jinja" %} +{% extends "base.html" %} {% block content %}
diff --git a/senju/templates/index.html b/senju/templates/index.html index 4f8e829..3e1bbbf 100644 --- a/senju/templates/index.html +++ b/senju/templates/index.html @@ -1,4 +1,4 @@ -{% extends "base.jinja" %} +{% extends "base.html" %} {% block content %}

yo mama

{% endblock %} From e6b10ce96e98602860b84e37033581d1bede0282 Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Tue, 25 Feb 2025 15:03:14 +0100 Subject: [PATCH 03/23] feat: store manager basic implementation Refs: OPS-16 --- poetry.lock | 14 +++++++++++- pyproject.toml | 10 ++++----- senju/store_manager.py | 50 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 7 deletions(-) create mode 100644 senju/store_manager.py diff --git a/poetry.lock b/poetry.lock index 8234754..72ccf61 100644 --- a/poetry.lock +++ b/poetry.lock @@ -243,6 +243,18 @@ tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] +[[package]] +name = "tinydb" +version = "3.15.2" +description = "TinyDB is a tiny, document oriented database optimized for your happiness :)" +optional = false +python-versions = "*" +groups = ["main"] +files = [ + {file = "tinydb-3.15.2-py2.py3-none-any.whl", hash = "sha256:1087ade5300c47dbf9539d9f6dafd53115bd5e85a67d480d8188bdbfa2d9eaf4"}, + {file = "tinydb-3.15.2.tar.gz", hash = "sha256:f273d9b6d8b1b5e1d094a6eb8b72851b39b81099293344132c73332b60e3b893"}, +] + [[package]] name = "tomli" version = "2.2.1" @@ -307,4 +319,4 @@ watchdog = ["watchdog (>=2.3)"] [metadata] lock-version = "2.1" python-versions = ">=3.10" -content-hash = "45718b68919d6fafaaed35cd58dbbb244f8ebb0f0c73de8050cd04b8cae82738" +content-hash = "29ea72f4fd9859486c77dc4fd0668e0c55b618c56c01c23a0e2ce0a2cf75d026" diff --git a/pyproject.toml b/pyproject.toml index daff9bb..d23026f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,19 +2,17 @@ name = "senju" version = "0.1.0" description = "API / Webservice for Phrases/Words/Kanji/Haiku" -authors = [ - {name = "PlexSheep",email = "software@cscherr.de"} -] +authors = [{ name = "PlexSheep", email = "software@cscherr.de" }] readme = "README.md" requires-python = ">=3.10" dependencies = [ "jinja2 (>=3.1.5,<4.0.0)", - "pytest>=7.0.0", - "flask (>=3.1.0,<4.0.0)", + "pytest>=7.0.0", + "flask (>=3.1.0,<4.0.0)", + "tinydb (>=3.1.0,<4.0.0)", ] - [build-system] requires = ["poetry-core>=2.0.0,<3.0.0"] build-backend = "poetry.core.masonry.api" diff --git a/senju/store_manager.py b/senju/store_manager.py new file mode 100644 index 0000000..a2df91c --- /dev/null +++ b/senju/store_manager.py @@ -0,0 +1,50 @@ +from typing import Optional +from tinydb import TinyDB, Query +from uuid import UUID, uuid1 +from pathlib import Path +import time + +from tinydb.queries import QueryImpl + +DEFAULT_DB_PATH: Path = Path("/var/lib/senju.json") + + +class StoreManager: + __slots__ = "_db" + _db: TinyDB + + def __init__(self, path_to_db: Path = DEFAULT_DB_PATH) -> None: + self._db = TinyDB(path_to_db) + + def new_id(self) -> UUID: + unix_timestamp: int = int(time.time()) + _guard: int = 0 + while True: + id = uuid1(node=None, clock_seq=unix_timestamp) + if len(self._query(Query().id == id)) > 0: + break + _guard += 1 + if _guard > 100: + raise Exception( + "tried 100 random UUIDs but found no unused one") + return id + + def _query(self, query: QueryImpl) -> list[dict]: + return self._db.search(query) + + def load(self, key: UUID) -> Optional[dict]: + results = self._query(Query().id == key) + if len(results) < 1: + raise Exception("foobar") + elif len(results) > 2: + raise KeyError("The requested item did not exist in our database") + else: + return results[0] + + def save(self, data: dict) -> UUID: + id = self.new_id() + self._db.insert({ + "id": id, + "data": data + }) + return id From 5aba3981ee42a74f7ee2f0154e2e09ab988f8e49 Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Tue, 25 Feb 2025 15:21:27 +0100 Subject: [PATCH 04/23] test: store_manager sanity check Refs: OPS.19 --- tests/conftest.py | 7 +++++++ tests/test_store.py | 21 +++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 tests/test_store.py diff --git a/tests/conftest.py b/tests/conftest.py index efe5392..27c4eb2 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3,8 +3,15 @@ from pathlib import Path import pytest +from senju.store_manager import StoreManager + @pytest.fixture(scope="session") def temp_data_dir(): """Create a temporary directory for test data""" return Path(tempfile.mkdtemp()) + + +@pytest.fixture(scope="session") +def store_manager(temp_data_dir): + return StoreManager(temp_data_dir/"store.db") diff --git a/tests/test_store.py b/tests/test_store.py new file mode 100644 index 0000000..a992282 --- /dev/null +++ b/tests/test_store.py @@ -0,0 +1,21 @@ +# do not remove this import. This is needed for +# pytest fixtures to work +import pytest + +from senju.store_manager import StoreManager # noqa: F401 + + +def test_temp_data_dir(store_manager: StoreManager): + thing = { + "color": "blue", + "number": 19, + "inner": { + "no": "yes" + } + } + thing_id = store_manager.save(thing) + thing_loaded = store_manager.load(thing_id) + if thing_loaded is None: + assert False, "the store manager load did not return anything" + for key in thing.keys(): + assert thing[key] == thing_loaded[key] From 1edfd7b0f5a84317b615a1b24571deb8601bdf9a Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Tue, 25 Feb 2025 15:22:05 +0100 Subject: [PATCH 05/23] fix: new_id in store_manager generated a bad id, only returns the actual data now --- senju/store_manager.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/senju/store_manager.py b/senju/store_manager.py index a2df91c..a70a68f 100644 --- a/senju/store_manager.py +++ b/senju/store_manager.py @@ -17,11 +17,11 @@ class StoreManager: self._db = TinyDB(path_to_db) def new_id(self) -> UUID: - unix_timestamp: int = int(time.time()) _guard: int = 0 while True: + unix_timestamp: int = int(time.time()) id = uuid1(node=None, clock_seq=unix_timestamp) - if len(self._query(Query().id == id)) > 0: + if len(self._query(Query().id == id)) < 1: break _guard += 1 if _guard > 100: @@ -33,18 +33,18 @@ class StoreManager: return self._db.search(query) def load(self, key: UUID) -> Optional[dict]: - results = self._query(Query().id == key) + results = self._query(Query().id == str(key)) if len(results) < 1: raise Exception("foobar") elif len(results) > 2: raise KeyError("The requested item did not exist in our database") else: - return results[0] + return results[0]["data"] def save(self, data: dict) -> UUID: id = self.new_id() self._db.insert({ - "id": id, + "id": str(id), "data": data }) return id From d7dece3424d3c803f6dab58ed74c1fef7dccbdf2 Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Tue, 25 Feb 2025 16:15:53 +0100 Subject: [PATCH 06/23] fix: flake8 lint for unused pytest in a test --- tests/test_store.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_store.py b/tests/test_store.py index a992282..fc05ef1 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -1,6 +1,6 @@ # do not remove this import. This is needed for # pytest fixtures to work -import pytest +import pytest # noqa: F401 from senju.store_manager import StoreManager # noqa: F401 From 6b6f4424088dd2d2af7ed8d072eed13b31ff3aae Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Tue, 25 Feb 2025 17:38:46 +0100 Subject: [PATCH 07/23] refactor: update store to use the document ids instead of uuids Refs: OPS-21 OPS-16 --- senju/store_manager.py | 45 ++++++++++++------------------------------ tests/test_store.py | 10 ++++++---- 2 files changed, 19 insertions(+), 36 deletions(-) diff --git a/senju/store_manager.py b/senju/store_manager.py index a70a68f..591e984 100644 --- a/senju/store_manager.py +++ b/senju/store_manager.py @@ -1,8 +1,7 @@ from typing import Optional -from tinydb import TinyDB, Query -from uuid import UUID, uuid1 +from tinydb import TinyDB from pathlib import Path -import time +from logging import Logger from tinydb.queries import QueryImpl @@ -10,41 +9,23 @@ DEFAULT_DB_PATH: Path = Path("/var/lib/senju.json") class StoreManager: - __slots__ = "_db" + __slots__ = "_db", "logger" _db: TinyDB + logger: Logger def __init__(self, path_to_db: Path = DEFAULT_DB_PATH) -> None: self._db = TinyDB(path_to_db) - - def new_id(self) -> UUID: - _guard: int = 0 - while True: - unix_timestamp: int = int(time.time()) - id = uuid1(node=None, clock_seq=unix_timestamp) - if len(self._query(Query().id == id)) < 1: - break - _guard += 1 - if _guard > 100: - raise Exception( - "tried 100 random UUIDs but found no unused one") - return id + self.logger = Logger(__name__) def _query(self, query: QueryImpl) -> list[dict]: return self._db.search(query) - def load(self, key: UUID) -> Optional[dict]: - results = self._query(Query().id == str(key)) - if len(results) < 1: - raise Exception("foobar") - elif len(results) > 2: - raise KeyError("The requested item did not exist in our database") - else: - return results[0]["data"] + def _load(self, id: int) -> Optional[dict]: + try: + return self._db.get(doc_id=id) + except IndexError as e: + self.logger.warning(f"could not get item with id {id}: {e}") + return None - def save(self, data: dict) -> UUID: - id = self.new_id() - self._db.insert({ - "id": str(id), - "data": data - }) - return id + def _save(self, data: dict) -> int: + return self._db.insert(data) diff --git a/tests/test_store.py b/tests/test_store.py index fc05ef1..66b3f01 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -5,7 +5,7 @@ import pytest # noqa: F401 from senju.store_manager import StoreManager # noqa: F401 -def test_temp_data_dir(store_manager: StoreManager): +def test_save_and_load_any(store_manager: StoreManager): thing = { "color": "blue", "number": 19, @@ -13,9 +13,11 @@ def test_temp_data_dir(store_manager: StoreManager): "no": "yes" } } - thing_id = store_manager.save(thing) - thing_loaded = store_manager.load(thing_id) + thing_id = store_manager._save(thing) + thing_loaded = store_manager._load(thing_id) + if thing_loaded is None: - assert False, "the store manager load did not return anything" + assert False, "store manager load did not return anything but \ + should have" for key in thing.keys(): assert thing[key] == thing_loaded[key] From ccbe7fd51b599d6db684ad9559906056c8ba5106 Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Tue, 25 Feb 2025 17:39:33 +0100 Subject: [PATCH 08/23] feat: add haiku dataclass Refs: OPS-23 From 3a3636686520adb85270ff015802c17b13f153af Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Tue, 25 Feb 2025 17:42:11 +0100 Subject: [PATCH 09/23] feat: add haiku specific methods to the store manager Refs: OPS-22 --- senju/store_manager.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/senju/store_manager.py b/senju/store_manager.py index 591e984..21cb2d7 100644 --- a/senju/store_manager.py +++ b/senju/store_manager.py @@ -5,6 +5,8 @@ from logging import Logger from tinydb.queries import QueryImpl +from senju.haiku import Haiku + DEFAULT_DB_PATH: Path = Path("/var/lib/senju.json") @@ -29,3 +31,21 @@ class StoreManager: def _save(self, data: dict) -> int: return self._db.insert(data) + + def load_haiku(self, key: int) -> Optional[Haiku]: + raw_haiku: dict | None = self._load(key) + if raw_haiku is None: + return None + h = Haiku(**raw_haiku) + return h + + def save_haiku(self, data: Haiku) -> int: + return self._save(data.__dict__) + + def load_latest_haiku(self) -> Optional[Haiku]: + try: + id = self._db.all()[-1].doc_id + self.load_haiku(id) + except IndexError as e: + self.logger.error(f"The database seems to be empty: {e}") + return None From 602cba280aea9bb4bf911e6f4028be5dfa1e62f0 Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Tue, 25 Feb 2025 17:42:38 +0100 Subject: [PATCH 10/23] test: tests for the new haiku specific methods of the store manager Refs: OPS-22 --- tests/test_store.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/test_store.py b/tests/test_store.py index 66b3f01..53d67b6 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -2,6 +2,7 @@ # pytest fixtures to work import pytest # noqa: F401 +from senju.haiku import Haiku from senju.store_manager import StoreManager # noqa: F401 @@ -21,3 +22,20 @@ def test_save_and_load_any(store_manager: StoreManager): should have" for key in thing.keys(): assert thing[key] == thing_loaded[key] + + +def test_save_and_load_haiku(store_manager: StoreManager): + h = Haiku(text="foobar") + hid = store_manager.save_haiku(h) + h_loaded = store_manager.load_haiku(hid) + + if h_loaded is None: + assert False, "store manager load_haiku did not return anything \ + but should have" + + assert h == h_loaded + + +def test_load_latest_with_empty_store(store_manager: StoreManager): + h = store_manager.load_latest_haiku() + assert h is None From e700771c53b0ee51a59cda795219a6139b61f952 Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Tue, 25 Feb 2025 17:43:51 +0100 Subject: [PATCH 11/23] feat: add haiku dataclass previous commit for this did not stage the right file. Refs: OPS-23 --- senju/haiku.py | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 senju/haiku.py diff --git a/senju/haiku.py b/senju/haiku.py new file mode 100644 index 0000000..6d7aeff --- /dev/null +++ b/senju/haiku.py @@ -0,0 +1,6 @@ +from dataclasses import dataclass + + +@dataclass +class Haiku: + text: str From 4ce43ec54df110f40387488fd4dee48c40c9e32e Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Tue, 25 Feb 2025 17:56:01 +0100 Subject: [PATCH 12/23] feat: get_id_of_latest_haiku instead of load_latest_haiku Refs: OP-22 --- senju/store_manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/senju/store_manager.py b/senju/store_manager.py index 21cb2d7..4886559 100644 --- a/senju/store_manager.py +++ b/senju/store_manager.py @@ -42,10 +42,10 @@ class StoreManager: def save_haiku(self, data: Haiku) -> int: return self._save(data.__dict__) - def load_latest_haiku(self) -> Optional[Haiku]: + def get_id_of_latest_haiku(self) -> Optional[int]: try: id = self._db.all()[-1].doc_id - self.load_haiku(id) + return id except IndexError as e: self.logger.error(f"The database seems to be empty: {e}") return None From 588cbeb00184547ffdd07313f0146a5c2782efff Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Tue, 25 Feb 2025 17:56:47 +0100 Subject: [PATCH 13/23] test: refactor store manager tests for changes Refs: 9f3ebf6e98d0fc8a7d32e251a4468866bd55a076 OPS-22 --- tests/conftest.py | 2 +- tests/test_store.py | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 27c4eb2..75a608c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -14,4 +14,4 @@ def temp_data_dir(): @pytest.fixture(scope="session") def store_manager(temp_data_dir): - return StoreManager(temp_data_dir/"store.db") + return StoreManager(temp_data_dir/"store.json") diff --git a/tests/test_store.py b/tests/test_store.py index 53d67b6..570448d 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -1,5 +1,6 @@ # do not remove this import. This is needed for # pytest fixtures to work +from pathlib import Path import pytest # noqa: F401 from senju.haiku import Haiku @@ -36,6 +37,7 @@ def test_save_and_load_haiku(store_manager: StoreManager): assert h == h_loaded -def test_load_latest_with_empty_store(store_manager: StoreManager): - h = store_manager.load_latest_haiku() +def test_load_latest_with_empty_store(temp_data_dir): + store = StoreManager(temp_data_dir / "empty_store.json") + h = store.get_id_of_latest_haiku() assert h is None From 44ad774ada0905857bbd20d675cba77b1ff7f6e9 Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Tue, 25 Feb 2025 18:05:16 +0100 Subject: [PATCH 14/23] feat: redirect /haiku to /haiku/ Refs: OPS-25 --- senju/main.py | 37 +++++++++++++++++++++++++++++++++---- senju/templates/base.html | 33 ++++++++++++++++----------------- 2 files changed, 49 insertions(+), 21 deletions(-) diff --git a/senju/main.py b/senju/main.py index e963f1b..195a3ff 100644 --- a/senju/main.py +++ b/senju/main.py @@ -1,16 +1,45 @@ -from flask import Flask, render_template +from logging import Logger +from pathlib import Path +from flask import Flask, redirect, render_template, url_for + +from senju.haiku import Haiku +from senju.store_manager import StoreManager app = Flask(__name__) +store = StoreManager(Path("/tmp/store.db")) + +testh = Haiku("hello world this is a haiku (not)") +some_uuid = store.save_haiku(testh) + @app.route("/") def index_view(): return render_template("index.html", title="Senju") -@app.route("/haiku") -def haiku_view(): +@app.route("/haiku/") +def haiku_index_view(): + haiku_id: int | None = store.get_id_of_latest_haiku() + if haiku_id is None: + # TODO: add "empty haiku list" error page + raise KeyError("no haiku exist yet") + return redirect(url_for("haiku_view", haiku_id=haiku_id)) + + +@app.route("/haiku/") +def haiku_view(haiku_id): + logger = Logger(__name__) + logger.debug(haiku_id) + haiku: Haiku | None = store.load_haiku(haiku_id) + if haiku is None: + # TODO: add "haiku not found" page + raise KeyError("haiku not found") + context: dict = { + "haiku": haiku + } return render_template( - "haiku.html", + "haiku.jinja", + context=context, title="Haiku of the Day") diff --git a/senju/templates/base.html b/senju/templates/base.html index d567c40..c48a7fe 100644 --- a/senju/templates/base.html +++ b/senju/templates/base.html @@ -25,24 +25,23 @@
-

{{ title }}

From 3fcfdb2c8eb7eef1cec8ab515d6542749cb4c5f3 Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Tue, 25 Feb 2025 18:32:13 +0100 Subject: [PATCH 15/23] chore: remove old hacky "test" code --- senju/main.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/senju/main.py b/senju/main.py index 195a3ff..8003d09 100644 --- a/senju/main.py +++ b/senju/main.py @@ -9,9 +9,6 @@ app = Flask(__name__) store = StoreManager(Path("/tmp/store.db")) -testh = Haiku("hello world this is a haiku (not)") -some_uuid = store.save_haiku(testh) - @app.route("/") def index_view(): From 5fa212297296479f07dc1b602b9d64dd96fc8993 Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Tue, 25 Feb 2025 18:32:29 +0100 Subject: [PATCH 16/23] fix: haiku_view still used jinja as extension --- senju/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/senju/main.py b/senju/main.py index 8003d09..4997d09 100644 --- a/senju/main.py +++ b/senju/main.py @@ -37,6 +37,6 @@ def haiku_view(haiku_id): } return render_template( - "haiku.jinja", + "haiku.html", context=context, title="Haiku of the Day") From 82f8c7a721a0d7c1f992cdecdb0a00c6d18573b2 Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Tue, 25 Feb 2025 18:32:50 +0100 Subject: [PATCH 17/23] feat: store lines of a haiku, not just as a str Refs: OPS-24 --- senju/haiku.py | 2 +- senju/templates/haiku.html | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/senju/haiku.py b/senju/haiku.py index 6d7aeff..15d2a28 100644 --- a/senju/haiku.py +++ b/senju/haiku.py @@ -3,4 +3,4 @@ from dataclasses import dataclass @dataclass class Haiku: - text: str + lines: list[str] diff --git a/senju/templates/haiku.html b/senju/templates/haiku.html index 39feb77..844dfff 100644 --- a/senju/templates/haiku.html +++ b/senju/templates/haiku.html @@ -2,19 +2,19 @@ {% block content %}
-
-
-

Haiku of the Day

-

- An old silent pond
- A frog jumps into the pond—
- Splash! Silence again. -

-
- - Back to Home - -
+
+
+

{{ title }}

+

+ {% for line in context.haiku.lines %} + {{ line }}
+ {% endfor %} +

+
+ + Back to Home + +
{% endblock %} - From 55d6e91a11f563adfa57d95db07cc69a42a16d7b Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Tue, 25 Feb 2025 18:36:08 +0100 Subject: [PATCH 18/23] docs: exchange my synonym for my real name in pyproject.toml --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index d23026f..686def7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,7 @@ name = "senju" version = "0.1.0" description = "API / Webservice for Phrases/Words/Kanji/Haiku" -authors = [{ name = "PlexSheep", email = "software@cscherr.de" }] +authors = [{ name = "Christoph J. Scherr", email = "software@cscherr.de" }] readme = "README.md" requires-python = ">=3.10" dependencies = [ From b32996499ce8db032b638daa7934eaa42d37d837 Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Tue, 25 Feb 2025 18:40:02 +0100 Subject: [PATCH 19/23] chore: remove unused import --- tests/test_store.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_store.py b/tests/test_store.py index 570448d..8f7165f 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -1,6 +1,5 @@ # do not remove this import. This is needed for # pytest fixtures to work -from pathlib import Path import pytest # noqa: F401 from senju.haiku import Haiku From c7d8b9504a3d3ddf103aa867d971533da56d32da Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Tue, 25 Feb 2025 18:40:23 +0100 Subject: [PATCH 20/23] test: test_save_and_load_haiku needed to be adjusted for the new Haiku dataclass --- tests/test_store.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_store.py b/tests/test_store.py index 8f7165f..f49b754 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -25,7 +25,7 @@ def test_save_and_load_any(store_manager: StoreManager): def test_save_and_load_haiku(store_manager: StoreManager): - h = Haiku(text="foobar") + h = Haiku(lines=["foobar", "qux"]) hid = store_manager.save_haiku(h) h_loaded = store_manager.load_haiku(hid) From 97dc2edbaf05b5938efe3104345b1350b3d26ce3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 25 Feb 2025 17:40:50 +0000 Subject: [PATCH 21/23] ci: automatic Python Formatter changes --- tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index 75a608c..0967994 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -14,4 +14,4 @@ def temp_data_dir(): @pytest.fixture(scope="session") def store_manager(temp_data_dir): - return StoreManager(temp_data_dir/"store.json") + return StoreManager(temp_data_dir / "store.json") From 1740f8d3dfedb102533cd042fcb3927ea020b071 Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Tue, 25 Feb 2025 18:45:22 +0100 Subject: [PATCH 22/23] refactor: remove unneeded log of haiku_id in haiku_view --- senju/main.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/senju/main.py b/senju/main.py index 4997d09..8c3d75d 100644 --- a/senju/main.py +++ b/senju/main.py @@ -26,8 +26,6 @@ def haiku_index_view(): @app.route("/haiku/") def haiku_view(haiku_id): - logger = Logger(__name__) - logger.debug(haiku_id) haiku: Haiku | None = store.load_haiku(haiku_id) if haiku is None: # TODO: add "haiku not found" page From 5068f0c38cb1a154d8589cabed7ce321090c930c Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Tue, 25 Feb 2025 18:51:29 +0100 Subject: [PATCH 23/23] chore: removed unused import --- senju/main.py | 1 - 1 file changed, 1 deletion(-) diff --git a/senju/main.py b/senju/main.py index 8c3d75d..c6d9bd0 100644 --- a/senju/main.py +++ b/senju/main.py @@ -1,4 +1,3 @@ -from logging import Logger from pathlib import Path from flask import Flask, redirect, render_template, url_for