Compare commits
3 Commits
35f2b9629b
...
976beade85
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
976beade85 | ||
|
|
bc54be237b | ||
|
|
61e1fb1192 |
@ -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
|
||||||
|
|||||||
@ -18,6 +18,8 @@ def get_relative_date(past_date, reference_date=None):
|
|||||||
return "get_relative_date() past_date is after relative_date"
|
return "get_relative_date() past_date is after relative_date"
|
||||||
|
|
||||||
weeks, days = divmod((reference_date - past_date).days, 7)
|
weeks, days = divmod((reference_date - past_date).days, 7)
|
||||||
|
if weeks == days == 0:
|
||||||
|
return "Today"
|
||||||
return f"{weeks} weeks, {days} days ago"
|
return f"{weeks} weeks, {days} days ago"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
11
app/model.py
11
app/model.py
@ -317,10 +317,17 @@ class PlaylistTracks(Base):
|
|||||||
else:
|
else:
|
||||||
# Destination playlist has tracks; add to end
|
# Destination playlist has tracks; add to end
|
||||||
new_row = max_row + 1
|
new_row = max_row + 1
|
||||||
|
try:
|
||||||
record = session.query(PlaylistTracks).filter(
|
record = session.query(PlaylistTracks).filter(
|
||||||
PlaylistTracks.playlist_id == from_playlist_id,
|
PlaylistTracks.playlist_id == from_playlist_id,
|
||||||
PlaylistTracks.row == row
|
PlaylistTracks.row == row).one()
|
||||||
).one()
|
except NoResultFound:
|
||||||
|
# Issue #38?
|
||||||
|
ERROR(
|
||||||
|
f"No rows matched in query: "
|
||||||
|
f"PlaylistTracks.playlist_id == {from_playlist_id}, "
|
||||||
|
f"PlaylistTracks.row == {row}"
|
||||||
|
)
|
||||||
record.playlist_id = to_playlist_id
|
record.playlist_id = to_playlist_id
|
||||||
record.row = new_row
|
record.row = new_row
|
||||||
session.commit()
|
session.commit()
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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:
|
||||||
|
if self._track_path_is_readable(track_id):
|
||||||
self._meta_set_next(self.currentRow())
|
self._meta_set_next(self.currentRow())
|
||||||
self._repaint()
|
|
||||||
self.master_process.set_next_track(track_id)
|
self.master_process.set_next_track(track_id)
|
||||||
|
else:
|
||||||
|
self._meta_set_unreadable(self.currentRow())
|
||||||
|
self._repaint()
|
||||||
|
|
||||||
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)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user