Check tracks for readability

Check on load and on setting next track. Also provide info popup that
shows path.
This commit is contained in:
Keith Edmunds 2021-08-10 08:18:05 +01:00
parent 61e1fb1192
commit bc54be237b
3 changed files with 68 additions and 10 deletions

View File

@ -14,6 +14,7 @@ class Config(object):
COLOUR_NEXT_PLAYLIST = "#ffc107" COLOUR_NEXT_PLAYLIST = "#ffc107"
COLOUR_NOTES_PLAYLIST = "#b8daff" COLOUR_NOTES_PLAYLIST = "#b8daff"
COLOUR_PREVIOUS_HEADER = "#f8d7da" COLOUR_PREVIOUS_HEADER = "#f8d7da"
COLOUR_UNREADABLE = "#dc3545"
COLOUR_WARNING_TIMER = "#ffc107" COLOUR_WARNING_TIMER = "#ffc107"
DBFS_FADE = -12 DBFS_FADE = -12
DBFS_SILENCE = -50 DBFS_SILENCE = -50

View File

@ -291,6 +291,11 @@ class Window(QMainWindow, Ui_MainWindow):
self.previous_track_position = self.music.fade() self.previous_track_position = self.music.fade()
self.end_of_track_actions() self.end_of_track_actions()
def file_is_readable(self, path):
"Return True if path is readable else False"
return os.access(self.next_track.path, os.R_OK)
def insert_note(self): def insert_note(self):
"Add non-track row to playlist" "Add non-track row to playlist"
@ -415,7 +420,7 @@ class Window(QMainWindow, Ui_MainWindow):
self.next_track = Tracks.get_track(session, next_track_id) self.next_track = Tracks.get_track(session, next_track_id)
self.next_track_playlist_tab = self.current_track_playlist_tab self.next_track_playlist_tab = self.current_track_playlist_tab
# Check we can read it # Check we can read it
if not os.access(self.next_track.path, os.R_OK): if not self.file_is_readable(self.next_track.path, os.R_OK):
self.show_warning( self.show_warning(
"Can't read next track", "Can't read next track",
self.next_track.path) self.next_track.path)

View File

