tinyjukebox 0.47.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. tinyjukebox/__init__.py +7 -0
  2. tinyjukebox/albumplayer/__init__.py +1 -0
  3. tinyjukebox/albumplayer/aalbumplayer.py +402 -0
  4. tinyjukebox/albumplayer/clock.py +39 -0
  5. tinyjukebox/albumplayer/dummyplayer.py +49 -0
  6. tinyjukebox/albumplayer/player_interface.py +97 -0
  7. tinyjukebox/albumplayer/radioplayer.py +391 -0
  8. tinyjukebox/albumplayer/simpleplayer.py +419 -0
  9. tinyjukebox/albumplayer/spotifyplayer.py +671 -0
  10. tinyjukebox/backup.py +176 -0
  11. tinyjukebox/backups.py +340 -0
  12. tinyjukebox/cli.py +1076 -0
  13. tinyjukebox/control.py +1386 -0
  14. tinyjukebox/core/__init__.py +1 -0
  15. tinyjukebox/core/config.py +100 -0
  16. tinyjukebox/core/logging/__init__.py +113 -0
  17. tinyjukebox/core/microservice.py +303 -0
  18. tinyjukebox/core/pubsub/__init__.py +15 -0
  19. tinyjukebox/core/pubsub/base.py +196 -0
  20. tinyjukebox/core/pubsub/localqueue.py +102 -0
  21. tinyjukebox/core/pubsub/statistics.py +57 -0
  22. tinyjukebox/core/py.typed +0 -0
  23. tinyjukebox/core/schema/__init__.py +5 -0
  24. tinyjukebox/core/schema/logger.py +40 -0
  25. tinyjukebox/core/schema/microservice.py +48 -0
  26. tinyjukebox/core/threads.py +39 -0
  27. tinyjukebox/core/ui/__init__.py +5 -0
  28. tinyjukebox/core/ui/cli.py +120 -0
  29. tinyjukebox/core/ui/tools.py +73 -0
  30. tinyjukebox/core/unexpected.py +46 -0
  31. tinyjukebox/data/__init__.py +0 -0
  32. tinyjukebox/data/activities.py +175 -0
  33. tinyjukebox/data/activity.py +138 -0
  34. tinyjukebox/data/common.py +91 -0
  35. tinyjukebox/data/degraded.py +39 -0
  36. tinyjukebox/data/jsondata.py +218 -0
  37. tinyjukebox/data/sanitycheck.py +71 -0
  38. tinyjukebox/data/tag.py +98 -0
  39. tinyjukebox/data/tags.py +160 -0
  40. tinyjukebox/data/target.py +568 -0
  41. tinyjukebox/data/targetalbumtools.py +88 -0
  42. tinyjukebox/data/targets.py +256 -0
  43. tinyjukebox/data/volumelimits.py +68 -0
  44. tinyjukebox/data_folder.py +180 -0
  45. tinyjukebox/devices/__init__.py +1 -0
  46. tinyjukebox/devices/baseclasses/__init__.py +1 -0
  47. tinyjukebox/devices/baseclasses/adriver.py +115 -0
  48. tinyjukebox/devices/baseclasses/aevents.py +47 -0
  49. tinyjukebox/devices/baseclasses/gpiolevel.py +16 -0
  50. tinyjukebox/devices/bluetooth/__init__.py +1 -0
  51. tinyjukebox/devices/bluetooth/avrcp_input.py +118 -0
  52. tinyjukebox/devices/bluetooth/bluez.py +446 -0
  53. tinyjukebox/devices/bluetooth/link.py +396 -0
  54. tinyjukebox/devices/bluetooth/virtual.py +155 -0
  55. tinyjukebox/devices/drivermanager/__init__.py +1 -0
  56. tinyjukebox/devices/drivermanager/driverfactory.py +75 -0
  57. tinyjukebox/devices/drivermanager/drivermanager.py +151 -0
  58. tinyjukebox/devices/drivers/__init__.py +31 -0
  59. tinyjukebox/devices/drivers/bluetooth.py +257 -0
  60. tinyjukebox/devices/drivers/input.py +165 -0
  61. tinyjukebox/devices/drivers/rfid.py +297 -0
  62. tinyjukebox/devices/drivers/rgbled.py +215 -0
  63. tinyjukebox/devices/py.typed +0 -0
  64. tinyjukebox/devices/schema/__init__.py +1 -0
  65. tinyjukebox/devices/schema/adriver.py +33 -0
  66. tinyjukebox/devices/schema/bluetooth.py +31 -0
  67. tinyjukebox/devices/schema/drivermanager.py +41 -0
  68. tinyjukebox/devices/schema/input.py +23 -0
  69. tinyjukebox/devices/schema/rfid.py +44 -0
  70. tinyjukebox/devices/schema/rgbled.py +26 -0
  71. tinyjukebox/diagnostics.py +179 -0
  72. tinyjukebox/errors.py +91 -0
  73. tinyjukebox/headset.py +296 -0
  74. tinyjukebox/images.py +133 -0
  75. tinyjukebox/latency.py +43 -0
  76. tinyjukebox/library/__init__.py +2 -0
  77. tinyjukebox/library/diagnostics.py +183 -0
  78. tinyjukebox/library/journal.py +94 -0
  79. tinyjukebox/library/releases.py +348 -0
  80. tinyjukebox/library/schema.py +98 -0
  81. tinyjukebox/library/service.py +1115 -0
  82. tinyjukebox/library/statistics.py +288 -0
  83. tinyjukebox/library/store.py +1386 -0
  84. tinyjukebox/messages.py +202 -0
  85. tinyjukebox/metadata.py +133 -0
  86. tinyjukebox/py.typed +0 -0
  87. tinyjukebox/restore.py +391 -0
  88. tinyjukebox/rgbled.py +158 -0
  89. tinyjukebox/schema/__init__.py +1 -0
  90. tinyjukebox/schema/activities.py +27 -0
  91. tinyjukebox/schema/tags.py +54 -0
  92. tinyjukebox/schema/targets.py +83 -0
  93. tinyjukebox/schema/tinyjukebox.py +217 -0
  94. tinyjukebox/schema/volume.py +28 -0
  95. tinyjukebox/slots.py +234 -0
  96. tinyjukebox/spotify/__init__.py +1 -0
  97. tinyjukebox/spotify/account.py +647 -0
  98. tinyjukebox/spotify/engine.py +568 -0
  99. tinyjukebox/spotify/oembed.py +65 -0
  100. tinyjukebox/spotify/soloist.py +198 -0
  101. tinyjukebox/spotify/sound.py +316 -0
  102. tinyjukebox/stm/__init__.py +0 -0
  103. tinyjukebox/stm/base.py +174 -0
  104. tinyjukebox/stm/playradio.py +237 -0
  105. tinyjukebox/stm/playspotify.py +418 -0
  106. tinyjukebox/stm/stmoperation.py +769 -0
  107. tinyjukebox/stm/stmplayalbum.py +655 -0
  108. tinyjukebox/stm/stmvolume.py +221 -0
  109. tinyjukebox/sync/__init__.py +42 -0
  110. tinyjukebox/sync/box.py +486 -0
  111. tinyjukebox/sync/client.py +189 -0
  112. tinyjukebox/sync/data.py +489 -0
  113. tinyjukebox/sync/files.py +447 -0
  114. tinyjukebox/sync/handshake.py +42 -0
  115. tinyjukebox/sync/link.py +379 -0
  116. tinyjukebox/sync/manifest.py +162 -0
  117. tinyjukebox/sync/util.py +137 -0
  118. tinyjukebox/tinyjukebox.py +680 -0
  119. tinyjukebox/tools/__init__.py +1 -0
  120. tinyjukebox/tools/backup.py +173 -0
  121. tinyjukebox/tools/fill_library.py +120 -0
  122. tinyjukebox/tools/import_cards.py +274 -0
  123. tinyjukebox/tools/import_covers.py +138 -0
  124. tinyjukebox/tools/migrate_box01.py +151 -0
  125. tinyjukebox/volumemanager.py +355 -0
  126. tinyjukebox/web/__init__.py +1 -0
  127. tinyjukebox/web/auth.py +373 -0
  128. tinyjukebox/web/certificates.py +111 -0
  129. tinyjukebox/web/logbuffer.py +62 -0
  130. tinyjukebox/web/server.py +1237 -0
  131. tinyjukebox/web/uploads.py +262 -0
  132. tinyjukebox/web/users.py +106 -0
  133. tinyjukebox/web/web/app.js +3050 -0
  134. tinyjukebox/web/web/favicon.svg +6 -0
  135. tinyjukebox/web/web/help/de/admin.html +714 -0
  136. tinyjukebox/web/web/help/de/manual.html +1147 -0
  137. tinyjukebox/web/web/help/de/quick-guide.html +79 -0
  138. tinyjukebox/web/web/help/en/admin.html +701 -0
  139. tinyjukebox/web/web/help/en/manual.html +1126 -0
  140. tinyjukebox/web/web/help/en/quick-guide.html +79 -0
  141. tinyjukebox/web/web/help/help.css +25 -0
  142. tinyjukebox/web/web/help/images/box-2026.jpg +0 -0
  143. tinyjukebox/web/web/help/images/box-back.jpg +0 -0
  144. tinyjukebox/web/web/help/images/lid-top.jpg +0 -0
  145. tinyjukebox/web/web/help/images/logo-mark.svg +38 -0
  146. tinyjukebox/web/web/index.html +867 -0
  147. tinyjukebox/web/web/style.css +412 -0
  148. tinyjukebox/web/web/texts/de.json +892 -0
  149. tinyjukebox/web/web/texts/en.json +892 -0
  150. tinyjukebox-0.47.0.dist-info/METADATA +236 -0
  151. tinyjukebox-0.47.0.dist-info/RECORD +154 -0
  152. tinyjukebox-0.47.0.dist-info/WHEEL +4 -0
  153. tinyjukebox-0.47.0.dist-info/entry_points.txt +9 -0
  154. tinyjukebox-0.47.0.dist-info/licenses/LICENSE.txt +21 -0
