Compare commits

..

No commits in common. "f22f209beeaa0d92347c620e17f6cc44e7cb5243" and "ca1b11b5458b594b7c37955e35401997e5835834" have entirely different histories.

2 changed files with 48 additions and 58 deletions

View File

@ -315,35 +315,32 @@ class Window(QMainWindow, Ui_MainWindow):
if not self.visible_playlist_tab(): if not self.visible_playlist_tab():
return return
with Session() as session: # Get output filename
playlist = Playlists.get_by_id( pathspec: Tuple[str, str] = QFileDialog.getSaveFileName(
session, self.visible_playlist_tab().playlist_id) self, 'Save Playlist',
# Get output filename directory=f"{self.visible_playlist_tab().name}.m3u",
pathspec: Tuple[str, str] = QFileDialog.getSaveFileName( filter="M3U files (*.m3u);;All files (*.*)"
self, 'Save Playlist', )
directory=f"{playlist.name}.m3u", if not pathspec:
filter="M3U files (*.m3u);;All files (*.*)" return
)
if not pathspec:
return
path: str = pathspec[0] path: str = pathspec[0]
if not path.endswith(".m3u"): if not path.endswith(".m3u"):
path += ".m3u" path += ".m3u"
with open(path, "w") as f: with open(path, "w") as f:
# Required directive on first line # Required directive on first line
f.write("#EXTM3U\n") f.write("#EXTM3U\n")
for _, track in playlist.tracks.items(): for track in self.playlist.tracks:
f.write( f.write(
"#EXTINF:" "#EXTINF:"
f"{int(track.duration / 1000)}," f"{int(track.duration / 1000)},"
f"{track.title} - " f"{track.title} - "
f"{track.artist}" f"{track.artist}"
"\n" "\n"
f"{track.path}" f"{track.path}"
"\n" "\n"
) )
def fade(self) -> None: def fade(self) -> None:
"""Fade currently playing track""" """Fade currently playing track"""

View File

