From: Christian Heller Date: Sat, 23 Nov 2024 08:19:56 +0000 (+0100) Subject: Add file deletion via "delete" flag. X-Git-Url: https://plomlompom.com/repos/%7B%7Bdb.prefix%7D%7D/%7B%7Btodo.comment%7D%7D?a=commitdiff_plain;h=10ba830cdabc8d27f722a7f7dfbfacf22c88df1a;p=ytplom Add file deletion via "delete" flag. --- diff --git a/templates/video.tmpl b/templates/video.tmpl index a0142bb..bcdaabb 100644 --- a/templates/video.tmpl +++ b/templates/video.tmpl @@ -5,7 +5,7 @@ - +
path:{{file.rel_path}}
YouTube ID:{{file.yt_id}}
present:{% if file.missing %}no{% else %}yes{% endif %}
present:{% if file.present %}yes{% else %}no{% endif %}
{% for flag_name in flag_names %} diff --git a/ytplom/misc.py b/ytplom/misc.py index 9e547ec..5d7a2f0 100644 --- a/ytplom/misc.py +++ b/ytplom/misc.py @@ -118,9 +118,7 @@ CREATE TABLE files ( ''' VIDEO_FLAGS: dict[FlagName, FlagsInt] = { - FlagName('foo'): FlagsInt(1 << 0), - FlagName('bar'): FlagsInt(1 << 1), - FlagName('baz'): FlagsInt(1 << 2) + FlagName('delete'): FlagsInt(1 << 62) } @@ -305,7 +303,6 @@ class VideoFile(DbData): self.rel_path = rel_path self.yt_id = yt_id self.flags = flags - self.missing = False @classmethod def get_by_yt_id(cls, conn: DatabaseConnection, yt_id: YoutubeId) -> Self: @@ -316,10 +313,32 @@ class VideoFile(DbData): raise NotFoundException return cls._from_table_row(row) + @property + def full_path(self) -> PathStr: + """Return self.rel_path suffixed under PATH_DOWNLOADS.""" + return PathStr(path_join(PATH_DOWNLOADS, self.rel_path)) + + @property + def present(self) -> bool: + """Return if file exists in filesystem.""" + return path_exists(self.full_path) + + @property + def missing(self) -> bool: + """Return if file absent despite absence of 'delete' flag.""" + return not (self.flag_set(FlagName('delete')) or self.present) + def flag_set(self, flag_name: FlagName) -> bool: """Return if flag of flag_name is set in self.flags.""" return self.flags & VIDEO_FLAGS[flag_name] + def ensure_absence_if_deleted(self) -> None: + """If 'delete' flag set, ensure no actual file in filesystem.""" + if self.flag_set(FlagName('delete')) and path_exists(self.full_path): + print(f'SYNC: {self.rel_path} set "delete", ' + 'removing from filesystem.') + os_remove(self.full_path) + class QuotaLog(DbData): """Collects API access quota costs.""" @@ -509,8 +528,7 @@ class DownloadsDb: file.save(conn) self._files = VideoFile.get_all(conn) for file in self._files: - if not isfile(path_join(file.rel_path)): - file.missing = True + file.ensure_absence_if_deleted() chdir(old_cwd) conn.commit_close() @@ -533,8 +551,7 @@ class DownloadsDb: def ids_to_paths(self) -> DownloadsIndex: """Return mapping YoutubeIds:paths of files downloaded to them.""" self._sync_db() - return {f.yt_id: PathStr(path_join(PATH_DOWNLOADS, f.rel_path)) - for f in self._files} + return {f.yt_id: f.full_path for f in self._files} @property def ids_unfinished(self) -> set[YoutubeId]: @@ -638,6 +655,7 @@ class TaskHandler(BaseHTTPRequestHandler): file.flags |= VIDEO_FLAGS[flag_name] file.save(conn) conn.commit_close() + file.ensure_absence_if_deleted() self._send_http(headers=[('Location', f'/video/{yt_id}')], code=302) def _post_query(self, query_txt: QueryText) -> None: