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,892 @@
1
+ {
2
+ "access.bootstrap.placeholder": "New bootstrap password (at least 16 characters)",
3
+ "access.bootstrap.saved": "Bootstrap password changed.",
4
+ "access.bootstrap.submit": "Change bootstrap password",
5
+ "access.help": "A new box logs in with the bootstrap password the first time; after that it has a key of its own. A token only allows a script to have the library look for a new version.",
6
+ "access.title": "Access for boxes and scripts",
7
+ "access.token.new": "Create token for scripts",
8
+ "access.verified": "Checked.",
9
+ "access.verify": "Check the files of albums and covers",
10
+ "album.added": "added on {date}",
11
+ "album.broken": "Reported by boxes:",
12
+ "album.broken.forget": "Discard reports",
13
+ "album.broken.forgotten": "Reports discarded.",
14
+ "album.broken.report": "{file}: box {box} reports an error while playing ({date})",
15
+ "album.delete.confirm": "Remove album “{title}” from the list? (The files are kept)",
16
+ "album.delete.confirm_files": "Delete album “{title}” and its files?",
17
+ "album.delete_files": "Delete the files as well",
18
+ "album.folder": "Folder: {folder}",
19
+ "album.more_problems": "… and {n} more",
20
+ "album.playlist.confirm": "Rebuild the playlist from all MP3 files of the folder? The old playlist is kept as .bak.",
21
+ "album.playlist.done": "Playlist rebuilt.",
22
+ "album.playlist.rebuild": "Rebuild playlist from the MP3 files",
23
+ "album.problems": "Problems with this album:",
24
+ "album.remove": "Remove album",
25
+ "album.removed": "Album removed.",
26
+ "album.title_saved": "Title saved.",
27
+ "album.track_missing": "(missing)",
28
+ "albums.add.done": "Album added.",
29
+ "albums.add.folder": "Folder relative to the albums folder",
30
+ "albums.add.submit": "Add folder as album",
31
+ "albums.add.title": "Title of the album",
32
+ "albums.broken": "broken",
33
+ "albums.broken.title": "Files of the album are broken",
34
+ "albums.column.created": "Added",
35
+ "albums.column.folder": "Folder",
36
+ "albums.column.length": "Length",
37
+ "albums.column.title": "Title",
38
+ "albums.column.tracks": "Tracks",
39
+ "albums.none": "No albums.",
40
+ "albums.scan": "Look for new folders",
41
+ "albums.scan.added": {
42
+ "one": "{n} album added.",
43
+ "other": "{n} albums added."
44
+ },
45
+ "albums.scan.added_skipped": {
46
+ "one": "{n} album added, {skipped} skipped.",
47
+ "other": "{n} albums added, {skipped} skipped."
48
+ },
49
+ "albums.scan.confirm": {
50
+ "one": "{n} new folder found:\n\n{folders}\n\nAdd it? The title can be changed in the album afterwards.",
51
+ "other": "{n} new folders found:\n\n{folders}\n\nAdd all? The title can be changed in the album afterwards."
52
+ },
53
+ "albums.scan.line": "{folder} → “{title}”",
54
+ "albums.scan.none": "No new album folders found.",
55
+ "albums.tracks": {
56
+ "one": "{n} track",
57
+ "other": "{n} tracks"
58
+ },
59
+ "albums.without_tag_only": "only albums without a tag",
60
+ "backup.albums_note": "With MP3s the file also contains the albums and is as large as all of them together.",
61
+ "backup.column.content": "Content",
62
+ "backup.column.size": "Size",
63
+ "backup.column.when": "Backup of",
64
+ "backup.delete.confirm": "Delete the backup of {when}?",
65
+ "backup.deleted": "Backup deleted.",
66
+ "backup.download": "Download backup",
67
+ "backup.download_albums": "Download backup with MP3s",
68
+ "backup.folder": "Folder for the backups",
69
+ "backup.folder.placeholder": "Folder for the backups (empty: {folder})",
70
+ "backup.folder.title": "Folder on the computer of the library or on the box in which these backups are put. Empty: the folder from the configuration.",
71
+ "backup.help.box": "One file with the tags, links, progress, volumes and covers of this box. Users, keys and passwords are not in it.",
72
+ "backup.help.library": "One file with the catalog, the progress and settings of all boxes, the statistics and the covers. Users, keys and passwords are not in it.",
73
+ "backup.none": "No backups yet.",
74
+ "backup.now": "Back up now",
75
+ "backup.now_albums": "Back up now with MP3s",
76
+ "backup.schedule.enabled": "regularly",
77
+ "backup.schedule.every": "every {every} {unit} at {time}",
78
+ "backup.schedule.keep": "backups are kept",
79
+ "backup.schedule.title": "Back up regularly",
80
+ "backup.started": "The backup is being made.",
81
+ "backup.state.failed": "The last backup failed ({when}): {message}",
82
+ "backup.state.folder": "The backups are in {folder}.",
83
+ "backup.state.last": "Last backup: {when}.",
84
+ "backup.state.next": "Next: {when}.",
85
+ "backup.state.running": "A backup is being made …",
86
+ "backup.title": "Backup",
87
+ "backup.unit.days": "days",
88
+ "backup.unit.months": "months",
89
+ "backup.unit.weeks": "weeks",
90
+ "backup.with_albums": "with MP3s",
91
+ "backup.without_albums": "without MP3s",
92
+ "bluetooth.battery": "Battery",
93
+ "bluetooth.connected": "Connected",
94
+ "bluetooth.help": "Pairing: put the headset into pairing mode, then choose “Pair” here or hold Next and Back on the box together for 5 s. The LED blinks blue quickly while the box searches (one minute at most). Only one headset is paired at a time – a new one replaces the old one. While the headset is connected, the box plays through it only; if the connection breaks, it pauses.",
95
+ "bluetooth.limits": "Change start value and maximum",
96
+ "bluetooth.none": "No headset paired.",
97
+ "bluetooth.pair": "Pair",
98
+ "bluetooth.pair.started": "Search started – the LED blinks blue quickly.",
99
+ "bluetooth.pairing.failed": "Pairing failed.",
100
+ "bluetooth.pairing.not_found": "No headset in pairing mode found.",
101
+ "bluetooth.pairing.paired": "Headset paired.",
102
+ "bluetooth.searching": "Searching – put the headset into pairing mode …",
103
+ "bluetooth.title": "Bluetooth headset",
104
+ "bluetooth.unavailable": "Bluetooth is not available (no driver or no adapter).",
105
+ "bluetooth.unpair": "Unpair",
106
+ "bluetooth.unpair.confirm": "Unpair “{name}”? An album that is playing pauses.",
107
+ "bluetooth.unpaired": "Unpaired.",
108
+ "bluetooth.virtual.help": "The box runs without hardware: this headset behaves like a real one, the sound still comes from the PC. “Pair” finds it after a few seconds.",
109
+ "bluetooth.virtual.off": "Switch off (connection lost)",
110
+ "bluetooth.virtual.on": "Switch on",
111
+ "bluetooth.virtual.title": "Virtual headset",
112
+ "boxes.column.contact": "Last contact, address",
113
+ "boxes.page": "Page of {name}",
114
+ "boxes.column.state": "State",
115
+ "boxes.degraded": {
116
+ "one": "works without {n} damaged or unknown piece of data (page of the box, tab System)",
117
+ "other": "works without {n} damaged or unknown pieces of data (page of the box, tab System)"
118
+ },
119
+ "boxes.fits": "box {name} speaks version {speaks} of the interface, this library version {serves}",
120
+ "boxes.fits_manual": "box {name} speaks version {speaks} of the interface, this library version {serves}; its updates are set to “by hand only”, it must be updated by hand",
121
+ "boxes.add.title": "Add a box",
122
+ "boxes.add.help": "On a Raspberry Pi with a fresh card (Raspberry Pi OS Lite, 64-bit), logged in over SSH, run this line: it sets up the box, installs version {version} and links the box to this library. It asks for the bootstrap password, which is set further down. The box must reach the library under this address.",
123
+ "boxes.add.older": "Version {newest} came to the library before it kept installers: the line installs {version}, and the box then updates itself.",
124
+ "boxes.add.none": "No version can be installed from this library yet: it keeps the installer of a box with every release from version 0.38.0 on.",
125
+ "boxes.add.copy": "Copy",
126
+ "boxes.add.copied": "The line is copied.",
127
+ "boxes.help": "Every box registers itself as soon as it knows the address of the library and the bootstrap password. Progress belongs to the box, everything else is the same for all.",
128
+ "boxes.manual_updates": "Updates by hand",
129
+ "boxes.no_bootstrap": "No bootstrap password is set yet.",
130
+ "boxes.none": "No box has registered yet.",
131
+ "boxes.positions": {
132
+ "one": "{n} album in progress",
133
+ "other": "{n} albums in progress"
134
+ },
135
+ "boxes.remove.confirm": "Remove box “{name}”? Its key is no longer valid then.",
136
+ "boxes.remove.done": "Box removed.",
137
+ "boxes.removed": "removed",
138
+ "boxes.rename": "Rename",
139
+ "boxes.rename.prompt": "Name of the box",
140
+ "boxes.startup": {
141
+ "one": "cannot start since {since} ({n} failed start) – tab Log",
142
+ "other": "cannot start since {since} ({n} failed starts) – tab Log"
143
+ },
144
+ "boxes.takeover": "Take over an old box",
145
+ "boxes.takeover.done": "Taken over.",
146
+ "boxes.takeover.prompt": "Take over the progress and settings of which box?\n{boxes}",
147
+ "boxes.updates_off": "Updates off",
148
+ "boxes.uploads.help": "Albums that were uploaded on a box and are not completely here yet.",
149
+ "boxes.uploads.line": {
150
+ "one": "“{folder}” – only on {box}, {transferred} of {n} file transferred",
151
+ "other": "“{folder}” – only on {box}, {transferred} of {n} files transferred"
152
+ },
153
+ "boxes.uploads.title": "Albums on their way",
154
+ "boxes.waiting": {
155
+ "one": "{n} change waits for an album",
156
+ "other": "{n} changes wait for an album"
157
+ },
158
+ "phones.phone": "Phone",
159
+ "phones.add.title": "Add a phone",
160
+ "phones.app.help": "The app for Android phones and tablets, version {version}: open this address on the phone, or point its camera at the QR code. The browser warns once about the certificate of the library, and Android asks once whether the browser may install apps.",
161
+ "phones.app.qr": "QR code of the address of the app",
162
+ "phones.app.none": "This library has no app to hand out yet: it keeps the app with every release from the version on that brings it.",
163
+ "phones.pair": "Pair",
164
+ "phones.pair.help": "Then pair the app with this library: tap “Pair” and scan the QR code with the app. The code can be used once and is valid for 10 minutes. The phone then appears in the table above, as a box does.",
165
+ "phones.pair.qr": "QR code for pairing the app",
166
+ "phones.pair.valid": "Valid for {minutes}:{seconds} more.",
167
+ "phones.pair.expired": "The QR code has expired. Tap “Pair” for a new one.",
168
+ "phones.limits": "Volume",
169
+ "phones.limits.title": "Volume of the phone: maximum",
170
+ "phones.limits.help": "The app plays with at most this share of what the phone is set to – so the limit holds whatever the keys of the phone say.",
171
+ "phones.limits.line": "speaker at most {speaker} %, headphones at most {headphones} %",
172
+ "common.address": "Address",
173
+ "common.album": "Album",
174
+ "common.back": "Back",
175
+ "common.cancel": "Cancel",
176
+ "common.close": "Close",
177
+ "common.create": "Create",
178
+ "common.default_volume": "Start value",
179
+ "common.delete": "Delete",
180
+ "common.download": "Download",
181
+ "common.image": "Image",
182
+ "common.louder": "Louder",
183
+ "common.max_volume": "Maximum",
184
+ "common.name": "Name",
185
+ "common.name_changed": "Name changed.",
186
+ "common.never": "never",
187
+ "common.next": "Next",
188
+ "common.no": "no",
189
+ "common.no_tag": "no tag",
190
+ "common.not_linked": "not linked",
191
+ "common.pause": "Pause",
192
+ "common.percent": "{n}%",
193
+ "common.play": "Play",
194
+ "common.present": "on the box",
195
+ "common.progress": "Progress",
196
+ "common.quieter": "Quieter",
197
+ "common.remove": "Remove",
198
+ "common.resume": "Resume",
199
+ "common.save": "Save",
200
+ "common.saved": "Saved.",
201
+ "common.size_unknown": "size unknown",
202
+ "common.state": "State",
203
+ "common.target": "Album / station",
204
+ "common.title": "Title",
205
+ "common.track": "Track",
206
+ "common.uid": "UID",
207
+ "common.unlink": "Unlink",
208
+ "common.unnamed": "unnamed",
209
+ "common.version": "Version",
210
+ "common.volume": "Volume",
211
+ "common.yes": "yes",
212
+ "cover.change": "Change cover",
213
+ "cover.saved": "Cover saved.",
214
+ "cover.send_failed": "The cover could not be sent.",
215
+ "duration.hours": "{h} h {m} min",
216
+ "duration.minutes": "{n} min",
217
+ "duration.seconds": "{n} s",
218
+ "error.album.add_failed": "The album was not added: {reason}",
219
+ "error.album.folder_known": "The folder “{folder}” is an album already.",
220
+ "error.album.folder_missing": "The folder of the album is missing: {folder}",
221
+ "error.album.folder_relative": "The folder must be inside the albums folder.",
222
+ "error.album.folder_required": "Please enter the folder.",
223
+ "error.album.linked": "The album is linked to tags – unlink them first.",
224
+ "error.album.no_mp3": "The folder of the album contains no MP3 files.",
225
+ "error.album.playing": "The album is playing.",
226
+ "error.album.title_required": "Please enter the title.",
227
+ "error.album.unknown": "The album does not exist any more.",
228
+ "error.backup.busy": "A backup is being made already.",
229
+ "error.backup.busy_folder": "A backup is being made: the folder cannot be changed now.",
230
+ "error.backup.folder_absolute": "The folder needs a complete path, e.g. /volume1/tinyjukebox/backups.",
231
+ "error.backup.folder_create": "The folder {folder} cannot be created.",
232
+ "error.backup.folder_write": "The folder {folder} cannot be written to.",
233
+ "error.backup.library": "This box works with a library, which makes the backups.",
234
+ "error.backup.unknown": "This backup does not exist any more.",
235
+ "error.bluetooth.not_paired": "No headset is paired.",
236
+ "error.bluetooth.searching": "The search is running already.",
237
+ "error.bootstrap.too_short": "The bootstrap password needs at least 16 characters.",
238
+ "error.boxes.takeover_self": "A box cannot take itself over.",
239
+ "error.boxes.volume_invalid": "The most a phone plays with is 0 to 100 %.",
240
+ "error.boxes.volume_not_a_phone": "Only a phone gets its volume limits here; a box sets them on its own page.",
241
+ "error.pairing.url": "The address of the library must begin with https://.",
242
+ "error.box.name_needs_library": "The box gets a name as soon as it works with a library.",
243
+ "error.box.not_linked": "This box is not linked to a library.",
244
+ "error.image.too_large": "The image is too large.",
245
+ "error.image.type": "Only JPEG, PNG or WebP images.",
246
+ "error.library.address_https": "The address of the library begins with https://.",
247
+ "error.name.empty": "The name must not be empty.",
248
+ "error.password.too_short": "The password needs at least {min} characters.",
249
+ "error.player.no_album": "No album is playing.",
250
+ "error.radio.invalid": "Name or address of the station do not work like this – the address begins with http:// or https://.",
251
+ "error.radio.linked": "The station is linked to tags – unlink them first.",
252
+ "error.radio.playing": "The station is playing.",
253
+ "error.radio.test_impossible": "The test is not possible now – only while no tag is on the box.",
254
+ "error.radio.unknown": "The station does not exist any more.",
255
+ "error.releases.keep_invalid": "The number of versions must be 1 or more.",
256
+ "error.releases.no_repository": "The configuration names no repository with releases.",
257
+ "error.releases.token_empty": "The token must not be empty.",
258
+ "error.releases.token_missing": "The token for the releases is missing: it is saved here, in the tab “Versions”.",
259
+ "error.releases.token_refused": "The token was not taken over: {reason}",
260
+ "error.restore.busy": "A backup is being put back already.",
261
+ "error.restore.format": "This backup was made by a newer version ({version}), which this one cannot read.",
262
+ "error.restore.full": "The disk is full: the backup is not put back.",
263
+ "error.restore.incomplete": "This is no backup, or it was cut off: {reason}",
264
+ "error.restore.kind": "This is a backup of another kind ({kind}).",
265
+ "error.restore.nothing": "No backup waits to be put back.",
266
+ "error.restore.space": "For a moment the albums need their space twice: {missing} bytes are missing.",
267
+ "error.scan.invalid_uid": "This UID cannot be a tag.",
268
+ "error.spotify.cannot_run": "The player of Spotify does not start on this box.",
269
+ "error.spotify.connecting": "The box is waiting to be chosen in the Spotify app.",
270
+ "error.spotify.expired": "The player of Spotify has expired – “Update now”.",
271
+ "error.spotify.fetching": "The player is being fetched already.",
272
+ "error.spotify.invalid": "Name or link of the entry do not work like this.",
273
+ "error.spotify.key": "The key must not be empty and has no blanks.",
274
+ "error.spotify.link": "That is no link of Spotify – copy it in the Spotify app under “Share” → “Copy link”.",
275
+ "error.spotify.linked": "The entry is linked to tags – unlink them first.",
276
+ "error.spotify.no_key": "Enter the key of Spotify first.",
277
+ "error.spotify.no_player": "The player of Spotify has not been fetched yet.",
278
+ "error.spotify.playing": "The entry is playing.",
279
+ "error.spotify.unknown": "The entry of Spotify does not exist any more.",
280
+ "error.spotify.client_invalid": "The client ID of Spotify has 32 characters, 0–9 and a–f.",
281
+ "error.status": "Error {status}",
282
+ "error.tag.exists": "The tag {uid} exists already.",
283
+ "error.tag.invalid_uid": "This UID does not work: only letters, digits and : . - _",
284
+ "error.tag.none_present": "No tag is on the box.",
285
+ "error.tag.unknown": "The tag {uid} does not exist any more.",
286
+ "error.upload.add_failed": "The album was not created: {reason}",
287
+ "error.upload.empty": "No file is uploaded yet.",
288
+ "error.upload.file_too_large": "“{filename}” is larger than {limit} MB.",
289
+ "error.upload.folder_exists": "The folder “{folder}” exists already.",
290
+ "error.upload.in_progress": "An upload for “{folder}” is running already.",
291
+ "error.upload.incomplete": "“{filename}” did not arrive completely.",
292
+ "error.upload.name_invalid": "This title does not work as the name of a folder.",
293
+ "error.upload.name_too_long": "The title is too long.",
294
+ "error.upload.no_space": "Not enough space on the box ({free} MB free).",
295
+ "error.upload.not_mp3": "“{filename}” is not a valid MP3 file.",
296
+ "error.upload.only_mp3": "MP3 files only: “{filename}” is none.",
297
+ "error.upload.reserved": "“{filename}” is the name of the playlist.",
298
+ "error.upload.too_many": "An album has {limit} files at most.",
299
+ "error.upload.unknown": "This upload does not exist any more.",
300
+ "error.user.exists": "The user “{name}” exists already.",
301
+ "error.user.invalid_name": "This user name does not work.",
302
+ "error.user.self": "The own user cannot be deleted.",
303
+ "error.user.unknown": "The user “{name}” does not exist any more.",
304
+ "hardware.ago.hours": "{n} h ago",
305
+ "hardware.ago.minutes": "{n} min ago",
306
+ "hardware.ago.seconds": "{n} s ago",
307
+ "hardware.button.next": "Next",
308
+ "hardware.button.prev": "Previous",
309
+ "hardware.button.volume-down": "Volume down",
310
+ "hardware.button.volume-up": "Volume up",
311
+ "hardware.buttons": "Buttons",
312
+ "hardware.column.button": "Button",
313
+ "hardware.column.driver": "Driver",
314
+ "hardware.column.last": "Last event",
315
+ "hardware.column.level": "Level",
316
+ "hardware.column.pin": "GPIO",
317
+ "hardware.column.presses": "Pressed since the start",
318
+ "hardware.driver.running": "running",
319
+ "hardware.driver.stopped": "stopped",
320
+ "hardware.event.held": "held",
321
+ "hardware.event.pressed": "pressed",
322
+ "hardware.event.released": "released",
323
+ "hardware.event_at": "{event} at {time} ({ago})",
324
+ "hardware.event_none": "none yet",
325
+ "hardware.help": "What the drivers of the box report right now, read twice a second. The level is the state of the GPIO pin at this moment, the last event is what the driver reported to the box last: a button whose level does not change when it is pressed does not arrive at the pin.",
326
+ "hardware.led": "LED",
327
+ "hardware.led.lit": "Lit right now",
328
+ "hardware.led.off": "off",
329
+ "hardware.led.pattern": "Pattern",
330
+ "hardware.led.step": "{color} for {seconds} s",
331
+ "hardware.level.open": "open",
332
+ "hardware.level.pressed": "pressed",
333
+ "hardware.level.unknown": "cannot be read",
334
+ "hardware.light.blue": "Blue",
335
+ "hardware.light.green": "Green",
336
+ "hardware.light.red": "Red",
337
+ "hardware.none": "This box runs without device drivers – there is no hardware whose state could be shown.",
338
+ "hardware.pin": "{name}: GPIO {pin}",
339
+ "hardware.pins": "GPIOs",
340
+ "hardware.reader": "RFID reader",
341
+ "hardware.reader.changed": "Last change",
342
+ "hardware.reader.error": "Error",
343
+ "hardware.reader.no_tag": "none placed",
344
+ "hardware.reader.not_running": "not running",
345
+ "hardware.reader.program": "Program rfid-reader",
346
+ "hardware.reader.tag": "Tag",
347
+ "hardware.time": "{time} ({ago})",
348
+ "hardware.title": "Hardware",
349
+ "help.button": "Help",
350
+ "help.title": "The help of the open tab: manual and administration",
351
+ "help.quick_guide": "Quick guide",
352
+ "help.hint": "New here? The quick guide shows the box and this page in two minutes; \"Help\" at the top opens the manual at the tab that is open.",
353
+ "help.hint.never": "Do not show it again",
354
+ "headset.connected": "Headset connected",
355
+ "language.label": "Language",
356
+ "led.color.aqua": "aqua",
357
+ "led.color.black": "off",
358
+ "led.color.blue": "blue",
359
+ "led.color.green": "green",
360
+ "led.color.magenta": "magenta",
361
+ "led.color.red": "red",
362
+ "led.color.white": "white",
363
+ "led.color.yellow": "yellow",
364
+ "led.label": "LED of the box",
365
+ "led.title": "LED: {colors}",
366
+ "library.address": "Address of the library",
367
+ "library.address.placeholder": "https://nas:8866",
368
+ "library.address.saved": "Address of the library saved.",
369
+ "library.alone.answered": "the library answers with an error",
370
+ "library.alone.certificate": "the library shows another certificate",
371
+ "library.alone.unreachable": "no connection",
372
+ "library.bootstrap": "Bootstrap password",
373
+ "library.bootstrap.placeholder": "Bootstrap password (the first time only)",
374
+ "library.connection": "Connection",
375
+ "library.help": "The library holds tags, albums and stations for all boxes. This box fetches what it lacks, and without the library it plays what it has already.",
376
+ "library.none": "none – this box works on its own",
377
+ "library.outbox": {
378
+ "one": "{n} change",
379
+ "other": "{n} changes"
380
+ },
381
+ "library.outbox_unsettled": {
382
+ "one": "{n} change, {unsettled} of them newly created",
383
+ "other": "{n} changes, {unsettled} of them newly created"
384
+ },
385
+ "library.state.blocked": "The library is too old for this box – the box plays nothing until this is fixed.",
386
+ "library.state.connected": "connected",
387
+ "library.state.next_start": "from the next start of the box",
388
+ "library.state.unreachable": "not reachable – the box works without it ({reason})",
389
+ "library.this_box": "This box",
390
+ "library.title": "Library",
391
+ "library.unlink": "Unlink from the library",
392
+ "library.unlink.absent": {
393
+ "one": "{n} album is not completely on the SD card and cannot be fetched afterwards.",
394
+ "other": "{n} albums are not completely on the SD card and cannot be fetched afterwards."
395
+ },
396
+ "library.unlink.changes": {
397
+ "one": "The library has not taken {n} change yet. It stays on the box and never reaches the library.",
398
+ "other": "The library has not taken {n} changes yet. They stay on the box and never reach the library."
399
+ },
400
+ "library.unlink.confirm": "Unlink this box from the library? The box keeps everything on its SD card and works on its own afterwards. The library is not asked.",
401
+ "library.unlink.wait": "“Cancel” if the box is to deliver or fetch that first.",
402
+ "library.unlinked": "The box works on its own now.",
403
+ "library.unsettled": "Not confirmed yet",
404
+ "limits.default": "Start value %",
405
+ "limits.default_over_max": "{output}: the start value must not be above the maximum.",
406
+ "limits.help": "The start value applies when the box starts, or every time the headset connects. The maximum applies at once – also for the buttons on the headset.",
407
+ "limits.max": "Maximum %",
408
+ "limits.saved": "Volume limits saved.",
409
+ "limits.title": "Volume: start value and maximum",
410
+ "log.cannot_start": "cannot start",
411
+ "log.code": "Code",
412
+ "log.code.all": "all codes",
413
+ "log.component": "Component",
414
+ "log.component.all": "all components",
415
+ "log.copied": {
416
+ "one": "{n} entry copied.",
417
+ "other": "{n} entries copied."
418
+ },
419
+ "log.copy": "Copy",
420
+ "log.export": "Save as file",
421
+ "log.export_failed": "The entries could not be fetched.",
422
+ "log.filter": "Filter",
423
+ "log.level": "Level",
424
+ "log.level.debug": "Debug",
425
+ "log.level.error": "Error",
426
+ "log.level.info": "Info",
427
+ "log.level.warning": "Warning",
428
+ "log.live": "live",
429
+ "log.none": "No entries.",
430
+ "log.recovery": "Emergency mode: {problem}",
431
+ "log.since": "since",
432
+ "log.source": "Whose log",
433
+ "log.source.library": "This library",
434
+ "log.startup": {
435
+ "one": "The box cannot start since {since}: {n} failed start, version {version} in slot {slot}.",
436
+ "other": "The box cannot start since {since}: {n} failed starts, version {version} in slot {slot}."
437
+ },
438
+ "log.traceback": "Traceback",
439
+ "log.version.all": "all versions",
440
+ "login.error.too_many": "Too many failed attempts – please try again later.",
441
+ "login.error.wrong": "Wrong user or password.",
442
+ "login.idle": "You were logged out: nothing was done on this page for {minutes} min.",
443
+ "login.password": "Password",
444
+ "login.place.box": "Box",
445
+ "login.place.box_named": "Box “{name}”",
446
+ "login.place.library": "Library",
447
+ "login.submit": "Log in",
448
+ "login.user": "User",
449
+ "logout": "Log out",
450
+ "now.connection_lost": "Connection lost",
451
+ "now.link.submit": "Link & play",
452
+ "now.link.text": "Tag {uid} is not linked to an album or a radio station.",
453
+ "now.link.title": "Unknown tag placed",
454
+ "now.linked.album": "Tag linked – the album starts.",
455
+ "now.linked.radio": "Tag linked – the station starts.",
456
+ "now.linked.spotify": "Tag linked – the entry of Spotify starts.",
457
+ "now.louder.title": "Louder (button)",
458
+ "now.next.title": "Next (button)",
459
+ "now.prev.title": "Back (button)",
460
+ "now.quieter.title": "Quieter (button)",
461
+ "now.radio.active": "Radio active",
462
+ "now.radio.test": "Radio test",
463
+ "now.restart": "Album from the start",
464
+ "now.spotify.active": "Spotify",
465
+ "now.spotify.speaker": "Spotify speaker",
466
+ "now.spotify.test": "Test of Spotify",
467
+ "now.tag": "Tag: {name} ({uid})",
468
+ "now.tracks": "Tracks",
469
+ "now.volume.change": "change",
470
+ "now.volume.info": "{output} · start value {default}% · maximum {max}%",
471
+ "output.headphones": "Headset",
472
+ "output.speaker": "Speaker",
473
+ "password.changed": "Password changed.",
474
+ "password.current": "Current password",
475
+ "password.help": "At least 8 characters. Afterwards you have to log in again on all other devices.",
476
+ "password.mismatch": "The two new passwords do not match.",
477
+ "password.new": "New password",
478
+ "password.repeat": "Repeat new password",
479
+ "password.submit": "Change",
480
+ "password.title": "Change own password",
481
+ "password.wrong": "The current password is wrong.",
482
+ "playback.delay": "pause between tracks",
483
+ "playback.end": "stopped",
484
+ "playback.finished": "album finished",
485
+ "playback.first": "album from the start",
486
+ "playback.init": "starting",
487
+ "playback.paused": "paused",
488
+ "playback.play": "playing",
489
+ "playback.prev": "back",
490
+ "playback.resume": "paused",
491
+ "playback.rewind": "track from the start",
492
+ "playback.tonext": "next track",
493
+ "playback.toprev": "previous track",
494
+ "playback.wait": "waiting for the track from the library",
495
+ "progress.column.finished": "Finished",
496
+ "progress.column.position": "Position",
497
+ "progress.column.tag": "Tag",
498
+ "progress.finished": "finished",
499
+ "progress.title": "Progress per tag",
500
+ "progress.track": "track {n}, {time}",
501
+ "radio.column.url": "Stream URL",
502
+ "radio.created": "Station “{name}” created.",
503
+ "radio.help": "A tag that is linked to a station plays the station as long as it is on the box. The buttons “Next” and “Back” have no effect with the radio.",
504
+ "radio.new.help": "Address of the stream or of a playlist (<code>.m3u</code>, <code>.pls</code>, <code>.m3u8</code>), beginning with <code>http://</code> or <code>https://</code>. “Test” plays the entered address for one minute – only while no tag is on the box.",
505
+ "radio.new.name": "Name, e.g. FM4",
506
+ "radio.new.title": "Create a new station",
507
+ "radio.new.url": "https://…",
508
+ "radio.none": "No radio stations.",
509
+ "radio.remove.confirm": "Delete station “{name}”?",
510
+ "radio.remove.linked": "“{name}” is linked to {tags} – unlink first (✕).",
511
+ "radio.removed": "Station deleted.",
512
+ "radio.saved": "Station saved.",
513
+ "radio.state.connecting": "connecting",
514
+ "radio.state.paused": "paused",
515
+ "radio.state.playing": "playing",
516
+ "radio.state.retrying": "connection interrupted – trying again",
517
+ "radio.state.stopped": "stopped",
518
+ "radio.test": "Test",
519
+ "radio.test.state": "Test: {station} – {state}",
520
+ "radio.test.state_error": "Test: {station} – {state} ({error})",
521
+ "radio.test.stop": "Stop",
522
+ "radio.title": "Radio stations",
523
+ "releases.access.title": "Access to the releases",
524
+ "releases.check": "Look for a new version now",
525
+ "releases.checked": {
526
+ "one": "Last looked: {date}, next search in {n} minute.",
527
+ "other": "Last looked: {date}, next search in {n} minutes."
528
+ },
529
+ "releases.column.prepared_on": "Prepared on",
530
+ "releases.column.runs_on": "Runs on",
531
+ "releases.column.set": "Set",
532
+ "releases.found": "Version {version} found.",
533
+ "releases.help": "<b>use</b>: boxes install the version by themselves. <b>manual</b>: by hand only. <b>dontuse</b>: every box that runs it leaves it at once. <b>Runs on</b> names the library itself too. <b>Prepared on</b>: the box has fetched the version and tries it the next time it is switched on.",
534
+ "releases.hidden": {
535
+ "one": "{n} version hidden",
536
+ "other": "{n} versions hidden"
537
+ },
538
+ "releases.hide_old": "hide old versions that are not in the archive",
539
+ "releases.keep.help": "Older versions leave the archive, first those in the state dontuse. What runs on a box or lies in one of its slots always stays, and so do the version of the library itself and the newest one in the state use. A version that is no longer in the archive is fetched again from the releases when a box needs it.",
540
+ "releases.keep.label": "Keep at most {versions} versions in the archive",
541
+ "releases.library": "The library serves the interface {interface}.",
542
+ "releases.needs_newer_library": "needs a newer library",
543
+ "releases.never_checked": "Nobody has looked for versions yet.",
544
+ "releases.no_repository": "The configuration of the library names no repository: it does not look for new versions.",
545
+ "releases.none": "No version in the archive yet.",
546
+ "releases.not_archived": "not in the archive",
547
+ "releases.nothing_new": "No new version.",
548
+ "releases.repository": "New versions come from the releases of {repository}.",
549
+ "releases.set.done": "State set.",
550
+ "releases.set.prompt": "Set version {version} to “{state}” – why?",
551
+ "releases.title": "Versions of the box software",
552
+ "releases.token.placeholder": "Token that may read the releases",
553
+ "releases.token.submit": "Save token",
554
+ "releases.token_saved": "Token saved.",
555
+ "releases.token_state.file": "The token for this comes from the file named in the configuration; one saved here replaces it.",
556
+ "releases.token_state.missing": "The token for this is still missing: until it is saved here, the library does not look.",
557
+ "releases.token_state.none": "The library asks without a token.",
558
+ "releases.token_state.page": "The token for this is saved here.",
559
+ "restore.choose": "Choose backup …",
560
+ "restore.confirm": "This replaces all data by those of {when}.",
561
+ "restore.confirm.albums": "With MP3s: all albums are deleted and replaced.",
562
+ "restore.confirm.backup": "No backup is made before. If the data of now may be needed again, cancel and download a backup first.",
563
+ "restore.confirm.library": "This box works with a library: at its next synchronization it gets the state of the library again.",
564
+ "restore.discard": "Discard",
565
+ "restore.discarded": "The backup is not put back.",
566
+ "restore.help": "Replaces the data by those of a backup – with MP3s also the albums. Users, passwords, keys and the folders of the backups stay as they are. Afterwards it starts again.",
567
+ "restore.put_back": "Put back",
568
+ "restore.send_failed": "The backup could not be sent.",
569
+ "restore.state.failed": "The backup was not put back: {message}",
570
+ "restore.state.last": "Last put back on {when}: the backup of {created}.",
571
+ "restore.state.missing": {
572
+ "one": "{n} album is in the data, but its folder is missing: {albums}.",
573
+ "other": "{n} albums are in the data, but their folders are missing: {albums}."
574
+ },
575
+ "restore.state.restarting": "The data is replaced and it starts again – the page loads anew in a moment.",
576
+ "restore.state.staged": "The backup of {when} is unpacked and waits to be put back.",
577
+ "restore.state.staging": "The backup is being read and unpacked …",
578
+ "restore.state.uploading": "The backup is sent and unpacked ({size}) …",
579
+ "restore.title": "Put a backup back",
580
+ "role.admin": "admin",
581
+ "role.user": "user",
582
+ "scan.error.NotReadableError": "NFC is switched off – switch it on in the settings of the phone.",
583
+ "scan.error.NotSupportedError": "This phone cannot read tags (no NFC).",
584
+ "scan.failed": "NFC: {message}",
585
+ "scan.help": "Hold a tag to the back of the phone. A new tag is added to the library.",
586
+ "scan.new": "new",
587
+ "scan.obstacle.browser": "This browser cannot read tags – open the page in Chrome.",
588
+ "scan.obstacle.chrome": "Chrome {version} does not offer NFC to this page.",
589
+ "scan.obstacle.https": "Chrome reads tags only on a page with HTTPS.",
590
+ "scan.obstacle.ios": "An iPhone or iPad cannot read tags – only an Android phone with Chrome.",
591
+ "scan.refused.blocked": "Chrome does not allow this page to use NFC. To allow it: tap the symbol to the left of the address, then “Permissions” and “NFC devices”. If the entry is missing there: Chrome menu, “Settings”, “Site settings”, “NFC devices” – the switch must be on, and this page must not be listed under “Blocked”.",
592
+ "scan.refused.closed": "Chrome asked whether this page may use NFC and got no permission. Tap “Scan tag” once more and then “Allow”.",
593
+ "scan.start": "Scan tag",
594
+ "scan.stop": "Stop scanning",
595
+ "scan.unreadable": "The phone cannot read this tag.",
596
+ "slot.installed": "installed",
597
+ "slot.name.a": "A",
598
+ "slot.name.b": "B",
599
+ "slot.name.fallback": "Emergency",
600
+ "slot.name.next": "from the next start",
601
+ "slot.since": {
602
+ "one": "{state} since {since}, {n} start",
603
+ "other": "{state} since {since}, {n} starts"
604
+ },
605
+ "slot.state.abandoned": "abandoned",
606
+ "slot.state.confirmed": "proven",
607
+ "slot.state.probation": "on trial",
608
+ "spotify.account.choose": "Now choose the box in the Spotify app.",
609
+ "spotify.account.connect": "Connect",
610
+ "spotify.account.disconnect": "Disconnect",
611
+ "spotify.account.disconnect.confirm": "Remove the Spotify account from this box?",
612
+ "spotify.account.help": "The key comes from developer.spotify.com (Dashboard → “Spotify Soloist API Key”, logged in with a Premium account). With it the box fetches the player of Spotify. After “Connect” choose this box within five minutes in the Spotify app of a phone in the same WLAN – logged in to the Spotify account of the box. Key and login stay on this box.",
613
+ "spotify.account.key": "Soloist API key",
614
+ "spotify.account.key_missing": "No key yet.",
615
+ "spotify.account.key_present": "Key entered.",
616
+ "spotify.account.key_save": "Save key",
617
+ "spotify.account.key_saved": "Key saved – the box fetches the player.",
618
+ "spotify.account.result.failed": "Connecting did not work.",
619
+ "spotify.account.result.stopped": "Connecting was interrupted.",
620
+ "spotify.account.result.timeout": "Nobody chose the box in time – try again.",
621
+ "spotify.account.speaker": "Spotify speaker while no tag is on the box",
622
+ "spotify.account.state.connected": "Connected since {since}.",
623
+ "spotify.account.state.connecting": "Waiting to be chosen in the Spotify app …",
624
+ "spotify.account.state.none": "Not connected to an account.",
625
+ "spotify.account.title": "Account",
626
+ "spotify.column.kind": "Kind",
627
+ "spotify.column.link": "Link",
628
+ "spotify.created": "Entry “{name}” created.",
629
+ "spotify.error.cannot_run": "the player of Spotify does not start",
630
+ "spotify.error.expired": "the player of Spotify has expired",
631
+ "spotify.error.no_key": "the key of Spotify is missing (tab Spotify, Account)",
632
+ "spotify.error.no_player": "the player of Spotify is not fetched yet",
633
+ "spotify.error.not_connected": "the box is not connected to Spotify (tab Spotify, Account)",
634
+ "spotify.error.unexpected": "an error in the box",
635
+ "spotify.help": "A tag that is linked to an entry of Spotify plays it like an album: it continues where it stopped, and “Next” and “Back” work. It needs the internet and a Spotify account connected to the box.",
636
+ "spotify.kind.album": "Album",
637
+ "spotify.kind.artist": "Artist",
638
+ "spotify.kind.audiobook": "Audiobook",
639
+ "spotify.kind.episode": "Episode",
640
+ "spotify.kind.playlist": "Playlist",
641
+ "spotify.kind.show": "Podcast",
642
+ "spotify.kind.track": "Track",
643
+ "spotify.new.help": "Paste the link that the Spotify app gives under “Share” → “Copy link”. Name and cover come from Spotify; the name can be changed before saving. A podcast has to be named by hand.",
644
+ "spotify.new.link": "https://open.spotify.com/…",
645
+ "spotify.new.name": "Name",
646
+ "spotify.new.title": "Create a new entry",
647
+ "spotify.none": "No entries of Spotify.",
648
+ "spotify.player.asked": "Spotify asked last on {time}: {result}",
649
+ "spotify.player.built": "Build of {built}, works until {last_day}; the box looks for a new one from {renew_from} on.",
650
+ "spotify.player.missing": "Missing on the box: {packages} – running the installer of the box again installs it.",
651
+ "spotify.player.never": "Spotify not asked yet.",
652
+ "spotify.player.result.broken": "a new build that does not start – the box keeps its build",
653
+ "spotify.player.result.failed": "no answer",
654
+ "spotify.player.result.new": "a new build",
655
+ "spotify.player.result.unchanged": "nothing new",
656
+ "spotify.player.state.cannot_run": "Does not start.",
657
+ "spotify.player.state.expired": "Expired.",
658
+ "spotify.player.state.fetching": "Being fetched …",
659
+ "spotify.player.state.none": "Not fetched yet.",
660
+ "spotify.player.state.ready": "Ready.",
661
+ "spotify.player.title": "Player",
662
+ "spotify.player.update": "Update now",
663
+ "spotify.player.updating": "Asking Spotify …",
664
+ "spotify.remove.confirm": "Delete entry “{name}”?",
665
+ "spotify.remove.linked": "“{name}” is linked to {tags} – unlink first (✕).",
666
+ "spotify.removed": "Entry deleted.",
667
+ "spotify.saved": "Entry saved.",
668
+ "spotify.state.connecting": "connecting",
669
+ "spotify.state.elsewhere": "plays on another device – “Play” takes it back",
670
+ "spotify.state.error": "cannot play",
671
+ "spotify.state.finished": "finished",
672
+ "spotify.state.paused": "paused",
673
+ "spotify.state.playing": "playing",
674
+ "spotify.state.retrying": "connection interrupted – trying again",
675
+ "spotify.state.stopped": "stopped",
676
+ "spotify.test.state": "Test: {name} – {state}",
677
+ "spotify.title": "Spotify",
678
+ "spotify.app.title": "The app on phones",
679
+ "spotify.app.help": "A tag of Spotify plays on a phone in its Spotify app if the app of Tiny Jukebox is registered at Spotify: on developer.spotify.com, create an app with the API “Android”, the redirect URI tinyjukebox://spotify and the package name and SHA-1 that the settings of the app on the phone show; under “User Management”, add the Spotify accounts of the phones (at most five). Then enter its client ID here; the phones get it with their next synchronization. Empty: a tag of Spotify plays on a box only.",
680
+ "spotify.app.client": "Client ID of the app at Spotify",
681
+ "state.blocked": "Box out of service – the library is too old for this box",
682
+ "state.broken_album": "Album broken",
683
+ "state.check_tag": "Checking the tag",
684
+ "state.end": "Ended",
685
+ "state.fetch_album": "Fetching the album from the library",
686
+ "state.idle_long": "Ready – no tag placed for a long time",
687
+ "state.play_album": "Album active",
688
+ "state.test_radio": "Radio test",
689
+ "state.spotify_speaker": "The Spotify app plays on the box",
690
+ "state.unknown_album": "Album missing",
691
+ "state.unknown_tag": "Unknown tag",
692
+ "state.wait_for_tag": "Ready – no tag placed",
693
+ "statistics.box.all": "All boxes",
694
+ "statistics.box.label": "Box",
695
+ "statistics.column.active": "Hours of operation (active)",
696
+ "statistics.column.box": "Box",
697
+ "statistics.column.boxes": "Boxes",
698
+ "statistics.column.day": "Day",
699
+ "statistics.column.errors": "Errors",
700
+ "statistics.column.fallbacks": "Fallbacks",
701
+ "statistics.column.finished": "Listened to the end",
702
+ "statistics.column.hours": "Listened between",
703
+ "statistics.column.installed": "Days installed",
704
+ "statistics.column.last": "Last",
705
+ "statistics.column.placed": "Placed",
706
+ "statistics.column.running": "Hours of operation (total)",
707
+ "statistics.column.skipped": "Skipped",
708
+ "statistics.column.starts": "Starts",
709
+ "statistics.column.station": "Station",
710
+ "statistics.column.tag": "Tag",
711
+ "statistics.column.time": "Listening time",
712
+ "statistics.days.none": "No days yet.",
713
+ "statistics.days.title": "Days",
714
+ "statistics.help.alone": "What was listened to on this box. Without a library the box keeps only the last {limit} entries of its journal – that is how far back the statistics reach.",
715
+ "statistics.help.box": "What was listened to on this box. The library does the counting: what the box has not delivered to it yet is still missing here.",
716
+ "statistics.help.library": "From the journals of the boxes. A box without WLAN delivers later – missing days mean “not delivered yet”, not “nothing listened to”.",
717
+ "statistics.hours": "{from}:00–{to}:00",
718
+ "statistics.missing.library_too_old": "The library is older than this box and does not hand out the statistics of a single box yet. After the update of the library they are shown here.",
719
+ "statistics.missing.unreachable": "The library counts what was listened to on this box – and it cannot be reached right now.",
720
+ "statistics.never.title": "Never placed",
721
+ "statistics.none": "Nothing listened to yet.",
722
+ "statistics.on_box": "{box} {duration}",
723
+ "statistics.operation.help": "<b>Days installed</b>: for so long the version was the one of a box, also while the box was switched off. <b>Operation (total)</b>: the box was switched on. <b>Operation (active)</b>: something was listened to. With several boxes the values are summed. Versions before 0.23.0 did not note how long the box was switched on: for them the time until the last event of a start counts.",
724
+ "statistics.operation.title": "Operation",
725
+ "statistics.radio_skipped.title": "Radio stations and skipped tracks",
726
+ "statistics.skipped.none": "No track was skipped.",
727
+ "statistics.stations.none": "No radio listened to.",
728
+ "statistics.time_unknown": "time unknown",
729
+ "statistics.title": "What was listened to?",
730
+ "statistics.total": "In total: {duration}.",
731
+ "statistics.unknown_time": "Plus {duration} without a known time of day: the box had no WLAN during that time.",
732
+ "system.rebuild": "Reset progress",
733
+ "system.rebuild.confirm": "Reset all progress? Every album then starts with its first track again.",
734
+ "system.rebuild.done": "Progress reset.",
735
+ "system.sanity": "Check consistency",
736
+ "system.sanity.ok": "✔ Everything is fine.",
737
+ "system.sanity.problems": "✘ Problems found:",
738
+ "system.tag": "Tag on the box",
739
+ "system.user": "Logged in as",
740
+ "tabs.albums": "Albums",
741
+ "tabs.bluetooth": "Bluetooth",
742
+ "tabs.boxes": "Boxes",
743
+ "tabs.log": "Log",
744
+ "tabs.now": "Now",
745
+ "tabs.radio": "Radio",
746
+ "tabs.spotify": "Spotify",
747
+ "tabs.statistics": "Statistics",
748
+ "tabs.system": "System",
749
+ "tabs.tagman": "Tag management",
750
+ "tabs.tags": "Tags",
751
+ "tabs.upload": "Upload",
752
+ "tabs.versions": "Versions",
753
+ "tagman.column.cover": "Cover",
754
+ "tagman.created": "Tag {uid} created.",
755
+ "tagman.help": "New tags appear here as soon as they were placed on the box once.",
756
+ "tagman.link_saved": "Link saved.",
757
+ "tagman.name_saved": "Name saved.",
758
+ "tagman.new.name": "Name, e.g. red cat",
759
+ "tagman.new.no_target": "— no album / station —",
760
+ "tagman.new.title": "Create a new tag",
761
+ "tagman.new.uid": "UID (empty = random)",
762
+ "tagman.none": "No tags.",
763
+ "tagman.remove.confirm": "Remove tag “{name}”?",
764
+ "tagman.remove.title": "Remove tag",
765
+ "tagman.removed": "Tag removed.",
766
+ "tagman.unlink.confirm": "Unlink tag “{name}”?",
767
+ "tagman.unlinked": "Unlinked.",
768
+ "tagman.unlinked_only": "only tags that are not linked",
769
+ "tags.filter.album": "Albums",
770
+ "tags.filter.all": "All",
771
+ "tags.filter.label": "Show",
772
+ "tags.filter.radio": "Radio",
773
+ "tags.filter.spotify": "Spotify",
774
+ "tags.help.box": "A click places the tag on the box, as if it lay on the reader. A second click takes it off again.",
775
+ "tags.help.library": "All tags of the library. They are placed on a box.",
776
+ "tags.none.box": "No tags – place a UID below or create a tag under Tag management.",
777
+ "tags.none.filtered": "No tags of this kind.",
778
+ "tags.none.library": "No tags – they appear here as soon as a box knows them or one was created under Tag management.",
779
+ "tags.place": "Place",
780
+ "tags.remove": "Take off tag",
781
+ "tags.title.box": "Place a tag",
782
+ "tags.uid.placeholder": "place any UID, e.g. 136:4:99:1",
783
+ "tags.view.label": "View",
784
+ "tags.view.list": "List",
785
+ "tags.view.tiles": "Tiles",
786
+ "target.album_missing": "album {id} is missing",
787
+ "target.album_without_tag": "{title} (no tag)",
788
+ "target.choose": "— choose album or station —",
789
+ "target.label": "Album or station",
790
+ "target.missing_option": "missing ({id})",
791
+ "target.none": "— not linked —",
792
+ "target.radio_missing": "station {id} is missing",
793
+ "target.required": "Please choose an album or a station.",
794
+ "target.spotify_missing": "Spotify entry {id} is missing",
795
+ "title.library": "Tiny Jukebox Library",
796
+ "upload.abort.confirm": "Cancel the upload and discard the uploaded files?",
797
+ "upload.album_title": "Title of the album (the folder gets the same name)",
798
+ "upload.album_title.placeholder": "e.g. Bedtime stories – part 1",
799
+ "upload.choose_files": "Choose files",
800
+ "upload.choose_folder": "Choose folder",
801
+ "upload.connection_lost": "Connection lost",
802
+ "upload.cover": "Cover (JPEG, PNG or WebP, can also be chosen later)",
803
+ "upload.created": "Album “{title}” created.",
804
+ "upload.created_linked": "Album “{title}” created and linked to the tag.",
805
+ "upload.drop": "<strong>Drag MP3 files here</strong> or",
806
+ "upload.files": {
807
+ "one": "{n} file",
808
+ "other": "{n} files"
809
+ },
810
+ "upload.finish": "Create album",
811
+ "upload.help": "Choose MP3 files – the playlist <code>playlist.m3u</code> is created automatically (in the order of the track numbers, otherwise of the file names). The order can be changed before the album is created.",
812
+ "upload.link_later": "— link later —",
813
+ "upload.link_tag": "Link to tag",
814
+ "upload.move_down": "down",
815
+ "upload.move_up": "up",
816
+ "upload.no_mp3": "No MP3 files chosen.",
817
+ "upload.pending.busy": "Finish the current upload first",
818
+ "upload.pending.discard": "Discard",
819
+ "upload.pending.discard.confirm": "Discard upload “{folder}”?",
820
+ "upload.pending.resume": "Continue",
821
+ "upload.pending.title": "Unfinished uploads",
822
+ "upload.present_tag": "Tag on the box: {name}",
823
+ "upload.progress": {
824
+ "one": "{done} of {n} file uploaded.",
825
+ "other": "{done} of {n} files uploaded."
826
+ },
827
+ "upload.remove": "remove",
828
+ "upload.title": "Upload a new album",
829
+ "upload.title_required": "Please enter the title of the album first.",
830
+ "upload.waiting": "waiting",
831
+ "users.created": "User “{name}” created.",
832
+ "users.help": "“admin” may do everything, “user” may operate the box but change nothing. A new password logs the user out everywhere.",
833
+ "users.new.password": "Password (at least 8 characters)",
834
+ "users.new.title": "Create a new user",
835
+ "users.password.done": "Password of “{name}” set.",
836
+ "users.password.label": "New password for {name}",
837
+ "users.password.placeholder": "new password",
838
+ "users.password.submit": "Set",
839
+ "users.remove.confirm": "Delete user “{name}”?",
840
+ "users.remove.self": "The own user cannot be deleted",
841
+ "users.removed": "User deleted.",
842
+ "users.role": "Role",
843
+ "users.self": "(you)",
844
+ "users.set_password": "Set password",
845
+ "users.title": "Users",
846
+ "version.banner": "Version {version} is available.",
847
+ "version.check": "Look for a new version",
848
+ "version.column.slot": "Slot",
849
+ "version.degraded": "Data left out",
850
+ "version.done": "done",
851
+ "version.failed": "That did not work – see the output.",
852
+ "version.fallback": "Start emergency mode",
853
+ "version.fallback.confirm": "Start emergency mode? The box restarts at once and plays nothing until it has installed a version that runs.",
854
+ "version.help.library": "The box fetches new versions from the library by itself and tries them on its next start. If a new version does not run, the previous one starts again.",
855
+ "version.help.none": "The box has no library and knows no address of releases: a new version comes from a file, with the installer or the playbook.",
856
+ "version.help.releases": "The box has no library: once a day it looks by itself whether there is a new release, and tries it on its next start. If a new version does not run, the previous one starts again.",
857
+ "version.install": "Install",
858
+ "version.install_now": "Install now",
859
+ "version.installing": "Version {version} is being installed in the background and starts the next time the box is switched on.",
860
+ "version.mode.ask": "ask",
861
+ "version.mode.automatic": "automatic",
862
+ "version.mode.label": "Updates of this box",
863
+ "version.mode.manual": "by hand only",
864
+ "version.mode.off": "off",
865
+ "version.new": "New",
866
+ "version.no_slots": "This box was set up without slots – the playbook changes its version.",
867
+ "version.note": "Note",
868
+ "version.offer": "Version {version} of {date}, {size}",
869
+ "version.offer.notes": "What is new",
870
+ "version.offer.soon": "Version {version} of {date}, {size} – installed as soon as the box looks the next time",
871
+ "version.offer.waiting": {
872
+ "one": "Version {version} of {date}, {size} – installed by itself on {due} (it waits {n} day)",
873
+ "other": "Version {version} of {date}, {size} – installed by itself on {due} (it waits {n} days)"
874
+ },
875
+ "version.promote": "Keep as emergency version",
876
+ "version.promote.confirm": "Keep the running version as the emergency version?",
877
+ "version.revert": "Back to the previous version",
878
+ "version.revert.confirm": "Go back to the previous version? The box restarts at once, even if something is playing.",
879
+ "version.running": "Running",
880
+ "version.running_slot": "{version} (slot {slot}, {state})",
881
+ "version.skip": "Skip",
882
+ "version.skipped": "Version {version} is not offered any more – the next release is.",
883
+ "version.source": "Source",
884
+ "version.source.library": "library {address}. As long as the box is linked to it, new versions come from there only – not from GitHub. To unlink: section “Library”.",
885
+ "version.source.none": "no library – a new version comes from a file, with the installer or the playbook",
886
+ "version.source.releases": {
887
+ "one": "releases of {address}. A release waits {n} day before the box installs it by itself.",
888
+ "other": "releases of {address}. A release waits {n} days before the box installs it by itself."
889
+ },
890
+ "version.update_now": "Update now",
891
+ "version.updates": "Updates"
892
+ }