From bfd9b2a7ea6914b024c705492cc7a4335c1c2c1a Mon Sep 17 00:00:00 2001 From: kisfenyo Date: Thu, 15 Oct 2026 22:37:08 +0200 Subject: [PATCH] app guides night: R-1085 (the floor can still offer spoiled tag 0.316.3), R-1086 (qBittorrent password advice breaks the media wiring); pilot evidence and tools Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS --- .../app-guides-2026-10-15/A/plex-box.txt | 49 ++++++ .../app-guides-2026-10-15/A/plex-draft.json | 136 +++++++++++++++ .../app-guides-2026-10-15/A/plex-labels.txt | 22 +++ .../app-guides-2026-10-15/A/prowlarr-box.txt | 2 + .../A/prowlarr-draft.json | 92 ++++++++++ .../A/prowlarr-labels.txt | 34 ++++ .../A/qbittorrent-box.txt | 2 + .../A/qbittorrent-draft.json | 94 ++++++++++ .../A/qbittorrent-labels.txt | 34 ++++ .../app-guides-2026-10-15/A/radarr-box.txt | 2 + .../app-guides-2026-10-15/A/radarr-draft.json | 100 +++++++++++ .../app-guides-2026-10-15/A/radarr-labels.txt | 48 +++++ .../app-guides-2026-10-15/A/sonarr-box.txt | 2 + .../app-guides-2026-10-15/A/sonarr-draft.json | 100 +++++++++++ .../app-guides-2026-10-15/A/sonarr-labels.txt | 44 +++++ .../app-guides-2026-10-15/part0-redproof.py | 36 ++++ .../app-guides-2026-10-15/part0-redproofs.txt | 12 ++ .../tools/apply_guide.py | 165 ++++++++++++++++++ .../app-guides-2026-10-15/tools/labelcheck.py | 109 ++++++++++++ .../tools/validate_draft.py | 105 +++++++++++ documentation/backlog/OPEN-ITEMS.md | 6 +- 21 files changed, 1192 insertions(+), 2 deletions(-) create mode 100644 documentation/audits/app-guides-2026-10-15/A/plex-box.txt create mode 100644 documentation/audits/app-guides-2026-10-15/A/plex-draft.json create mode 100644 documentation/audits/app-guides-2026-10-15/A/plex-labels.txt create mode 100644 documentation/audits/app-guides-2026-10-15/A/prowlarr-box.txt create mode 100644 documentation/audits/app-guides-2026-10-15/A/prowlarr-draft.json create mode 100644 documentation/audits/app-guides-2026-10-15/A/prowlarr-labels.txt create mode 100644 documentation/audits/app-guides-2026-10-15/A/qbittorrent-box.txt create mode 100644 documentation/audits/app-guides-2026-10-15/A/qbittorrent-draft.json create mode 100644 documentation/audits/app-guides-2026-10-15/A/qbittorrent-labels.txt create mode 100644 documentation/audits/app-guides-2026-10-15/A/radarr-box.txt create mode 100644 documentation/audits/app-guides-2026-10-15/A/radarr-draft.json create mode 100644 documentation/audits/app-guides-2026-10-15/A/radarr-labels.txt create mode 100644 documentation/audits/app-guides-2026-10-15/A/sonarr-box.txt create mode 100644 documentation/audits/app-guides-2026-10-15/A/sonarr-draft.json create mode 100644 documentation/audits/app-guides-2026-10-15/A/sonarr-labels.txt create mode 100644 documentation/audits/app-guides-2026-10-15/part0-redproof.py create mode 100644 documentation/audits/app-guides-2026-10-15/part0-redproofs.txt create mode 100644 documentation/audits/app-guides-2026-10-15/tools/apply_guide.py create mode 100644 documentation/audits/app-guides-2026-10-15/tools/labelcheck.py create mode 100644 documentation/audits/app-guides-2026-10-15/tools/validate_draft.py diff --git a/documentation/audits/app-guides-2026-10-15/A/plex-box.txt b/documentation/audits/app-guides-2026-10-15/A/plex-box.txt new file mode 100644 index 00000000..8b255eba --- /dev/null +++ b/documentation/audits/app-guides-2026-10-15/A/plex-box.txt @@ -0,0 +1,49 @@ +== taken: 2026-10-15T20:29:41Z guest 9201 (demo-hp), read-only +== docker ps (before = after: nothing installed, removed or restarted) +adventurelog ghcr.io/seanmorley15/adventurelog-backend:v0.13.0 Up 18 hours (healthy) +adventurelog-frontend ghcr.io/seanmorley15/adventurelog-frontend:v0.13.0 Up 18 hours (healthy) +adventurelog-postgres postgis/postgis:16-3.5-alpine Up 18 hours (healthy) +bentopdf ghcr.io/alam00000/bentopdf:v2.8.6 Up 18 hours (healthy) +bookstack lscr.io/linuxserver/bookstack:26.09.1 Up 18 hours (healthy) +bookstack-db mariadb:12.3 Up 18 hours (healthy) +calibre-web crocodilestick/calibre-web-automated:v4.0.8 Up 18 hours (healthy) +cloudflared cloudflare/cloudflared:2026.9.3 Up 29 hours (healthy) +docmost docmost/docmost:0.96.0 Up 18 hours (healthy) +docmost-postgres postgres:18-alpine Up 18 hours (healthy) +docmost-redis redis:7-alpine Up 18 hours (healthy) +felhom-controller gitea.dooplex.hu/admin/felhom-controller:0.317.0 Up 56 minutes (healthy) +filebrowser gtstef/filebrowser:1.5.6-stable Up 6 hours (healthy) +home-assistant ghcr.io/home-assistant/home-assistant:2026.9.4 Up 18 hours (healthy) +opengist ghcr.io/thomiceli/opengist:1.15 Up 18 hours (healthy) +paperless-postgres postgres:18-alpine Up 18 hours (healthy) +paperless-redis redis:7-alpine Up 18 hours (healthy) +paperless-webserver ghcr.io/paperless-ngx/paperless-ngx:2.20.15 Up 18 hours (healthy) +plex plexinc/pms-docker:1.41.4.9463-630c9f557 Up 12 hours (healthy) +privatebin privatebin/pdo:2.0.6 Up 18 hours (healthy) +traefik traefik:v3.7.13 Up 18 hours +== plex image +plexinc/pms-docker:1.41.4.9463-630c9f557 +== plex mounts (FAQ: Plex only READS the drive) +/config rw=true +/media rw=false +/transcode rw=true +/mnt/felhom-drives/hdd_1/userdata/media rw=false + +== plex env KEYS (FAQ: the box set the public address) - names only +ADVERTISE_IP +TZ +PLEX_CLAIM +== /identity (claimed flag) +claimed="1" +== controller log: media wiring lines for plex (positive observable: the box added folders / found nothing to add) + +== VERDICT (read-only box check, Part A.3 under night rule 2) +- „Plex only reads the drive" (FAQ 2): PASS — /media and the per-drive media bind are rw=false. +- „The box set Plex up to answer on your own address" (FAQ 5): PASS — ADVERTISE_IP is in the container env (value not printed). +- Claimed state the guide assumes (sections 1 and 4, FAQ 6): PASS — /identity claimed="1". +- „The box adds a new drive's folders to your existing libraries and starts a scan" (section 2): NOT RE-READ TONIGHT. + The wiring runs on a media app's start; nothing started since the controller came up at 19:33 UTC, so the log holds + no wiring line, and an absent line is not evidence either way. Reading the libraries needs Plex's own token, which a + read-only night check does not take. The claim rests on the media build's live proof (G2 on Tester 1: a drive wired into every app, Plex included; G7 on this box: the live catalog) + — felhom.eu documentation/audits/media-build-2026-10-15/G and G7 — and on felhom-controller mediawire.go plex(). +- Nothing installed, removed, restarted or changed (docker ps above; no POST sent). diff --git a/documentation/audits/app-guides-2026-10-15/A/plex-draft.json b/documentation/audits/app-guides-2026-10-15/A/plex-draft.json new file mode 100644 index 00000000..423849c9 --- /dev/null +++ b/documentation/audits/app-guides-2026-10-15/A/plex-draft.json @@ -0,0 +1,136 @@ +{ + "app": "plex", + "checked_version": "1.41.4.9463-630c9f557", + "hu": { + "sections": [ + { + "title": "Nézés tévén vagy telefonon", + "intro": "A Plex appok a Plex fiókodon keresztül találják meg a szerveredet.", + "steps": [ + "Nyisd meg a Plex appot, és jelentkezz be ugyanazzal a Plex fiókkal, amellyel a kódot kérted.", + "A „Kezdőképernyő” oldalon megjelennek a könyvtáraid.", + "Válassz egy filmet, és kattints a „Lejátszás” gombra." + ] + }, + { + "title": "Új filmek és új meghajtó", + "intro": "Amit a meghajtód media mappájába teszel, azt a Plex magától észreveszi.", + "steps": [ + "A Radarr a media/movies, a Sonarr a media/tv mappába tesz mindent, a Plex innen olvas.", + "Új meghajtónál a doboz hozzáadja a meghajtó mappáit a meglévő film- és sorozatkönyvtáraidhoz, és elindít egy beolvasást.", + "Ha egy új fájl mégsem jelenik meg, a könyvtár menüjében kattints a „Könyvtárfájlok beolvasása” pontra." + ] + }, + { + "title": "Rossz cím vagy borító javítása", + "intro": "A Plex a fájl és a mappa nevéből találja ki, melyik film ez.", + "steps": [ + "Nyisd meg a filmet, és kattints a „Több” menüre.", + "Válaszd a „Találatok pontosítása” pontot, és keresd meg a helyes címet.", + "Legközelebb segít, ha a mappa neve a film címe és éve, például: Nosferatu (1922)." + ] + }, + { + "title": "Megosztás a családdal", + "intro": "Minden családtag a saját Plex fiókjával nézhet.", + "steps": [ + "A „Beállítások” oldalon nyisd meg a „Könyvtár hozzáférés kezelése” részt.", + "Válaszd ki, kivel és mely könyvtárakat osztod meg.", + "A családtag a saját Plex fiókjával lép be az appba." + ] + } + ], + "faq": [ + { + "q": "Miért nem látom a filmet?", + "a": "Nézd meg, hogy a fájl a media/movies mappában van-e, és hogy a mappa neve a film címe és éve. Utána kattints a „Könyvtárfájlok beolvasása” pontra." + }, + { + "q": "Törölhetek filmet a Plexből?", + "a": "Nem: a Plex csak olvassa a meghajtót. Törölni a fájlböngészőben, a Radarrban vagy a Sonarrban tudsz." + }, + { + "q": "Kell Plex Pass?", + "a": "Otthoni nézéshez nem. Néhány funkcióhoz igen, például a bevezető átugrásához; ezt a Plex dönti el, nem a doboz." + }, + { + "q": "Akadozik a lejátszás. Mit tehetek?", + "a": "A Plex ilyenkor átalakítja a videót, és ez a dobozon lassú lehet. Az appban a „Videó minőség” beállításnál válaszd az „Eredeti” értéket." + }, + { + "q": "Elérem otthonon kívül?", + "a": "A doboz beállította, hogy a Plex a saját címeden is elérhető legyen. Otthonon kívüli nézéshez a Plex előfizetést kérhet; ezt a Plex szabja meg." + }, + { + "q": "Lejárt a kód. Hol kérek újat?", + "a": "Ugyanott, ahol az elsőt: a címet az első lépések között találod. Az új kódot a vezérlőpulton, a Plex „Beállítások” fülén add meg." + } + ] + }, + "en": { + "sections": [ + { + "title": "Watch on a TV or a phone", + "intro": "The Plex apps find your server through your Plex account.", + "steps": [ + "Open the Plex app and sign in with the same Plex account you got the code with.", + "Your libraries appear on the „Home” page.", + "Choose a film and select „Play”." + ] + }, + { + "title": "New films and a new drive", + "intro": "Whatever you put into your drive's media folder, Plex notices by itself.", + "steps": [ + "Radarr puts everything into media/movies and Sonarr into media/tv; Plex reads from there.", + "With a new drive, the box adds its folders to your existing film and series libraries and starts a scan.", + "If a new file still does not show up, select „Scan Library Files” in the library's menu." + ] + }, + { + "title": "Fix a wrong title or cover", + "intro": "Plex works out which film it is from the names of the file and the folder.", + "steps": [ + "Open the film and select the „More” menu.", + "Choose „Fix Match” and search for the right title.", + "Next time it helps to name the folder after the film's title and year, for example: Nosferatu (1922)." + ] + }, + { + "title": "Share with the family", + "intro": "Every family member can watch with their own Plex account.", + "steps": [ + "On the „Settings” page, open „Manage Library Access”.", + "Choose who gets which libraries.", + "The family member signs in to the app with their own Plex account." + ] + } + ], + "faq": [ + { + "q": "Why can I not see the film?", + "a": "Check that the file is in the media/movies folder and that the folder is named after the film's title and year. Then select „Scan Library Files”." + }, + { + "q": "Can I delete a film from Plex?", + "a": "No: Plex only reads the drive. You delete in the file browser, in Radarr or in Sonarr." + }, + { + "q": "Do I need Plex Pass?", + "a": "Not for watching at home. Some features need it, for example skipping intros; Plex decides that, not the box." + }, + { + "q": "Playback stutters. What can I do?", + "a": "Plex is converting the video, and that can be slow on the box. In the app, set „Video Quality” to „Original”." + }, + { + "q": "Can I reach it away from home?", + "a": "The box set Plex up to answer on your own address. To watch away from home, Plex may ask for a subscription; Plex sets that rule." + }, + { + "q": "The code ran out. Where do I get a new one?", + "a": "In the same place as the first one: its address is in the first steps. Enter the new code on the dashboard, on Plex's „Settings” tab." + } + ] + } +} \ No newline at end of file diff --git a/documentation/audits/app-guides-2026-10-15/A/plex-labels.txt b/documentation/audits/app-guides-2026-10-15/A/plex-labels.txt new file mode 100644 index 00000000..fbf62144 --- /dev/null +++ b/documentation/audits/app-guides-2026-10-15/A/plex-labels.txt @@ -0,0 +1,22 @@ +app: plex checked against: 1.41.4.9463-630c9f557 +corpora: plexinc/pms-docker:1.41.4.9463-630c9f557 image, Plex Web 4.143.0 (WebClient.bundle/Contents/Resources, copied from demo-hp 9201's running container):translations/hu.json felhom-controller@123d2d5:controller/internal/i18n/locales/hu.json felhom-controller@123d2d5:controller/internal/i18n/locales/en.json +labels: 18 (Hungarian and English guide strings, every „…” occurrence) +OK [hu] „Kezdőképernyő” plexinc/pms-docker:1.41.4.9463-630c9f557 image, Plex Web 4.143.0 (WebClient.bundle/Contents/Resources, copied from demo-hp 9201's running container):translations/hu.json:920 +OK [hu] „Lejátszás” plexinc/pms-docker:1.41.4.9463-630c9f557 image, Plex Web 4.143.0 (WebClient.bundle/Contents/Resources, copied from demo-hp 9201's running container):translations/hu.json:1407 +OK [hu] „Könyvtárfájlok beolvasása” plexinc/pms-docker:1.41.4.9463-630c9f557 image, Plex Web 4.143.0 (WebClient.bundle/Contents/Resources, copied from demo-hp 9201's running container):translations/hu.json:1693 +OK [hu] „Több” plexinc/pms-docker:1.41.4.9463-630c9f557 image, Plex Web 4.143.0 (WebClient.bundle/Contents/Resources, copied from demo-hp 9201's running container):translations/hu.json:1172 +OK [hu] „Találatok pontosítása” plexinc/pms-docker:1.41.4.9463-630c9f557 image, Plex Web 4.143.0 (WebClient.bundle/Contents/Resources, copied from demo-hp 9201's running container):translations/hu.json:817 +OK [hu] „Beállítások” plexinc/pms-docker:1.41.4.9463-630c9f557 image, Plex Web 4.143.0 (WebClient.bundle/Contents/Resources, copied from demo-hp 9201's running container):translations/hu.json:1355 +OK [hu] „Könyvtár hozzáférés kezelése” plexinc/pms-docker:1.41.4.9463-630c9f557 image, Plex Web 4.143.0 (WebClient.bundle/Contents/Resources, copied from demo-hp 9201's running container):translations/hu.json:1111 +OK [hu] „Videó minőség” plexinc/pms-docker:1.41.4.9463-630c9f557 image, Plex Web 4.143.0 (WebClient.bundle/Contents/Resources, copied from demo-hp 9201's running container):translations/hu.json:2360 +OK [hu] „Eredeti” plexinc/pms-docker:1.41.4.9463-630c9f557 image, Plex Web 4.143.0 (WebClient.bundle/Contents/Resources, copied from demo-hp 9201's running container):translations/hu.json:1359 +OK [en] „Home” plexinc/pms-docker:1.41.4.9463-630c9f557 image, Plex Web 4.143.0 (WebClient.bundle/Contents/Resources, copied from demo-hp 9201's running container):translations/hu.json:920 +OK [en] „Play” plexinc/pms-docker:1.41.4.9463-630c9f557 image, Plex Web 4.143.0 (WebClient.bundle/Contents/Resources, copied from demo-hp 9201's running container):translations/hu.json:1407 +OK [en] „Scan Library Files” plexinc/pms-docker:1.41.4.9463-630c9f557 image, Plex Web 4.143.0 (WebClient.bundle/Contents/Resources, copied from demo-hp 9201's running container):translations/hu.json:1693 +OK [en] „More” plexinc/pms-docker:1.41.4.9463-630c9f557 image, Plex Web 4.143.0 (WebClient.bundle/Contents/Resources, copied from demo-hp 9201's running container):translations/hu.json:1172 +OK [en] „Fix Match” plexinc/pms-docker:1.41.4.9463-630c9f557 image, Plex Web 4.143.0 (WebClient.bundle/Contents/Resources, copied from demo-hp 9201's running container):translations/hu.json:817 +OK [en] „Settings” plexinc/pms-docker:1.41.4.9463-630c9f557 image, Plex Web 4.143.0 (WebClient.bundle/Contents/Resources, copied from demo-hp 9201's running container):translations/hu.json:1774 +OK [en] „Manage Library Access” plexinc/pms-docker:1.41.4.9463-630c9f557 image, Plex Web 4.143.0 (WebClient.bundle/Contents/Resources, copied from demo-hp 9201's running container):translations/hu.json:1111 +OK [en] „Video Quality” plexinc/pms-docker:1.41.4.9463-630c9f557 image, Plex Web 4.143.0 (WebClient.bundle/Contents/Resources, copied from demo-hp 9201's running container):translations/hu.json:2360 +OK [en] „Original” plexinc/pms-docker:1.41.4.9463-630c9f557 image, Plex Web 4.143.0 (WebClient.bundle/Contents/Resources, copied from demo-hp 9201's running container):translations/hu.json:1359 +RESULT: ALL FOUND — 18 label(s), 0 missing diff --git a/documentation/audits/app-guides-2026-10-15/A/prowlarr-box.txt b/documentation/audits/app-guides-2026-10-15/A/prowlarr-box.txt new file mode 100644 index 00000000..4cf20ed5 --- /dev/null +++ b/documentation/audits/app-guides-2026-10-15/A/prowlarr-box.txt @@ -0,0 +1,2 @@ +BOX CHECK OWED — prowlarr was not running on demo-hp 9201 at 2026-10-15T20:29Z (docker ps in plex-box.txt), and night rule 2 +allows no install there tonight. Label check only (§8 row „all found / not run"); checked_version set. diff --git a/documentation/audits/app-guides-2026-10-15/A/prowlarr-draft.json b/documentation/audits/app-guides-2026-10-15/A/prowlarr-draft.json new file mode 100644 index 00000000..19f2c92a --- /dev/null +++ b/documentation/audits/app-guides-2026-10-15/A/prowlarr-draft.json @@ -0,0 +1,92 @@ +{ + "app": "prowlarr", + "checked_version": "version-2.6.5.5623", + "hu": { + "sections": [ + {"title": "Első forrás hozzáadása", + "intro": "A forrásokat (indexereket) csak itt adod meg, egyszer.", + "steps": [ + "Az „Indexers” (Indexerek) oldalon kattints az „Add Indexer” (indexer hozzáadása) gombra.", + "Keresd meg a listában azt a forrást, amelyhez hozzáférésed van, és kattints rá.", + "Töltsd ki, amit a forrás kér, például a saját felhasználónevedet vagy kulcsodat.", + "Kattints a „Test” (próba) gombra, és ha sikeres, a „Save” (mentés) gombra." + ]}, + {"title": "A Sonarr és a Radarr megkapja", + "intro": "Ezt a doboz bekötötte, neked nincs vele teendőd.", + "steps": [ + "A „Settings” (Beállítások) menü „Apps” (alkalmazások) oldalán látod a Sonarrt és a Radarrt.", + "Egy új forrás magától átkerül hozzájuk, mert a kapcsolat „Full Sync” (teljes szinkron) módban van.", + "Ha mégsem jelenik meg, az „Indexers” oldalon kattints a „Sync App Indexers” (indexerek átküldése) gombra." + ]}, + {"title": "Egy forrás kipróbálása", + "intro": "Letöltés nélkül is megnézheted, ad-e találatot egy forrás.", + "steps": [ + "A „Search” (Keresés) oldalon írj be egy címet, és nézd meg a találatokat.", + "Az „Indexers” oldalon a „Test All Indexers” (összes kipróbálása) gomb minden forrást egyszerre ellenőriz." + ]}, + {"title": "Ha egy forrás hibás", + "intro": "A Prowlarr egy ideig kihagyja azt a forrást, amelyik többször hibázott, majd újra próbálja.", + "steps": [ + "Nézd meg a „System” (Rendszer) menü „Status” (Állapot) lapját: a „Health” (állapot) rész sorolja a hibás forrásokat.", + "A „History” (Előzmények) oldalon látod, melyik keresés mit hozott.", + "Ha egy forrás véglegesen elromlott, nyisd meg az „Indexers” oldalon, és javítsd vagy töröld." + ]} + ], + "faq": [ + {"q": "Melyik forrást válasszam?", + "a": "Ezt te döntöd el. A Felhom nem ad, nem ajánl és nem keres forrást. Csak olyat használj, amelyhez jogod van."}, + {"q": "Kell a Sonarrban vagy a Radarrban is felvennem a forrásokat?", + "a": "Nem. A Prowlarr átküldi nekik, és ha itt módosítasz egy forrást, ott is módosul."}, + {"q": "Mi a különbség a Prowlarr és a Sonarr között?", + "a": "A Prowlarr csak a forrásokat tartja nyilván. A Sonarr és a Radarr dönti el, mit keres és mit tölt le."}, + {"q": "Mi történik, ha a Sonarrt később telepítem?", + "a": "A doboz akkor is összeköti őket: amikor a Sonarr vagy a Radarr elindul, megkapja a forrásokat, gombnyomás nélkül."}, + {"q": "Mit mutat a „Stats” oldal?", + "a": "Forrásonként mutatja, hány keresésre és hány találatra jutott, és mennyi idő alatt válaszolt. Így látod, melyik forrás lassú."} + ] + }, + "en": { + "sections": [ + {"title": "Add your first source", + "intro": "You add your sources (indexers) here only, and only once.", + "steps": [ + "On the „Indexers” page, select „Add Indexer”.", + "Find the source you have access to in the list and select it.", + "Fill in what the source asks for, for example your own user name or key.", + "Select „Test”, and if it succeeds, select „Save”." + ]}, + {"title": "Sonarr and Radarr get them", + "intro": "The box connected this; there is nothing for you to do.", + "steps": [ + "The „Apps” page of the „Settings” menu shows Sonarr and Radarr.", + "A new source reaches them by itself, because the link is set to „Full Sync”.", + "If one does not show up, select „Sync App Indexers” on the „Indexers” page." + ]}, + {"title": "Try a source", + "intro": "You can see whether a source finds anything without downloading.", + "steps": [ + "On the „Search” page, type a title and look at the results.", + "On the „Indexers” page, „Test All Indexers” checks every source at once." + ]}, + {"title": "When a source fails", + "intro": "Prowlarr skips a source that failed several times for a while, then tries it again.", + "steps": [ + "Look at the „Status” tab of the „System” menu: the „Health” part lists the failing sources.", + "The „History” page shows what each search brought back.", + "If a source is broken for good, open it on the „Indexers” page and fix it or delete it." + ]} + ], + "faq": [ + {"q": "Which source should I choose?", + "a": "That is your decision. Felhom neither provides, suggests nor searches for a source. Use only one you have the right to use."}, + {"q": "Do I also have to add the sources in Sonarr or Radarr?", + "a": "No. Prowlarr sends them over, and when you change a source here, it changes there too."}, + {"q": "What is the difference between Prowlarr and Sonarr?", + "a": "Prowlarr only keeps the list of sources. Sonarr and Radarr decide what to search for and what to download."}, + {"q": "What happens if I install Sonarr later?", + "a": "The box still connects them: when Sonarr or Radarr starts, it gets the sources, with no button to press."}, + {"q": "What does the „Stats” page show?", + "a": "For each source: how many searches and results it had, and how long it took to answer. That shows you which source is slow."} + ] + } +} diff --git a/documentation/audits/app-guides-2026-10-15/A/prowlarr-labels.txt b/documentation/audits/app-guides-2026-10-15/A/prowlarr-labels.txt new file mode 100644 index 00000000..79714827 --- /dev/null +++ b/documentation/audits/app-guides-2026-10-15/A/prowlarr-labels.txt @@ -0,0 +1,34 @@ +app: prowlarr checked against: version-2.6.5.5623 +corpora: Prowlarr/Prowlarr@v2.6.5.5623(12c3278):src/NzbDrone.Core/Localization/Core/en.json Prowlarr/Prowlarr@v2.6.5.5623(12c3278):frontend/src felhom-controller@123d2d5:controller/internal/i18n/locales/hu.json felhom-controller@123d2d5:controller/internal/i18n/locales/en.json +labels: 30 (Hungarian and English guide strings, every „…” occurrence) +OK [hu] „Indexers” Prowlarr/Prowlarr@v2.6.5.5623(12c3278):src/NzbDrone.Core/Localization/Core/en.json:456 +OK [hu] „Add Indexer” Prowlarr/Prowlarr@v2.6.5.5623(12c3278):src/NzbDrone.Core/Localization/Core/en.json:17 +OK [hu] „Test” Prowlarr/Prowlarr@v2.6.5.5623(12c3278):src/NzbDrone.Core/Localization/Core/en.json:731 +OK [hu] „Save” Prowlarr/Prowlarr@v2.6.5.5623(12c3278):src/NzbDrone.Core/Localization/Core/en.json:653 +OK [hu] „Settings” Prowlarr/Prowlarr@v2.6.5.5623(12c3278):src/NzbDrone.Core/Localization/Core/en.json:682 +OK [hu] „Apps” Prowlarr/Prowlarr@v2.6.5.5623(12c3278):src/NzbDrone.Core/Localization/Core/en.json:75 +OK [hu] „Full Sync” Prowlarr/Prowlarr@v2.6.5.5623(12c3278):src/NzbDrone.Core/Localization/Core/en.json:306 +OK [hu] „Sync App Indexers” Prowlarr/Prowlarr@v2.6.5.5623(12c3278):src/NzbDrone.Core/Localization/Core/en.json:714 +OK [hu] „Search” Prowlarr/Prowlarr@v2.6.5.5623(12c3278):src/NzbDrone.Core/Localization/Core/en.json:659 +OK [hu] „Test All Indexers” Prowlarr/Prowlarr@v2.6.5.5623(12c3278):src/NzbDrone.Core/Localization/Core/en.json:735 +OK [hu] „System” Prowlarr/Prowlarr@v2.6.5.5623(12c3278):src/NzbDrone.Core/Localization/Core/en.json:720 +OK [hu] „Status” Prowlarr/Prowlarr@v2.6.5.5623(12c3278):src/NzbDrone.Core/Localization/Core/en.json:710 +OK [hu] „Health” Prowlarr/Prowlarr@v2.6.5.5623(12c3278):src/NzbDrone.Core/Localization/Core/en.json:317 +OK [hu] „History” Prowlarr/Prowlarr@v2.6.5.5623(12c3278):src/NzbDrone.Core/Localization/Core/en.json:320 +OK [hu] „Stats” Prowlarr/Prowlarr@v2.6.5.5623(12c3278):src/NzbDrone.Core/Localization/Core/en.json:709 +OK [en] „Indexers” Prowlarr/Prowlarr@v2.6.5.5623(12c3278):src/NzbDrone.Core/Localization/Core/en.json:456 +OK [en] „Add Indexer” Prowlarr/Prowlarr@v2.6.5.5623(12c3278):src/NzbDrone.Core/Localization/Core/en.json:17 +OK [en] „Test” Prowlarr/Prowlarr@v2.6.5.5623(12c3278):src/NzbDrone.Core/Localization/Core/en.json:731 +OK [en] „Save” Prowlarr/Prowlarr@v2.6.5.5623(12c3278):src/NzbDrone.Core/Localization/Core/en.json:653 +OK [en] „Apps” Prowlarr/Prowlarr@v2.6.5.5623(12c3278):src/NzbDrone.Core/Localization/Core/en.json:75 +OK [en] „Settings” Prowlarr/Prowlarr@v2.6.5.5623(12c3278):src/NzbDrone.Core/Localization/Core/en.json:682 +OK [en] „Full Sync” Prowlarr/Prowlarr@v2.6.5.5623(12c3278):src/NzbDrone.Core/Localization/Core/en.json:306 +OK [en] „Sync App Indexers” Prowlarr/Prowlarr@v2.6.5.5623(12c3278):src/NzbDrone.Core/Localization/Core/en.json:714 +OK [en] „Search” Prowlarr/Prowlarr@v2.6.5.5623(12c3278):src/NzbDrone.Core/Localization/Core/en.json:659 +OK [en] „Test All Indexers” Prowlarr/Prowlarr@v2.6.5.5623(12c3278):src/NzbDrone.Core/Localization/Core/en.json:735 +OK [en] „Status” Prowlarr/Prowlarr@v2.6.5.5623(12c3278):src/NzbDrone.Core/Localization/Core/en.json:710 +OK [en] „System” Prowlarr/Prowlarr@v2.6.5.5623(12c3278):src/NzbDrone.Core/Localization/Core/en.json:720 +OK [en] „Health” Prowlarr/Prowlarr@v2.6.5.5623(12c3278):src/NzbDrone.Core/Localization/Core/en.json:317 +OK [en] „History” Prowlarr/Prowlarr@v2.6.5.5623(12c3278):src/NzbDrone.Core/Localization/Core/en.json:320 +OK [en] „Stats” Prowlarr/Prowlarr@v2.6.5.5623(12c3278):src/NzbDrone.Core/Localization/Core/en.json:709 +RESULT: ALL FOUND — 30 label(s), 0 missing diff --git a/documentation/audits/app-guides-2026-10-15/A/qbittorrent-box.txt b/documentation/audits/app-guides-2026-10-15/A/qbittorrent-box.txt new file mode 100644 index 00000000..fad32787 --- /dev/null +++ b/documentation/audits/app-guides-2026-10-15/A/qbittorrent-box.txt @@ -0,0 +1,2 @@ +BOX CHECK OWED — qbittorrent was not running on demo-hp 9201 at 2026-10-15T20:29Z (docker ps in plex-box.txt), and night rule 2 +allows no install there tonight. Label check only (§8 row „all found / not run"); checked_version set. diff --git a/documentation/audits/app-guides-2026-10-15/A/qbittorrent-draft.json b/documentation/audits/app-guides-2026-10-15/A/qbittorrent-draft.json new file mode 100644 index 00000000..8332595b --- /dev/null +++ b/documentation/audits/app-guides-2026-10-15/A/qbittorrent-draft.json @@ -0,0 +1,94 @@ +{ + "app": "qbittorrent", + "checked_version": "5.2.4-1", + "hu": { + "sections": [ + {"title": "Torrent hozzáadása", + "intro": "Csak olyan torrentet adj hozzá, amelynek a tartalmához jogod van, például egy Linux telepítőét a kiadó saját oldaláról.", + "steps": [ + "Kattints a felső sávban az „Add Torrent Link...” (torrent hozzáadása linkkel) gombra.", + "Illeszd be a torrent vagy a magnet linkjét, és kattints a „Download” (Letöltés) gombra.", + "Ha torrentfájlod van, használd az „Add Torrent File...” (torrentfájl hozzáadása) gombot." + ]}, + {"title": "Leállítás és törlés", + "intro": "Egy torrentet bármikor megállíthatsz vagy eltávolíthatsz.", + "steps": [ + "Jelöld ki a torrentet, és kattints a „Stop” (leállítás) gombra. A „Start” (indítás) folytatja.", + "Eltávolításhoz kattints a „Remove” (eltávolítás) gombra.", + "Ha a letöltött fájlokat is törölnéd, jelöld be az „Also remove the content files” (a fájlok törlése is) jelölőt." + ]}, + {"title": "Lassabb letöltés napközben", + "intro": "Beállíthatod, hogy napközben kevésbé terhelje a netedet.", + "steps": [ + "Kattints az „Options” (beállítások) gombra, majd a „Speed” (sebesség) lapra.", + "Az „Alternative Rate Limits” (másodlagos korlát) részben adj meg alacsonyabb értékeket.", + "Jelöld be a „Schedule the use of alternative rate limits” (ütemezés) jelölőt, és add meg, mikor legyen érvényes.", + "Mentsd el a beállításokat a lap alján." + ]}, + {"title": "Meddig ossza tovább?", + "intro": "A kész letöltést a qBittorrent tovább küldi másoknak. Ezt korlátozhatod.", + "steps": [ + "Az „Options” (beállítások) „BitTorrent” lapján keresd a „Seeding Limits” (megosztási korlát) részt.", + "A „When ratio reaches” (ha az arány eléri) jelölővel megadhatod, hányszoros feltöltés után álljon le.", + "Mentsd el a beállításokat a lap alján." + ]} + ], + "faq": [ + {"q": "Hová kerülnek a letöltések?", + "a": "A meghajtódra, a media/torrents mappába. A fájlböngészőben is látod őket."}, + {"q": "Be kell állítanom a Sonarr és a Radarr kategóriáit?", + "a": "Nem. A doboz minden meghajtóhoz létrehozta a tv- és a movies- kezdetű kategóriákat, és bekapcsolta az automatikus kezelést. Ezeket ne töröld és ne nevezd át."}, + {"q": "Ha eltávolítom a torrentet, eltűnik a film a könyvtárból is?", + "a": "Nem. A Sonarr és a Radarr ugyanazt a fájlt egy második néven tette a könyvtárba, ez a torrent eltávolítása után is megmarad."}, + {"q": "Mit jelent a „Seeding” állapot?", + "a": "A letöltés kész, és a qBittorrent most másoknak küldi tovább. Ezt a „Stop” gombbal leállíthatod."}, + {"q": "Megváltoztathatom, hová mentsen?", + "a": "Ne tedd. A qBittorrent csak a media/torrents mappát látja a meghajtódon, máshová mentett fájl nem a meghajtóra kerül, és a Sonarr meg a Radarr sem találja."} + ] + }, + "en": { + "sections": [ + {"title": "Add a torrent", + "intro": "Add only a torrent whose content you have the right to, for example a Linux installer from its publisher's own site.", + "steps": [ + "In the bar at the top, select „Add Torrent Link...”.", + "Paste the torrent or magnet link and select „Download”.", + "If you have a torrent file, use „Add Torrent File...”." + ]}, + {"title": "Stop and remove", + "intro": "You can stop or remove a torrent at any time.", + "steps": [ + "Select the torrent and select „Stop”. „Start” carries on.", + "To remove it, select „Remove”.", + "To delete the downloaded files as well, tick „Also remove the content files”." + ]}, + {"title": "Slower downloads by day", + "intro": "You can make it use less of your internet line during the day.", + "steps": [ + "Select „Options”, then the „Speed” tab.", + "Under „Alternative Rate Limits”, enter lower values.", + "Tick „Schedule the use of alternative rate limits” and set when it applies.", + "Save the settings at the bottom of the page." + ]}, + {"title": "How long does it share?", + "intro": "qBittorrent keeps sending a finished download to others. You can limit that.", + "steps": [ + "On the „BitTorrent” tab of „Options”, find „Seeding Limits”.", + "With „When ratio reaches”, set after how many times the size it stops uploading.", + "Save the settings at the bottom of the page." + ]} + ], + "faq": [ + {"q": "Where do the downloads go?", + "a": "To your drive, into the media/torrents folder. You see them in the file browser too."}, + {"q": "Do I have to set up the categories for Sonarr and Radarr?", + "a": "No. For every drive, the box created the categories that start with tv- and movies-, and switched on automatic management. Do not delete or rename them."}, + {"q": "If I remove the torrent, does the film leave the library too?", + "a": "No. Sonarr and Radarr put the same file into the library under a second name, and that stays after the torrent is removed."}, + {"q": "What does „Seeding” mean?", + "a": "The download is finished and qBittorrent is now sending it on to others. „Stop” ends that."}, + {"q": "Can I change where it saves?", + "a": "Do not. qBittorrent sees only the media/torrents folder on your drive; a file saved anywhere else is not on the drive, and Sonarr and Radarr cannot find it."} + ] + } +} diff --git a/documentation/audits/app-guides-2026-10-15/A/qbittorrent-labels.txt b/documentation/audits/app-guides-2026-10-15/A/qbittorrent-labels.txt new file mode 100644 index 00000000..2f9ea560 --- /dev/null +++ b/documentation/audits/app-guides-2026-10-15/A/qbittorrent-labels.txt @@ -0,0 +1,34 @@ +app: qbittorrent checked against: 5.2.4-1 +corpora: qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/private qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/public felhom-controller@123d2d5:controller/internal/i18n/locales/hu.json felhom-controller@123d2d5:controller/internal/i18n/locales/en.json +labels: 30 (Hungarian and English guide strings, every „…” occurrence) +OK [hu] „Add Torrent Link...” qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/private/index.html:70 +OK [hu] „Download” qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/private/addtorrent.html:401 +OK [hu] „Add Torrent File...” qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/private/index.html:64 +OK [hu] „Stop” qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/private/shareratio.html:201 +OK [hu] „Start” qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/private/index.html:78 +OK [hu] „Remove” qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/private/shareratio.html:202 +OK [hu] „Also remove the content files” qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/private/views/confirmdeletion.html:11 +OK [hu] „Options” qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/private/index.html:140 +OK [hu] „Speed” qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/private/views/preferencesToolbar.html:14 +OK [hu] „Alternative Rate Limits” qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/private/views/preferences.html:643 +OK [hu] „Schedule the use of alternative rate limits” qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/private/views/preferences.html:664 +OK [hu] „BitTorrent” qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/private/views/preferencesToolbar.html:17 +OK [hu] „Seeding Limits” qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/private/views/preferences.html:811 +OK [hu] „When ratio reaches” qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/private/views/preferences.html:817 +OK [hu] „Seeding” qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/private/views/filters.html:8 +OK [en] „Add Torrent Link...” qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/private/index.html:70 +OK [en] „Download” qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/private/addtorrent.html:401 +OK [en] „Add Torrent File...” qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/private/index.html:64 +OK [en] „Stop” qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/private/shareratio.html:201 +OK [en] „Start” qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/private/index.html:78 +OK [en] „Remove” qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/private/shareratio.html:202 +OK [en] „Also remove the content files” qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/private/views/confirmdeletion.html:11 +OK [en] „Options” qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/private/index.html:140 +OK [en] „Speed” qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/private/views/preferencesToolbar.html:14 +OK [en] „Alternative Rate Limits” qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/private/views/preferences.html:643 +OK [en] „Schedule the use of alternative rate limits” qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/private/views/preferences.html:664 +OK [en] „BitTorrent” qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/private/views/preferencesToolbar.html:17 +OK [en] „Seeding Limits” qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/private/views/preferences.html:811 +OK [en] „When ratio reaches” qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/private/views/preferences.html:817 +OK [en] „Seeding” qbittorrent/qBittorrent@release-5.2.4(a1e4649):src/webui/www/private/views/filters.html:8 +RESULT: ALL FOUND — 30 label(s), 0 missing diff --git a/documentation/audits/app-guides-2026-10-15/A/radarr-box.txt b/documentation/audits/app-guides-2026-10-15/A/radarr-box.txt new file mode 100644 index 00000000..93bbfb0f --- /dev/null +++ b/documentation/audits/app-guides-2026-10-15/A/radarr-box.txt @@ -0,0 +1,2 @@ +BOX CHECK OWED — radarr was not running on demo-hp 9201 at 2026-10-15T20:29Z (docker ps in plex-box.txt), and night rule 2 +allows no install there tonight. Label check only (§8 row „all found / not run"); checked_version set. diff --git a/documentation/audits/app-guides-2026-10-15/A/radarr-draft.json b/documentation/audits/app-guides-2026-10-15/A/radarr-draft.json new file mode 100644 index 00000000..10704289 --- /dev/null +++ b/documentation/audits/app-guides-2026-10-15/A/radarr-draft.json @@ -0,0 +1,100 @@ +{ + "app": "radarr", + "checked_version": "6.4.4", + "hu": { + "sections": [ + {"title": "Első film hozzáadása", + "intro": "A Radarr megkeresi és letölti a filmet, amint elérhető.", + "steps": [ + "A bal oldali menüben a „Movies” (Filmek) alatt kattints az „Add New” (Új hozzáadása) pontra.", + "Írd be a film címét, és kattints a megfelelő találatra.", + "A „Root Folder” (gyökérmappa) mezőben válaszd annak a meghajtónak a media/movies mappáját, ahová a filmet szeretnéd.", + "A „Tags” (címkék) mezőbe írd ugyanannak a meghajtónak a címkéjét, például hdd-1. Címke nélkül a film nem kap letöltőt.", + "Hagyd bejelölve a „Start search for missing movie” (film keresése) jelölőt, és kattints az „Add Movie” (Film hozzáadása) gombra." + ]}, + {"title": "Mikor keresi a filmet?", + "intro": "A Radarr csak akkor keres, amikor a film már elérhető lehet.", + "steps": [ + "A film hozzáadásakor a „Minimum Availability” (legkorábbi elérhetőség) mezőben állítod, mikor kezdjen keresni.", + "Az „Announced” (bejelentve) és az „In Cinemas” (moziban) korán keres, gyakran eredmény nélkül.", + "A „Released” (megjelent) a legbiztosabb: akkor keres, amikor a filmet már kiadták otthoni nézésre." + ]}, + {"title": "A letöltés követése", + "intro": "A letöltés a háttérben fut, az oldalt be is zárhatod.", + "steps": [ + "Az „Activity” (Tevékenység) menü „Queue” (Sor) lapján látod, mi töltődik éppen.", + "Ha a film letöltődött, a Radarr magától átteszi a film mappájába. A Plex és a Jellyfin innen látja.", + "A „Calendar” (Naptár) mutatja, mikor jelenik meg egy figyelt film." + ]}, + {"title": "Ha valami nem működik", + "intro": "A Radarr maga jelzi, ha valami hibás.", + "steps": [ + "Nézd meg a „System” (Rendszer) menü „Status” (Állapot) lapját: a „Health” (állapot) rész sorolja a hibákat.", + "A „Settings” (Beállítások) menü „Download Clients” (letöltő kliensek) oldalán látod a letöltőket, amelyeket a doboz bekötött.", + "Ha nincs találat, nézd meg a Prowlarr „Indexers” (indexerek) oldalát: legalább egy forrás kell." + ]} + ], + "faq": [ + {"q": "Honnan tölt le a Radarr?", + "a": "Azokról a forrásokról (indexerekről), amelyeket te adsz meg a Prowlarrban. A doboz összeköti a kettőt, de forrást nem ad és nem ajánl: ez a te döntésed."}, + {"q": "Be kell állítanom a letöltő klienst és a mappákat?", + "a": "Nem. A doboz minden meghajtódhoz bekötötte a telepített letöltőket (qBittorrent, Transmission), a gyökérmappát és a címkét. Neked csak a filmet kell hozzáadnod."}, + {"q": "Miért van ugyanaz a fájl a torrents és a movies mappában is?", + "a": "Nem foglal dupla helyet: ugyanaz a fájl két néven (hardlink). A letöltő tovább oszthatja, a könyvtárad pedig rendezett marad."}, + {"q": "Letöltötte, de nem került a könyvtárba. Miért?", + "a": "Ha a meghajtón kevesebb mint 10 GB maradna, a Radarr nem importál. Ezt a doboz állította be: „Settings”, „Media Management”, „Minimum Free Space” (legkevesebb szabad hely). Szabadíts fel helyet, és a következő ellenőrzéskor folytatja."}, + {"q": "Ajánl filmeket?", + "a": "Igen: a „Discover” (Felfedezés) oldal a meglévő filmjeid alapján mutat ötleteket, és onnan egy kattintással hozzáadhatod őket."}, + {"q": "Mit tölthetek le?", + "a": "Csak olyan tartalmat, amihez jogod van, például közkincs (public domain) filmeket."} + ] + }, + "en": { + "sections": [ + {"title": "Add your first film", + "intro": "Radarr finds and downloads a film as soon as it is available.", + "steps": [ + "In the menu on the left, under „Movies”, select „Add New”.", + "Type the title of the film and select the right result.", + "In „Root Folder”, choose the media/movies folder of the drive you want the film on.", + "In „Tags”, type the tag of that same drive, for example hdd-1. Without a tag the film gets no download client.", + "Leave „Start search for missing movie” ticked and select „Add Movie”." + ]}, + {"title": "When does it search?", + "intro": "Radarr searches only once a film may be available.", + "steps": [ + "When you add a film, „Minimum Availability” sets when the search starts.", + "„Announced” and „In Cinemas” search early, and often find nothing.", + "„Released” is the safest: it searches once the film is out for home viewing." + ]}, + {"title": "Follow a download", + "intro": "Downloads run in the background, so you can close the page.", + "steps": [ + "The „Queue” tab of the „Activity” menu shows what is downloading now.", + "When a film is done, Radarr moves it into the film's folder by itself. Plex and Jellyfin see it there.", + "The „Calendar” shows when a film you watch for comes out." + ]}, + {"title": "When something does not work", + "intro": "Radarr tells you itself when something is wrong.", + "steps": [ + "Look at the „Status” tab of the „System” menu: the „Health” part lists the problems.", + "The „Download Clients” page of the „Settings” menu shows the download clients the box connected.", + "If nothing is found, look at the „Indexers” page in Prowlarr: you need at least one source." + ]} + ], + "faq": [ + {"q": "Where does Radarr download from?", + "a": "From the sources (indexers) you add in Prowlarr. The box connects the two, but it neither provides nor suggests a source: that is your choice."}, + {"q": "Do I have to set up the download client and the folders?", + "a": "No. For every drive, the box connected the installed download clients (qBittorrent, Transmission), the root folder and the tag. You only add the film."}, + {"q": "Why is the same file in both the torrents and the movies folder?", + "a": "It does not take double space: it is one file with two names (a hardlink). The download client can keep sharing it, and your library stays tidy."}, + {"q": "It downloaded, but it is not in the library. Why?", + "a": "Radarr does not import if less than 10 GB would be left on the drive. The box set this: „Settings”, „Media Management”, „Minimum Free Space”. Free up some space and it goes on at the next check."}, + {"q": "Does it suggest films?", + "a": "Yes: the „Discover” page shows ideas based on the films you have, and you can add one from there with a click."}, + {"q": "What may I download?", + "a": "Only content you have the right to, for example films in the public domain."} + ] + } +} diff --git a/documentation/audits/app-guides-2026-10-15/A/radarr-labels.txt b/documentation/audits/app-guides-2026-10-15/A/radarr-labels.txt new file mode 100644 index 00000000..a2f2102b --- /dev/null +++ b/documentation/audits/app-guides-2026-10-15/A/radarr-labels.txt @@ -0,0 +1,48 @@ +app: radarr checked against: 6.4.4 +corpora: Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json Radarr/Radarr@v6.4.4.10685(a96bf7c):frontend/src felhom-controller@123d2d5:controller/internal/i18n/locales/hu.json felhom-controller@123d2d5:controller/internal/i18n/locales/en.json +labels: 44 (Hungarian and English guide strings, every „…” occurrence) +OK [hu] „Movies” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:1188 +OK [hu] „Add New” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:35 +OK [hu] „Root Folder” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:132 +OK [hu] „Tags” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:1902 +OK [hu] „Start search for missing movie” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:1868 +OK [hu] „Add Movie” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:33 +OK [hu] „Minimum Availability” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:1092 +OK [hu] „Announced” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:78 +OK [hu] „In Cinemas” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:867 +OK [hu] „Released” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:1613 +OK [hu] „Activity” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:4 +OK [hu] „Queue” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:1559 +OK [hu] „Calendar” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:181 +OK [hu] „System” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:1886 +OK [hu] „Status” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:133 +OK [hu] „Health” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:748 +OK [hu] „Settings” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:1786 +OK [hu] „Download Clients” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:570 +OK [hu] „Indexers” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:942 +OK [hu] „Media Management” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:1062 +OK [hu] „Minimum Free Space” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:1097 +OK [hu] „Discover” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:410 +OK [en] „Movies” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:1188 +OK [en] „Add New” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:35 +OK [en] „Root Folder” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:132 +OK [en] „Tags” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:1902 +OK [en] „Start search for missing movie” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:1868 +OK [en] „Add Movie” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:33 +OK [en] „Minimum Availability” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:1092 +OK [en] „Announced” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:78 +OK [en] „In Cinemas” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:867 +OK [en] „Released” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:1613 +OK [en] „Queue” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:1559 +OK [en] „Activity” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:4 +OK [en] „Calendar” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:181 +OK [en] „Status” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:133 +OK [en] „System” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:1886 +OK [en] „Health” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:748 +OK [en] „Download Clients” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:570 +OK [en] „Settings” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:1786 +OK [en] „Indexers” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:942 +OK [en] „Media Management” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:1062 +OK [en] „Minimum Free Space” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:1097 +OK [en] „Discover” Radarr/Radarr@v6.4.4.10685(a96bf7c):src/NzbDrone.Core/Localization/Core/en.json:410 +RESULT: ALL FOUND — 44 label(s), 0 missing diff --git a/documentation/audits/app-guides-2026-10-15/A/sonarr-box.txt b/documentation/audits/app-guides-2026-10-15/A/sonarr-box.txt new file mode 100644 index 00000000..6c3bb408 --- /dev/null +++ b/documentation/audits/app-guides-2026-10-15/A/sonarr-box.txt @@ -0,0 +1,2 @@ +BOX CHECK OWED — sonarr was not running on demo-hp 9201 at 2026-10-15T20:29Z (docker ps in plex-box.txt), and night rule 2 +allows no install there tonight. Label check only (§8 row „all found / not run"); checked_version set. diff --git a/documentation/audits/app-guides-2026-10-15/A/sonarr-draft.json b/documentation/audits/app-guides-2026-10-15/A/sonarr-draft.json new file mode 100644 index 00000000..e98f4637 --- /dev/null +++ b/documentation/audits/app-guides-2026-10-15/A/sonarr-draft.json @@ -0,0 +1,100 @@ +{ + "app": "sonarr", + "checked_version": "4.0.20", + "hu": { + "sections": [ + {"title": "Első sorozat hozzáadása", + "intro": "A Sonarr figyeli a sorozatot, és letölti az új részeket, amint megjelennek.", + "steps": [ + "A bal oldali menüben a „Series” (Sorozatok) alatt kattints az „Add New” (Új hozzáadása) pontra.", + "Írd be a sorozat címét, és kattints a megfelelő találatra.", + "A „Root Folder” (gyökérmappa) mezőben válaszd annak a meghajtónak a media/tv mappáját, ahová a sorozatot szeretnéd.", + "A „Tags” (címkék) mezőbe írd ugyanannak a meghajtónak a címkéjét, például hdd-1. Címke nélkül a sorozat nem kap letöltőt.", + "Hagyd bejelölve a „Start search for missing episodes” (hiányzó részek keresése) jelölőt, és add hozzá a sorozatot." + ]}, + {"title": "A letöltés követése", + "intro": "A letöltés a háttérben fut, az oldalt be is zárhatod.", + "steps": [ + "Az „Activity” (Tevékenység) menü „Queue” (Sor) lapján látod, mi töltődik éppen.", + "Ha egy rész letöltődött, a Sonarr magától átteszi a sorozat mappájába. A Plex és a Jellyfin innen látja.", + "A „Calendar” (Naptár) mutatja, mikor jön a következő rész." + ]}, + {"title": "Hiányzó részek keresése", + "intro": "Ha egy régebbi évad hiányzik, egyszerre kerestetheted.", + "steps": [ + "Nyisd meg a „Wanted” (Keresett) menü „Missing” (Hiányzó) lapját.", + "Jelöld be a kívánt részeket, és kattints a „Search Selected” (kijelöltek keresése) gombra.", + "Ha mindet keresnéd, használd a „Search All” (összes keresése) gombot." + ]}, + {"title": "Ha valami nem működik", + "intro": "A Sonarr maga jelzi, ha valami hibás.", + "steps": [ + "Nézd meg a „System” (Rendszer) menü „Status” (Állapot) lapját: a „Health” (állapot) rész sorolja a hibákat.", + "A „Settings” (Beállítások) menü „Download Clients” (letöltő kliensek) oldalán látod a letöltőket, amelyeket a doboz bekötött.", + "Ha nincs találat, nézd meg a Prowlarr „Indexers” (indexerek) oldalát: legalább egy forrás kell." + ]} + ], + "faq": [ + {"q": "Honnan tölt le a Sonarr?", + "a": "Azokról a forrásokról (indexerekről), amelyeket te adsz meg a Prowlarrban. A doboz összeköti a kettőt, de forrást nem ad és nem ajánl: ez a te döntésed."}, + {"q": "Be kell állítanom a letöltő klienst és a mappákat?", + "a": "Nem. A doboz minden meghajtódhoz bekötötte a telepített letöltőket (qBittorrent, Transmission), a gyökérmappát és a címkét. Neked csak a sorozatot kell hozzáadnod."}, + {"q": "Miért van ugyanaz a fájl a torrents és a tv mappában is?", + "a": "Nem foglal dupla helyet: ugyanaz a fájl két néven (hardlink). A letöltő tovább oszthatja, a könyvtárad pedig rendezett marad."}, + {"q": "Letöltötte, de nem került a könyvtárba. Miért?", + "a": "Ha a meghajtón kevesebb mint 10 GB maradna, a Sonarr nem importál. Ezt a doboz állította be: „Settings”, „Media Management”, „Minimum Free Space” (legkevesebb szabad hely). Szabadíts fel helyet, és a következő ellenőrzéskor folytatja."}, + {"q": "Hol nézhetem meg a sorozatokat?", + "a": "A Plexben vagy a Jellyfinben. A Sonarr csak letölt és rendez, lejátszani nem tud."}, + {"q": "Mit tölthetek le?", + "a": "Csak olyan tartalmat, amihez jogod van, például szabad licencű műsorokat."} + ] + }, + "en": { + "sections": [ + {"title": "Add your first series", + "intro": "Sonarr watches a series and downloads each new episode as it comes out.", + "steps": [ + "In the menu on the left, under „Series”, select „Add New”.", + "Type the title of the series and select the right result.", + "In „Root Folder”, choose the media/tv folder of the drive you want the series on.", + "In „Tags”, type the tag of that same drive, for example hdd-1. Without a tag the series gets no download client.", + "Leave „Start search for missing episodes” ticked and add the series." + ]}, + {"title": "Follow a download", + "intro": "Downloads run in the background, so you can close the page.", + "steps": [ + "The „Queue” tab of the „Activity” menu shows what is downloading now.", + "When an episode is done, Sonarr moves it into the series folder by itself. Plex and Jellyfin see it there.", + "The „Calendar” shows when the next episode is due." + ]}, + {"title": "Search for missing episodes", + "intro": "If an older season is missing, you can search for it in one go.", + "steps": [ + "Open the „Missing” tab of the „Wanted” menu.", + "Tick the episodes you want and select „Search Selected”.", + "To search for all of them, use „Search All”." + ]}, + {"title": "When something does not work", + "intro": "Sonarr tells you itself when something is wrong.", + "steps": [ + "Look at the „Status” tab of the „System” menu: the „Health” part lists the problems.", + "The „Download Clients” page of the „Settings” menu shows the download clients the box connected.", + "If nothing is found, look at the „Indexers” page in Prowlarr: you need at least one source." + ]} + ], + "faq": [ + {"q": "Where does Sonarr download from?", + "a": "From the sources (indexers) you add in Prowlarr. The box connects the two, but it neither provides nor suggests a source: that is your choice."}, + {"q": "Do I have to set up the download client and the folders?", + "a": "No. For every drive, the box connected the installed download clients (qBittorrent, Transmission), the root folder and the tag. You only add the series."}, + {"q": "Why is the same file in both the torrents and the tv folder?", + "a": "It does not take double space: it is one file with two names (a hardlink). The download client can keep sharing it, and your library stays tidy."}, + {"q": "It downloaded, but it is not in the library. Why?", + "a": "Sonarr does not import if less than 10 GB would be left on the drive. The box set this: „Settings”, „Media Management”, „Minimum Free Space”. Free up some space and it goes on at the next check."}, + {"q": "Where do I watch the series?", + "a": "In Plex or Jellyfin. Sonarr only downloads and files; it cannot play anything."}, + {"q": "What may I download?", + "a": "Only content you have the right to, for example shows under a free licence."} + ] + } +} diff --git a/documentation/audits/app-guides-2026-10-15/A/sonarr-labels.txt b/documentation/audits/app-guides-2026-10-15/A/sonarr-labels.txt new file mode 100644 index 00000000..d1fc3d59 --- /dev/null +++ b/documentation/audits/app-guides-2026-10-15/A/sonarr-labels.txt @@ -0,0 +1,44 @@ +app: sonarr checked against: 4.0.20 +corpora: Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json Sonarr/Sonarr@v4.0.20.3014(cab419a):frontend/src felhom-controller@123d2d5:controller/internal/i18n/locales/hu.json felhom-controller@123d2d5:controller/internal/i18n/locales/en.json +labels: 40 (Hungarian and English guide strings, every „…” occurrence) +OK [hu] „Series” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:1860 +OK [hu] „Add New” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:38 +OK [hu] „Root Folder” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:139 +OK [hu] „Tags” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:1998 +OK [hu] „Start search for missing episodes” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:45 +OK [hu] „Activity” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:7 +OK [hu] „Queue” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:1631 +OK [hu] „Calendar” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:184 +OK [hu] „Wanted” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:2139 +OK [hu] „Missing” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:1207 +OK [hu] „Search Selected” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:1819 +OK [hu] „Search All” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:1806 +OK [hu] „System” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:1984 +OK [hu] „Status” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:141 +OK [hu] „Health” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:781 +OK [hu] „Settings” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:1901 +OK [hu] „Download Clients” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:571 +OK [hu] „Indexers” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:1043 +OK [hu] „Media Management” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:1159 +OK [hu] „Minimum Free Space” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:1201 +OK [en] „Series” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:1860 +OK [en] „Add New” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:38 +OK [en] „Root Folder” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:139 +OK [en] „Tags” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:1998 +OK [en] „Start search for missing episodes” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:45 +OK [en] „Queue” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:1631 +OK [en] „Activity” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:7 +OK [en] „Calendar” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:184 +OK [en] „Missing” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:1207 +OK [en] „Wanted” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:2139 +OK [en] „Search Selected” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:1819 +OK [en] „Search All” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:1806 +OK [en] „Status” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:141 +OK [en] „System” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:1984 +OK [en] „Health” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:781 +OK [en] „Download Clients” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:571 +OK [en] „Settings” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:1901 +OK [en] „Indexers” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:1043 +OK [en] „Media Management” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:1159 +OK [en] „Minimum Free Space” Sonarr/Sonarr@v4.0.20.3014(cab419a):src/NzbDrone.Core/Localization/Core/en.json:1201 +RESULT: ALL FOUND — 40 label(s), 0 missing diff --git a/documentation/audits/app-guides-2026-10-15/part0-redproof.py b/documentation/audits/app-guides-2026-10-15/part0-redproof.py new file mode 100644 index 00000000..5f5ec28f --- /dev/null +++ b/documentation/audits/app-guides-2026-10-15/part0-redproof.py @@ -0,0 +1,36 @@ +import io, os, sys, subprocess, shutil +ROOT = "/mnt/5_hdd/felhom.eu/git/app-catalog-felhom.eu" +sys.path.insert(0, os.path.join(ROOT, "scripts")) +import test_gate_decoys as T +CG = os.path.join(ROOT, "scripts", "check-copy-i18n.py") +GV = os.path.join(ROOT, "scripts", "check-guide-version.py") +P = [ + ("R1 guide strings counted as copy", CG, ' g = ai.get("guide") if isinstance(ai.get("guide"), dict) else {}', ' g = {}'), + ("R2 overlay accepts guide", CG, '"prerequisites",\n "guide"):', '"prerequisites"):'), + ("R3 checked_version refused in overlay", CG, ' if k == "checked_version":', ' if False:'), + ("R4 empty steps refused", CG, ' if not isinstance(steps, list) or not steps:', ' if not isinstance(steps, list):'), + ("R5 faq answer required", CG, ' if not (isinstance(qa.get(k), str) and qa.get(k).strip()):', ' if not isinstance(qa.get(k), (str, type(None))):'), + ("R6 quoted version", CG, ' if cv is not None and not isinstance(cv, str):', ' if False:'), + ("R7 section/faq counts", CG, ' if len(lst) != len(hu_lst):', ' if len(lst) < len(hu_lst):'), + ("R8 step counts", CG, ' if len(st) != hu_n:', ' if len(st) > hu_n + 99:'), + ("R9 inert English guide", CG, ' if not isinstance(hu_g, dict):\n errs.append', ' if False:\n errs.append'), + ("R10 source deny-list", CG, ' for name in SOURCE_DENYLIST:', ' for name in []:'), + ("R11 WARN on a moved image", GV, ' if cv in cands:', ' if cv:'), + ("R12 the app service, not a sidecar", GV, ' cands = [tags[s] for s in main_svcs] or list(tags.values())', ' cands = list(tags.values())'), +] +for name, path, old, new in P: + src = io.open(path, encoding="utf-8").read() + assert src.count(old) == 1, name + io.open(path, "w", encoding="utf-8").write(src.replace(old, new)) + try: + T.fails[:] = [] + clone = T.make_clone() + import contextlib + buf = io.StringIO() + with contextlib.redirect_stdout(buf): + T.guide_cases(clone) + shutil.rmtree(clone, ignore_errors=True) + names = [f.split(":")[0] + ":" + f.split(":")[1] for f in T.fails] + print("%-42s -> %d case(s) FAIL: %s" % (name, len(T.fails), "; ".join(n.strip() for n in names))) + finally: + io.open(path, "w", encoding="utf-8").write(src) diff --git a/documentation/audits/app-guides-2026-10-15/part0-redproofs.txt b/documentation/audits/app-guides-2026-10-15/part0-redproofs.txt new file mode 100644 index 00000000..11e3816d --- /dev/null +++ b/documentation/audits/app-guides-2026-10-15/part0-redproofs.txt @@ -0,0 +1,12 @@ +R1 guide strings counted as copy -> 3 case(s) FAIL: GENUINE: a full Hungarian guide with its English overlay; FACT: guide strings that are not in the freeze; FACT: a tracker named in a Hungarian answer (folded, any case) +R2 overlay accepts guide -> 3 case(s) FAIL: GENUINE: a full Hungarian guide with its English overlay; DECOY: a tracker named only in a YAML comment; DECOY: a source-like word only in docs_url (configuration) +R3 checked_version refused in overlay -> 1 case(s) FAIL: FACT: checked_version in the English block +R4 empty steps refused -> 1 case(s) FAIL: FACT: a section with an empty steps list +R5 faq answer required -> 1 case(s) FAIL: FACT: an FAQ entry with a question and no answer +R6 quoted version -> 1 case(s) FAIL: FACT: an unquoted checked_version (YAML reads 4.10 as 4.1) +R7 section/faq counts -> 1 case(s) FAIL: FACT: more English sections than Hungarian +R8 step counts -> 1 case(s) FAIL: FACT: an English section with a different step count +R9 inert English guide -> 1 case(s) FAIL: FACT: an English guide with no Hungarian guide +R10 source deny-list -> 2 case(s) FAIL: FACT: a tracker named in an English step; FACT: a tracker named in a Hungarian answer (folded, any case) +R11 WARN on a moved image -> 2 case(s) FAIL: FACT: the app's image moved off the checked tag (4.0.20 -> 4.0.21); DECOY: the checked tag survives only on a SIDECAR +R12 the app service, not a sidecar -> 1 case(s) FAIL: DECOY: the checked tag survives only on a SIDECAR diff --git a/documentation/audits/app-guides-2026-10-15/tools/apply_guide.py b/documentation/audits/app-guides-2026-10-15/tools/apply_guide.py new file mode 100644 index 00000000..5a6c5ad1 --- /dev/null +++ b/documentation/audits/app-guides-2026-10-15/tools/apply_guide.py @@ -0,0 +1,165 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +"""apply_guide.py — write one draft guide into templates//.felhom.yml, by TEXT, and prove the parse. + + python3 apply_guide.py [--hidden] + +The draft is {"app", "checked_version", "hu": {"sections", "faq"}, "en": {"sections", "faq"}}. The Hungarian guide +goes at the END of the top-level `app_info:` block (two spaces), the English one at the end of `i18n.en.app_info` +(six spaces). An existing guide block is replaced, so a morning format change is one more run. Every string is +written JSON-quoted (valid YAML double-quoted: Hungarian quotes, apostrophes and colons cannot break it — the +„Hungarian-quote YAML kill" trap). + +`--hidden` writes `checked_version: ""` (a label was not found: the box does not show the guide). + +PROOF, after writing: the file parses; `app_info.guide` and `i18n.en.app_info.guide` equal the draft; and the +WHOLE document minus those two keys equals the document before. Any difference restores the old file and exits 1. +""" +import copy +import io +import json +import sys + +import yaml + + +def q(s): + return json.dumps(s, ensure_ascii=False) + + +def block(g, ind, cv=None): + p = " " * ind + out = [p + "guide:"] + if cv is not None: + out.append(p + " checked_version: " + q(cv)) + out.append(p + " sections:") + for se in g["sections"]: + out.append(p + " - title: " + q(se["title"])) + if se.get("intro"): + out.append(p + " intro: " + q(se["intro"])) + out.append(p + " steps:") + for st in se["steps"]: + out.append(p + " - " + q(st)) + if g.get("faq"): + out.append(p + " faq:") + for qa in g["faq"]: + out.append(p + " - q: " + q(qa["q"])) + out.append(p + " a: " + q(qa["a"])) + return out + + +def indent(line): + return len(line) - len(line.lstrip(" ")) + + +def is_content(line): + s = line.strip() + return s != "" and not s.startswith("#") + + +def span(lines, start, ind): + """Index just past the last CONTENT line belonging to the block whose header is lines[start] (children are + indented deeper than `ind`). Trailing blank and comment lines stay outside, with whatever follows.""" + end = start + 1 + last = start + i = start + 1 + while i < len(lines): + if is_content(lines[i]): + if indent(lines[i]) <= ind: + break + last = i + i += 1 + return last + 1 + + +def remove_guide(lines, parent, ind): + """Remove a `guide:` child (at indent `ind`) of the block headed at lines[parent].""" + end = span(lines, parent, ind - 2) + for i in range(parent + 1, end): + if lines[i] == " " * ind + "guide:": + j = span(lines, i, ind) + del lines[i:j] + return True + return False + + +def find_line(lines, text, after=0, before=None): + for i in range(after, before if before is not None else len(lines)): + if lines[i] == text: + return i + return -1 + + +def strip_guides(doc): + d = copy.deepcopy(doc) + (d.get("app_info") or {}).pop("guide", None) + en = ((d.get("i18n") or {}).get("en") or {}) + (en.get("app_info") or {}).pop("guide", None) + return d + + +def main(argv): + root, draft_path = argv[1], argv[2] + hidden = "--hidden" in argv + d = json.load(io.open(draft_path, encoding="utf-8")) + app = d["app"] + path = "%s/templates/%s/.felhom.yml" % (root, app) + old_text = io.open(path, encoding="utf-8").read() + old_doc = yaml.safe_load(old_text) + lines = old_text.split("\n") + + # Hungarian: top-level app_info + ai = find_line(lines, "app_info:") + if ai < 0: + print("FAIL %s: no top-level app_info:" % app) + return 1 + remove_guide(lines, ai, 2) + end = span(lines, ai, 0) + cv = "" if hidden else d["checked_version"] + lines[end:end] = block(d["hu"], 2, cv) + + # English: i18n -> en -> app_info + i18 = find_line(lines, "i18n:") + en = find_line(lines, " en:", i18 + 1) if i18 >= 0 else -1 + if en < 0: + print("FAIL %s: no i18n.en block — every app is translated; refusing to invent one" % app) + return 1 + en_end = span(lines, en, 2) + eai = find_line(lines, " app_info:", en + 1, en_end) + if eai < 0: + lines[en_end:en_end] = [" app_info:"] + eai = en_end + remove_guide(lines, eai, 6) + e_end = span(lines, eai, 4) + lines[e_end:e_end] = block(d["en"], 6) + + new_text = "\n".join(lines) + new_doc = yaml.safe_load(new_text) + want_hu = {"checked_version": cv, "sections": d["hu"]["sections"], "faq": d["hu"]["faq"]} + want_en = {"sections": d["en"]["sections"], "faq": d["en"]["faq"]} + + def norm(g): # the writer omits an empty intro; compare like for like + g = copy.deepcopy(g) + for se in g.get("sections") or []: + if not se.get("intro"): + se.pop("intro", None) + return g + problems = [] + if norm(new_doc["app_info"].get("guide")) != norm(want_hu): + problems.append("Hungarian guide does not read back as the draft") + if norm(new_doc["i18n"]["en"]["app_info"].get("guide")) != norm(want_en): + problems.append("English guide does not read back as the draft") + if strip_guides(new_doc) != strip_guides(old_doc): + problems.append("the rest of the document CHANGED") + if problems: + print("FAIL %s: %s — file left as it was" % (app, "; ".join(problems))) + return 1 + with io.open(path, "w", encoding="utf-8") as fh: + fh.write(new_text) + print("OK %s: guide written (%d sections, %d faq; checked_version %r)" + % (app, len(d["hu"]["sections"]), len(d["hu"]["faq"]), cv)) + return 0 + + +if __name__ == "__main__": + sys.exit(main(sys.argv)) diff --git a/documentation/audits/app-guides-2026-10-15/tools/labelcheck.py b/documentation/audits/app-guides-2026-10-15/tools/labelcheck.py new file mode 100644 index 00000000..cbe12369 --- /dev/null +++ b/documentation/audits/app-guides-2026-10-15/tools/labelcheck.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +"""labelcheck.py — every quoted label in a guide draft, looked up in the app's source AT THE PINNED TAG. + + python3 labelcheck.py [ ...] + +A label is the text between „ and ” (or “ and ”) in any guide string, Hungarian or English. It is FOUND +when it occurs DELIMITED in a corpus file: as a whole JSON key or value, inside QBT_TR(…)QBT_TR, between +quotes, or between > and <. A bare substring is not enough ("Add" is inside every file). The first hit's +file:line is recorded. Exit 0 = every label found, 1 = at least one MISSING (the guide stays hidden). + +The corpus is the app's upstream source at the image's tag (or the files the image itself ships), plus the +controller's own locale files for the Felhom labels a guide points at (a tab name, „Kész, beállítottam"). +""" +import io +import json +import os +import re +import sys + +LABEL = re.compile(r"[„“]([^”„“]+)”") +TEXT_EXT = (".json", ".js", ".jsx", ".ts", ".tsx", ".html", ".htm", ".vue", ".svelte", ".py", ".go", ".php", + ".twig", ".blade.php", ".po", ".pot", ".yml", ".yaml", ".xml", ".ts.xml", ".properties", ".dart", + ".kt", ".java", ".cs", ".rb", ".erb", ".hbs", ".mjs", ".cjs", ".svg", ".md", ".txt", ".ini", ".toml", + ".strings", ".resx", ".arb", ".csv", ".tmpl", ".gohtml", ".j2", ".jinja", ".lua", ".rs", ".ex", ".exs", + ".heex", ".eex", ".elm", ".swift", ".c", ".cpp", ".h", ".ui") + + +def labels_of(draft): + out = [] + for lang in ("hu", "en"): + g = draft.get(lang) or {} + strings = [] + for se in g.get("sections") or []: + strings += [se.get("title") or "", se.get("intro") or ""] + list(se.get("steps") or []) + for qa in g.get("faq") or []: + strings += [qa.get("q") or "", qa.get("a") or ""] + for s in strings: + for m in LABEL.finditer(s): + lab = m.group(1).strip() + if (lang, lab) not in out: + out.append((lang, lab)) + return out + + +def files_of(corpus): + if os.path.isfile(corpus): + yield corpus + return + for dp, dn, fn in os.walk(corpus): + dn[:] = [d for d in dn if d not in (".git", "node_modules", "test", "tests", "__tests__")] + for f in fn: + if f.endswith(TEXT_EXT): + yield os.path.join(dp, f) + + +def find(label, corpora, cache): + e = re.escape(label) + pats = [re.compile(p) for p in ( + r'QBT_TR\(%s\)QBT_TR' % e, + r'"%s"' % e, r"'%s'" % e, r'`%s`' % e, + r'>\s*%s\s*<' % e, + r'msgstr "%s"' % e, r'%s' % e, r'%s' % e, + r'(?m)^\s*[\w.\-]+\s*=\s*%s\s*$' % e, # .properties / .ini value + r'(?m)^\s*"?[\w.\-]+"?\s*:\s*%s\s*$' % e, # YAML value, unquoted + )] + for c in corpora: + for path in files_of(c): + if path not in cache: + try: + cache[path] = io.open(path, encoding="utf-8", errors="replace").read() + except OSError: + cache[path] = "" + text = cache[path] + if label not in text: + continue + for p in pats: + m = p.search(text) + if m: + line = text.count("\n", 0, m.start()) + 1 + return "%s:%d" % (path, line) + return None + + +def main(argv): + draft = json.load(io.open(argv[1], encoding="utf-8")) + out_path, corpora = argv[2], argv[3:] + cache, lines, missing = {}, [], 0 + labs = labels_of(draft) + lines.append("app: %s checked against: %s" % (draft.get("app"), draft.get("checked_version"))) + lines.append("corpora: %s" % " ".join(corpora)) + lines.append("labels: %d (Hungarian and English guide strings, every „…” occurrence)" % len(labs)) + for lang, lab in labs: + hit = find(lab, corpora, cache) + if hit: + lines.append("OK [%s] „%s” %s" % (lang, lab, hit)) + else: + missing += 1 + lines.append("MISSING [%s] „%s”" % (lang, lab)) + lines.append("RESULT: %s — %d label(s), %d missing" % ("ALL FOUND" if not missing else "NOT ALL FOUND", + len(labs), missing)) + with io.open(out_path, "w", encoding="utf-8") as fh: + fh.write("\n".join(lines) + "\n") + print(lines[-1]) + return 1 if missing else 0 + + +if __name__ == "__main__": + sys.exit(main(sys.argv)) diff --git a/documentation/audits/app-guides-2026-10-15/tools/validate_draft.py b/documentation/audits/app-guides-2026-10-15/tools/validate_draft.py new file mode 100644 index 00000000..4f4d5a51 --- /dev/null +++ b/documentation/audits/app-guides-2026-10-15/tools/validate_draft.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +"""validate_draft.py — would this draft pass the catalog's copy gate? Checked on a THROWAWAY copy, never the repo. + + python3 validate_draft.py + +Copies `templates//`, `scripts/` and the freeze into a temp directory, writes the guide there with +apply_guide.py, admits the app to the temp freeze, and runs check-copy-i18n.py --root . Also checks the +night's format: 3-5 sections, each with a title, a one-sentence intro and 2-5 steps; 4-6 FAQ entries; no URL, no +markdown, no bare DOMAIN outside `