diff --git a/app/helpers.py b/app/helpers.py index 579cc11..0a019e5 100644 --- a/app/helpers.py +++ b/app/helpers.py @@ -59,13 +59,14 @@ def fade_point( return int(trim_ms) -def file_is_readable(path: str) -> bool: +def file_is_readable(path: Optional[str]) -> bool: """ Returns True if passed path is readable, else False - - vlc cannot read files with a colon in the path """ + if not path: + return False + return os.access(path, os.R_OK) diff --git a/app/playlists.py b/app/playlists.py index 6429e31..06eae60 100644 --- a/app/playlists.py +++ b/app/playlists.py @@ -38,7 +38,7 @@ from PyQt5.QtWidgets import ( ) from config import Config -from dbconfig import Session +from dbconfig import Session, scoped_session from helpers import ( ask_yes_no, file_is_readable, @@ -126,7 +126,7 @@ class PlaylistTab(QTableWidget): ROW_DURATION = Qt.UserRole + 2 PLAYLISTROW_ID = Qt.UserRole + 3 - def __init__(self, musicmuster: QMainWindow, session: Session, + def __init__(self, musicmuster: QMainWindow, session: scoped_session, playlist_id: int, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self.musicmuster = musicmuster @@ -554,7 +554,7 @@ class PlaylistTab(QTableWidget): return [self._get_playlistrow_id(a) for a in self._get_selected_rows()] - def get_selected_playlistrows(self, session: Session) -> Optional[List]: + def get_selected_playlistrows(self, session: scoped_session) -> Optional[List]: """ Return a list of PlaylistRows of the selected rows """ @@ -562,7 +562,7 @@ class PlaylistTab(QTableWidget): plr_ids = self.get_selected_playlistrow_ids() return [session.get(PlaylistRows, a) for a in plr_ids] - def insert_header(self, session: Session, note: str, + def insert_header(self, session: scoped_session, note: str, repaint: bool = True) -> None: """ Insert section header into playlist tab. @@ -579,7 +579,7 @@ class PlaylistTab(QTableWidget): self.insert_row(session, plr, repaint) self.save_playlist(session) - def insert_row(self, session: Session, plr: PlaylistRows, + def insert_row(self, session: scoped_session, plr: PlaylistRows, repaint: bool = True) -> None: """ Insert passed playlist row (plr) into playlist tab. @@ -668,7 +668,7 @@ class PlaylistTab(QTableWidget): if repaint: self.update_display(session) - def insert_track(self, session: Session, track: Tracks, + def insert_track(self, session: scoped_session, track: Tracks, note: str = None, repaint: bool = True) -> None: """ Insert track into playlist tab. @@ -705,7 +705,7 @@ class PlaylistTab(QTableWidget): # Let display update, then save playlist QTimer.singleShot(0, lambda: self.save_playlist(session)) - def play_started(self, session: Session) -> None: + def play_started(self, session: scoped_session) -> None: """ Notification from musicmuster that track has started playing. @@ -719,6 +719,10 @@ class PlaylistTab(QTableWidget): """ search_from = self._get_current_track_row_number() + 1 + + # Mark current row as played + self._set_played_row(session, current_row) + next_row = self._find_next_track_row(session, search_from) if next_row: self._set_next(session, next_row) @@ -726,7 +730,7 @@ class PlaylistTab(QTableWidget): # Update display self.update_display(session) - def populate_display(self, session: Session, playlist_id: int, + def populate_display(self, session: scoped_session, playlist_id: int, scroll_to_top: bool = True) -> None: """ Populate display from the associated playlist ID @@ -775,7 +779,7 @@ class PlaylistTab(QTableWidget): # Reset drag mode self.setDragEnabled(False) - def save_playlist(self, session: Session) -> None: + def save_playlist(self, session: scoped_session) -> None: """ Get the PlaylistRow objects for each row in the display. Correct the row_number and playlist_id if necessary. Remove any row @@ -941,7 +945,7 @@ class PlaylistTab(QTableWidget): with Session() as session: self.update_display(session) - def update_display(self, session: Session) -> None: + def update_display(self, session: scoped_session) -> None: """ Set row colours, fonts, etc @@ -1263,7 +1267,7 @@ class PlaylistTab(QTableWidget): return (index.row() + 1 if self._is_below(event.pos(), index) else index.row()) - def _find_next_track_row(self, session: Session, + def _find_next_track_row(self, session: scoped_session, starting_row: int = None) -> Optional[int]: """ Find next track to play. If a starting row is given, start there; @@ -1344,7 +1348,7 @@ class PlaylistTab(QTableWidget): return playlistrow_id - def _get_playlistrow_object(self, session: Session, row: int) -> int: + def _get_playlistrow_object(self, session: scoped_session, row: int) -> int: """Return the playlistrow object associated with this row""" playlistrow_id = (self.item(row, USERDATA).data(self.PLAYLISTROW_ID)) @@ -1515,7 +1519,7 @@ class PlaylistTab(QTableWidget): ) raise AttributeError(f"Multiple '{metadata}' metadata {matches}") - def _move_row(self, session: Session, plr: PlaylistRows, + def _move_row(self, session: scoped_session, plr: PlaylistRows, new_row_number: int) -> None: """Move playlist row to new_row_number using parent copy/paste""" @@ -1726,7 +1730,7 @@ class PlaylistTab(QTableWidget): else: self.musicmuster.lblSumPlaytime.setText("") - def _set_column_widths(self, session: Session) -> None: + def _set_column_widths(self, session: scoped_session) -> None: """Column widths from settings""" for column_name, data in columns.items(): @@ -1742,7 +1746,7 @@ class PlaylistTab(QTableWidget): else: self.setColumnWidth(idx, Config.DEFAULT_COLUMN_WIDTH) - def _set_next(self, session: Session, row_number: int) -> None: + def _set_next(self, session: scoped_session, row_number: int) -> None: """ Set passed row as next playlist row to play. @@ -1777,10 +1781,13 @@ class PlaylistTab(QTableWidget): self.clear_selection() self.update_display(session) - def _set_played_row(self, session: Session, row: int) -> None: + def _set_played_row(self, session: scoped_session, row: int) -> None: """Mark this row as played""" plr = session.get(PlaylistRows, self._get_playlistrow_id(row)) + if not plr: + return + plr.played = True session.commit()