Compare commits

..

3 Commits

Author SHA1 Message Date
Keith Edmunds
75b814e26c Session acquisitiong logging 2022-03-19 20:30:14 +00:00
Keith Edmunds
47f53428f6 Session fixes, MSS colour 2022-03-19 20:20:22 +00:00
Keith Edmunds
e2c5bba4ae Minor tweak to tests 2022-03-15 21:29:36 +00:00
6 changed files with 123 additions and 81 deletions

View File

@ -1,7 +1,9 @@
import inspect
import os import os
import sqlalchemy import sqlalchemy
from config import Config from config import Config
from contextlib import contextmanager
from sqlalchemy.orm import (sessionmaker, scoped_session) from sqlalchemy.orm import (sessionmaker, scoped_session)
MM_ENV = os.environ.get('MM_ENV', 'PRODUCTION') MM_ENV = os.environ.get('MM_ENV', 'PRODUCTION')
@ -35,4 +37,20 @@ engine = sqlalchemy.create_engine(
pool_pre_ping=True pool_pre_ping=True
) )
# Session = scoped_session(sessionmaker(bind=engine))
@contextmanager
def Session():
frame = inspect.stack()[2]
file = frame.filename
function = frame.function
lineno = frame.lineno
print(f"Session acquired, {file=}, {function=}, {lineno=}")
# yield scoped_session(sessionmaker(bind=engine))
Session = scoped_session(sessionmaker(bind=engine)) Session = scoped_session(sessionmaker(bind=engine))
yield Session
print(" Session released")
Session.commit()
print(" Session committed")
Session.close()
print(" Session closed")

View File

@ -190,14 +190,13 @@ class Playdates(Base):
tracks: RelationshipProperty = relationship( tracks: RelationshipProperty = relationship(
"Tracks", back_populates="playdates", lazy="joined") "Tracks", back_populates="playdates", lazy="joined")
def __init__(self, session: Session, track: "Tracks") -> None: def __init__(self, session: Session, track_id: int) -> None:
"""Record that track was played""" """Record that track was played"""
DEBUG(f"add_playdate(track={track})") DEBUG(f"add_playdate({track_id=})")
self.lastplayed = datetime.now() self.lastplayed = datetime.now()
self.track_id = track.id self.track_id = track_id
track.update_lastplayed(session)
session.add(self) session.add(self)
session.flush() session.flush()
@ -594,9 +593,13 @@ class Tracks(Base):
.order_by(cls.title) .order_by(cls.title)
).all() ).all()
def update_lastplayed(self, session: Session) -> None: @staticmethod
self.lastplayed = datetime.now() def update_lastplayed(session: Session, track_id: int) -> None:
session.add(self) """Update the last_played field to current datetime"""
rec = session.query(Tracks).get(track_id)
rec.lastplayed = datetime.now()
session.add(rec)
session.flush() session.flush()
def update_artist(self, session: Session, artist: str) -> None: def update_artist(self, session: Session, artist: str) -> None:

View File

