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
gates / gates (push) Successful in 6m38s
gates / gates (push) Successful in 6m38s
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -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).
|
||||
@@ -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."
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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."}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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."}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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."}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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."}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -0,0 +1,165 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""apply_guide.py — write one draft guide into templates/<app>/.felhom.yml, by TEXT, and prove the parse.
|
||||
|
||||
python3 apply_guide.py <catalog-root> <draft.json> [--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))
|
||||
@@ -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 <draft.json> <out.txt> <corpus-dir-or-file> [<corpus> ...]
|
||||
|
||||
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'<translation>%s</translation>' % e, r'<source>%s</source>' % 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))
|
||||
@@ -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 <catalog-root> <draft.json>
|
||||
|
||||
Copies `templates/<app>/`, `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 <temp> <app>. 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 `<label>.DOMAIN`. Prints PASS or the findings; exit 0 / 1. The repo is only read.
|
||||
"""
|
||||
import io
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
|
||||
def fmt_problems(d):
|
||||
p = []
|
||||
for lang in ("hu", "en"):
|
||||
g = d.get(lang) or {}
|
||||
secs, faq = g.get("sections") or [], g.get("faq") or []
|
||||
if not 3 <= len(secs) <= 5:
|
||||
p.append("%s: %d sections (format: 3-5)" % (lang, len(secs)))
|
||||
if not 4 <= len(faq) <= 6:
|
||||
p.append("%s: %d FAQ entries (format: 4-6)" % (lang, len(faq)))
|
||||
for i, se in enumerate(secs):
|
||||
if not se.get("intro"):
|
||||
p.append("%s: sections[%d] has no intro (format: one sentence each)" % (lang, i))
|
||||
if not 2 <= len(se.get("steps") or []) <= 5:
|
||||
p.append("%s: sections[%d] has %d steps (format: 2-5)" % (lang, i, len(se.get("steps") or [])))
|
||||
strings = []
|
||||
for se in secs:
|
||||
strings += [se.get("title", ""), se.get("intro", "")] + list(se.get("steps") or [])
|
||||
for qa in faq:
|
||||
strings += [qa.get("q", ""), qa.get("a", "")]
|
||||
for s in strings:
|
||||
if re.search(r"https?://|www\.", s):
|
||||
p.append("%s: a URL in guide text (not allowed): %r" % (lang, s))
|
||||
if re.search(r"\*\*|__|`|<[a-zA-Z/][^>]*>|^#|\[[^\]]+\]\(", s):
|
||||
p.append("%s: markdown or HTML in guide text (rendered as plain text): %r" % (lang, s))
|
||||
for m in re.finditer(r"\bDOMAIN\b", s):
|
||||
if not re.search(r"[a-z0-9-]+\.DOMAIN\b", s[max(0, m.start() - 40):m.end()]):
|
||||
p.append("%s: bare DOMAIN (the box fills it with the household's domain): %r" % (lang, s))
|
||||
if "—" in s and lang == "hu":
|
||||
p.append("hu: em dash (R-932): %r" % s)
|
||||
if re.search(r"[\U0001F300-\U0001FAFF☀-➿]", s):
|
||||
p.append("%s: emoji: %r" % (lang, s))
|
||||
return p
|
||||
|
||||
|
||||
def main(argv):
|
||||
root, draft = os.path.abspath(argv[1]), os.path.abspath(argv[2])
|
||||
d = json.load(io.open(draft, encoding="utf-8"))
|
||||
app = d["app"]
|
||||
probs = fmt_problems(d)
|
||||
tmp = tempfile.mkdtemp(prefix="guide-validate-")
|
||||
try:
|
||||
shutil.copytree(os.path.join(root, "scripts"), os.path.join(tmp, "scripts"),
|
||||
ignore=shutil.ignore_patterns("__pycache__"))
|
||||
os.makedirs(os.path.join(tmp, "templates"))
|
||||
for a in os.listdir(os.path.join(root, "templates")):
|
||||
src = os.path.join(root, "templates", a)
|
||||
if os.path.isdir(src):
|
||||
shutil.copytree(src, os.path.join(tmp, "templates", a))
|
||||
r = subprocess.run([sys.executable, os.path.join(HERE, "apply_guide.py"), tmp, draft], capture_output=True,
|
||||
text=True)
|
||||
if r.returncode != 0:
|
||||
probs.append("apply: " + (r.stdout + r.stderr).strip())
|
||||
else:
|
||||
subprocess.run([sys.executable, os.path.join(tmp, "scripts", "check-copy-i18n.py"), "--root", tmp,
|
||||
"--add-app", app, "--reason", "validate_draft"], capture_output=True, text=True)
|
||||
# The ratchet is about the whole catalog; measure it on the temp copy and hand it back.
|
||||
probe = subprocess.run([sys.executable, os.path.join(tmp, "scripts", "check-copy-i18n.py"), "--root", tmp,
|
||||
"--expect-missing", "-1"], capture_output=True, text=True)
|
||||
m = re.search(r"(\d+) strings have no English", probe.stdout)
|
||||
miss = m.group(1) if m else "0"
|
||||
r = subprocess.run([sys.executable, os.path.join(tmp, "scripts", "check-copy-i18n.py"), "--root", tmp,
|
||||
"--expect-missing", miss, app], capture_output=True, text=True)
|
||||
if r.returncode != 0:
|
||||
probs += ["copy gate: " + l.strip() for l in r.stdout.splitlines() if l.strip().startswith("- ")
|
||||
and app in l]
|
||||
if not any(app in l for l in r.stdout.splitlines() if l.strip().startswith("- ")):
|
||||
probs.append("copy gate failed:\n" + r.stdout[-1500:])
|
||||
if miss != "0":
|
||||
probs.append("English coverage: %s copy string(s) of the catalog would have no English" % miss)
|
||||
finally:
|
||||
shutil.rmtree(tmp, ignore_errors=True)
|
||||
if probs:
|
||||
print("FAIL %s" % app)
|
||||
for x in probs:
|
||||
print(" - " + x)
|
||||
return 1
|
||||
print("PASS %s — format and copy gate clean" % app)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main(sys.argv))
|
||||
Reference in New Issue
Block a user