@ -155,6 +155,8 @@ class PlaylistTab(QTableWidget):
self.menu.addSeparator() self.menu.addSeparator()
act_delete = self.menu.addAction('Delete') act_delete = self.menu.addAction('Delete')
act_delete.triggered.connect(lambda: self._delete_row(row)) act_delete.triggered.connect(lambda: self._delete_row(row))
act_delete = self.menu.addAction('Info')
act_delete.triggered.connect(lambda: self._info_row(row))
return super(PlaylistTab, self).eventFilter(source, event) return super(PlaylistTab, self).eventFilter(source, event)
@ -274,6 +276,9 @@ class PlaylistTab(QTableWidget):
# Scroll to new row # Scroll to new row
self.scrollToItem(titleitem, QAbstractItemView.PositionAtCenter) self.scrollToItem(titleitem, QAbstractItemView.PositionAtCenter)
if not self._track_path_is_readable(track.id):
self._meta_set_unreadable(row)
if repaint: if repaint:
self._save_playlist(session) self._save_playlist(session)
self._repaint(clear_selection=False) self._repaint(clear_selection=False)
@ -529,11 +534,6 @@ class PlaylistTab(QTableWidget):
duration = Tracks.get_duration(session, self._get_row_id(row)) duration = Tracks.get_duration(session, self._get_row_id(row))
return start + timedelta(milliseconds=duration) return start + timedelta(milliseconds=duration)
def _can_read_track(self, track):
"Check track file is readable"
return os.access(track.path, os.R_OK)
def _context_menu(self, pos): def _context_menu(self, pos):
self.menu.exec_(self.mapToGlobal(pos)) self.menu.exec_(self.mapToGlobal(pos))
@ -608,6 +608,30 @@ class PlaylistTab(QTableWidget):
except ValueError: except ValueError:
return None return None
def _info_row(self, row):
"Display popup with info re row"
id = self._get_row_id(row)
if row in self._meta_get_notes():
note_text = self.item(row, self.COL_TITLE).text()
txt = f"Note: {note_text}"
else:
with Session() as session:
track = Tracks.get_track(session, id)
if not track:
txt = f"Track not found (track.id={id})"
else:
txt = f"""
Title: {track.title}\n
Artist: {track.artist}\n
Path: {track.path}"""
info = QMessageBox(self)
info.setIcon(QMessageBox.Information)
info.setText(txt)
info.setStandardButtons(QMessageBox.Ok)
info.setDefaultButton(QMessageBox.Cancel)
info.exec()
def _is_below(self, pos, index): def _is_below(self, pos, index):
rect = self.visualRect(index) rect = self.visualRect(index)
margin = 2 margin = 2
@ -724,6 +748,11 @@ class PlaylistTab(QTableWidget):
return self._meta_find("note", one=False) return self._meta_find("note", one=False)
def _meta_get_unreadable(self):
"Return rows marked as unreadable, or None"
return self._meta_find("unreadable", one=False)
def _meta_set_current(self, row): def _meta_set_current(self, row):
"Mark row as current track" "Mark row as current track"
@ -745,6 +774,11 @@ class PlaylistTab(QTableWidget):
self._meta_set(row, "note") self._meta_set(row, "note")
def _meta_set_unreadable(self, row):
"Mark row as unreadable"
self._meta_set(row, "unreadable")
def _meta_set(self, row, metadata): def _meta_set(self, row, metadata):
"Set row metadata" "Set row metadata"
@ -763,8 +797,9 @@ class PlaylistTab(QTableWidget):
def _set_next(self, row): def _set_next(self, row):
""" """
If passed row is track row, set that track as the next track to If passed row is track row, check track is readable and, if it is,
be played and return track_id. Otherwise return None. set that track as the next track to be played and return track_id.
Otherwise return None.
""" """
DEBUG(f"_set_next({row})") DEBUG(f"_set_next({row})")
@ -774,9 +809,12 @@ class PlaylistTab(QTableWidget):
track_id = self._get_row_id(row) track_id = self._get_row_id(row)
if track_id: if track_id:
self._meta_set_next(self.currentRow()) if self._track_path_is_readable(track_id):
self._meta_set_next(self.currentRow())
self.master_process.set_next_track(track_id)
else:
self._meta_set_unreadable(self.currentRow())
self._repaint() self._repaint()
self.master_process.set_next_track(track_id)
def _repaint(self, clear_selection=True): def _repaint(self, clear_selection=True):
"Set row colours, fonts, etc" "Set row colours, fonts, etc"
@ -793,6 +831,7 @@ class PlaylistTab(QTableWidget):
current = self._meta_get_current() current = self._meta_get_current()
next = self._meta_get_next() next = self._meta_get_next()
notes = self._meta_get_notes() notes = self._meta_get_notes()
unreadable = self._meta_get_unreadable()
# Set colours and start times # Set colours and start times
next_start_time = None next_start_time = None
@ -813,6 +852,13 @@ class PlaylistTab(QTableWidget):
) )
self._set_row_bold(row) self._set_row_bold(row)
elif row in unreadable:
# Set colour
self._set_row_colour(
row, QColor(Config.COLOUR_UNREADABLE)
)
self._set_row_bold(row)
elif row == current: elif row == current:
# Set start time # Set start time
self._set_row_start_time( self._set_row_start_time(
@ -990,3 +1036,9 @@ class PlaylistTab(QTableWidget):
time_str = "" time_str = ""
item = QTableWidgetItem(time_str) item = QTableWidgetItem(time_str)
self.setItem(row, self.COL_START_TIME, item) self.setItem(row, self.COL_START_TIME, item)
def _track_path_is_readable(self, track_id):
"Returns True if track path is readable, else False"
with Session() as session:
return os.access(Tracks.get_path(session, track_id), os.R_OK)