Refactor FileItem

This commit is contained in:
Jan Hamal Dvořák 2025-03-09 09:57:24 +01:00
parent 1f32d17d19
commit f89623a201
2 changed files with 44 additions and 52 deletions

View file

@ -3,7 +3,7 @@ from __future__ import annotations
import os
import sys
from pathlib import Path
from typing import Any, cast, overload
from typing import Any, cast
import gi
@ -152,13 +152,13 @@ class MainWindow(Gtk.ApplicationWindow):
self._populate_file_list()
return
position = self._load_attribute("position", 0)
position = file_item.load_attribute("position", 0)
# Start playing the video
full_path = os.path.abspath(file_item.full_path)
self.playbin.set_property("uri", f"file://{full_path}")
track = self._load_attribute("subtitle_track", -2)
track = file_item.load_attribute("subtitle_track", -2)
if track >= 0:
flags = self.playbin.get_property("flags")
@ -207,18 +207,10 @@ class MainWindow(Gtk.ApplicationWindow):
self.set_child(self.stack)
@property
def currently_playing(self):
def selection(self) -> FileItem:
selected_item = self.selection_model.get_selected_item()
if not selected_item:
return None
file_item = cast(FileItem, selected_item)
if file_item.file_type == FileType.DIRECTORY:
return None
return file_item.full_path
assert selected_item
return cast(FileItem, selected_item)
def _setup_list_item(self, factory: Gtk.SignalListItemFactory, list_item: Gtk.ListItem):
# Create horizontal box to hold icon and label
@ -367,46 +359,15 @@ class MainWindow(Gtk.ApplicationWindow):
def _save_position(self) -> None:
"""Save current playback position as xattr"""
file_item = self.selection
assert file_item.file_type != FileType.DIRECTORY
success, position = self.pipeline.query_position(Gst.Format.TIME)
success2, duration = self.pipeline.query_duration(Gst.Format.TIME)
if success and success2:
self._save_attribute("position", position)
self._save_attribute("duration", duration)
def _save_attribute(self, name: str, value: str | float | int | None):
path = self.currently_playing
if path is None:
return
try:
if value is None:
os.removexattr(path, f"user.lazy_player.{name}")
else:
os.setxattr(path, f"user.lazy_player.{name}", str(value).encode("utf8"))
except OSError as err:
print(err, file=sys.stderr)
@overload
def _load_attribute(self, name: str, dfl: str) -> str: ...
@overload
def _load_attribute(self, name: str, dfl: int) -> int: ...
def _load_attribute(self, name: str, dfl: str | int) -> str | int:
path = self.currently_playing
if path is None:
return dfl
try:
strval = os.getxattr(path, f"user.lazy_player.{name}")
return type(dfl)(strval)
except OSError as err:
print(err, file=sys.stderr)
return dfl
file_item.save_attribute("position", position)
file_item.save_attribute("duration", duration)
def _cycle_subtitles(self) -> None:
"""Cycle through available subtitle tracks, including off state"""
@ -427,7 +388,9 @@ class MainWindow(Gtk.ApplicationWindow):
self.playbin.set_property("current-text", 0)
track_info = self._get_subtitle_info(0)
self.show_overlay_text(f"Subtitle track: {track_info}")
self._save_attribute("subtitle_track", 0)
file_item = self.selection
assert file_item.file_type != FileType.DIRECTORY
file_item.save_attribute("subtitle_track", 0)
return
# If we're on the last track, disable subtitles
@ -435,7 +398,9 @@ class MainWindow(Gtk.ApplicationWindow):
flags &= ~0x00000004 # TEXT flag
self.playbin.set_property("flags", flags)
self.show_overlay_text("Subtitles: Off")
self._save_attribute("subtitle_track", -1)
file_item = self.selection
assert file_item.file_type != FileType.DIRECTORY
file_item.save_attribute("subtitle_track", -1)
return
# Otherwise cycle to next track
@ -443,7 +408,9 @@ class MainWindow(Gtk.ApplicationWindow):
self.playbin.set_property("current-text", next_track)
track_info = self._get_subtitle_info(next_track)
self.show_overlay_text(f"Subtitle track: {track_info}")
self._save_attribute("subtitle_track", next_track)
file_item = self.selection
assert file_item.file_type != FileType.DIRECTORY
file_item.save_attribute("subtitle_track", next_track)
def show_overlay_text(self, text: str, timeout_seconds: float = 1.0) -> None:
"""Show text in a centered overlay that disappears after timeout"""

View file

@ -1,7 +1,9 @@
from __future__ import annotations
import os
import sys
from enum import Enum, auto
from typing import overload
import gi
@ -39,3 +41,26 @@ class FileItem(GObject.Object):
return FileItem(name, FileType.VIDEO, path)
raise ValueError(f"Unsupported file type: {path}")
@overload
def load_attribute(self, name: str, dfl: str) -> str: ...
@overload
def load_attribute(self, name: str, dfl: int) -> int: ...
def load_attribute(self, name: str, dfl: str | int) -> str | int:
try:
strval = os.getxattr(self.full_path, f"user.lazy_player.{name}")
return type(dfl)(strval)
except OSError as err:
print(err, file=sys.stderr)
return dfl
def save_attribute(self, name: str, value: str | float | int | None) -> None:
try:
if value is None:
os.removexattr(self.full_path, f"user.lazy_player.{name}")
else:
os.setxattr(self.full_path, f"user.lazy_player.{name}", str(value).encode("utf8"))
except OSError as err:
print(err, file=sys.stderr)