From 745bf9a29aad7ac9f14c1585f857e18d0d624762 Mon Sep 17 00:00:00 2001 From: aron Date: Thu, 27 Nov 2025 13:59:18 +0100 Subject: [PATCH] add autokanban --- README.md | 31 +++++- bookstack_api_create_page.py | 97 ++++++++++++++++++ .../indexers/issues.bleve/store/root.bolt | Bin 65536 -> 65536 bytes forgejo/data/gitea/queues/common/CURRENT | 2 +- forgejo/data/gitea/queues/common/LOG | 45 ++++++++ .../data/gitea/queues/common/MANIFEST-000004 | Bin 191 -> 0 bytes .../data/gitea/queues/common/MANIFEST-000014 | Bin 0 -> 116 bytes .../data/gitea/sessions/6/7/671ec6cf26e818fa | Bin 74 -> 0 bytes templates/landing.html | 9 ++ 9 files changed, 181 insertions(+), 3 deletions(-) create mode 100644 bookstack_api_create_page.py delete mode 100644 forgejo/data/gitea/queues/common/MANIFEST-000004 create mode 100644 forgejo/data/gitea/queues/common/MANIFEST-000014 delete mode 100644 forgejo/data/gitea/sessions/6/7/671ec6cf26e818fa diff --git a/README.md b/README.md index 03706f9..63de9aa 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ - **📓 JupyterHub**: Multi-user Jupyter notebook server for drone programming (port 8001) - **🦊 Forgejo**: Self-hosted Git service for code collaboration (port 3003) - **🔄 Watchtower**: Automatic container updates every 24 hours +- **🗂️ Autokanban**: Kollektive To‑Do‑Liste / Aufgabenboard (port 8000) --- @@ -132,6 +133,7 @@ graph TB - **curl** - for testing and healthchecks (install: `brew install curl` on macOS) - **Poppler** (for pdf2image - included in Docker) - **Port availability**: 80, 3003, 6875, 8001, 8008, 8080, 8082, 9000, 11434 + - **Port availability**: 80, 3003, 6875, 8000, 8001, 8008, 8080, 8082, 9000, 11434 **Note:** Python dependencies are containerized and don't need to be installed on the host. @@ -164,9 +166,9 @@ graph TB - Portainer: - Matrix: - Element Web: + - Autokanban: - JupyterHub: - Forgejo: - - Forgejo: ### First-Time Setup @@ -339,7 +341,32 @@ Creates timestamped backups of: --- -## 🚢 Deployment & Portability +## � BookStack API (create pages programmatically) + +You can automate content creation in BookStack using the HTTP API and a Personal Access Token (User Settings → API Tokens). + +Example `curl` to list books: + +```bash +curl -H "Authorization: Token token=\"$BOOKSTACK_API_TOKEN\"" \ + "$BOOKSTACK_APP_URL/api/books" +``` + +Create a page with `curl`: + +```bash +curl -X POST -H "Authorization: Token token=\"$BOOKSTACK_API_TOKEN\"" \ + -H "Content-Type: application/json" \ + -d '{"name":"My Page","book_id":1,"html":"

Hello

"}' \ + "$BOOKSTACK_APP_URL/api/pages" +``` + +There's a small helper script in the repo: `bookstack_api_create_page.py` which demonstrates listing books and creating a page interactively. + + +--- + +## �🚢 Deployment & Portability This application is designed to be **fully portable**. To move to a new server: diff --git a/bookstack_api_create_page.py b/bookstack_api_create_page.py new file mode 100644 index 0000000..d063826 --- /dev/null +++ b/bookstack_api_create_page.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python3 +""" +Small helper to demonstrate creating a BookStack page via the BookStack HTTP API. + +Usage: + - Create a Personal Access Token in BookStack (User Settings → API Tokens). + - Add the token and app URL to your `.env` or export env vars: + BOOKSTACK_APP_URL=http://124.local:6875 + BOOKSTACK_API_TOKEN=your_token_here + - Run: python bookstack_api_create_page.py + +This script will list available books and create a page in the chosen book. +""" +import os +import sys +import json +import requests +from urllib.parse import urljoin + +try: + from dotenv import load_dotenv + load_dotenv() +except Exception: + pass + + +BOOKSTACK_APP_URL = os.environ.get("BOOKSTACK_APP_URL") +BOOKSTACK_API_TOKEN = os.environ.get("BOOKSTACK_API_TOKEN") + +if not BOOKSTACK_APP_URL or not BOOKSTACK_API_TOKEN: + print("Please set BOOKSTACK_APP_URL and BOOKSTACK_API_TOKEN in the environment or .env file.") + sys.exit(1) + + +def auth_headers(): + # BookStack expects: Authorization: Token token="" + return { + "Authorization": f'Token token="{BOOKSTACK_API_TOKEN}"', + "Content-Type": "application/json", + "Accept": "application/json", + } + + +def list_books(): + url = urljoin(BOOKSTACK_APP_URL, "/api/books") + r = requests.get(url, headers=auth_headers(), timeout=10) + r.raise_for_status() + data = r.json() + return data.get("data", []) + + +def create_page(book_id: int, name: str, html: str): + url = urljoin(BOOKSTACK_APP_URL, "/api/pages") + payload = { + "name": name, + "book_id": book_id, + "html": html, + "markdown": None, + "draft": False, + } + r = requests.post(url, headers=auth_headers(), data=json.dumps(payload), timeout=10) + r.raise_for_status() + return r.json() + + +def main(): + print(f"Using BookStack: {BOOKSTACK_APP_URL}") + books = list_books() + if not books: + print("No books found. Create a book in BookStack first or verify token permissions.") + return + + print("Available books:") + for i, b in enumerate(books): + print(f" [{i}] {b.get('name')} (id={b.get('id')})") + + choice = input("Choose a book index to create the page in (default 0): ") or "0" + try: + idx = int(choice) + except ValueError: + idx = 0 + + book = books[idx] + book_id = book.get("id") + + title = input("Page title: ") or "Automated Page" + content = input("Simple HTML content (or leave empty for a sample): ") + if not content: + content = f"

{title}

Created automatically via API.

" + + resp = create_page(book_id, title, content) + print("Created page:") + print(json.dumps(resp, indent=2)) + + +if __name__ == "__main__": + main() diff --git a/forgejo/data/gitea/indexers/issues.bleve/store/root.bolt b/forgejo/data/gitea/indexers/issues.bleve/store/root.bolt index 9c67bfa6cede047865e2af04278be9624cf5c52e..e4fb508c4a951eda5cf8ca06d08a6641b790718b 100644 GIT binary patch delta 232 zcmZo@U}&P%#3ltD z0mi<`x(1G(N>F)kAk6~A%uv1)kOt{x1>%y-+|=Nb#M}ZS10z#iLqlC7^AH0|D^m+A z6GJ^CV{=0zOG~rOI}AMdH~+U^A|MKsHZ-s@Ftjo>)-$m*H?TA_GBw(~BOpj$9b_B> Y0~44;SjGwEb3titpexVwFPcyQ04`=NMF0Q* delta 161 zcmZo@U}$)Ph6W*qCRQefR)&Up7G@^K=0@h0CYyHzc<^s>SS$dRHnK7>vNAH) jGd3`?G&iv{GY3is>GMIXg;~B?al(E6i3yyGCKLbwR+}ey diff --git a/forgejo/data/gitea/queues/common/CURRENT b/forgejo/data/gitea/queues/common/CURRENT index cacca75..23b73d9 100644 --- a/forgejo/data/gitea/queues/common/CURRENT +++ b/forgejo/data/gitea/queues/common/CURRENT @@ -1 +1 @@ -MANIFEST-000004 +MANIFEST-000014 diff --git a/forgejo/data/gitea/queues/common/LOG b/forgejo/data/gitea/queues/common/LOG index fe93b1e..f187d07 100644 --- a/forgejo/data/gitea/queues/common/LOG +++ b/forgejo/data/gitea/queues/common/LOG @@ -14,3 +14,48 @@ 14:41:11.539093 version@stat F·[1] S·542B[542B] Sc·[0.25] 14:41:11.543912 db@janitor F·3 G·0 14:41:11.543982 db@open done T·6.225416ms +=============== Nov 12, 2025 (CET) =============== +09:57:26.179138 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed +09:57:26.186435 version@stat F·[1] S·542B[542B] Sc·[0.25] +09:57:26.191524 db@open opening +09:57:26.194711 journal@recovery F·1 +09:57:26.195667 journal@recovery recovering @3 +09:57:26.197988 version@stat F·[1] S·542B[542B] Sc·[0.25] +09:57:26.216087 db@janitor F·3 G·0 +09:57:26.217023 db@open done T·24.267292ms +=============== Nov 22, 2025 (CET) =============== +10:01:25.477377 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed +10:01:25.477990 version@stat F·[1] S·542B[542B] Sc·[0.25] +10:01:25.478025 db@open opening +10:01:25.478154 journal@recovery F·1 +10:01:25.478214 journal@recovery recovering @5 +10:01:25.478556 version@stat F·[1] S·542B[542B] Sc·[0.25] +10:01:25.480013 db@janitor F·3 G·0 +10:01:25.480040 db@open done T·1.995458ms +=============== Nov 27, 2025 (CET) =============== +09:57:27.459640 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed +09:57:27.463226 version@stat F·[1] S·542B[542B] Sc·[0.25] +09:57:27.463855 db@open opening +09:57:27.464798 journal@recovery F·1 +09:57:27.465256 journal@recovery recovering @7 +09:57:27.472782 version@stat F·[1] S·542B[542B] Sc·[0.25] +09:57:27.511286 db@janitor F·3 G·0 +09:57:27.511538 db@open done T·47.508458ms +=============== Nov 27, 2025 (CET) =============== +09:58:40.940724 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed +09:58:40.944445 version@stat F·[1] S·542B[542B] Sc·[0.25] +09:58:40.945532 db@open opening +09:58:40.946059 journal@recovery F·1 +09:58:40.946299 journal@recovery recovering @9 +09:58:40.951856 version@stat F·[1] S·542B[542B] Sc·[0.25] +09:58:40.957677 db@janitor F·3 G·0 +09:58:40.958035 db@open done T·12.392458ms +=============== Nov 27, 2025 (CET) =============== +10:01:13.275972 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed +10:01:13.278440 version@stat F·[1] S·542B[542B] Sc·[0.25] +10:01:13.278524 db@open opening +10:01:13.278925 journal@recovery F·1 +10:01:13.279002 journal@recovery recovering @11 +10:01:13.279809 version@stat F·[1] S·542B[542B] Sc·[0.25] +10:01:13.283533 db@janitor F·3 G·0 +10:01:13.283640 db@open done T·4.933416ms diff --git a/forgejo/data/gitea/queues/common/MANIFEST-000004 b/forgejo/data/gitea/queues/common/MANIFEST-000004 deleted file mode 100644 index 3431bdd4729bd9549ac46f92638e5d103df72c7c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 191 zcmZ1?sHMAufss)vC$%g!CnZVGsj?)sJhM2}IX|}`u_&=5zle#MnUzJFoq=f{i%Md0 zNoIataePr~VoGIvR(?`^VQFe + + +
+
Autokanban
+
Kollektive To‑Do‑Liste: Jede*r kann Aufgaben posten und lösen. Für das Lösen + von Aufgaben gibt es Badges — sammle Anerkennung für deinen Beitrag!
+
+
+