From b9c34d80e1fb2ff12fc2592166b48aeedbab8f54 Mon Sep 17 00:00:00 2001 From: Christian Heller Date: Tue, 3 Dec 2024 05:21:16 +0100 Subject: [PATCH] Add file tagging. --- src/migrations/6_add_files_tags.sql | 1 + src/migrations/new_init.sql | 1 + src/templates/file_data.tmpl | 18 +++++++++++++++--- src/ytplom/db.py | 2 +- src/ytplom/http.py | 14 ++++++++------ src/ytplom/migrations.py | 3 ++- src/ytplom/misc.py | 13 ++++++++++--- 7 files changed, 38 insertions(+), 14 deletions(-) create mode 100644 src/migrations/6_add_files_tags.sql diff --git a/src/migrations/6_add_files_tags.sql b/src/migrations/6_add_files_tags.sql new file mode 100644 index 0000000..7d70c18 --- /dev/null +++ b/src/migrations/6_add_files_tags.sql @@ -0,0 +1 @@ +ALTER TABLE files ADD COLUMN tags TEXT NOT NULL DEFAULT ""; diff --git a/src/migrations/new_init.sql b/src/migrations/new_init.sql index 8153a75..ad11670 100644 --- a/src/migrations/new_init.sql +++ b/src/migrations/new_init.sql @@ -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) ); diff --git a/src/templates/file_data.tmpl b/src/templates/file_data.tmpl index ceb6c2a..e0d415d 100644 --- a/src/templates/file_data.tmpl +++ b/src/templates/file_data.tmpl @@ -14,11 +14,23 @@ td.flags { text-align: right; } path:{{file.rel_path}} YouTube ID:{{file.yt_id}} present:{% if file.present %}yes{% else %}no{% endif %} -flags: + +flags: + {% for flag_name in flag_names %} -{{ flag_name }}:
+{{ flag_name }}:
{% endfor %} - + + + +tags + +{% for tag in file.tags %} + {{tag}}
+{% endfor %} + + + diff --git a/src/ytplom/db.py b/src/ytplom/db.py index 30d84fc..549df4a 100644 --- a/src/ytplom/db.py +++ b/src/ytplom/db.py @@ -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') diff --git a/src/ytplom/http.py b/src/ytplom/http.py index f4d394d..08ca629 100644 --- a/src/ytplom/http.py +++ b/src/ytplom/http.py @@ -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() diff --git a/src/ytplom/migrations.py b/src/ytplom/migrations.py index ccda307..2c9c1e8 100644 --- a/src/ytplom/migrations.py +++ b/src/ytplom/migrations.py @@ -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')) ] diff --git a/src/ytplom/misc.py b/src/ytplom/misc.py index 0dc4a9d..b8605d3 100644 --- a/src/ytplom/misc.py +++ b/src/ytplom/misc.py @@ -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.""" -- 2.30.2