home · contact · privacy
Add file tagging. master
authorChristian Heller <c.heller@plomlompom.de>
Tue, 3 Dec 2024 04:21:16 +0000 (05:21 +0100)
committerChristian Heller <c.heller@plomlompom.de>
Tue, 3 Dec 2024 04:21:16 +0000 (05:21 +0100)
src/migrations/6_add_files_tags.sql [new file with mode: 0644]
src/migrations/new_init.sql
src/templates/file_data.tmpl
src/ytplom/db.py
src/ytplom/http.py
src/ytplom/migrations.py
src/ytplom/misc.py

diff --git a/src/migrations/6_add_files_tags.sql b/src/migrations/6_add_files_tags.sql
new file mode 100644 (file)
index 0000000..7d70c18
--- /dev/null
@@ -0,0 +1 @@
+ALTER TABLE files ADD COLUMN tags TEXT NOT NULL DEFAULT "";
index 8153a75be0367ddec2c0d65dc1c9f243d7f8ca72..ad116702752b33c976fa9d7380cd93dad19e2b7b 100644 (file)
@@ -29,5 +29,6 @@ CREATE TABLE files (
   flags INTEGER NOT NULL DEFAULT 0,
   yt_id TEXT,
   last_update TEXT NOT NULL,
+  tags TEXT NOT NULL DEFAULT "",
   FOREIGN KEY (yt_id) REFERENCES yt_videos(id)
 );
index ceb6c2ac31a115bb7e93e36dc7d76ae74c3f41e1..e0d415d97e238e51f1ba62358ef243b6ae4f4d3d 100644 (file)
@@ -14,11 +14,23 @@ td.flags { text-align: right; }
 <tr><th>path:</th><td>{{file.rel_path}}</td></tr>
 <tr><th>YouTube ID:</th><td><a href="/{{page_names.yt_result}}/{{file.yt_id}}">{{file.yt_id}}</a></tr>
 <tr><th>present:</th><td>{% if file.present %}<a href="/{{page_names.download}}/{{file.yt_id}}">yes</a>{% else %}no{% endif %}</td></tr>
-<tr><th>flags:</th><td class="flags">
+<tr>
+<th>flags:</th>
+<td class="flags">
 {% for flag_name in flag_names %}
-{{ flag_name }}: <input type="checkbox" name="{{flag_name}}" {% if file.is_flag_set(flag_name) %}checked {% endif %} /><br />
+{{ flag_name }}: <input type="checkbox" name="flags" value="{{flag_name}}" {% if file.is_flag_set(flag_name) %}checked {% endif %} /><br />
 {% endfor %}
-</td></tr>
+</td>
+</tr>
+<tr>
+<th>tags</th>
+<td>
+{% for tag in file.tags %}
+<input type="checkbox" name="tags" value="{{tag}}" checked /> {{tag}}<br />
+{% endfor %}
+<input name="tags" />
+</td>
+</tr>
 </table>
 <input type="submit" />
 </form>
index 30d84fc1bfffff70acdc16f4ef66a1a2cde6fa4e..549df4a8270bf7692bc853571ef52456651587fa 100644 (file)
@@ -10,7 +10,7 @@ from ytplom.primitives import (
 
 SqlText = NewType('SqlText', str)
 
-EXPECTED_DB_VERSION = 5
+EXPECTED_DB_VERSION = 6
 PATH_DB = PATH_APP_DATA.joinpath('db.sql')
 SQL_DB_VERSION = SqlText('PRAGMA user_version')
 PATH_MIGRATIONS = PATH_APP_DATA.joinpath('migrations')
index f4d394def80c9b847ec5b8a16ddf4eb10231edc3..08ca629e57833ec3f5ff67a15163581db08cf3d2 100644 (file)
@@ -106,8 +106,8 @@ class _TaskHandler(BaseHTTPRequestHandler):
         if PAGE_NAMES['files'] == page_name:
             self._receive_files_command(list(postvars.keys())[0])
         elif PAGE_NAMES['file'] == page_name:
-            self._receive_video_flag(Hash.from_b64(toks_url[2]),
-                                     [FlagName(k) for k in postvars])
+            self._receive_file_data(Hash.from_b64(toks_url[2]),
+                                    postvars)
         elif PAGE_NAMES['yt_queries'] == page_name:
             self._receive_yt_query(QueryText(postvars['query'][0]))
 
@@ -139,13 +139,15 @@ class _TaskHandler(BaseHTTPRequestHandler):
             self.server.player.inject_and_play(file)
         self._redirect(Path('/'))
 
-    def _receive_video_flag(self,
-                            digest: Hash,
-                            flag_names: list[FlagName]
-                            ) -> None:
+    def _receive_file_data(self,
+                           digest: Hash,
+                           postvars: dict[str, list[str]]
+                           ) -> None:
+        flag_names = [FlagName(f) for f in postvars.get('flags', [])]
         with DbConn() as conn:
             file = VideoFile.get_one(conn, digest)
             file.set_flags([FILE_FLAGS[name] for name in flag_names])
+            file.tags = postvars.get('tags', [])
             file.save(conn)
             conn.commit()
         file.ensure_absence_if_deleted()
index ccda307b97f22da3a6d14701ecaac72236a25742..2c9c1e8baa94f564786e641e62d6b892cb1b7cec 100644 (file)
@@ -115,5 +115,6 @@ MIGRATIONS = [
     _Migration(2, Path('2_add_files_sha512.sql'), _mig_2_calc_digests),
     _Migration(3, Path('3_files_redo.sql')),
     _Migration(4, Path('4_add_files_sha512_blob.sql'), _mig_4_convert_digests),
-    _Migration(5, Path('5_files_redo.sql'))
+    _Migration(5, Path('5_files_redo.sql')),
+    _Migration(6, Path('6_add_files_tags.sql'))
 ]
index 0dc4a9d35617d0b22697ea002a2b9a3e0e700b72..b8605d33bc98c72c6ca03e7fcb13ae62ceca8c6f 100644 (file)
@@ -246,7 +246,7 @@ class VideoFile(DbData):
     """Collects data about downloaded files."""
     id_name = 'digest'
     _table_name = 'files'
-    _cols = ('digest', 'rel_path', 'flags', 'yt_id', 'last_update')
+    _cols = ('digest', 'rel_path', 'flags', 'yt_id', 'last_update', 'tags_str')
     last_update: DatetimeStr
     rel_path: Path
     digest: Hash
@@ -256,12 +256,14 @@ class VideoFile(DbData):
                  rel_path: Path,
                  flags: FlagsInt = FlagsInt(0),
                  yt_id: Optional[YoutubeId] = None,
-                 last_update: Optional[DatetimeStr] = None
+                 last_update: Optional[DatetimeStr] = None,
+                 tags_str: str = ''
                  ) -> None:
         self.rel_path = rel_path
         self.digest = digest if digest else Hash.from_file(self.full_path)
-        self.yt_id = yt_id
         self.flags = flags
+        self.tags = tags_str.split(',') if tags_str else []
+        self.yt_id = yt_id
         if last_update is None:
             self._renew_last_update()
         else:
@@ -279,6 +281,11 @@ class VideoFile(DbData):
             raise NotFoundException(f'no entry for file to Youtube ID {yt_id}')
         return cls._from_table_row(row)
 
+    @property
+    def tags_str(self):
+        """Return self.tags joined by ','."""
+        return ','.join(self.tags)
+
     @property
     def full_path(self) -> Path:
         """Return self.rel_path suffixed under PATH_DOWNLOADS."""