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_NOTES_PLAYLIST = "#b8daff"
COLOUR_PREVIOUS_HEADER = "#f8d7da"
COLOUR_UNREADABLE = "#dc3545"
COLOUR_WARNING_TIMER = "#ffc107"
DBFS_FADE = -12
DBFS_SILENCE = -50

View File

@ -291,6 +291,11 @@ class Window(QMainWindow, Ui_MainWindow):
self.previous_track_position = self.music.fade()
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):
"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_playlist_tab = self.current_track_playlist_tab
# 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(
"Can't read next track",
self.next_track.path)

View File

@ -155,6 +155,8 @@ class PlaylistTab(QTableWidget):
self.menu.addSeparator()
act_delete = self.menu.addAction('Delete')
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)
@ -274,6 +276,9 @@ class PlaylistTab(QTableWidget):
# Scroll to new row
self.scrollToItem(titleitem, QAbstractItemView.PositionAtCenter)
if not self._track_path_is_readable(track.id):
self._meta_set_unreadable(row)
if repaint:
self._save_playlist(session)
self._repaint(clear_selection=False)
@ -529,11 +534,6 @@ class PlaylistTab(QTableWidget):
duration = Tracks.get_duration(session, self._get_row_id(row))
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):
self.menu.exec_(self.mapToGlobal(pos))
@ -608,6 +608,30 @@ class PlaylistTab(QTableWidget):
except ValueError:
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):
rect = self.visualRect(index)
margin = 2
@ -724,6 +748,11 @@ class PlaylistTab(QTableWidget):
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):
"Mark row as current track"
@ -745,6 +774,11 @@ class PlaylistTab(QTableWidget):
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):
"Set row metadata"
@ -763,8 +797,9 @@ class PlaylistTab(QTableWidget):
def _set_next(self, row):
"""
If passed row is track row, set that track as the next track to
be played and return track_id. Otherwise return None.
If passed row is track row, check track is readable and, if it is,
set that track as the next track to be played and return track_id.
Otherwise return None.
"""
DEBUG(f"_set_next({row})")
@ -774,9 +809,12 @@ class PlaylistTab(QTableWidget):
track_id = self._get_row_id(row)
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.master_process.set_next_track(track_id)
def _repaint(self, clear_selection=True):
"Set row colours, fonts, etc"
@ -793,6 +831,7 @@ class PlaylistTab(QTableWidget):
current = self._meta_get_current()
next = self._meta_get_next()
notes = self._meta_get_notes()
unreadable = self._meta_get_unreadable()
# Set colours and start times
next_start_time = None
@ -813,6 +852,13 @@ class PlaylistTab(QTableWidget):
)
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:
# Set start time
self._set_row_start_time(
@ -990,3 +1036,9 @@ class PlaylistTab(QTableWidget):
time_str = ""
item = QTableWidgetItem(time_str)
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)