Check tracks for readability
Check on load and on setting next track. Also provide info popup that shows path.
This commit is contained in:
parent
61e1fb1192
commit
bc54be237b
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user