@@ -0,0 +1,714 @@
1
+ <!doctype html>
2
+ <html lang="de">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <meta name="color-scheme" content="light dark">
7
+ <title>Tiny Jukebox – Verwaltung – Tiny Jukebox</title>
8
+ <link rel="icon" href="../../favicon.svg" type="image/svg+xml">
9
+ <link rel="stylesheet" href="../../style.css">
10
+ <link rel="stylesheet" href="../help.css">
11
+ </head>
12
+ <body class="help">
13
+ <!-- made by scripts/help/build.py from docs/user/de/admin.md - not to be changed by hand -->
14
+ <header class="topbar">
15
+ <a class="brand" href="../../"><svg class="brand-logo" viewBox="0 0 64 64" aria-hidden="true"><circle class="lid" cx="32" cy="32" r="29"/><circle class="window" cx="31" cy="41" r="10.5"/><circle class="brand-led" cx="13.29" cy="28.7" r="2.8"/><circle class="key" cx="17.45" cy="19.79" r="4.2"/><circle class="key" cx="25.5" cy="14.15" r="4.2"/><circle class="key key-yellow" cx="35.3" cy="13.29" r="4.2"/><circle class="key key-yellow" cx="44.21" cy="17.45" r="4.2"/></svg>Tiny Jukebox</a>
16
+ <span class="muted small">Hilfe</span>
17
+ <nav class="tabs help-tabs"><a href="quick-guide.html">Kurzanleitung</a><a href="manual.html">Handbuch</a><a href="admin.html" class=active aria-current=page>Verwaltung</a></nav>
18
+ <div class="user"><a href="../en/admin.html" hreflang="en" lang="en">English</a>
19
+ <a class="button" href="../../">Zurück zur Seite</a></div>
20
+ </header>
21
+ <main class="help-text">
22
+ <h1 id="tiny-jukebox--verwaltung">Tiny Jukebox – Verwaltung</h1>
23
+ <p>Für die Person, die zu Hause die Boxen und die Bibliothek einrichtet und betreibt: mit einem Terminal, einem NAS oder
24
+ einem PC und einem Browser. Was zu tun ist, Schritt für Schritt, und was dann passiert. Wie man die Box bedient und
25
+ was die Webseite bietet, steht im <a href="manual.html">Benutzerhandbuch</a>; hier wird darauf verwiesen statt es zu wiederholen.
26
+ Jedes Detail – jeder Befehl, jede Option, jede Datei – steht in den Entwickler-Dokumenten
27
+ (<a href="https://tgd1975.github.io/tinyjukebox/reference/operations/"><code>docs/developer/</code></a>, auf Englisch).</p>
28
+ <p>Inhalt:</p>
29
+ <ol>
30
+ <li><a href="#1-überblick">Überblick</a></li>
31
+ <li><a href="#2-eine-box-einrichten">Eine Box einrichten</a></li>
32
+ <li><a href="#3-die-bibliothek">Die Bibliothek</a></li>
33
+ <li><a href="#4-updates">Updates</a></li>
34
+ <li><a href="#5-benutzer-und-zugang">Benutzer und Zugang</a></li>
35
+ <li><a href="#6-daten-und-sicherungen">Daten und Sicherungen</a></li>
36
+ <li><a href="#7-logs-und-diagnose">Logs und Diagnose</a></li>
37
+ <li><a href="#8-konfiguration">Konfiguration</a></li>
38
+ <li><a href="#9-wenn-etwas-nicht-funktioniert">Wenn etwas nicht funktioniert</a></li>
39
+ </ol>
40
+ <hr />
41
+ <h2 id="1-überblick"><span id="s1"></span>1. Überblick</h2>
42
+ <h3 id="11-was-wo-läuft"><span id="s1-1"></span>1.1 Was wo läuft</h3>
43
+ <table>
44
+ <thead>
45
+ <tr>
46
+ <th>Was</th>
47
+ <th>Wo es läuft</th>
48
+ <th>Seite</th>
49
+ <th>Daten</th>
50
+ </tr>
51
+ </thead>
52
+ <tbody>
53
+ <tr>
54
+ <td>Box</td>
55
+ <td>ein Raspberry Pi im Holzgehäuse</td>
56
+ <td><code>https://&lt;Name der Box&gt;.local</code>, z. B. <code>https://tinyjukebox.local</code></td>
57
+ <td><code>/srv/tinyjukebox/</code> auf ihrer SD-Karte</td>
58
+ </tr>
59
+ <tr>
60
+ <td>Bibliothek auf dem NAS</td>
61
+ <td>das Synology-Paket <code>tinyjukebox-library</code></td>
62
+ <td><code>https://&lt;nas&gt;:8866</code></td>
63
+ <td><code>/var/packages/tinyjukebox-library/var/</code> und der freigegebene Ordner <code>tinyjukebox</code></td>
64
+ </tr>
65
+ <tr>
66
+ <td>Bibliothek in Docker oder auf einem PC</td>
67
+ <td>das Image <code>ghcr.io/tgd1975/tinyjukebox</code> oder <code>tinyjukebox-library --data ORDNER</code></td>
68
+ <td><code>https://&lt;Rechner&gt;:8866</code></td>
69
+ <td>das Volume <code>/data</code> oder der Ordner <code>ORDNER</code></td>
70
+ </tr>
71
+ <tr>
72
+ <td>App</td>
73
+ <td>ein Android-Telefon: ein Telefon als Box oder die Seite der Bibliothek</td>
74
+ <td>–</td>
75
+ <td>auf dem Telefon (<a href="manual.html#137-die-app-ein-telefon-als-box">Benutzerhandbuch</a>, Abschnitt 13.7)</td>
76
+ </tr>
77
+ </tbody>
78
+ </table>
79
+ <p>Eine Box arbeitet für sich allein. Mit einer Bibliothek teilen sich die Boxen Alben, Tags, Sender und Titelbilder,
80
+ und die Bibliothek merkt sich den Fortschritt jeder Box (<a href="manual.html#13-bibliothek">Benutzerhandbuch</a>, Abschnitt 13).
81
+ Eine Box ohne Bibliothek holt neue Versionen ihrer Software von GitHub, eine Box mit Bibliothek aus der Bibliothek.</p>
82
+ <h3 id="12-rollen"><span id="s1-2"></span>1.2 Rollen</h3>
83
+ <ul>
84
+ <li><code>admin</code> darf alles: Alben, Tags, Sender, Benutzer, Backups, Versionen.</li>
85
+ <li><code>user</code> darf die Box bedienen – Status, Wiedergabe, Lautstärke, Tasten – und das eigene Passwort ändern; an der
86
+ Bibliothek außerdem einen Tag durch Scannen bekannt machen.</li>
87
+ </ul>
88
+ <p>Box und Bibliothek haben jede ihre eigenen Benutzer. Benutzer und Passwörter auf der Seite:
89
+ <a href="manual.html#11-benutzer-und-passwörter">Benutzerhandbuch</a>, Abschnitt 11.</p>
90
+ <h3 id="13-die-dateien-einer-box"><span id="s1-3"></span>1.3 Die Dateien einer Box</h3>
91
+ <table>
92
+ <thead>
93
+ <tr>
94
+ <th>Ordner</th>
95
+ <th>Inhalt</th>
96
+ </tr>
97
+ </thead>
98
+ <tbody>
99
+ <tr>
100
+ <td><code>/srv/tinyjukebox/albums/</code></td>
101
+ <td>ein Ordner je Album: MP3-Dateien und <code>playlist.m3u</code></td>
102
+ </tr>
103
+ <tr>
104
+ <td><code>/srv/tinyjukebox/json/</code></td>
105
+ <td>Tags, Alben, Sender, Fortschritte, Lautstärkegrenzen; <code>images/</code>: die Titelbilder</td>
106
+ </tr>
107
+ <tr>
108
+ <td><code>/srv/tinyjukebox/ssl/</code></td>
109
+ <td>Zertifikat der Seite und <code>users.yaml</code>, die Benutzer</td>
110
+ </tr>
111
+ <tr>
112
+ <td><code>/srv/tinyjukebox/log/</code></td>
113
+ <td><code>tinyjukebox.log</code>, das Log der Box</td>
114
+ </tr>
115
+ <tr>
116
+ <td><code>/srv/tinyjukebox/slots/</code>, <code>current</code></td>
117
+ <td>die Versionen der Box-Software und die, die gerade läuft</td>
118
+ </tr>
119
+ <tr>
120
+ <td><code>/srv/tinyjukebox/state/</code></td>
121
+ <td>welche Version läuft und warum; <code>history.log</code>, eine Zeile je Wechsel</td>
122
+ </tr>
123
+ <tr>
124
+ <td><code>/srv/tinyjukebox/identity/</code>, <code>sync/</code></td>
125
+ <td>der Schlüssel der Box und die Adresse ihrer Bibliothek; was sie mit der Bibliothek austauscht</td>
126
+ </tr>
127
+ <tr>
128
+ <td><code>/srv/tinyjukebox/spotify/</code></td>
129
+ <td>Schlüssel, Player und Anmeldung von Spotify</td>
130
+ </tr>
131
+ <tr>
132
+ <td><code>/srv/tinyjukebox/config/</code></td>
133
+ <td><code>tinyjukebox.yaml</code>, falls es sie gibt (Abschnitt 8)</td>
134
+ </tr>
135
+ </tbody>
136
+ </table>
137
+ <p>Alles gehört dem Benutzer der Box, auf unserer Box <code>pi</code>. Die vollständige Liste:
138
+ <a href="https://tgd1975.github.io/tinyjukebox/hardware/box/#6-file-system-layout">box.md</a>, Abschnitt 6.</p>
139
+ <hr />
140
+ <h2 id="2-eine-box-einrichten"><span id="s2"></span>2. Eine Box einrichten</h2>
141
+ <h3 id="21-was-man-braucht"><span id="s2-1"></span>2.1 Was man braucht</h3>
142
+ <ul>
143
+ <li>einen Raspberry Pi mit der Hardware der Box (<a href="https://tgd1975.github.io/tinyjukebox/hardware/box/#1-hardware">box.md</a>, Abschnitt 1) – auch eine
144
+ Box, die noch nicht verdrahtet ist, lässt sich installieren; ihre Seite antwortet, und das Log nennt, was fehlt</li>
145
+ <li>eine SD-Karte und den Raspberry Pi Imager auf dem PC</li>
146
+ <li>ein WLAN mit Internet: Der Installer holt die Pakete des Betriebssystems</li>
147
+ <li>das Passwort, das der Benutzer <code>admin</code> der Seite der Box bekommen soll, mindestens 8 Zeichen</li>
148
+ <li>mit Bibliothek: ihr Bootstrap-Passwort, festgelegt bei der Installation der Bibliothek (Abschnitt 3)</li>
149
+ </ul>
150
+ <h3 id="22-die-karte-schreiben"><span id="s2-2"></span>2.2 Die Karte schreiben</h3>
151
+ <ol>
152
+ <li>Im Raspberry Pi Imager „Raspberry Pi OS Lite (64 Bit)“ wählen.</li>
153
+ <li>In den Einstellungen des Imagers den Hostnamen setzen (z. B. <code>kueche</code> – die Seite ist dann <code>https://kueche.local</code>),
154
+ den Benutzer, das WLAN mit seinem Land, die Zeitzone und SSH; der Imager bietet an, nur die Anmeldung mit
155
+ Schlüssel zu erlauben.</li>
156
+ <li>Die Karte schreiben, in die Box stecken und die Box einschalten.</li>
157
+ <li>Vom PC aus anmelden: <code>ssh &lt;Benutzer&gt;@&lt;Hostname&gt;.local</code>.</li>
158
+ </ol>
159
+ <p>Was der Imager eingestellt hat, fasst der Installer nie an: Hostname, Benutzer, WLAN, Zeitzone, SSH.</p>
160
+ <h3 id="23-der-installer"><span id="s2-3"></span>2.3 Der Installer</h3>
161
+ <p>Eine Box, die für sich allein arbeitet, holt den Installer von GitHub:</p>
162
+ <pre><code class="language-bash">curl -fsSL https://github.com/tgd1975/tinyjukebox/releases/latest/download/install.sh | sudo bash
163
+ </code></pre>
164
+ <p>Eine Box für eine Bibliothek bekommt ihre Zeile von der Seite der Bibliothek: Tab „Boxen“, Abschnitt „Box
165
+ hinzufügen“, „Kopieren“. Die Zeile nennt die Bibliothek und den Schlüssel ihres Zertifikats, damit die Box genau
166
+ dieser Bibliothek vertraut.</p>
167
+ <p>Was passiert:</p>
168
+ <ul>
169
+ <li><strong>Alle Fragen kommen zuerst:</strong> das Passwort des Benutzers <code>admin</code> der Seite und, mit Bibliothek, das
170
+ Bootstrap-Passwort. Sie werden vom Terminal gelesen, nie von der Befehlszeile.</li>
171
+ <li>Der Installer prüft, ob er auf Raspberry Pi OS Lite (64 Bit), Debian 13, läuft. Auf allem anderen hört er auf,
172
+ bevor er etwas ändert, und sagt, was er gefunden hat.</li>
173
+ <li>Er richtet das System ein, installiert die Box-Software in einen Slot und zeigt die Adresse der Seite. Er startet
174
+ die Box einmal neu. Auf einem Pi 3 dauert das ein paar Minuten; kompiliert wird nichts.</li>
175
+ <li>Eine Box für eine Bibliothek meldet sich bei ihrem ersten Start an und erscheint von selbst im Tab „Boxen“ der
176
+ Bibliothek.</li>
177
+ <li>Was er ausgegeben hat, steht in <code>/var/log/tinyjukebox-install.log</code>, auch was nach dem Neustart geschah.</li>
178
+ </ul>
179
+ <p><strong>Ein zweiter Lauf</strong> schadet nicht: Er ändert nichts, was schon stimmt, und er fasst Alben, Tags, Fortschritte,
180
+ Benutzer und die Verbindung zu einer Bibliothek nie an. Er ist auch der Weg, das System einer Box auf den neuen Stand
181
+ zu bringen (Abschnitt 4.4). Ein Deinstallationsprogramm gibt es nicht: Einen Pi macht man frei, indem man seine Karte
182
+ neu schreibt.</p>
183
+ <p>Alle Optionen des Installers: <a href="https://tgd1975.github.io/tinyjukebox/reference/deployment/#51-with-the-installer">deployment.md</a>, Abschnitt 5.1.</p>
184
+ <h3 id="24-nach-der-installation"><span id="s2-4"></span>2.4 Nach der Installation</h3>
185
+ <ul>
186
+ <li>Der erste Start sollte mit WLAN geschehen: Die Box hat keine Uhr, und das Zertifikat der Seite entsteht dabei.</li>
187
+ <li>Die Seite öffnen und als <code>admin</code> anmelden. Beim ersten Mal warnt der Browser vor dem Zertifikat (Abschnitt 5.4).</li>
188
+ <li>Die Sprache unter der Anmeldung wählen, „Deutsch / English“.</li>
189
+ <li>Einen Tag auflegen: Die LED wird gelb, und der Tab „Jetzt“ bietet an, ihn zu verknüpfen
190
+ (<a href="manual.html#72-einen-tag-verknüpfen">Benutzerhandbuch</a>, Abschnitt 7.2).</li>
191
+ <li>Gibt es mehrere Boxen, der Box einen Namen geben: Tab „System“, Abschnitt „Bibliothek“, „Umbenennen“.</li>
192
+ </ul>
193
+ <p>Für eine neu eingerichtete Box geht die <a href="https://tgd1975.github.io/tinyjukebox/reference/deployment/#8-acceptance-checklist">Abnahme-Checkliste</a>
194
+ Start, Tasten, LED, Tags und Kopfhörer der Reihe nach durch.</p>
195
+ <h3 id="25-mit-dem-playbook"><span id="s2-5"></span>2.5 Mit dem Playbook</h3>
196
+ <p>Unsere eigene Box wird vom PC aus mit einem Ansible-Playbook eingerichtet. Es führt den Installer aus und schreibt
197
+ außerdem die Konfiguration der Box und ihre Benutzer. Das ist der Weg für Entwickler, die die Box im Repository
198
+ führen: <a href="https://tgd1975.github.io/tinyjukebox/reference/deployment/#52-with-the-playbook">deployment.md</a>, Abschnitt 5.2.</p>
199
+ <hr />
200
+ <h2 id="3-die-bibliothek"><span id="s3"></span>3. Die Bibliothek</h2>
201
+ <h3 id="31-wo-sie-läuft"><span id="s3-1"></span>3.1 Wo sie läuft</h3>
202
+ <table>
203
+ <thead>
204
+ <tr>
205
+ <th>Wo</th>
206
+ <th>Wie</th>
207
+ <th>Aktualisiert</th>
208
+ </tr>
209
+ </thead>
210
+ <tbody>
211
+ <tr>
212
+ <td>Synology-NAS</td>
213
+ <td>das Paket <code>tinyjukebox-library</code>, installiert im Paket-Zentrum</td>
214
+ <td>von Hand, mit einem neueren Paket (Abschnitt 4.3)</td>
215
+ </tr>
216
+ <tr>
217
+ <td>Docker</td>
218
+ <td>das Image <code>ghcr.io/tgd1975/tinyjukebox</code> (<code>linux/amd64</code>, <code>linux/arm64</code>)</td>
219
+ <td>durch Holen eines neueren Images</td>
220
+ </tr>
221
+ <tr>
222
+ <td>PC</td>
223
+ <td><code>pip install tinyjukebox</code>, dann <code>tinyjukebox-library --data ORDNER</code></td>
224
+ <td>mit <code>pip install --upgrade tinyjukebox</code></td>
225
+ </tr>
226
+ </tbody>
227
+ </table>
228
+ <p>Das Paket ist für eine Plattform gebaut, <code>rtd1296</code> – die DS418j und NAS mit demselben Prozessor. Ein anderes NAS
229
+ braucht einen anderen Build oder Docker.</p>
230
+ <h3 id="32-auf-dem-nas"><span id="s3-2"></span>3.2 Auf dem NAS</h3>
231
+ <ol>
232
+ <li><strong>Vorher:</strong> das Python 3.12 von SynoCommunity auf dem NAS installieren (das Paket <code>python312</code>). Ein
233
+ Bootstrap-Passwort mit mindestens 16 Zeichen wählen, z. B. mit <code>openssl rand -hex 24</code>. Jede Box weist es einmal
234
+ vor, beim ersten Verbinden.</li>
235
+ <li><strong>Das Paket holen</strong> (<code>tinyjukebox-library-&lt;version&gt;-&lt;build&gt;-rtd1296.spk</code>), aus dem neuesten Release auf GitHub. Mit
236
+ einem Klon des Repositorys auf dem PC holt <code>./fetch_release.sh</code> es nach <code>dist/</code> und prüft es.</li>
237
+ <li><strong>Installieren:</strong> Paket-Zentrum von DSM, „Manuelle Installation“, die Datei wählen, die Warnung vor Paketen von
238
+ Drittanbietern bestätigen. Der Dialog fragt nach dem Passwort des Benutzers <code>admin</code> der Seite (mindestens
239
+ 8 Zeichen) und nach dem Bootstrap-Passwort.</li>
240
+ <li><strong>Prüfen:</strong> Das Paket-Zentrum zeigt das Paket als laufend, und <code>https://&lt;nas&gt;:8866</code> öffnet die Seite. Als <code>admin</code>
241
+ anmelden. Ist der Start fehlgeschlagen, steht der Grund in <code>var/server.log</code> (Abschnitt 7.2).</li>
242
+ <li><strong>Benutzer:</strong> Die Bibliothek hat nur den Benutzer <code>admin</code>. Die anderen auf ihrer Seite anlegen, Tab „System“,
243
+ Abschnitt „Benutzer“.</li>
244
+ </ol>
245
+ <p>Das Paket läuft als eigener Benutzer, <code>tinyjukebox-library</code>. DSM legt beim ersten Start den freigegebenen Ordner
246
+ <code>tinyjukebox</code> an, darin <code>albums/</code>, <code>images/</code> und <code>json/</code>; Alben lassen sich auch per SMB oder File Station dort
247
+ ablegen, und Hyper Backup sichert den Ordner mit. Zertifikat, Benutzer und Konfiguration liegen in
248
+ <code>/var/packages/tinyjukebox-library/var/</code>. Ein Update behält diesen Ordner, und DSM löscht ihn nie – auch nicht, wenn
249
+ das Paket entfernt wird. Ganz von vorn beginnen:
250
+ <a href="https://tgd1975.github.io/tinyjukebox/reference/library/#37-first-installation-on-the-nas">library.md</a>, Abschnitt 3.7.</p>
251
+ <h3 id="33-in-docker"><span id="s3-3"></span>3.3 In Docker</h3>
252
+ <p>Zwei Passwörter als Dateien, dann startet compose eine Bibliothek und eine Box ohne Hardware zum Ausprobieren:</p>
253
+ <pre><code class="language-bash">cd deploy/docker &amp;&amp; openssl rand -hex 12 &gt; admin-password &amp;&amp; openssl rand -hex 24 &gt; bootstrap-password
254
+ docker compose up -d # https://localhost:8866/ und https://localhost:8443/, Benutzer admin, das Passwort in admin-password
255
+ </code></pre>
256
+ <p>Die Bibliothek allein:</p>
257
+ <pre><code class="language-bash">docker run -d --name library --restart unless-stopped -p 8866:8866 \
258
+ -v library:/data -v /pfad/zu/alben:/data/albums ghcr.io/tgd1975/tinyjukebox
259
+ </code></pre>
260
+ <ul>
261
+ <li>Alles, was bleiben muss, liegt unter <code>/data</code>: ein Volume, und wenn gewünscht die Alben als Ordner des Rechners. Ein
262
+ eingebundener Ordner muss für den Benutzer des Images (uid 1000) beschreibbar sein.</li>
263
+ <li>Ohne <code>TINYJUKEBOX_ADMIN_PASSWORD</code> wird das Passwort von <code>admin</code> erzeugt und einmal ausgegeben: <code>docker logs library</code>.</li>
264
+ <li>Das Bootstrap-Passwort kommt aus <code>TINYJUKEBOX_BOOTSTRAP_PASSWORD</code>, oder es wird im Tab „Boxen“ gesetzt.</li>
265
+ <li>Statt der Passwörter selbst nennen <code>TINYJUKEBOX_ADMIN_PASSWORD_FILE</code> und <code>TINYJUKEBOX_BOOTSTRAP_PASSWORD_FILE</code> eine
266
+ Datei, die sie enthält; eine Variable lässt sich mit <code>docker inspect</code> lesen.</li>
267
+ <li>Eine Box kommt mit der Zeile des Tabs „Boxen“ dazu. Ihre Adresse muss die des Rechners sein, nicht der Name des
268
+ Containers.</li>
269
+ </ul>
270
+ <p>Mehr: <a href="https://tgd1975.github.io/tinyjukebox/reference/library/#39-the-library-in-docker-and-with-one-folder">library.md</a>, Abschnitt 3.9.</p>
271
+ <h3 id="34-auf-einem-pc"><span id="s3-4"></span>3.4 Auf einem PC</h3>
272
+ <pre><code class="language-bash">pip install tinyjukebox
273
+ tinyjukebox-library --data ~/bibliothek # https://localhost:8866/
274
+ </code></pre>
275
+ <p>Alles liegt unter dem Ordner: <code>data/</code>, <code>albums/</code>, <code>images/</code>, <code>ssl/</code>, <code>log/</code>, <code>backups/</code>. Beim ersten Start fragt sie
276
+ im Terminal nach dem Passwort von <code>admin</code>. Ein ausgeschalteter Rechner ist für die Boxen keine Bibliothek: Sie spielen
277
+ mit dem weiter, was sie haben, und liefern ihre Änderungen später ab.</p>
278
+ <h3 id="35-mit-den-daten-einer-box-füllen"><span id="s3-5"></span>3.5 Mit den Daten einer Box füllen</h3>
279
+ <p>Die Bibliothek beginnt leer. Hat eine Box schon Alben und Tags, bringt ein Befehl auf dem PC sie hinüber. Er behält
280
+ die Nummern, damit Box und Bibliothek von Anfang an übereinstimmen, und er lässt sich wiederholen: Was schon da ist,
281
+ wird übersprungen.</p>
282
+ <pre><code class="language-bash">rsync -a pi@tinyjukebox.local:/srv/tinyjukebox/json/ ~/box-copy/json/
283
+ rsync -a pi@tinyjukebox.local:/srv/tinyjukebox/albums/ ~/box-copy/albums/
284
+ tinyjukebox-fill-library https://&lt;nas&gt;:8866 --user admin \
285
+ --json ~/box-copy/json --albums ~/box-copy/albums --images ~/box-copy/json/images
286
+ </code></pre>
287
+ <p>Er fragt nach dem Passwort und zeigt den Fingerabdruck des Zertifikats der Bibliothek zur Bestätigung (Abschnitt 5.4).
288
+ In einem Klon des Repositorys heißt der Befehl <code>uv run tinyjukebox-fill-library …</code>. Die Fortschritte kommen mit der
289
+ ersten Synchronisation von der Box selbst. Eine Box, die man einfach mit der Bibliothek verbindet, bringt ihre Daten
290
+ ebenfalls mit (<a href="manual.html#132-eine-box-mit-der-bibliothek-verbinden">Benutzerhandbuch</a>, Abschnitt 13.2); dieser
291
+ Befehl ist für viele Alben auf einmal.</p>
292
+ <h3 id="36-die-boxen-verbinden"><span id="s3-6"></span>3.6 Die Boxen verbinden</h3>
293
+ <ul>
294
+ <li><strong>Eine Box, die schon läuft:</strong> auf ihrer Seite, Tab „System“, Abschnitt „Bibliothek“: Adresse und
295
+ Bootstrap-Passwort (<a href="manual.html#132-eine-box-mit-der-bibliothek-verbinden">Benutzerhandbuch</a>, Abschnitt 13.2).</li>
296
+ <li><strong>Eine neue Box:</strong> die Zeile des Tabs „Boxen“, Abschnitt „Box hinzufügen“ (Abschnitt 2.3).</li>
297
+ <li><strong>Eine neu eingerichtete Box</strong> ist eine neue Box. Auf der Seite der Bibliothek, Tab „Boxen“, übernimmt sie die
298
+ Fortschritte und Einstellungen der alten.</li>
299
+ </ul>
300
+ <h3 id="37-neue-versionen-für-die-boxen"><span id="s3-7"></span>3.7 Neue Versionen für die Boxen</h3>
301
+ <p>Die Bibliothek holt die Versionen der Box-Software aus den Releases auf GitHub und gibt sie an ihre Boxen weiter.
302
+ Dafür braucht sie Zugang zu den Releases:</p>
303
+ <ul>
304
+ <li><strong>Das Repository ist öffentlich:</strong> Eine leere Datei <code>var/github-token</code> auf dem NAS genügt, mit dem Benutzer
305
+ <code>tinyjukebox-library</code> als Eigentümer; danach das Paket stoppen und starten.</li>
306
+ <li><strong>Das Repository ist privat:</strong> auf GitHub einen fein granulierten Token für dieses eine Repository mit dem Recht
307
+ „Contents: Read-only“ anlegen und auf der Seite der Bibliothek eintragen, Tab „Versionen“, Abschnitt „Zugang zu den
308
+ Releases“. Die Bibliothek prüft ihn, bevor sie ihn speichert, und sucht sofort nach einem Release.</li>
309
+ </ul>
310
+ <p>Das Docker-Image und <code>tinyjukebox-library --data</code> fragen die Releases des Projekts ohne Token. Welche Version eine Box
311
+ bekommt und wie sie ausprobiert wird: Abschnitt 4.1.</p>
312
+ <hr />
313
+ <h2 id="4-updates"><span id="s4"></span>4. Updates</h2>
314
+ <h3 id="41-die-box-software"><span id="s4-1"></span>4.1 Die Box-Software</h3>
315
+ <p>Eine Box installiert neue Versionen selbst: mit Bibliothek aus der Bibliothek, ohne von GitHub. Eine neue Version
316
+ startet beim nächsten Einschalten der Box, auf Probe. Funktioniert sie nicht – startet sie nicht oder scheitert sie in
317
+ den ersten Sekunden –, startet die Box nach wenigen Sekunden von selbst die Version davor. Auf Probe bleibt eine
318
+ Version, bis ein Tag aufgelegt wurde und deswegen ein Album gespielt hat.</p>
319
+ <ul>
320
+ <li><strong>Ohne Bibliothek</strong> sieht die Box einmal am Tag nach einem neuen Release und installiert es nach einer Wartezeit
321
+ von drei Tagen; eine Korrektur in dieser Zeit ersetzt es, bevor irgendeine Box es bekommen hat.</li>
322
+ <li><strong>Mit Bibliothek</strong> bekommt eine Box eine neue Version sofort. Im Tab „Versionen“ der Bibliothek hat jede Version
323
+ einen Zustand: <code>use</code> (Boxen installieren sie von selbst), <code>manual</code> (nur von Hand), <code>dontuse</code> (jede Box verlässt sie
324
+ sofort).</li>
325
+ <li><strong>Die Update-Art</strong> einer Box – „automatisch“, „nur von Hand“ („nachfragen“ ohne Bibliothek) oder „aus“ – wird auf
326
+ ihrer Seite eingestellt, Tab „System“, Abschnitt „Version“ (<a href="manual.html#134-version-der-box">Benutzerhandbuch</a>,
327
+ Abschnitt 13.4).</li>
328
+ </ul>
329
+ <p>Auf der Box ist dasselbe ein Befehl. Er läuft als Benutzer der Box, nie mit <code>sudo</code>:</p>
330
+ <pre><code class="language-bash">tinyjukebox-slot status # die Versionen auf der Box, die laufende, die Update-Art, die letzten Wechsel
331
+ tinyjukebox-slot check # was die Bibliothek anbietet - ohne Bibliothek: GitHub
332
+ tinyjukebox-slot update --now # die neueste erlaubte Version, sofort
333
+ tinyjukebox-slot update 0.45.0 # genau diese Version
334
+ tinyjukebox-slot mode manual # automatic, manual oder off
335
+ </code></pre>
336
+ <p>Jeder Aufruf: <a href="https://tgd1975.github.io/tinyjukebox/reference/library/#68-the-command-tinyjukebox-slot">library.md</a>, Abschnitt 6.8.</p>
337
+ <h3 id="42-zurück-zur-version-davor"><span id="s4-2"></span>4.2 Zurück zur Version davor</h3>
338
+ <p>Ein Schritt zurück wirkt sofort, auch wenn gerade etwas spielt. Die verlassene Version installiert danach keine Box
339
+ mehr von selbst.</p>
340
+ <table>
341
+ <thead>
342
+ <tr>
343
+ <th>Weg</th>
344
+ <th>Für</th>
345
+ </tr>
346
+ </thead>
347
+ <tbody>
348
+ <tr>
349
+ <td>Seite der Box, Tab „System“, „Zurück zur vorigen Version“</td>
350
+ <td>diese Box</td>
351
+ </tr>
352
+ <tr>
353
+ <td><code>tinyjukebox-slot revert</code> auf der Box</td>
354
+ <td>diese Box</td>
355
+ </tr>
356
+ <tr>
357
+ <td>eine leere Datei <code>tinyjukebox-revert</code> auf der Boot-Partition der SD-Karte (<code>bootfs</code> am PC)</td>
358
+ <td>diese Box, ohne Netz: Der nächste Start geht zurück und schreibt an ihre Stelle <code>tinyjukebox-ergebnis.txt</code></td>
359
+ </tr>
360
+ <tr>
361
+ <td>Seite der Bibliothek, Tab „Versionen“: die Version auf <code>dontuse</code></td>
362
+ <td>alle Boxen</td>
363
+ </tr>
364
+ </tbody>
365
+ </table>
366
+ <p><code>revert</code> wechselt in den anderen Slot, egal was darin liegt. Nach einer gescheiterten Probe kann das die gescheiterte
367
+ Version sein: vorher mit <code>tinyjukebox-slot status</code> nachsehen. Startet keine Version mehr, ist die Box im Notfall-Modus
368
+ (<a href="manual.html#134-version-der-box">Benutzerhandbuch</a>, Abschnitt 13.4;
369
+ <a href="https://tgd1975.github.io/tinyjukebox/reference/library/#610-fallback-slot-and-recovery-mode">library.md</a>, Abschnitt 6.10).</p>
370
+ <h3 id="43-die-bibliothek"><span id="s4-3"></span>4.3 Die Bibliothek</h3>
371
+ <p>Die Bibliothek aktualisiert sich nie selbst.</p>
372
+ <ul>
373
+ <li><strong>Auf dem NAS:</strong> das neuere Paket genauso installieren, Paket-Zentrum, „Manuelle Installation“ – ohne Dialog; die
374
+ Daten bleiben. Aus einem Klon des Repositorys auf dem PC erledigt das <code>./update_library.sh &lt;nas&gt;</code>: Es holt das Paket
375
+ des neuesten Releases und fragt nach Benutzer und Passwort von DSM, die es nicht speichert – oder nimmt NAS,
376
+ Benutzer und Passwort aus dem Vault des Playbooks
377
+ (<a href="https://tgd1975.github.io/tinyjukebox/reference/library/#37-first-installation-on-the-nas">library.md</a>, Abschnitt 3.7).</li>
378
+ <li><strong>In Docker:</strong> Die Seite zeigt, dass es eine neuere Version gibt. Das neuere Image holen und den Container neu
379
+ starten; mit compose <code>docker compose pull</code>, dann <code>docker compose up -d</code>.</li>
380
+ <li><strong>Auf einem PC:</strong> <code>pip install --upgrade tinyjukebox</code>, dann die Bibliothek neu starten.</li>
381
+ </ul>
382
+ <p>Eine Bibliothek, die älter ist als die Version einer Box, hält die Box an: Die LED wechselt zwischen rot, weiß,
383
+ magenta und gelb, und die Box spielt nichts. Dann zuerst die Bibliothek aktualisieren.</p>
384
+ <h3 id="44-das-betriebssystem-der-box"><span id="s4-4"></span>4.4 Das Betriebssystem der Box</h3>
385
+ <p>Ihr Betriebssystem aktualisiert die Box nie selbst. Von Hand, ab und zu:</p>
386
+ <pre><code class="language-bash">sudo apt update &amp;&amp; sudo apt full-upgrade
387
+ </code></pre>
388
+ <p>Nach einem Upgrade von Python, ALSA oder BlueZ die Zeile des Installers noch einmal ausführen (Abschnitt 2.3) – auf
389
+ einer Box des Playbooks <code>./update_box.sh</code> – und Ton, Tasten und Kopfhörer prüfen. Braucht eine Version ein neueres
390
+ System, sagt sie das auf der Seite der Box: Dann muss der Installer ebenfalls noch einmal laufen.</p>
391
+ <hr />
392
+ <h2 id="5-benutzer-und-zugang"><span id="s5"></span>5. Benutzer und Zugang</h2>
393
+ <h3 id="51-benutzer-auf-der-befehlszeile"><span id="s5-1"></span>5.1 Benutzer auf der Befehlszeile</h3>
394
+ <p>Auf der Seite legt ein Admin Benutzer an, löscht sie und setzt Passwörter
395
+ (<a href="manual.html#11-benutzer-und-passwörter">Benutzerhandbuch</a>, Abschnitt 11). Auf der Box, als Benutzer der Box:</p>
396
+ <pre><code class="language-bash">tinyjukebox-users -f /srv/tinyjukebox/ssl/users.yaml list
397
+ tinyjukebox-users -f /srv/tinyjukebox/ssl/users.yaml add NAME --role admin
398
+ tinyjukebox-users -f /srv/tinyjukebox/ssl/users.yaml passwd NAME
399
+ tinyjukebox-users -f /srv/tinyjukebox/ssl/users.yaml role NAME admin
400
+ tinyjukebox-users -f /srv/tinyjukebox/ssl/users.yaml remove NAME
401
+ </code></pre>
402
+ <ul>
403
+ <li>Nur hier lässt sich eine Rolle ändern. Den letzten Admin löscht der Befehl nicht und macht ihn auch nicht zum <code>user</code>.</li>
404
+ <li>Eine Änderung wirkt sofort, ohne Neustart. Ein neues Passwort beendet die anderen Sitzungen dieses Benutzers.</li>
405
+ <li>Für eine Bibliothek auf einem PC ist die Datei <code>ssl/users.yaml</code> in ihrem Ordner. In Docker führt das Image den
406
+ Befehl aus, mit dem Volume der Bibliothek: <code>docker run --rm -v library:/data ghcr.io/tgd1975/tinyjukebox
407
+ tinyjukebox-users -f /data/ssl/users.yaml list</code>.</li>
408
+ <li>Das Paket auf dem NAS hat keinen Befehl <code>tinyjukebox-users</code>: Der Aufruf mit dem Python des Pakets steht in
409
+ <a href="https://tgd1975.github.io/tinyjukebox/reference/operations/#4-users-of-the-web-page">operations.md</a>, Abschnitt 4.</li>
410
+ </ul>
411
+ <h3 id="52-ein-vergessenes-passwort"><span id="s5-2"></span>5.2 Ein vergessenes Passwort</h3>
412
+ <ol>
413
+ <li>Ein anderer Admin setzt auf der Seite ein neues Passwort, Tab „System“, Abschnitt „Benutzer“.</li>
414
+ <li>Kennt kein Admin mehr sein Passwort: sich mit SSH auf der Box anmelden.</li>
415
+ <li><code>tinyjukebox-users -f /srv/tinyjukebox/ssl/users.yaml passwd admin</code> – fragt zweimal nach dem neuen Passwort.</li>
416
+ <li>Damit auf der Seite anmelden.</li>
417
+ </ol>
418
+ <h3 id="53-ssh"><span id="s5-3"></span>5.3 SSH</h3>
419
+ <p>Erreichbar ist die Box mit <code>ssh &lt;Benutzer&gt;@&lt;Hostname&gt;.local</code>, so wie der Imager sie eingerichtet hat. Wird der Name
420
+ nicht gefunden, hilft die Adresse der Box im Router. Eine neu geschriebene Karte hat einen neuen Schlüssel: Kennt der
421
+ PC noch den alten, verweigert SSH die Verbindung, bis der alte Eintrag mit <code>ssh-keygen -R &lt;Hostname&gt;.local</code> entfernt
422
+ ist.</p>
423
+ <h3 id="54-das-zertifikat-der-seite"><span id="s5-4"></span>5.4 Das Zertifikat der Seite</h3>
424
+ <p>Box und Bibliothek erzeugen ihr eigenes Zertifikat, bei ihrem ersten Start. Beim ersten Mal warnt der Browser davor.</p>
425
+ <ul>
426
+ <li>Den Fingerabdruck, den der Browser zeigt, mit dem im Log vergleichen: Die Box schreibt ihn, wenn die Seite startet
427
+ (<code>rest api listening on … fingerprint</code>), die Bibliothek ebenfalls in ihr Log.</li>
428
+ <li>Oder das Zertifikat der Box als vertrauenswürdig importieren: <code>/srv/tinyjukebox/ssl/tinyjukebox.crt</code>.</li>
429
+ <li>Die Befehle auf dem PC, <code>tinyjukebox-backup</code> und <code>tinyjukebox-fill-library</code>, zeigen den Fingerabdruck ebenfalls
430
+ und fragen, bevor sie weitermachen.</li>
431
+ </ul>
432
+ <hr />
433
+ <h2 id="6-daten-und-sicherungen"><span id="s6"></span>6. Daten und Sicherungen</h2>
434
+ <h3 id="61-was-ein-backup-enthält"><span id="s6-1"></span>6.1 Was ein Backup enthält</h3>
435
+ <p>Ein Backup ist eine Datei mit den Daten einer Box oder der Bibliothek, erstellt im laufenden Betrieb:</p>
436
+ <ul>
437
+ <li>eine Box: Tags, Alben, Sender und Spotify-Einträge, Fortschritte, Lautstärkegrenzen und die Titelbilder</li>
438
+ <li>die Bibliothek: der Katalog, Fortschritte und Einstellungen jeder Box, die Statistik, die Zustände der Versionen und
439
+ die Titelbilder</li>
440
+ <li>mit „MP3s“ auch die Alben – die Datei ist dann so groß wie alle Alben zusammen</li>
441
+ </ul>
442
+ <p>Eine Box mit Bibliothek braucht kein eigenes Backup: Die Bibliothek hat alles, und eine neu eingerichtete Box holt es
443
+ sich von dort.</p>
444
+ <h3 id="62-backups-erstellen"><span id="s6-2"></span>6.2 Backups erstellen</h3>
445
+ <table>
446
+ <thead>
447
+ <tr>
448
+ <th>Weg</th>
449
+ <th>Box</th>
450
+ <th>Bibliothek</th>
451
+ </tr>
452
+ </thead>
453
+ <tbody>
454
+ <tr>
455
+ <td>Seite, Tab „System“, Karte „Backup“</td>
456
+ <td>„Backup herunterladen“, „Backup mit MP3s herunterladen“</td>
457
+ <td>ebenso</td>
458
+ </tr>
459
+ <tr>
460
+ <td>Seite, „Regelmäßig sichern“</td>
461
+ <td>eine Box ohne Bibliothek, nach <code>/srv/tinyjukebox/backups</code></td>
462
+ <td>in den freigegebenen Ordner <code>tinyjukebox</code> auf dem NAS, den Hyper Backup mitsichert</td>
463
+ </tr>
464
+ <tr>
465
+ <td>Befehl auf dem PC</td>
466
+ <td><code>tinyjukebox-backup https://tinyjukebox.local --user admin [--albums] [ORDNER]</code></td>
467
+ <td><code>tinyjukebox-backup https://&lt;nas&gt;:8866 --user admin [--albums] [ORDNER]</code></td>
468
+ </tr>
469
+ </tbody>
470
+ </table>
471
+ <p>Zwei Zeitpläne, einer ohne und einer mit den Alben, jeder mit seinem Ordner und der Zahl der Backups, die bleiben:
472
+ <a href="manual.html#112-regelmäßig-sichern">Benutzerhandbuch</a>, Abschnitt 11.2. Die Backups einer Box liegen auf ihrer
473
+ SD-Karte: Gegen eine kaputte Karte hilft nur ein Backup, das man von ihr geholt hat.</p>
474
+ <h3 id="63-ein-backup-zurückspielen"><span id="s6-3"></span>6.3 Ein Backup zurückspielen</h3>
475
+ <p>Auf der Seite, Tab „System“, Karte „Backup“, „Backup zurückspielen“ – oder <code>tinyjukebox-backup … --restore DATEI</code> auf
476
+ dem PC. Die Seite fragt einmal nach, dann startet die Box oder die Bibliothek mit den Daten des Backups neu
477
+ (<a href="manual.html#113-backup-zurückspielen">Benutzerhandbuch</a>, Abschnitt 11.3).</p>
478
+ <ul>
479
+ <li>Ein Backup ohne die Alben lässt den Ordner der Alben in Ruhe. Alben, die in den Daten stehen, deren Ordner aber
480
+ fehlt, werden nach dem Zurückspielen aufgelistet.</li>
481
+ <li>Auf einer Box mit Bibliothek gewinnt bei der nächsten Synchronisation die Bibliothek. Zurückspielen ist für eine Box
482
+ ohne Bibliothek und für die Bibliothek gedacht.</li>
483
+ <li>Die Bibliothek auf einem anderen NAS, oder von Hand ohne das Programm:
484
+ <a href="https://tgd1975.github.io/tinyjukebox/reference/operations/#103-putting-a-backup-back">operations.md</a>, Abschnitt 10.3.</li>
485
+ </ul>
486
+ <h3 id="64-was-in-keinem-backup-ist"><span id="s6-4"></span>6.4 Was in keinem Backup ist</h3>
487
+ <ul>
488
+ <li>Benutzer, Passwörter, das Zertifikat, Tokens – in der Bibliothek auch <code>settings.json</code> mit dem Bootstrap-Passwort</li>
489
+ <li>der Schlüssel der Box und ihre Verbindung zur Bibliothek</li>
490
+ <li>Schlüssel, Player und Anmeldung von Spotify: Der Schlüssel wird neu eingefügt, die Box holt den Player neu und wird
491
+ neu verbunden („Verbinden“)</li>
492
+ <li>die Konfigurationsdatei</li>
493
+ </ul>
494
+ <hr />
495
+ <h2 id="7-logs-und-diagnose"><span id="s7"></span>7. Logs und Diagnose</h2>
496
+ <h3 id="71-die-logs-einer-box"><span id="s7-1"></span>7.1 Die Logs einer Box</h3>
497
+ <table>
498
+ <thead>
499
+ <tr>
500
+ <th>Log</th>
501
+ <th>Inhalt</th>
502
+ </tr>
503
+ </thead>
504
+ <tbody>
505
+ <tr>
506
+ <td>Seite, Tab „Log“ (admin)</td>
507
+ <td>die letzten 5000 Einträge, live, mit Filtern für Stufe und Text; „Als Datei speichern“</td>
508
+ </tr>
509
+ <tr>
510
+ <td><code>/srv/tinyjukebox/log/tinyjukebox.log</code> (+ <code>.1</code> … <code>.4</code>)</td>
511
+ <td>das vollständige Log; es bleibt über einen Neustart</td>
512
+ </tr>
513
+ <tr>
514
+ <td><code>journalctl -u tinyjukebox</code></td>
515
+ <td>Warnungen und Fehler, und was das Start-Skript sagt; nach einem Neustart weg</td>
516
+ </tr>
517
+ <tr>
518
+ <td><code>/srv/tinyjukebox/state/history.log</code></td>
519
+ <td>eine Zeile je Wechsel der Version: wann, von, nach, warum, durch wen</td>
520
+ </tr>
521
+ <tr>
522
+ <td><code>/var/log/tinyjukebox-install.log</code></td>
523
+ <td>was der Installer getan hat</td>
524
+ </tr>
525
+ </tbody>
526
+ </table>
527
+ <p>Der Dienst selbst: <code>sudo systemctl status tinyjukebox</code>, <code>sudo systemctl restart tinyjukebox</code>. Nach einem Absturz
528
+ startet systemd ihn von selbst neu.</p>
529
+ <h3 id="72-die-logs-der-bibliothek"><span id="s7-2"></span>7.2 Die Logs der Bibliothek</h3>
530
+ <table>
531
+ <thead>
532
+ <tr>
533
+ <th>Log</th>
534
+ <th>Inhalt</th>
535
+ </tr>
536
+ </thead>
537
+ <tbody>
538
+ <tr>
539
+ <td>Seite der Bibliothek, Tab „Log“</td>
540
+ <td>das Log der Bibliothek und das jeder Box: Warnungen, Fehler und Ereignisse, die die Boxen geschickt haben, mit Filtern; „Als Datei speichern“</td>
541
+ </tr>
542
+ <tr>
543
+ <td>NAS: <code>/var/packages/tinyjukebox-library/var/library.log</code></td>
544
+ <td>das Log der Bibliothek; beim Start ihr Fingerabdruck</td>
545
+ </tr>
546
+ <tr>
547
+ <td>NAS: <code>var/server.log</code></td>
548
+ <td>warum ein Start fehlgeschlagen ist</td>
549
+ </tr>
550
+ <tr>
551
+ <td>NAS: <code>/var/log/packages/tinyjukebox-library.log</code></td>
552
+ <td>was die Skripte des Pakets ausgegeben haben</td>
553
+ </tr>
554
+ <tr>
555
+ <td>Docker: <code>docker logs library</code></td>
556
+ <td>die Ausgabe der Bibliothek, das erzeugte Passwort von <code>admin</code></td>
557
+ </tr>
558
+ </tbody>
559
+ </table>
560
+ <p>Der Tab „Log“ der Bibliothek hilft, wenn eine Box nicht zur Hand ist: Die Boxen schicken ihre Warnungen und Fehler an
561
+ die Bibliothek, ohne Passwörter, Schlüssel oder UIDs von Tags. Eine Box, die nicht starten kann, meldet auch das; der
562
+ Tab „Boxen“ zeigt sie dann mit „startet seit … nicht“
563
+ (<a href="https://tgd1975.github.io/tinyjukebox/reference/library/#422-central-diagnostics">library.md</a>, Abschnitt 4.22).</p>
564
+ <h3 id="73-mehr-details-im-log"><span id="s7-3"></span>7.3 Mehr Details im Log</h3>
565
+ <p>Die Box schreibt ins Log auf der Stufe INFO. Für eine Fehlersuche auf DEBUG stellen:</p>
566
+ <ol>
567
+ <li>Eine Box des Installers hat keine eigene Konfigurationsdatei. Zuerst die ihres Slots kopieren:
568
+ <code>cp /srv/tinyjukebox/current/config/tinyjukebox.yaml /srv/tinyjukebox/config/</code>.</li>
569
+ <li>In <code>/srv/tinyjukebox/config/tinyjukebox.yaml</code> <code>log-level: DEBUG</code> setzen.</li>
570
+ <li><code>sudo systemctl restart tinyjukebox</code>.</li>
571
+ <li>Nach der Fehlersuche die Kopie wieder entfernen und den Dienst neu starten: Sonst wäre die Datei ab da die
572
+ Konfiguration jeder Version, auch jeder späteren.</li>
573
+ </ol>
574
+ <h3 id="74-tasten-led-und-leser"><span id="s7-4"></span>7.4 Tasten, LED und Leser</h3>
575
+ <p>Der Tab „System“ hat für Admins die Karte „Hardware“: was die Treiber über die Tasten, die LED und den RFID-Leser
576
+ sagen, zweimal pro Sekunde. Hat eine Taste keine Wirkung, zeigt sie, ob die Taste überhaupt an der Box ankommt. Die
577
+ Hardware von Hand auf der Konsole prüfen:
578
+ <a href="https://tgd1975.github.io/tinyjukebox/reference/operations/#92-check-the-hardware-by-hand">operations.md</a>, Abschnitt 9.2.</p>
579
+ <hr />
580
+ <h2 id="8-konfiguration"><span id="s8"></span>8. Konfiguration</h2>
581
+ <h3 id="81-wo-die-datei-liegt"><span id="s8-1"></span>8.1 Wo die Datei liegt</h3>
582
+ <table>
583
+ <thead>
584
+ <tr>
585
+ <th>Box oder Bibliothek</th>
586
+ <th>Konfiguration</th>
587
+ </tr>
588
+ </thead>
589
+ <tbody>
590
+ <tr>
591
+ <td>Box des Installers</td>
592
+ <td>die Konfiguration ihres Slots, <code>/srv/tinyjukebox/current/config/tinyjukebox.yaml</code>; sie kommt mit jeder Version</td>
593
+ </tr>
594
+ <tr>
595
+ <td>Box des Playbooks</td>
596
+ <td><code>/srv/tinyjukebox/config/tinyjukebox.yaml</code>, geschrieben bei jedem Lauf des Playbooks</td>
597
+ </tr>
598
+ <tr>
599
+ <td>Bibliothek auf dem NAS</td>
600
+ <td><code>/var/packages/tinyjukebox-library/var/library.yaml</code></td>
601
+ </tr>
602
+ <tr>
603
+ <td><code>--data ORDNER</code> (Docker, PC)</td>
604
+ <td>eingebaut; <code>ORDNER/config.yaml</code>, falls es sie gibt, ändert einzelne Werte</td>
605
+ </tr>
606
+ </tbody>
607
+ </table>
608
+ <p>Das meiste, was ein Admin einstellt, steht auf der Seite und braucht keine Datei: Lautstärkegrenzen
609
+ (<a href="manual.html#10-lautstärke-begrenzen">Benutzerhandbuch</a>, Abschnitt 10), die Bibliothek einer Box, Update-Art, Backups.
610
+ Eine Änderung der Datei wirkt nach <code>sudo systemctl restart tinyjukebox</code>.</p>
611
+ <h3 id="82-schlüssel-die-ein-admin-ändert"><span id="s8-2"></span>8.2 Schlüssel, die ein Admin ändert</h3>
612
+ <table>
613
+ <thead>
614
+ <tr>
615
+ <th>Schlüssel</th>
616
+ <th>Bedeutung</th>
617
+ <th>Auf der Box</th>
618
+ </tr>
619
+ </thead>
620
+ <tbody>
621
+ <tr>
622
+ <td><code>logger/log-level</code></td>
623
+ <td>wie viel das Log sagt</td>
624
+ <td><code>INFO</code></td>
625
+ </tr>
626
+ <tr>
627
+ <td><code>tinyjukebox/rest-api/session-timeout</code></td>
628
+ <td>Abmeldung nach so vielen Sekunden ohne Anfrage</td>
629
+ <td><code>604800</code> (7 Tage)</td>
630
+ </tr>
631
+ <tr>
632
+ <td><code>tinyjukebox/rest-api/idle-timeout</code></td>
633
+ <td>Abmeldung nach so vielen Sekunden, in denen auf einer offenen Seite nichts bedient wurde; <code>0</code>: nie</td>
634
+ <td><code>1800</code> (30 Minuten)</td>
635
+ </tr>
636
+ <tr>
637
+ <td><code>tinyjukebox/rest-api/max-upload-size</code></td>
638
+ <td>MB je hochgeladener MP3-Datei</td>
639
+ <td><code>500</code></td>
640
+ </tr>
641
+ <tr>
642
+ <td><code>tinyjukebox/sync/keep-free</code></td>
643
+ <td>MB, die auf der Karte einer Box mit Bibliothek frei bleiben; ist weniger frei, gehen die Alben, die am längsten nicht gespielt wurden</td>
644
+ <td><code>500</code></td>
645
+ </tr>
646
+ <tr>
647
+ <td><code>tinyjukebox/backups-folder</code></td>
648
+ <td>wo eine Box ohne Bibliothek ihre Backups ablegt, bis auf ihrer Seite ein anderer Ordner gesetzt ist</td>
649
+ <td><code>backups</code> neben den Alben</td>
650
+ </tr>
651
+ </tbody>
652
+ </table>
653
+ <p>Jeder Schlüssel: <a href="https://tgd1975.github.io/tinyjukebox/reference/configuration/#4-section-tinyjukebox">configuration.md</a>, Abschnitte 4 bis 6, und
654
+ auf der Dokumentations-Seite die erzeugte Tabelle aller Schlüssel (Tab „Reference“, „Configuration keys“). Unbekannte
655
+ Schlüssel verhindern den Start: Die Meldung nennt den Pfad des Schlüssels.</p>
656
+ <hr />
657
+ <h2 id="9-wenn-etwas-nicht-funktioniert"><span id="s9"></span>9. Wenn etwas nicht funktioniert</h2>
658
+ <p>Das Benutzerhandbuch nennt, was ein Benutzer tun kann
659
+ (<a href="manual.html#12-wenn-etwas-nicht-funktioniert">Benutzerhandbuch</a>, Abschnitt 12). Für einen Admin:</p>
660
+ <table>
661
+ <thead>
662
+ <tr>
663
+ <th>Symptom</th>
664
+ <th>Nachsehen</th>
665
+ <th>Ursache und Abhilfe</th>
666
+ </tr>
667
+ </thead>
668
+ <tbody>
669
+ <tr>
670
+ <td>LED bleibt rot</td>
671
+ <td><code>sudo systemctl status tinyjukebox</code>, <code>journalctl -u tinyjukebox</code></td>
672
+ <td>der Dienst läuft nicht oder scheitert beim Start, z. B. an einer ungültigen Konfiguration: die Meldung nennt den Pfad</td>
673
+ </tr>
674
+ <tr>
675
+ <td>Kein Tag wird erkannt</td>
676
+ <td>das Log: <code>RFID - …</code></td>
677
+ <td>die Zeile sagt, warum: Der Leser lässt sich nicht starten, er antwortet nicht (Verdrahtung, Versorgung), oder dem Programm der Version wird nicht vertraut – dann den Installer noch einmal ausführen</td>
678
+ </tr>
679
+ <tr>
680
+ <td>Webseite nicht erreichbar</td>
681
+ <td><code>sudo systemctl status tinyjukebox</code></td>
682
+ <td>der Dienst läuft nicht; oder der Name <code>….local</code> wird nicht gefunden: die Adresse der Box verwenden</td>
683
+ </tr>
684
+ <tr>
685
+ <td>LED abwechselnd rot, weiß, magenta, gelb; nichts spielt</td>
686
+ <td>Tab „System“; <code>tinyjukebox-slot status</code></td>
687
+ <td>die Bibliothek ist zu alt für die Version der Box: die Bibliothek aktualisieren (Abschnitt 4.3) oder an der Box zurückgehen (Abschnitt 4.2)</td>
688
+ </tr>
689
+ <tr>
690
+ <td>Die Box bekommt keine neue Version</td>
691
+ <td><code>tinyjukebox-slot status</code>, <code>tinyjukebox-slot check</code>; Tab „Versionen“ der Bibliothek</td>
692
+ <td>Update-Art „nur von Hand“ oder „aus“; die Version ist nicht <code>use</code>; die Box ist schon einmal von ihr zurückgegangen; die Bibliothek hat keinen Zugang zu den Releases (Abschnitt 3.7)</td>
693
+ </tr>
694
+ <tr>
695
+ <td>Die Box läuft wieder mit einer älteren Version</td>
696
+ <td><code>/srv/tinyjukebox/state/history.log</code>, Tab „Boxen“ der Bibliothek</td>
697
+ <td>die neue Version hat ihre Probe nicht bestanden, und die Box ist zurückgegangen; die Zeile sagt, warum</td>
698
+ </tr>
699
+ <tr>
700
+ <td>Die Seite der Box sagt, die Bibliothek sei nicht verbunden</td>
701
+ <td>Tab „System“, Abschnitt „Bibliothek“; das Log</td>
702
+ <td>das NAS ist aus oder nicht in diesem WLAN: Die Box spielt, was sie hat, und liefert ihre Änderungen später ab</td>
703
+ </tr>
704
+ <tr>
705
+ <td>Die Bibliothek startet nicht</td>
706
+ <td><code>var/server.log</code> auf dem NAS; <code>docker logs library</code></td>
707
+ <td>die Zeile sagt, warum, z. B. fehlt <code>var/library.yaml</code></td>
708
+ </tr>
709
+ </tbody>
710
+ </table>
711
+ <p>Weitere Symptome, mit den Zeilen des Logs: <a href="https://tgd1975.github.io/tinyjukebox/reference/operations/#93-symptoms">operations.md</a>, Abschnitt 9.3.</p>
712
+ </main>
713
+ </body>
714
+ </html>