@ -24,12 +24,13 @@ from PyQt5.QtWidgets import (
) )
import dbconfig import dbconfig
from dbconfig import Session
import helpers import helpers
import music import music
from config import Config from config import Config
from models import (Playdates, Playlists, PlaylistTracks, from models import (Base, Playdates, Playlists, PlaylistTracks,
Session, Settings, Tracks) Settings, Tracks)
from playlists import PlaylistTab from playlists import PlaylistTab
from utilities import create_track_from_file from utilities import create_track_from_file
from sqlalchemy.orm.exc import DetachedInstanceError from sqlalchemy.orm.exc import DetachedInstanceError
@ -38,6 +39,20 @@ from ui.dlg_SelectPlaylist_ui import Ui_dlgSelectPlaylist
from ui.main_window_ui import Ui_MainWindow from ui.main_window_ui import Ui_MainWindow
class TrackData:
def __init__(self, track):
self.id = track.id
self.title = track.title
self.artist = track.artist
self.duration = track.duration
self.start_gap = track.start_gap
self.fade_at = track.fade_at
self.silence_at = track.silence_at
self.path = track.path
self.mtime = track.mtime
self.lastplayed = track.lastplayed
class Window(QMainWindow, Ui_MainWindow): class Window(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None) -> None: def __init__(self, parent=None) -> None:
super().__init__(parent) super().__init__(parent)
@ -503,6 +518,8 @@ class Window(QMainWindow, Ui_MainWindow):
DEBUG("musicmuster.play_next(): no next track selected", True) DEBUG("musicmuster.play_next(): no next track selected", True)
return return
self.kae()
with Session() as session: with Session() as session:
# If there's currently a track playing, fade it. # If there's currently a track playing, fade it.
self.stop_playing(fade=True) self.stop_playing(fade=True)
@ -511,10 +528,6 @@ class Window(QMainWindow, Ui_MainWindow):
self.current_track = self.next_track self.current_track = self.next_track
self.next_track = None self.next_track = None
# Ensure track is in session
if self.current_track not in session:
session.add(self.current_track)
# If current track on different playlist_tab to last, reset # If current track on different playlist_tab to last, reset
# last track playlist_tab colour # last track playlist_tab colour
# Set current track playlist_tab colour # Set current track playlist_tab colour
@ -534,7 +547,10 @@ class Window(QMainWindow, Ui_MainWindow):
self.music.play(self.current_track.path) self.music.play(self.current_track.path)
# Tell database to record it as played # Tell database to record it as played
Playdates(session, self.current_track) Playdates(session, self.current_track.id)
# Set last_played date
Tracks.update_lastplayed(session, self.current_track.id)
# Tell playlist track is now playing # Tell playlist track is now playing
self.current_track_playlist_tab.play_started(session) self.current_track_playlist_tab.play_started(session)
@ -713,7 +729,7 @@ class Window(QMainWindow, Ui_MainWindow):
QColor(Config.COLOUR_NEXT_TAB)) QColor(Config.COLOUR_NEXT_TAB))
# Note next track # Note next track
self.next_track = track self.next_track = TrackData(track)
# Update headers # Update headers
self.update_headers() self.update_headers()
@ -747,10 +763,7 @@ class Window(QMainWindow, Ui_MainWindow):
# If track is playing, update track clocks time and colours # If track is playing, update track clocks time and colours
if self.music.player and self.music.playing(): if self.music.player and self.music.playing():
with Session() as session:
self.playing = True self.playing = True
if self.current_track not in session:
session.add(self.current_track)
playtime: int = self.music.get_playtime() playtime: int = self.music.get_playtime()
time_to_fade: int = (self.current_track.fade_at - playtime) time_to_fade: int = (self.current_track.fade_at - playtime)
time_to_silence: int = ( time_to_silence: int = (
@ -983,7 +996,6 @@ class SelectPlaylistDialog(QDialog):
if __name__ == "__main__": if __name__ == "__main__":
try: try:
Base.metadata.create_all(dbconfig.engine) Base.metadata.create_all(dbconfig.engine)
Session = dbconfig.Session
app = QApplication(sys.argv) app = QApplication(sys.argv)
win = Window() win = Window()
win.show() win.show()

View File

@ -341,7 +341,7 @@ class PlaylistTab(QTableWidget):
# Add track details to columns # Add track details to columns
mss_item: QTableWidgetItem = QTableWidgetItem(str(track.start_gap)) mss_item: QTableWidgetItem = QTableWidgetItem(str(track.start_gap))
if track.start_gap and track.start_gap >= 500: if track.start_gap and track.start_gap >= 500:
item.setBackground(QColor(Config.COLOUR_LONG_START)) mss_item.setBackground(QColor(Config.COLOUR_LONG_START))
self.setItem(row, self.COL_MSS, mss_item) self.setItem(row, self.COL_MSS, mss_item)
title_item: QTableWidgetItem = QTableWidgetItem(track.title) title_item: QTableWidgetItem = QTableWidgetItem(track.title)
@ -485,7 +485,7 @@ class PlaylistTab(QTableWidget):
self._insert_note(session, item, repaint=False) self._insert_note(session, item, repaint=False)
# Scroll to top # Scroll to top
scroll_to: QTableWidgetItem = self.item(0, self.COL_TITLE) scroll_to: QTableWidgetItem = self.item(0, 0)
self.scrollToItem(scroll_to, QAbstractItemView.PositionAtTop) self.scrollToItem(scroll_to, QAbstractItemView.PositionAtTop)
# We possibly don't need to save the playlist here, but row # We possibly don't need to save the playlist here, but row
@ -1364,6 +1364,10 @@ class PlaylistTab(QTableWidget):
# Get the row number of all selected items and put into a set # Get the row number of all selected items and put into a set
# to deduplicate # to deduplicate
sel_rows: Set[int] = set([item.row() for item in self.selectedItems()]) sel_rows: Set[int] = set([item.row() for item in self.selectedItems()])
# If no rows are selected, we have nothing to do
if len(sel_rows) == 0:
return
notes_rows: Set[int] = set(self._get_notes_rows()) notes_rows: Set[int] = set(self._get_notes_rows())
ms: int = 0 ms: int = 0
with Session() as session: with Session() as session:

View File

@ -246,7 +246,7 @@ def update_db(session):
for path in list(os_paths - db_paths): for path in list(os_paths - db_paths):
DEBUG(f"songdb.update_db: {path=} not in database") DEBUG(f"songdb.update_db: {path=} not in database")
# is filename in database? # is filename in database?
track = Tracks.get_from_filename(session, os.path.basename(path)) track = Tracks.get_by_filename(session, os.path.basename(path))
if not track: if not track:
messages.append(f"Track missing from database: {path}") messages.append(f"Track missing from database: {path}")
else: else:
@ -262,7 +262,7 @@ def update_db(session):
# Remote any tracks from database whose paths don't exist # Remote any tracks from database whose paths don't exist
for path in list(db_paths - os_paths): for path in list(db_paths - os_paths):
# Manage tracks listed in database but where path is invalid # Manage tracks listed in database but where path is invalid
track = Tracks.get_from_path(session, path) track = Tracks.get_by_path(session, path)
messages.append(f"Remove from database: {path=} {track=}") messages.append(f"Remove from database: {path=} {track=}")
# Remove references from Playdates # Remove references from Playdates

View File

@ -229,6 +229,8 @@ def test_get_selected_row(qtbot, monkeypatch, session):
qtbot.mouseClick( qtbot.mouseClick(
playlist_tab.viewport(), Qt.LeftButton, pos=rect.center() playlist_tab.viewport(), Qt.LeftButton, pos=rect.center()
) )
row_number = playlist_tab.get_selected_row()
assert row_number == 0
def test_set_next(qtbot, monkeypatch, session): def test_set_next(qtbot, monkeypatch, session):
@ -248,6 +250,9 @@ def test_set_next(qtbot, monkeypatch, session):
# Add some tracks # Add some tracks
track1 = models.Tracks.get_by_filename(session, "isa.mp3") track1 = models.Tracks.get_by_filename(session, "isa.mp3")
track1_title = track1.title
assert track1_title
playlist_tab.insert_track(session, track1) playlist_tab.insert_track(session, track1)
track2 = models.Tracks.get_by_filename(session, "mom.mp3") track2 = models.Tracks.get_by_filename(session, "mom.mp3")
playlist_tab.insert_track(session, track2) playlist_tab.insert_track(session, track2)
@ -261,11 +266,12 @@ def test_set_next(qtbot, monkeypatch, session):
qtbot.mouseClick( qtbot.mouseClick(
playlist_tab.viewport(), Qt.LeftButton, pos=rect.center() playlist_tab.viewport(), Qt.LeftButton, pos=rect.center()
) )
# qtbot.wait(10000) selected_title = playlist_tab.get_selected_title()
assert selected_title == track1_title
qtbot.keyPress(playlist_tab.viewport(), "N", qtbot.keyPress(playlist_tab.viewport(), "N",
modifier=Qt.ControlModifier) modifier=Qt.ControlModifier)
qtbot.wait(2000) qtbot.wait(1000)
pass
def test_kae(monkeypatch, session): def test_kae(monkeypatch, session):
@ -277,4 +283,3 @@ def test_kae(monkeypatch, session):
# monkeypatch.setattr(dbconfig, "Session", session) # monkeypatch.setattr(dbconfig, "Session", session)
# monkeypatch.setattr(models, "Session", session) # monkeypatch.setattr(models, "Session", session)
# monkeypatch.setattr(playlists, "Session", session) # monkeypatch.setattr(playlists, "Session", session)