This commit is contained in:
Keith Edmunds 2025-04-22 21:56:44 +01:00
parent a4ba013306
commit 86c3c3fd80
12 changed files with 115 additions and 103 deletions

View File

@ -29,5 +29,3 @@ class DatabaseManager:
if DatabaseManager.__instance is None:
DatabaseManager(database_url, **kwargs)
return DatabaseManager.__instance

View File

@ -94,7 +94,9 @@ class Playdates(Model):
playdate_id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
lastplayed: Mapped[dt.datetime] = mapped_column(index=True)
track_id: Mapped[int] = mapped_column(ForeignKey("tracks.track_id", ondelete="CASCADE"))
track_id: Mapped[int] = mapped_column(
ForeignKey("tracks.track_id", ondelete="CASCADE")
)
track: Mapped["Tracks"] = relationship(
"Tracks",
back_populates="playdates",
@ -219,8 +221,12 @@ class Queries(Model):
query_id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
name: Mapped[str] = mapped_column(String(128), nullable=False)
_filter_data: Mapped[dict | None] = mapped_column("filter_data", JSONEncodedDict, nullable=False)
favourite: Mapped[bool] = mapped_column(Boolean, nullable=False, index=False, default=False)
_filter_data: Mapped[dict | None] = mapped_column(
"filter_data", JSONEncodedDict, nullable=False
)
favourite: Mapped[bool] = mapped_column(
Boolean, nullable=False, index=False, default=False
)
def _get_filter(self) -> Filter:
"""Convert stored JSON dictionary to a Filter object."""

View File

@ -223,7 +223,9 @@ def _tracks_where(
Tracks.title,
latest_playdate_subq.c.lastplayed,
)
.outerjoin(latest_playdate_subq, Tracks.track_id == latest_playdate_subq.c.track_id)
.outerjoin(
latest_playdate_subq, Tracks.track_id == latest_playdate_subq.c.track_id
)
.where(query)
)
@ -697,7 +699,9 @@ def playlist_mark_status(playlist_id: int, open: bool) -> None:
with db.Session() as session:
session.execute(
update(Playlists).where(Playlists.playlist_id == playlist_id).values(open=open)
update(Playlists)
.where(Playlists.playlist_id == playlist_id)
.values(open=open)
)
session.commit()
@ -744,9 +748,7 @@ def _playlist_move_rows_between_playlists(
# Sanity check destination not being moved
if to_row in from_rows:
log.error(
f"ds._playlist_move_rows_within_playlist: {to_row=} in {from_rows=}"
)
log.error(f"ds._playlist_move_rows_within_playlist: {to_row=} in {from_rows=}")
return
with db.Session() as session:
@ -765,12 +767,8 @@ def _playlist_move_rows_between_playlists(
for from_row in from_rows:
plrid = old_row_to_id[from_row]
update_list.append(
{"id": plrid, "row_number": next_row}
)
update_list.append(
{"id": plrid, "playlist_id": to_playlist_id}
)
update_list.append({"id": plrid, "row_number": next_row})
update_list.append({"id": plrid, "playlist_id": to_playlist_id})
next_row += 1
session.execute(update(PlaylistRows), update_list)
@ -788,8 +786,7 @@ def _playlist_rows_to_id(playlist_id: int) -> dict[int, int]:
"""
row_to_id = {
p.row_number: p.playlistrow_id
for p in playlistrows_by_playlist(playlist_id)
p.row_number: p.playlistrow_id for p in playlistrows_by_playlist(playlist_id)
}
return row_to_id
@ -813,9 +810,7 @@ def _playlist_move_rows_within_playlist(
# Sanity check destination not being moved
if to_row in from_rows:
log.error(
f"ds._playlist_move_rows_within_playlist: {to_row=} in {from_rows=}"
)
log.error(f"ds._playlist_move_rows_within_playlist: {to_row=} in {from_rows=}")
return
with db.Session() as session:
@ -867,7 +862,9 @@ def playlist_rename(playlist_id: int, new_name: str) -> None:
with db.Session() as session:
session.execute(
update(Playlists).where(Playlists.playlist_id == playlist_id).values(name=new_name)
update(Playlists)
.where(Playlists.playlist_id == playlist_id)
.values(name=new_name)
)
session.commit()
@ -994,7 +991,9 @@ def playlist_save_tabs(playlist_id_to_tab: dict[int, int]) -> None:
)
for playlist_id, tab in playlist_id_to_tab.items():
session.execute(
update(Playlists).where(Playlists.playlist_id == playlist_id).values(tab=tab)
update(Playlists)
.where(Playlists.playlist_id == playlist_id)
.values(tab=tab)
)
session.commit()
@ -1024,7 +1023,9 @@ def playlistrow_by_id(playlistrow_id: int) -> PlaylistRowDTO | None:
with db.Session() as session:
record = (
session.execute(
select(PlaylistRows).where(PlaylistRows.playlistrow_id == playlistrow_id)
select(PlaylistRows).where(
PlaylistRows.playlistrow_id == playlistrow_id
)
)
.scalars()
.one_or_none()
@ -1272,7 +1273,9 @@ def query_update_favourite(query_id: int, favourite: bool) -> None:
with db.Session() as session:
session.execute(
update(Queries).where(Queries.query_id == query_id).values(favourite=favourite)
update(Queries)
.where(Queries.query_id == query_id)
.values(favourite=favourite)
)
session.commit()
@ -1291,7 +1294,9 @@ def query_update_name(query_id: int, name: str) -> None:
"""Update query name"""
with db.Session() as session:
session.execute(update(Queries).where(Queries.query_id == query_id).values(name=name))
session.execute(
update(Queries).where(Queries.query_id == query_id).values(name=name)
)
session.commit()

View File

@ -101,9 +101,13 @@ def handle_exception(exc_type, exc_value, exc_traceback):
log.error(logmsg)
else:
# Handle unexpected errors (log and display)
error_msg = "".join(traceback.format_exception(exc_type, exc_value, exc_traceback))
error_msg = "".join(
traceback.format_exception(exc_type, exc_value, exc_traceback)
)
print(stackprinter.format(exc_value, suppressed_paths=['/.venv'], style='darkbg'))
print(
stackprinter.format(exc_value, suppressed_paths=["/.venv"], style="darkbg")
)
stack = stackprinter.format(exc_value)
log.error(stack)
@ -147,6 +151,7 @@ def log_call(func):
except Exception as e:
log.debug(f"exception in {func.__name__}: {e}", stacklevel=2)
raise
return wrapper

View File

@ -179,8 +179,12 @@ class Music:
return
self.events = self.player.event_manager()
self.events.event_attach(vlc.EventType.MediaPlayerEndReached, self.track_end_event_handler)
self.events.event_attach(vlc.EventType.MediaPlayerStopped, self.track_end_event_handler)
self.events.event_attach(
vlc.EventType.MediaPlayerEndReached, self.track_end_event_handler
)
self.events.event_attach(
vlc.EventType.MediaPlayerStopped, self.track_end_event_handler
)
_ = self.player.play()
self.set_volume(self.max_volume)
@ -197,9 +201,7 @@ class Music:
if self.player:
self.player.set_position(position)
def set_volume(
self, volume: int | None = None, set_default: bool = True
) -> None:
def set_volume(self, volume: int | None = None, set_default: bool = True) -> None:
"""Set maximum volume used for player"""
if not self.player:

View File

@ -1742,7 +1742,9 @@ class Window(QMainWindow):
self.signals.signal_set_next_track.connect(self.set_next_track_handler)
self.signals.status_message_signal.connect(self.show_status_message)
self.signals.signal_track_ended.connect(self.track_ended_handler)
self.signals.signal_playlist_selected_rows.connect(self.playlist_selected_rows_handler)
self.signals.signal_playlist_selected_rows.connect(
self.playlist_selected_rows_handler
)
self.timer10.timeout.connect(self.tick_10ms)
self.timer500.timeout.connect(self.tick_500ms)
@ -2562,9 +2564,7 @@ class Window(QMainWindow):
self._active_tab().scroll_to_top(playlist_track.row_number)
def playlist_selected_rows_handler(
self, selected_rows: SelectedRows
) -> None:
def playlist_selected_rows_handler(self, selected_rows: SelectedRows) -> None:
"""
Handle signal_playlist_selected_rows to keep track of which rows
are selected in the current model
@ -2746,7 +2746,7 @@ class Window(QMainWindow):
base_model: PlaylistModel,
proxy_model: PlaylistProxyModel,
playlist_id: int,
selected_row_numbers: list[int]
selected_row_numbers: list[int],
) -> None:
"""
Update self.current when playlist tab changes. Called by new playlist
@ -2756,7 +2756,7 @@ class Window(QMainWindow):
base_model=base_model,
proxy_model=proxy_model,
playlist_id=playlist_id,
selected_row_numbers=selected_row_numbers
selected_row_numbers=selected_row_numbers,
)
def update_headers(self) -> None:

View File

@ -93,11 +93,15 @@ class PlaylistModel(QAbstractTableModel):
self.played_tracks_hidden = False
# Connect signals
self.signals.signal_add_track_to_header.connect(self.signal_add_track_to_header_handler)
self.signals.signal_add_track_to_header.connect(
self.signal_add_track_to_header_handler
)
self.signals.signal_begin_insert_rows.connect(self.begin_insert_rows_handler)
self.signals.signal_end_insert_rows.connect(self.end_insert_rows_handler)
self.signals.signal_insert_track.connect(self.insert_row_signal_handler)
self.signals.signal_playlist_selected_rows.connect(self.playlist_selected_rows_handler)
self.signals.signal_playlist_selected_rows.connect(
self.playlist_selected_rows_handler
)
self.signals.signal_set_next_row.connect(self.set_next_row_handler)
self.signals.signal_track_started.connect(self.track_started_handler)
self.signals.signal_track_ended.connect(self.signal_track_ended_handler)
@ -150,7 +154,9 @@ class PlaylistModel(QAbstractTableModel):
return header_row
# @log_call
def signal_add_track_to_header_handler(self, track_and_playlist: TrackAndPlaylist) -> None:
def signal_add_track_to_header_handler(
self, track_and_playlist: TrackAndPlaylist
) -> None:
"""
Handle signal_add_track_to_header
"""
@ -1547,7 +1553,9 @@ class PlaylistModel(QAbstractTableModel):
current_track_row_number, current_track_start_time
)
if self.update_start_end_times(plr, current_track_start_time, current_track_end_time):
if self.update_start_end_times(
plr, current_track_start_time, current_track_end_time
):
update_rows.append(current_track_row_number)
# If we have a next track, note row number
@ -1582,7 +1590,9 @@ class PlaylistModel(QAbstractTableModel):
# Set start time for next row if we have a current track
if current_track_row_number is not None and row_number == next_track_row:
next_start_time = self.get_end_time(row_number, current_track_end_time)
if self.update_start_end_times(plr, current_track_end_time, next_start_time):
if self.update_start_end_times(
plr, current_track_end_time, next_start_time
):
update_rows.append(row_number)
# If we're between the current and next row, zero out

View File

@ -41,7 +41,7 @@ from classes import (
MusicMusterSignals,
PlaylistStyle,
SelectedRows,
TrackInfo
TrackInfo,
)
from config import Config
from dialogs import TrackInsertDialog
@ -190,9 +190,7 @@ class PlaylistDelegate(QStyledItemDelegate):
# Close editor if no changes have been made
data_modified = False
if isinstance(editor, QTextEdit):
data_modified = (
self.original_model_data != editor.toPlainText()
)
data_modified = self.original_model_data != editor.toPlainText()
elif isinstance(editor, QDoubleSpinBox):
data_modified = (
self.original_model_data != int(editor.value()) * 1000
@ -544,7 +542,9 @@ class PlaylistTab(QTableView):
header_row = self.get_base_model().is_header_row(model_row_number)
track_row = not header_row
if self.track_sequence.current:
this_is_current_row = model_row_number == self.track_sequence.current.row_number
this_is_current_row = (
model_row_number == self.track_sequence.current.row_number
)
else:
this_is_current_row = False
if self.track_sequence.next:
@ -844,7 +844,9 @@ class PlaylistTab(QTableView):
if not selected_indexes:
return []
return sorted(list(set([self.model().mapToSource(a).row() for a in selected_indexes])))
return sorted(
list(set([self.model().mapToSource(a).row() for a in selected_indexes]))
)
# @log_call
def get_top_visible_row(self) -> int:

View File

@ -177,9 +177,7 @@ class MyTestCase(unittest.TestCase):
track = tracks[0]
assert track.title == "I'm So Afraid"
assert track.artist == "Fleetwood Mac"
track_file = os.path.join(
self.musicstore, os.path.basename(test_track_path)
)
track_file = os.path.join(self.musicstore, os.path.basename(test_track_path))
assert track.path == track_file
assert os.path.exists(track_file)
assert os.listdir(self.import_source) == []
@ -222,9 +220,7 @@ class MyTestCase(unittest.TestCase):
track = tracks[1]
assert track.title == "The Lovecats"
assert track.artist == "The Cure"
track_file = os.path.join(
self.musicstore, os.path.basename(test_track_path)
)
track_file = os.path.join(self.musicstore, os.path.basename(test_track_path))
assert track.path == track_file
assert os.path.exists(track_file)
assert os.listdir(self.import_source) == []
@ -275,9 +271,7 @@ class MyTestCase(unittest.TestCase):
assert track.title == "The Lovecats"
assert track.artist == "The Cure"
assert track.track_id == 2
track_file = os.path.join(
self.musicstore, os.path.basename(test_track_path)
)
track_file = os.path.join(self.musicstore, os.path.basename(test_track_path))
assert track.path == track_file
assert os.path.exists(track_file)
assert os.listdir(self.import_source) == []
@ -470,9 +464,7 @@ class MyTestCase(unittest.TestCase):
assert track.title == "The Lovecats xyz"
assert track.artist == "The Cure"
assert track.track_id == 2
track_file = os.path.join(
self.musicstore, os.path.basename(test_track_path)
)
track_file = os.path.join(self.musicstore, os.path.basename(test_track_path))
assert track.path == track_file
assert os.path.exists(track_file)
assert os.listdir(self.import_source) == []

View File

@ -34,7 +34,9 @@ class TestMMMiscTracks(unittest.TestCase):
# Create a playlist and model
self.playlist = ds.playlist_create(PLAYLIST_NAME, template_id=0)
self.model = playlistmodel.PlaylistModel(self.playlist.playlist_id, is_template=False)
self.model = playlistmodel.PlaylistModel(
self.playlist.playlist_id, is_template=False
)
for row in range(len(self.test_tracks)):
track_path = self.test_tracks[row % len(self.test_tracks)]
@ -68,18 +70,12 @@ class TestMMMiscTracks(unittest.TestCase):
self.model.selected_rows = [self.model.playlist_rows[START_ROW]]
self.model.insert_row_signal_handler(
InsertTrack(
playlist_id=self.playlist.playlist_id,
track_id=None,
note="start+"
playlist_id=self.playlist.playlist_id, track_id=None, note="start+"
)
)
self.model.selected_rows = [self.model.playlist_rows[END_ROW]]
self.model.insert_row_signal_handler(
InsertTrack(
playlist_id=self.playlist.playlist_id,
track_id=None,
note="-+"
)
InsertTrack(playlist_id=self.playlist.playlist_id, track_id=None, note="-+")
)
prd = self.model.playlist_rows[START_ROW]
@ -144,7 +140,9 @@ class TestMMMiscRowMove(unittest.TestCase):
db.create_all()
self.playlist = ds.playlist_create(self.PLAYLIST_NAME, template_id=0)
self.model = playlistmodel.PlaylistModel(self.playlist.playlist_id, is_template=False)
self.model = playlistmodel.PlaylistModel(
self.playlist.playlist_id, is_template=False
)
for row in range(self.ROWS_TO_CREATE):
self.model.insert_row_signal_handler(
InsertTrack(
@ -165,9 +163,7 @@ class TestMMMiscRowMove(unittest.TestCase):
assert self.model.rowCount() == self.ROWS_TO_CREATE
self.model.insert_row_signal_handler(
InsertTrack(
playlist_id=self.playlist.playlist_id,
track_id=None,
note=note_text
playlist_id=self.playlist.playlist_id, track_id=None, note=note_text
)
)
assert self.model.rowCount() == self.ROWS_TO_CREATE + 1
@ -192,9 +188,7 @@ class TestMMMiscRowMove(unittest.TestCase):
self.model.insert_row_signal_handler(
InsertTrack(
playlist_id=self.playlist.playlist_id,
track_id=None,
note=note_text
playlist_id=self.playlist.playlist_id, track_id=None, note=note_text
)
)
assert self.model.rowCount() == self.ROWS_TO_CREATE + 1
@ -214,9 +208,7 @@ class TestMMMiscRowMove(unittest.TestCase):
self.model.insert_row_signal_handler(
InsertTrack(
playlist_id=self.playlist.playlist_id,
track_id=None,
note=note_text
playlist_id=self.playlist.playlist_id, track_id=None, note=note_text
)
)
assert self.model.rowCount() == self.ROWS_TO_CREATE + 1
@ -257,13 +249,13 @@ class TestMMMiscRowMove(unittest.TestCase):
for row in range(self.ROWS_TO_CREATE):
model_dst.insert_row_signal_handler(
InsertTrack(
playlist_id=playlist_dst.playlist_id,
track_id=None,
note=str(row)
playlist_id=playlist_dst.playlist_id, track_id=None, note=str(row)
)
)
model_src.move_rows_between_playlists(from_rows, to_row, playlist_dst.playlist_id)
model_src.move_rows_between_playlists(
from_rows, to_row, playlist_dst.playlist_id
)
assert model_src.rowCount() == self.ROWS_TO_CREATE - len(from_rows)
assert model_dst.rowCount() == self.ROWS_TO_CREATE + len(from_rows)
@ -284,13 +276,13 @@ class TestMMMiscRowMove(unittest.TestCase):
for row in range(self.ROWS_TO_CREATE):
model_dst.insert_row_signal_handler(
InsertTrack(
playlist_id=playlist_dst.playlist_id,
track_id=None,
note=str(row)
playlist_id=playlist_dst.playlist_id, track_id=None, note=str(row)
)
)
model_src.move_rows_between_playlists(from_rows, to_row, playlist_dst.playlist_id)
model_src.move_rows_between_playlists(
from_rows, to_row, playlist_dst.playlist_id
)
# Check the rows of the destination model
row_notes = []
@ -318,13 +310,13 @@ class TestMMMiscRowMove(unittest.TestCase):
for row in range(self.ROWS_TO_CREATE):
model_dst.insert_row_signal_handler(
InsertTrack(
playlist_id=playlist_dst.playlist_id,
track_id=None,
note=str(row)
playlist_id=playlist_dst.playlist_id, track_id=None, note=str(row)
)
)
model_src.move_rows_between_playlists(from_rows, to_row, playlist_dst.playlist_id)
model_src.move_rows_between_playlists(
from_rows, to_row, playlist_dst.playlist_id
)
# Check the rows of the destination model
row_notes = []

View File

@ -31,7 +31,7 @@ class MyTestCase(unittest.TestCase):
path="/alpha/bravo/charlie",
silence_at=0,
start_gap=0,
title="abc"
title="abc",
)
_ = ds.track_create(track1_meta)
track2_meta = dict(
@ -42,7 +42,7 @@ class MyTestCase(unittest.TestCase):
path="/xray/yankee/zulu",
silence_at=0,
start_gap=0,
title="xyz"
title="xyz",
)
track2 = ds.track_create(track2_meta)
@ -74,7 +74,7 @@ class MyTestCase(unittest.TestCase):
results = ds.tracks_filtered(filter)
assert len(results) == 1
assert 'alpha' in results[0].path
assert "alpha" in results[0].path
def test_search_path_2(self):
"""Search for unplayed track that doesn't exist"""
@ -91,7 +91,7 @@ class MyTestCase(unittest.TestCase):
results = ds.tracks_filtered(filter)
assert len(results) == 1
assert 'zulu' in results[0].path
assert "zulu" in results[0].path
def test_played_over_two_years_ago(self):
"""Search for tracks played over 2 years ago"""
@ -108,7 +108,7 @@ class MyTestCase(unittest.TestCase):
results = ds.tracks_filtered(filter)
assert len(results) == 1
assert 'alpha' in results[0].path
assert "alpha" in results[0].path
def test_played_anytime(self):
"""Search for tracks played over a year ago"""
@ -117,4 +117,4 @@ class MyTestCase(unittest.TestCase):
results = ds.tracks_filtered(filter)
assert len(results) == 1
assert 'zulu' in results[0].path
assert "zulu" in results[0].path

View File

@ -100,7 +100,7 @@ class MyTestCase(unittest.TestCase):
InsertTrack(
playlist_id=playlist.playlist_id,
track_id=self.track1.track_id,
note=note_text
note=note_text,
)
)