From 8dd0b9e6f82427ecbef6654b44bcd4da49dbb567 Mon Sep 17 00:00:00 2001 From: Christian Heller <c.heller@plomlompom.de> Date: Mon, 17 Feb 2025 02:21:28 +0100 Subject: [PATCH] Remove playlist manipulation form from /playlist, turn play buttons in /file and /files into inject buttons. --- src/templates/file_data.tmpl | 9 +++++++- src/templates/files.tmpl | 14 ++++-------- src/templates/playlist.tmpl | 44 ++++++++---------------------------- src/ytplom/http.py | 40 ++++++++++---------------------- src/ytplom/misc.py | 19 ++++++++++------ 5 files changed, 47 insertions(+), 79 deletions(-) diff --git a/src/templates/file_data.tmpl b/src/templates/file_data.tmpl index c3f4dc8..634f41a 100644 --- a/src/templates/file_data.tmpl +++ b/src/templates/file_data.tmpl @@ -23,7 +23,14 @@ input[type=submit].dangerous { color: red; } <tr> <th>present:</th> -<td>{% if file.present %}<a href="/{{page_names.download}}/{{file.yt_id}}">yes</a> <input type="submit" name="play" value="play" />{% else %}no{% endif %}</td> +<td> +{% if file.present %} +<a href="/{{page_names.download}}/{{file.yt_id}}">yes</a> +<input type="button" onclick="player_command('inject_{{file.digest.b64}}');" value="inject" /> +{% else %} +no +{% endif %} +</td> </tr> <tr> diff --git a/src/templates/files.tmpl b/src/templates/files.tmpl index 70c0877..d78805b 100644 --- a/src/templates/files.tmpl +++ b/src/templates/files.tmpl @@ -58,12 +58,11 @@ async function update_files_list() { const tr = new_child_to('tr', table); tr.classList.add("file_row"); new_child_to('td', tr, file.size); - const td_play = new_child_to('td', tr); - const btn_play = new_child_to('input', td_play); - btn_play.type = 'submit'; - btn_play.name = `play_${file.digest}`; - btn_play.value = 'play'; - btn_play.disabled = !file.present; + const td_inject = new_child_to('td', tr); + const btn_inject = new_child_to('button', td_inject); + btn_inject.onclick = function() { player_command(`inject_${file.digest}`) }; + btn_inject.disabled = !file.present; + btn_inject.textContent = 'inject'; new_child_to('td', tr, file.tags_showable.join(", ")); const td_link = new_child_to('td', tr); const a = new_child_to('a', td_link, file.rel_path); @@ -82,10 +81,7 @@ needed tags: <select id="tags_select" onchange="select_tag()"></select><br /> <span id="tags"></span><br /> <hr /> <p>known files (shown: <span id="files_count">?</span>):</p> -<form action="/{{page_names.files}}" method="POST"> -<input type="hidden" name="redir_target" value="{{redir_target}}" /> <table id="files_table"> <tr><th>size</th><th>actions</th><th>tags</th><th>path</th></tr> </table> -</form> {% endblock %} diff --git a/src/templates/playlist.tmpl b/src/templates/playlist.tmpl index 669e723..9d4aa22 100644 --- a/src/templates/playlist.tmpl +++ b/src/templates/playlist.tmpl @@ -1,6 +1,11 @@ {% extends '_base.tmpl' %} +{% block css %} +td.entry_control { width: 6em; } +{% endblock %} + + {% block script %} {{ macros.js_new_child_to() }} @@ -33,50 +38,21 @@ event_handlers.push(function(data) { // update playlist else { for (const [symbol, prefix] of [['>', 'jump'], ['^', 'up'], - ['v', 'down']]) { + ['v', 'down'], + ['x', 'rm']]) { const btn = new_child_to('button', td_entry_control, symbol); btn.onclick = function() { player_command(`${prefix}_${i}`) }; }} const td_link = new_child_to('td', tr); const a_file = new_child_to('a', td_link, file.rel_path); a_file.href = `${PATH_PREFIX_FILE}${file.digest}`; }}) -function redo_playlist() { - post_to({filter_path: [document.getElementsByName('filter_path')[0].value], - needed_tags: [document.getElementsByName('needed_tags')[0].value]}, - PATH_PLAYER); - player_command('reload'); -} - -{% endblock %} - - -{% block css %} -td.screen_half { width: 50%; } -th.screen_half_titles { text-align: center; } -td.entry_control { width: 5em; } {% endblock %} {% block body %} -<table> -<td class="screen_half"> - -<table> -<tr><th colspan=2 class="screen_half_titles">playlist config</th></tr> -<tr><th>filter filename</th><td><input name="filter_path" value="{{filter_path}}" /></td></tr> -<tr><th>needed tags</th><td><input name="needed_tags" value="{{needed_tags}}" /></td></tr> -<tr><td colspan=2><button onclick="redo_playlist()">reload</button></td></tr> -</table> - -</td> -<td class="screen_half"> - +<a href="#playing">#playing</a> +<button onclick="player_command('rebuild')">rebuild</button> +<hr /> <table id="playlist_rows"> -<tr><th colspan=3 class="screen_half_titles">playlist (<a href="#playing">#playing</a>)</th></tr> -</table> - -</td> -</tr> </table> {% endblock %} - diff --git a/src/ytplom/http.py b/src/ytplom/http.py index 15e3a46..a47a4e6 100644 --- a/src/ytplom/http.py +++ b/src/ytplom/http.py @@ -106,8 +106,6 @@ class _TaskHandler(PlomHttpHandler): """Map POST requests to handlers for various paths.""" if self.pagename == PAGE_NAMES['file']: self._receive_file_data() - elif self.pagename == PAGE_NAMES['files']: - self._receive_files_command() elif self.pagename == PAGE_NAMES['player']: self._receive_player_command() elif self.pagename == PAGE_NAMES['purge']: @@ -116,19 +114,12 @@ class _TaskHandler(PlomHttpHandler): self._receive_yt_query() def _receive_file_data(self) -> None: - digest = Hash.from_b64(self.path_toks[2]) - if self.postvars.has_key('play'): - with DbConn() as conn: - file = VideoFile.get_one(conn, digest) - self.server.player.inject_and_play(file) - self._redirect(Path(self.postvars.first_for('redir_target'))) - return if not (self.server.config.allow_file_edit # also if whitelist, ⦠and self.server.config.tags_display_whitelist.empty): self.send_http(b'no way', code=403) # ⦠cuz input form under ⦠return # ⦠this display filter might have suppressed set tags with DbConn() as conn: - file = VideoFile.get_one(conn, digest) + file = VideoFile.get_one(conn, Hash.from_b64(self.path_toks[2])) if self.postvars.has_key('unlink'): file.unlink_locally() file.set_flags({FILE_FLAGS[FlagName(name)] @@ -139,14 +130,6 @@ class _TaskHandler(PlomHttpHandler): file.ensure_absence_if_deleted() self._redirect(Path(self.postvars.first_for('redir_target'))) - def _receive_files_command(self) -> None: - for k in self.postvars.keys_starting_with('play_'): - with DbConn() as conn: - file = VideoFile.get_one( - conn, Hash.from_b64(k.split('_', 1)[1])) - self.server.player.inject_and_play(file) - self._redirect(Path(self.postvars.first_for('redir_target'))) - def _receive_player_command(self) -> None: command = self.postvars.first_for('command') if 'play' == command: @@ -155,7 +138,7 @@ class _TaskHandler(PlomHttpHandler): self.server.player.prev() elif 'next' == command: self.server.player.next() - elif 'reload' == command: + elif 'rebuild' == command: self.server.player.load_files_and_mpv() elif command.startswith('jump_'): self.server.player.jump_to(int(command.split('_')[1])) @@ -163,12 +146,13 @@ class _TaskHandler(PlomHttpHandler): self.server.player.move_entry(int(command.split('_')[1])) elif command.startswith('down_'): self.server.player.move_entry(int(command.split('_')[1]), False) - if self.postvars.has_key('filter_path'): - self.server.player.filter_path = FilterStr( - self.postvars.first_for('filter_path')) - if self.postvars.has_key('needed_tags'): - self.server.player.needed_tags = TagSet.from_joined( - self.postvars.first_for('needed_tags')) + elif command.startswith('rm_'): + self.server.player.remove(int(command.split('_')[1])) + elif command.startswith('inject_'): + with DbConn() as conn: + file = VideoFile.get_one( + conn, Hash.from_b64(command.split('_', 1)[1])) + self.server.player.inject(file) self.send_http(b'OK') def _purge_deleted_files(self) -> None: @@ -221,7 +205,6 @@ class _TaskHandler(PlomHttpHandler): tmpl_ctx: dict[str, Any] ) -> None: tmpl_ctx['selected'] = tmpl_ctx.get('selected', '') - tmpl_ctx['redir_target'] = self.path tmpl_ctx['background_color'] = self.server.config.background_color tmpl_ctx['page_names'] = PAGE_NAMES self.send_rendered(tmpl_name, tmpl_ctx) @@ -297,9 +280,10 @@ class _TaskHandler(PlomHttpHandler): unused_tags = file.unused_tags(conn) self._send_rendered_template( _NAME_TEMPLATE_FILE_DATA, - {'file': file, - 'allow_edit': self.server.config.allow_file_edit, + {'allow_edit': self.server.config.allow_file_edit, + 'file': file, 'flag_names': list(FILE_FLAGS), + 'redir_target': self.path, 'unused_tags': unused_tags}) def _send_files_index(self) -> None: diff --git a/src/ytplom/misc.py b/src/ytplom/misc.py index ac017ed..030f2e0 100644 --- a/src/ytplom/misc.py +++ b/src/ytplom/misc.py @@ -708,15 +708,20 @@ class Player: self.playlist[i0]) self._signal_update() - def inject_and_play(self, file: VideoFile) -> None: - """Inject file after current title, then jump to it.""" - if self.playlist: - self._idx += 1 - self.playlist.insert(self._idx, file) + def remove(self, idx: int) -> None: + """Remove from playlist title at idx.""" + if self._mpv: + self._mpv.command('playlist-remove', idx) + self.playlist[idx:idx + 1] = [] + self._signal_update() + + def inject(self, file: VideoFile) -> None: + """Inject file after current title.""" + self.playlist.insert(self._idx + 1, file) if self._mpv: self._mpv.command('loadfile', file.full_path, - 'insert-at', self._idx) - self._play_at_index() + 'insert-at', self._idx + 1) + self._signal_update() class DownloadsManager: -- 2.30.2