@ -268,7 +268,7 @@ class PlaylistTab(QTableWidget):
set note row to be end of playlist. set note row to be end of playlist.
""" """
row: Optional[int] = self.get_selected_row() row: int = self.get_selected_row()
if not row: if not row:
row = self.rowCount() row = self.rowCount()
@ -277,7 +277,7 @@ class PlaylistTab(QTableWidget):
dlg.setInputMode(QInputDialog.TextInput) dlg.setInputMode(QInputDialog.TextInput)
dlg.setLabelText("Note:") dlg.setLabelText("Note:")
dlg.resize(500, 100) dlg.resize(500, 100)
ok: int = dlg.exec() ok: bool = dlg.exec()
if ok: if ok:
with Session() as session: with Session() as session:
note: Notes = Notes( note: Notes = Notes(
@ -407,8 +407,6 @@ class PlaylistTab(QTableWidget):
# Mark next-track row as current # Mark next-track row as current
current_row = self._get_next_track_row() current_row = self._get_next_track_row()
if not current_row:
return
self._set_current_track_row(current_row) self._set_current_track_row(current_row)
# Mark current row as played # Mark current row as played
@ -658,9 +656,9 @@ class PlaylistTab(QTableWidget):
next_row: Optional[int] = self._get_next_track_row() next_row: Optional[int] = self._get_next_track_row()
notes: List[int] = self._get_notes_rows() notes: List[int] = self._get_notes_rows()
played: Optional[List[int]] = self._get_played_track_rows() played: Optional[List[int]] = self._get_played_track_rows()
unreadable: List[int] = self._get_unreadable_track_rows() unreadable: Optional[List[int]] = self._get_unreadable_track_rows()
last_played_str: str last_played_str: Optional[str]
last_playedtime: Optional[datetime] last_playedtime: Optional[datetime]
next_start_time: Optional[datetime] = None next_start_time: Optional[datetime] = None
note_colour: str note_colour: str
@ -813,8 +811,8 @@ class PlaylistTab(QTableWidget):
open_in_audacity(track.path) open_in_audacity(track.path)
@staticmethod @staticmethod
def _calculate_track_end_time( def _calculate_track_end_time(track: Tracks,
track: Tracks, start: Optional[datetime]) -> Optional[datetime]: start: datetime) -> Optional[datetime]:
"""Return this track's end time given its start time""" """Return this track's end time given its start time"""
if start is None: if start is None:
@ -830,7 +828,7 @@ class PlaylistTab(QTableWidget):
self.menu.exec_(self.mapToGlobal(pos)) self.menu.exec_(self.mapToGlobal(pos))
def _copy_path(self, row: int) -> None: def _copy_path(self, row: int) -> Optional[str]:
""" """
If passed row is track row, copy the track path to the clipboard. If passed row is track row, copy the track path to the clipboard.
Otherwise, return None. Otherwise, return None.
@ -844,7 +842,7 @@ class PlaylistTab(QTableWidget):
with Session() as session: with Session() as session:
track: Optional[Tracks] = self._get_row_track_object(row, session) track: Optional[Tracks] = self._get_row_track_object(row, session)
if track: if track:
cb = QApplication.clipboard() cb: QApplication.clipboard = QApplication.clipboard()
cb.clear(mode=cb.Clipboard) cb.clear(mode=cb.Clipboard)
cb.setText(track.path, mode=cb.Clipboard) cb.setText(track.path, mode=cb.Clipboard)
@ -1037,20 +1035,12 @@ class PlaylistTab(QTableWidget):
def _get_current_track_row(self) -> Optional[int]: def _get_current_track_row(self) -> Optional[int]:
"""Return row marked as current, or None""" """Return row marked as current, or None"""
row = self._meta_search(RowMeta.CURRENT) return self._meta_search(RowMeta.CURRENT)
if len(row) > 0:
return row[0]
else:
return None
def _get_next_track_row(self) -> Optional[int]: def _get_next_track_row(self) -> Optional[int]:
"""Return row marked as next, or None""" """Return row marked as next, or None"""
row = self._meta_search(RowMeta.NEXT) return self._meta_search(RowMeta.NEXT)
if len(row) > 0:
return row[0]
else:
return None
@staticmethod @staticmethod
def _get_note_text_time(text: str) -> Optional[datetime]: def _get_note_text_time(text: str) -> Optional[datetime]:
@ -1132,7 +1122,7 @@ class PlaylistTab(QTableWidget):
return self._meta_notset(RowMeta.NOTE) return self._meta_notset(RowMeta.NOTE)
def _get_unreadable_track_rows(self) -> List[int]: def _get_unreadable_track_rows(self) -> Optional[List[int]]:
"""Return rows marked as unreadable, or None""" """Return rows marked as unreadable, or None"""
return self._meta_search(RowMeta.UNREADABLE, one=False) return self._meta_search(RowMeta.UNREADABLE, one=False)
@ -1238,7 +1228,7 @@ class PlaylistTab(QTableWidget):
if next_row is not None: if next_row is not None:
self._meta_clear_attribute(next_row, RowMeta.NEXT) self._meta_clear_attribute(next_row, RowMeta.NEXT)
def _meta_get(self, row: int) -> int: def _meta_get(self, row: int) -> Optional[int]:
"""Return row metadata""" """Return row metadata"""
return self.item(row, self.COL_USERDATA).data(self.ROW_METADATA) return self.item(row, self.COL_USERDATA).data(self.ROW_METADATA)
@ -1259,7 +1249,8 @@ class PlaylistTab(QTableWidget):
return matches return matches
def _meta_search(self, metadata: int, one: bool = True) -> List[int]: def _meta_search(self, metadata: int, one: bool = True) -> Union[
List[int], int, None]:
""" """
Search rows for metadata. Search rows for metadata.
@ -1278,8 +1269,10 @@ class PlaylistTab(QTableWidget):
if not one: if not one:
return matches return matches
if len(matches) <= 1: if len(matches) == 0:
return matches return None
elif len(matches) == 1:
return matches[0]
else: else:
ERROR( ERROR(
f"Multiple matches for metadata '{metadata}' found " f"Multiple matches for metadata '{metadata}' found "
@ -1295,9 +1288,9 @@ class PlaylistTab(QTableWidget):
current_metadata: int = self._meta_get(row) current_metadata: int = self._meta_get(row)
if not current_metadata: if not current_metadata:
new_metadata: int = (1 << attribute) new_metadata = (1 << attribute)
else: else:
new_metadata = self._meta_get(row) | (1 << attribute) new_metadata: int = self._meta_get(row) | (1 << attribute)
self.item(row, self.COL_USERDATA).setData( self.item(row, self.COL_USERDATA).setData(
self.ROW_METADATA, new_metadata) self.ROW_METADATA, new_metadata)
@ -1406,8 +1399,8 @@ class PlaylistTab(QTableWidget):
- Check row is a track row - Check row is a track row
- Check track is readable - Check track is readable
- Mark as next track - Mark as next track
- Update display
- Notify musicmuster - Notify musicmuster
- Update display
""" """
DEBUG(f"_set_next({row=})") DEBUG(f"_set_next({row=})")
@ -1428,12 +1421,12 @@ class PlaylistTab(QTableWidget):
# Mark as next track # Mark as next track
self._set_next_track_row(row) self._set_next_track_row(row)
# Update display
self.update_display(session)
# Notify musicmuster # Notify musicmuster
self.musicmuster.this_is_the_next_track(self, track) self.musicmuster.this_is_the_next_track(self, track)
# Update display
self.update_display(session)
def _set_row_bold(self, row: int, bold: bool = True) -> None: def _set_row_bold(self, row: int, bold: bool = True) -> None:
"""Make row bold (bold=True) or not bold""" """Make row bold (bold=True) or not bold"""