{{ content().heading }}
++ + {{ content().subheading }} + +
+diff --git a/AdminInterface/www/mupi.php b/AdminInterface/www/mupi.php index 7b1441fb..2cd90f2c 100644 --- a/AdminInterface/www/mupi.php +++ b/AdminInterface/www/mupi.php @@ -441,6 +441,75 @@ $CHANGE_TXT=$CHANGE_TXT."
Caps the total daily listening time on the box. When the limit is reached, playback stops and new playback is refused until the next day. Set a day to 0 to block playback completely on that day. Settings take effect after saving (the player is restarted automatically).
+Enable / disable the daily limit:
+ +Hour of day at which the counter resets to 0. 0 = midnight. Use e.g. 4 if you don't want a reset to interrupt late evening listening.
+ +When the daily limit is reached, allow playback to continue for up to this many additional minutes so the current track can finish naturally. The player stops at the next track boundary (for local files / radio / RSS) or at the latest when this grace runs out. 0 = stop immediately at the limit. Default: 10. Maximum: 60.
+ + min +Set 0 to block playback entirely on that day. Maximum 1440 (= 24 h).
+| Day | Minutes per day |
|---|---|
| '.$label.' | min |
Define time windows per weekday during which playback is automatically blocked (e.g. homework, mealtimes, bedtime). Multiple windows per day are supported.
+How a window is interpreted:
+from 20:00 → to 08:00 blocks playback Monday evening and Tuesday morning until 08:00. You do not need a separate Tuesday entry for the same night.14:00 → 16:00 (Homework) alongside 20:00 → 08:00 (Bedtime) to block both periods.Settings take effect after saving (the player is restarted automatically).
+Enable / disable quiet hours:
+ +When a quiet window starts, allow up to this many additional minutes for the current track to finish naturally. 0 = stop immediately at the window boundary. Default: 10. Maximum: 60.
+ min +Use „+ Add window" to add another row to a day. Empty rows are ignored on save.
+ 'Monday', + 'tue' => 'Tuesday', + 'wed' => 'Wednesday', + 'thu' => 'Thursday', + 'fri' => 'Friday', + 'sat' => 'Saturday', + 'sun' => 'Sunday', + ); + foreach( $qh_day_labels as $key => $label ) { + $windows = isset($qh_schedule[$key]) && is_array($qh_schedule[$key]) ? $qh_schedule[$key] : array(); + echo '| From | To | Label (optional) | |
|---|---|---|---|
| '; + echo ' | '; + echo ' | '; + echo ' | '; + echo ' |
Please enter your telegram ChatId.
+ +Eine Zeile pro Chat oder Gruppe. Label ist optional und nur fürs eigene Wiedererkennen. Leere Zeilen werden beim Speichern verworfen. „Generate Telegram Chat ID" hängt einen neu erkannten Chat an die Liste an.
/help\nto get easy way to use command\n\n/reboot\nto reboot\n\n/shutdown\nto shutdown the mupibox\n\n/screen\nto get a current screenshot\n\n/sleep [No in minutes]\nto set a sleep timer in minutes\nExample: /sleep 30\n\n/vol [No in percent (0-100)]\nto set a sleep timer in minutes\nExample: /vol 30\n\n/media\nUpdate media database...\n\n/finishalbum\nActivates the shutdown after the end of the current album.",parse_mode='HTML')
+ bot.sendMessage(chat_id, "Possible commands:\n\n/help\nshows the inline keyboard\n\n/status\nshow current playtime + quiet hours status\n\n/extend [minutes, default 30]\nadd bonus minutes to today's playtime cap\n\n/release [minutes, default 60]\nbypass all blocks for N minutes\n\n/quietnow [minutes, default 60]\nforce-block playback for N minutes\n\n/limit set <day> <minutes>\nset the playtime limit for one weekday (mon..sun, 0..1440)\n\n/reboot\n/shutdown\n/screen\n/sleep [minutes]\n/vol [0-100]\n/media\n/finishalbum", parse_mode='HTML')
elif command == '/media':
bot.sendMessage(chat_id, "Starting media data update... This take a while, please wait for complete message")
subprocess.run(["sudo", "/usr/local/bin/mupibox/./m3u_generator.sh"])
@@ -73,6 +278,9 @@ def on_chat_message(msg):
def on_callback_query(msg):
query_id, from_id, query_data = telepot.glance(msg, flavor='callback_query')
print('Callback Query:', query_id, from_id, query_data)
+ if not is_authorized(from_id):
+ print(f'Rejected callback from unauthorized user_id: {from_id}')
+ return
global message_with_inline_keyboard
@@ -80,6 +288,33 @@ def on_callback_query(msg):
subprocess.run(["sudo", "rm", "/tmp/telegram_screen.png"])
subprocess.run(["sudo", "-H", "-u", "dietpi", "bash", "-c", "DISPLAY=:0 scrot /tmp/telegram_screen.png"])
bot.sendPhoto(from_id, open('/tmp/telegram_screen.png', 'rb'))
+ elif query_data == 'status':
+ status_code, body = call_api_get('/playtime')
+ if status_code == 200:
+ bot.sendMessage(from_id, format_status(body), parse_mode='HTML')
+ else:
+ bot.answerCallbackQuery(query_id, text=f'Status-Abfrage fehlgeschlagen: {status_code}', show_alert=True)
+ elif query_data[:7] == 'extend_':
+ mins = int(query_data.split('_')[1])
+ status_code, body = call_api_post('/playtime/extend', {'minutes': mins})
+ if status_code == 200:
+ bot.answerCallbackQuery(query_id, text=f'+{mins} min hinzugefügt', show_alert=True)
+ else:
+ bot.answerCallbackQuery(query_id, text=f'Fehler: {status_code}', show_alert=True)
+ elif query_data[:8] == 'release_':
+ mins = int(query_data.split('_')[1])
+ status_code, body = call_api_post('/playtime/release', {'minutes': mins})
+ if status_code == 200:
+ bot.answerCallbackQuery(query_id, text=f'Override für {mins} min aktiv', show_alert=True)
+ else:
+ bot.answerCallbackQuery(query_id, text=f'Fehler: {status_code}', show_alert=True)
+ elif query_data[:9] == 'quietnow_':
+ mins = int(query_data.split('_')[1])
+ status_code, body = call_api_post('/quiethours/now', {'minutes': mins})
+ if status_code == 200:
+ bot.answerCallbackQuery(query_id, text=f'Stop für {mins} min aktiviert', show_alert=True)
+ else:
+ bot.answerCallbackQuery(query_id, text=f'Fehler: {status_code}', show_alert=True)
elif query_data == 'vol':
markup = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="10",callback_data='vol_10'), InlineKeyboardButton(text="20",callback_data='vol_20')],
@@ -101,15 +336,25 @@ def on_callback_query(msg):
msg_idf = telepot.message_identifier(message_with_inline_keyboard)
bot.editMessageText(msg_idf, 'In how many minutes should the MuPiBox go to sleep?', reply_markup = markup )
elif query_data[:4] == 'vol_':
- split_cmd = query_data.split("_")
- volume = split_cmd[1]+"%"
- subprocess.run(["/usr/bin/amixer", "sset", "Master", volume])
- bot.answerCallbackQuery(query_id, text='Volume set to ' + volume, show_alert=True)
+ # Inline-keyboard values are hardcoded (10/30/50/70/100) but defense-
+ # in-depth: clamp anyway so a future button change can't bypass
+ # maxVolume. Same for /sleep_
+