home · contact · privacy
Remove playlist manipulation form from /playlist, turn play buttons in /file and...
authorChristian Heller <c.heller@plomlompom.de>
Mon, 17 Feb 2025 01:21:28 +0000 (02:21 +0100)
committerChristian Heller <c.heller@plomlompom.de>
Mon, 17 Feb 2025 01:21:28 +0000 (02:21 +0100)
src/templates/file_data.tmpl
src/templates/files.tmpl
src/templates/playlist.tmpl
src/ytplom/http.py
src/ytplom/misc.py

index c3f4dc8fe8713b7f43e6726c9aab1bff80b20478..634f41a5f1723070c9c74a3ffb103134475f509c 100644 (file)
@@ -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>
index 70c087786b0f3b434b8a948f7c586530effc3a73..d78805b4c9d49d6c21cb4c3ef5cac86861de7ca4 100644 (file)
@@ -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 %}
index 669e723a8dcb5c5f72b90a82abaa239cca09f29d..9d4aa22f0c3ba7052df8f322fc47e1e46d121382 100644 (file)
@@ -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 %}
-
index 15e3a465918f8b88b4db4cbc0109929c60d06467..a47a4e65b64951291657a3e6080c21ab82e80cc9 100644 (file)
@@ -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:
index ac017ede9e1c6c8054f626c32bac74c1c69af602..030f2e0ea7d763ec42da9f600dfcc139325dc005 100644 (file)
@@ -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: