This commit is contained in:
Keith Edmunds 2022-03-14 20:10:59 +00:00
parent a31718d2b9
commit 87f9e1e81b
8 changed files with 192 additions and 158 deletions

View File

@ -1,12 +1,11 @@
#!/usr/bin/python3 #!/usr/bin/python3
import dbconfig
import os.path import os.path
import re import re
from dbconfig import Session
from datetime import datetime from datetime import datetime
from dbconfig import engine
from typing import List, Optional from typing import List, Optional
from pydub import AudioSegment from pydub import AudioSegment
@ -40,10 +39,8 @@ from helpers import (
) )
from log import DEBUG, ERROR from log import DEBUG, ERROR
Session = dbconfig.session
Base: DeclarativeMeta = declarative_base() Base: DeclarativeMeta = declarative_base()
Base.metadata.create_all(engine)
# Database classes # Database classes
@ -70,7 +67,7 @@ class NoteColours(Base):
self.order = order self.order = order
session.add(self) session.add(self)
session.commit() session.flush()
def __repr__(self) -> str: def __repr__(self) -> str:
return ( return (
@ -142,7 +139,7 @@ class Notes(Base):
self.row = row self.row = row
self.note = text self.note = text
session.add(self) session.add(self)
session.commit() session.flush()
def __repr__(self) -> str: def __repr__(self) -> str:
return ( return (
@ -155,7 +152,7 @@ class Notes(Base):
DEBUG(f"delete_note({self.id=}") DEBUG(f"delete_note({self.id=}")
session.query(Notes).filter_by(id=self.id).delete() session.query(Notes).filter_by(id=self.id).delete()
session.commit() session.flush()
@classmethod @classmethod
def get_by_id(cls, session: Session, note_id: int) -> Optional["Notes"]: def get_by_id(cls, session: Session, note_id: int) -> Optional["Notes"]:
@ -181,7 +178,7 @@ class Notes(Base):
self.row = row self.row = row
if text: if text:
self.note = text self.note = text
session.commit() session.flush()
class Playdates(Base): class Playdates(Base):
@ -202,7 +199,7 @@ class Playdates(Base):
self.track_id = track.id self.track_id = track.id
track.update_lastplayed(session) track.update_lastplayed(session)
session.add(self) session.add(self)
session.commit() session.flush()
@staticmethod @staticmethod
def last_played(session: Session, track_id: int) -> Optional[datetime]: def last_played(session: Session, track_id: int) -> Optional[datetime]:
@ -224,9 +221,8 @@ class Playdates(Base):
""" """
session.query(Playdates).filter( session.query(Playdates).filter(
Playdates.track_id == track_id, Playdates.track_id == track_id).delete()
).delete() session.flush()
session.commit()
class Playlists(Base): class Playlists(Base):
@ -251,7 +247,7 @@ class Playlists(Base):
def __init__(self, session: Session, name: str) -> None: def __init__(self, session: Session, name: str) -> None:
self.name = name self.name = name
session.add(self) session.add(self)
session.commit() session.flush()
def __repr__(self) -> str: def __repr__(self) -> str:
return f"<Playlists(id={self.id}, name={self.name}>" return f"<Playlists(id={self.id}, name={self.name}>"
@ -279,7 +275,7 @@ class Playlists(Base):
self.loaded = False self.loaded = False
session.add(self) session.add(self)
session.commit() session.flush()
@classmethod @classmethod
def get_all(cls, session: Session) -> List["Playlists"]: def get_all(cls, session: Session) -> List["Playlists"]:
@ -320,25 +316,38 @@ class Playlists(Base):
self.loaded = True self.loaded = True
self.last_used = datetime.now() self.last_used = datetime.now()
session.commit() session.flush()
def move_track(self, session: Session, rows: List[int],
to_playlist: "Playlists") -> None:
"""Move tracks to another playlist"""
for row in rows:
track = self.tracks[row]
to_playlist.add_track(session, track.id)
del self.tracks[row]
session.flush()
def remove_all_tracks(self, session: Session) -> None: def remove_all_tracks(self, session: Session) -> None:
""" """
Remove all tracks from this playlist Remove all tracks from this playlist
""" """
session.query(PlaylistTracks).filter( self.tracks = {}
PlaylistTracks.playlist_id == self.id, session.flush()
).delete()
session.commit()
def remove_track(self, session: Session, row: int) -> None: def remove_track(self, session: Session, row: int) -> None:
DEBUG(f"Playlist.remove_track({self.id=}, {row=})") DEBUG(f"Playlist.remove_track({self.id=}, {row=})")
session.query(PlaylistTracks).filter( # Get tracks collection for this playlist
PlaylistTracks.playlist_id == self.id, tracks_collections = self.tracks
PlaylistTracks.row == row # Tracks are a dictionary of tracks keyed on row
).delete() # number. Remove the relevant row.
del tracks_collections[row]
# Save the new tracks collection
self.tracks = tracks_collections
session.flush()
class PlaylistTracks(Base): class PlaylistTracks(Base):
@ -355,7 +364,8 @@ class PlaylistTracks(Base):
backref=backref( backref=backref(
"playlist_tracks", "playlist_tracks",
collection_class=attribute_mapped_collection("row"), collection_class=attribute_mapped_collection("row"),
lazy="joined" lazy="joined",
cascade="all, delete-orphan"
) )
) )
@ -368,45 +378,7 @@ class PlaylistTracks(Base):
self.track_id = track_id self.track_id = track_id
self.row = row self.row = row
session.add(self) session.add(self)
session.commit() session.flush()
@staticmethod
def move_track(
session: Session, from_playlist_id: int, row: int,
to_playlist_id: int) -> None:
"""
Move track between playlists. This would be more efficient with
an ORM-enabled UPDATE statement, but this works just fine.
"""
DEBUG(
"PlaylistTracks.move_tracks("
f"{from_playlist_id=}, {row=}, {to_playlist_id=})"
)
new_row: int
max_row: Optional[int] = session.query(
func.max(PlaylistTracks.row)).filter(
PlaylistTracks.playlist_id == to_playlist_id).scalar()
if max_row is None:
# Destination playlist is empty; use row 0
new_row = 0
else:
# Destination playlist has tracks; add to end
new_row = max_row + 1
try:
record: PlaylistTracks = session.query(PlaylistTracks).filter(
PlaylistTracks.playlist_id == from_playlist_id,
PlaylistTracks.row == row).one()
except NoResultFound:
ERROR(
f"No rows matched in query: "
f"PlaylistTracks.playlist_id == {from_playlist_id}, "
f"PlaylistTracks.row == {row}"
)
return
record.playlist_id = to_playlist_id
record.row = new_row
session.commit()
@staticmethod @staticmethod
def next_free_row(session: Session, playlist: Playlists) -> int: def next_free_row(session: Session, playlist: Playlists) -> int:
@ -449,14 +421,14 @@ class Settings(Base):
int_setting.name = name int_setting.name = name
int_setting.f_int = None int_setting.f_int = None
session.add(int_setting) session.add(int_setting)
session.commit() session.flush()
return int_setting return int_setting
def update(self, session: Session, data): def update(self, session: Session, data):
for key, value in data.items(): for key, value in data.items():
assert hasattr(self, key) assert hasattr(self, key)
setattr(self, key, value) setattr(self, key, value)
session.commit() session.flush()
class Tracks(Base): class Tracks(Base):
@ -479,10 +451,30 @@ class Tracks(Base):
back_populates="tracks", back_populates="tracks",
lazy="joined") lazy="joined")
def __init__(self, session: Session, path: str) -> None: def __init__(self,
session: Session,
path: str,
title: Optional[str] = None,
artist: Optional[str] = None,
duration: Optional[int] = None,
start_gap: Optional[int] = None,
fade_at: Optional[int] = None,
silence_at: Optional[int] = None,
mtime: Optional[float] = None,
lastplayed: Optional[datetime] = None,
) -> None:
self.path = path self.path = path
self.title = title
self.artist = artist
self.duration = duration
self.start_gap = start_gap
self.fade_at = fade_at
self.silence_at = silence_at
self.mtime = mtime
self.lastplayed = lastplayed
session.add(self) session.add(self)
session.commit() session.flush()
def __repr__(self) -> str: def __repr__(self) -> str:
return ( return (
@ -571,7 +563,7 @@ class Tracks(Base):
Config.MILLISECOND_SIGFIGS) * 1000 Config.MILLISECOND_SIGFIGS) * 1000
self.start_gap = leading_silence(audio) self.start_gap = leading_silence(audio)
session.add(self) session.add(self)
session.commit() session.flush()
@staticmethod @staticmethod
def remove_by_path(session: Session, path: str) -> None: def remove_by_path(session: Session, path: str) -> None:
@ -581,7 +573,7 @@ class Tracks(Base):
try: try:
session.query(Tracks).filter(Tracks.path == path).delete() session.query(Tracks).filter(Tracks.path == path).delete()
session.commit() session.flush()
except IntegrityError as exception: except IntegrityError as exception:
ERROR(f"Can't remove track with {path=} ({exception=})") ERROR(f"Can't remove track with {path=} ({exception=})")
@ -605,17 +597,17 @@ class Tracks(Base):
def update_lastplayed(self, session: Session) -> None: def update_lastplayed(self, session: Session) -> None:
self.lastplayed = datetime.now() self.lastplayed = datetime.now()
session.add(self) session.add(self)
session.commit() session.flush()
def update_artist(self, session: Session, artist: str) -> None: def update_artist(self, session: Session, artist: str) -> None:
self.artist = artist self.artist = artist
session.add(self) session.add(self)
session.commit() session.flush()
def update_title(self, session: Session, title: str) -> None: def update_title(self, session: Session, title: str) -> None:
self.title = title self.title = title
session.add(self) session.add(self)
session.commit() session.flush()
def update_path(self, newpath: str) -> None: def update_path(self, newpath: str) -> None:
self.path = newpath self.path = newpath

View File

@ -23,6 +23,7 @@ from PyQt5.QtWidgets import (
QMainWindow, QMainWindow,
) )
import dbconfig
import helpers import helpers
import music import music
@ -979,15 +980,13 @@ class SelectPlaylistDialog(QDialog):
self.accept() self.accept()
def main(): if __name__ == "__main__":
try: try:
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()
sys.exit(app.exec()) sys.exit(app.exec())
except Exception: except Exception:
EXCEPTION("Unhandled Exception caught by musicmuster.main()") EXCEPTION("Unhandled Exception caught by musicmuster.main()")
if __name__ == "__main__":
main()

View File

@ -27,11 +27,11 @@ from models import (
Notes, Notes,
Playdates, Playdates,
Playlists, Playlists,
Session,
Settings, Settings,
Tracks, Tracks,
NoteColours NoteColours
) )
from dbconfig import Session
class RowMeta: class RowMeta:
@ -101,7 +101,7 @@ class PlaylistTab(QTableWidget):
self.setHorizontalHeaderItem(7, item) self.setHorizontalHeaderItem(7, item)
self.horizontalHeader().setMinimumSectionSize(0) self.horizontalHeader().setMinimumSectionSize(0)
self._set_column_widths() self._set_column_widths(session)
self.setHorizontalHeaderLabels([ self.setHorizontalHeaderLabels([
Config.COLUMN_NAME_AUTOPLAY, Config.COLUMN_NAME_AUTOPLAY,
Config.COLUMN_NAME_LEADING_SILENCE, Config.COLUMN_NAME_LEADING_SILENCE,
@ -1368,7 +1368,7 @@ class PlaylistTab(QTableWidget):
ms: int = 0 ms: int = 0
with Session() as session: with Session() as session:
for row in (sel_rows - notes_rows): for row in (sel_rows - notes_rows):
ms += self._get_row_track_object(row, session).duration ms += self._get_row_track_object(row, session).duration or 0
# Only paint message if there are selected track rows # Only paint message if there are selected track rows
if ms > 0: if ms > 0:
@ -1398,17 +1398,16 @@ class PlaylistTab(QTableWidget):
# Reset extended selection # Reset extended selection
self.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) self.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
def _set_column_widths(self) -> None: def _set_column_widths(self, session: Session) -> None:
"""Column widths from settings""" """Column widths from settings"""
with Session() as session: for column in range(self.columnCount()):
for column in range(self.columnCount()): name: str = f"playlist_col_{str(column)}_width"
name: str = f"playlist_col_{str(column)}_width" record: Settings = Settings.get_int_settings(session, name)
record: Settings = Settings.get_int_settings(session, name) if record and record.f_int is not None:
if record and record.f_int is not None: self.setColumnWidth(column, record.f_int)
self.setColumnWidth(column, record.f_int) else:
else: self.setColumnWidth(column, Config.DEFAULT_COLUMN_WIDTH)
self.setColumnWidth(column, Config.DEFAULT_COLUMN_WIDTH)
def _set_next(self, row: int, session: Session) -> None: def _set_next(self, row: int, session: Session) -> None:
""" """

View File

@ -53,7 +53,7 @@ def main():
DEBUG("Finished") DEBUG("Finished")
def create_track_from_file(session, path, interactive=False): def create_track_from_file(session, path, normalise=None, interactive=False):
""" """
Create track in database from passed path, or update database entry Create track in database from passed path, or update database entry
if path already in database. if path already in database.
@ -100,7 +100,7 @@ def create_track_from_file(session, path, interactive=False):
track.mtime = os.path.getmtime(path) track.mtime = os.path.getmtime(path)
session.commit() session.commit()
if Config.NORMALISE_ON_IMPORT: if normalise or normalise is None and Config.NORMALISE_ON_IMPORT:
if interactive: if interactive:
INFO("Normalise...") INFO("Normalise...")
# Check type # Check type

View File

@ -2,11 +2,12 @@
import pytest import pytest
import sys import sys
sys.path.append("app")
import models
from sqlalchemy import create_engine from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker from sqlalchemy.orm import scoped_session, sessionmaker
sys.path.append("app")
@pytest.fixture(scope="session") @pytest.fixture(scope="session")
@ -18,23 +19,6 @@ def connection():
return engine.connect() return engine.connect()
def seed_database():
pass
# users = [
# {
# "id": 1,
# "name": "John Doe",
# },
# # ...
# ]
# for user in users:
# db_user = User(**user)
# db_session.add(db_user)
# db_session.commit()
@pytest.fixture(scope="session") @pytest.fixture(scope="session")
def setup_database(connection): def setup_database(connection):
from app.models import Base # noqa E402 from app.models import Base # noqa E402

6
poetry.lock generated
View File

@ -943,6 +943,12 @@ pytest = [
{file = "pytest-7.0.1-py3-none-any.whl", hash = "sha256:9ce3ff477af913ecf6321fe337b93a2c0dcf2a0a1439c43f5452112c1e4280db"}, {file = "pytest-7.0.1-py3-none-any.whl", hash = "sha256:9ce3ff477af913ecf6321fe337b93a2c0dcf2a0a1439c43f5452112c1e4280db"},
{file = "pytest-7.0.1.tar.gz", hash = "sha256:e30905a0c131d3d94b89624a1cc5afec3e0ba2fbdb151867d8e0ebd49850f171"}, {file = "pytest-7.0.1.tar.gz", hash = "sha256:e30905a0c131d3d94b89624a1cc5afec3e0ba2fbdb151867d8e0ebd49850f171"},
] ]
pytest-profiling = [
{file = "pytest-profiling-1.7.0.tar.gz", hash = "sha256:93938f147662225d2b8bd5af89587b979652426a8a6ffd7e73ec4a23e24b7f29"},
{file = "pytest_profiling-1.7.0-py2.7.egg", hash = "sha256:3b255f9db36cb2dd7536a8e7e294c612c0be7f7850a7d30754878e4315d56600"},
{file = "pytest_profiling-1.7.0-py2.py3-none-any.whl", hash = "sha256:999cc9ac94f2e528e3f5d43465da277429984a1c237ae9818f8cfd0b06acb019"},
{file = "pytest_profiling-1.7.0-py3.6.egg", hash = "sha256:6bce4e2edc04409d2f3158c16750fab8074f62d404cc38eeb075dff7fcbb996c"},
]
pytest-qt = [ pytest-qt = [
{file = "pytest-qt-4.0.2.tar.gz", hash = "sha256:dfc5240dec7eb43b76bcb5f9a87eecae6ef83592af49f3af5f1d5d093acaa93e"}, {file = "pytest-qt-4.0.2.tar.gz", hash = "sha256:dfc5240dec7eb43b76bcb5f9a87eecae6ef83592af49f3af5f1d5d093acaa93e"},
{file = "pytest_qt-4.0.2-py2.py3-none-any.whl", hash = "sha256:e03847ac02a890ccaac0fde1748855b9dce425aceba62005c6cfced6cf7d5456"}, {file = "pytest_qt-4.0.2-py2.py3-none-any.whl", hash = "sha256:e03847ac02a890ccaac0fde1748855b9dce425aceba62005c6cfced6cf7d5456"},

View File

@ -126,7 +126,7 @@ def test_playdates_add_playdate(session):
assert playdate assert playdate
last_played = Playdates.last_played(session, track.id) last_played = Playdates.last_played(session, track.id)
assert playdate.lastplayed == last_played assert abs((playdate.lastplayed - last_played).total_seconds()) < 2
def test_playdates_remove_track(session): def test_playdates_remove_track(session):
@ -274,6 +274,9 @@ def test_playlist_remove_tracks(session):
playlist1.remove_track(session, 1) playlist1.remove_track(session, 1)
assert len(playlist1.tracks) == 2 assert len(playlist1.tracks) == 2
# Check the track itself still exists
original_track = Tracks.get_by_id(session, track1.id)
assert original_track
playlist1.remove_all_tracks(session) playlist1.remove_all_tracks(session)
assert len(playlist1.tracks) == 0 assert len(playlist1.tracks) == 0
@ -330,8 +333,7 @@ def test_playlisttracks_move_track(session):
assert tracks[track2_row] == track2 assert tracks[track2_row] == track2
# Move track2 to playlist2 and check # Move track2 to playlist2 and check
PlaylistTracks.move_track( playlist1.move_track(session, [track2_row], playlist2)
session, playlist1.id, track2_row, playlist2.id)
tracks1 = playlist1.tracks tracks1 = playlist1.tracks
tracks2 = playlist2.tracks tracks2 = playlist2.tracks

View File

@ -1,15 +1,47 @@
from PyQt5.QtCore import Qt from PyQt5.QtCore import Qt
from app.playlists import Notes, PlaylistTab, Tracks from app import playlists
from app.models import Playlists from app import models
import musicmuster from app import musicmuster
from app import dbconfig
def seed2tracks(session):
tracks = [
{
"path": "testdata/isa.mp3",
"title": "I'm so afraid",
"artist": "Fleetwood Mac",
"duration": 263000,
"start_gap": 60,
"fade_at": 236263,
"silence_at": 260343,
"mtime": 371900000,
},
{
"path": "testdata/mom.mp3",
"title": "Man of Mystery",
"artist": "The Shadows",
"duration": 120000,
"start_gap": 70,
"fade_at": 115000,
"silence_at": 118000,
"mtime": 1642760000,
},
]
for track in tracks:
db_track = models.Tracks(session=session, **track)
session.add(db_track)
session.commit()
def test_init(qtbot, session): def test_init(qtbot, session):
"""Just check we can create a playlist_tab""" """Just check we can create a playlist_tab"""
playlist = Playlists(session, "my playlist") playlist = models.Playlists(session, "my playlist")
playlist_tab = PlaylistTab(None, session, playlist.id) playlist_tab = playlists.PlaylistTab(None, session, playlist.id)
assert playlist_tab assert playlist_tab
@ -17,46 +49,51 @@ def test_save_and_restore(qtbot, session):
"""Playlist with one track, one note, save and restore""" """Playlist with one track, one note, save and restore"""
# Create playlist # Create playlist
playlist = Playlists(session, "my playlist") playlist = models.Playlists(session, "my playlist")
playlist_tab = PlaylistTab(None, session, playlist.id) playlist_tab = playlists.PlaylistTab(None, session, playlist.id)
# Insert a note # Insert a note
note_text = "my note" note_text = "my note"
note_row = 7 note_row = 7
note = Notes(session, playlist.id, note_row, note_text) note = models.Notes(session, playlist.id, note_row, note_text)
playlist_tab._insert_note(session, note) playlist_tab._insert_note(session, note)
# Add a track # Add a track
track_path = "/a/b/c" track_path = "/a/b/c"
track = Tracks(session, track_path) track = models.Tracks(session, track_path)
playlist_tab.insert_track(session, track) playlist_tab.insert_track(session, track)
# Save playlist # Save playlist
playlist_tab.save_playlist(session) playlist_tab.save_playlist(session)
# We need to commit the session before re-querying
session.commit()
# Retrieve playlist # Retrieve playlist
playlists = Playlists.get_open(session) all_playlists = playlists.Playlists.get_open(session)
assert len(playlists) == 1 assert len(all_playlists) == 1
retrieved_playlist = playlists[0] retrieved_playlist = all_playlists[0]
assert track_path in [a.path for a in retrieved_playlist.tracks.values()] paths = [a.path for a in retrieved_playlist.tracks.values()]
assert note_text in [a.note for a in retrieved_playlist.notes] assert track_path in paths
notes = [a.note for a in retrieved_playlist.notes]
assert note_text in notes
def test_meta_all_clear(qtbot, session): def test_meta_all_clear(qtbot, session):
# Create playlist # Create playlist
playlist = Playlists(session, "my playlist") playlist = models.Playlists(session, "my playlist")
playlist_tab = PlaylistTab(None, session, playlist.id) playlist_tab = playlists.PlaylistTab(None, session, playlist.id)
# Add some tracks # Add some tracks
track1_path = "/a/b/c" track1_path = "/a/b/c"
track1 = Tracks(session, track1_path) track1 = models.Tracks(session, track1_path)
playlist_tab.insert_track(session, track1) playlist_tab.insert_track(session, track1)
track2_path = "/d/e/f" track2_path = "/d/e/f"
track2 = Tracks(session, track2_path) track2 = models.Tracks(session, track2_path)
playlist_tab.insert_track(session, track2) playlist_tab.insert_track(session, track2)
track3_path = "/h/i/j" track3_path = "/h/i/j"
track3 = Tracks(session, track3_path) track3 = models.Tracks(session, track3_path)
playlist_tab.insert_track(session, track3) playlist_tab.insert_track(session, track3)
assert playlist_tab._get_current_track_row() is None assert playlist_tab._get_current_track_row() is None
@ -69,18 +106,18 @@ def test_meta_all_clear(qtbot, session):
def test_meta(qtbot, session): def test_meta(qtbot, session):
# Create playlist # Create playlist
playlist = Playlists(session, "my playlist") playlist = playlists.Playlists(session, "my playlist")
playlist_tab = PlaylistTab(None, session, playlist.id) playlist_tab = playlists.PlaylistTab(None, session, playlist.id)
# Add some tracks # Add some tracks
track1_path = "/a/b/c" track1_path = "/a/b/c"
track1 = Tracks(session, track1_path) track1 = models.Tracks(session, track1_path)
playlist_tab.insert_track(session, track1) playlist_tab.insert_track(session, track1)
track2_path = "/d/e/f" track2_path = "/d/e/f"
track2 = Tracks(session, track2_path) track2 = models.Tracks(session, track2_path)
playlist_tab.insert_track(session, track2) playlist_tab.insert_track(session, track2)
track3_path = "/h/i/j" track3_path = "/h/i/j"
track3 = Tracks(session, track3_path) track3 = models.Tracks(session, track3_path)
playlist_tab.insert_track(session, track3) playlist_tab.insert_track(session, track3)
assert len(playlist_tab._get_unreadable_track_rows()) == 3 assert len(playlist_tab._get_unreadable_track_rows()) == 3
@ -99,7 +136,7 @@ def test_meta(qtbot, session):
# Add a note # Add a note
note_text = "my note" note_text = "my note"
note_row = 7 # will be added as row 3 note_row = 7 # will be added as row 3
note = Notes(session, playlist.id, note_row, note_text) note = models.Notes(session, playlist.id, note_row, note_text)
playlist_tab._insert_note(session, note) playlist_tab._insert_note(session, note)
assert playlist_tab._get_played_track_rows() == [0] assert playlist_tab._get_played_track_rows() == [0]
@ -147,15 +184,15 @@ def test_meta(qtbot, session):
def test_clear_next(qtbot, session): def test_clear_next(qtbot, session):
# Create playlist # Create playlist
playlist = Playlists(session, "my playlist") playlist = models.Playlists(session, "my playlist")
playlist_tab = PlaylistTab(None, session, playlist.id) playlist_tab = playlists.PlaylistTab(None, session, playlist.id)
# Add some tracks # Add some tracks
track1_path = "/a/b/c" track1_path = "/a/b/c"
track1 = Tracks(session, track1_path) track1 = models.Tracks(session, track1_path)
playlist_tab.insert_track(session, track1) playlist_tab.insert_track(session, track1)
track2_path = "/d/e/f" track2_path = "/d/e/f"
track2 = Tracks(session, track2_path) track2 = models.Tracks(session, track2_path)
playlist_tab.insert_track(session, track2) playlist_tab.insert_track(session, track2)
playlist_tab._set_next_track_row(1) playlist_tab._set_next_track_row(1)
@ -165,21 +202,24 @@ def test_clear_next(qtbot, session):
assert playlist_tab._get_next_track_row() is None assert playlist_tab._get_next_track_row() is None
def test_get_selected_row(qtbot, session): def test_get_selected_row(qtbot, monkeypatch, session):
# Create playlist monkeypatch.setattr(musicmuster, "Session", session)
playlist = Playlists(session, "test playlist") monkeypatch.setattr(playlists, "Session", session)
playlist_tab = PlaylistTab(None, session, playlist.id)
# Create playlist and playlist_tab
window = musicmuster.Window()
playlist = models.Playlists(session, "test playlist")
playlist_tab = playlists.PlaylistTab(window, session, playlist.id)
# Add some tracks # Add some tracks
track1_path = "/a/b/c" track1_path = "/a/b/c"
track1 = Tracks(session, track1_path) track1 = models.Tracks(session, track1_path)
playlist_tab.insert_track(session, track1) playlist_tab.insert_track(session, track1)
track2_path = "/d/e/f" track2_path = "/d/e/f"
track2 = Tracks(session, track2_path) track2 = models.Tracks(session, track2_path)
playlist_tab.insert_track(session, track2) playlist_tab.insert_track(session, track2)
window = Window()
qtbot.addWidget(playlist_tab) qtbot.addWidget(playlist_tab)
with qtbot.waitExposed(window): with qtbot.waitExposed(window):
window.show() window.show()
@ -191,31 +231,37 @@ def test_get_selected_row(qtbot, session):
) )
def test_set_next(qtbot, session): def test_set_next(qtbot, monkeypatch, session):
monkeypatch.setattr(musicmuster, "Session", session)
monkeypatch.setattr(playlists, "Session", session)
seed2tracks(session)
playlist_name = "test playlist"
# Create testing playlist # Create testing playlist
playlist = Playlists(session, "test playlist") window = musicmuster.Window()
playlist_tab = PlaylistTab(None, session, playlist.id) playlist = models.Playlists(session, playlist_name)
playlist_tab = playlists.PlaylistTab(window, session, playlist.id)
idx = window.tabPlaylist.addTab(playlist_tab, playlist_name)
window.tabPlaylist.setCurrentIndex(idx)
qtbot.addWidget(playlist_tab)
# Add some tracks # Add some tracks
track1_path = "testdata/isa.mp3" track1 = models.Tracks.get_from_filename(session, "isa.mp3")
track1 = Tracks(session, track1_path)
playlist_tab.insert_track(session, track1) playlist_tab.insert_track(session, track1)
track2_path = "mom.mp3" track2 = models.Tracks.get_from_filename(session, "mom.mp3")
track2 = Tracks(session, track2_path)
playlist_tab.insert_track(session, track2) playlist_tab.insert_track(session, track2)
window = Window()
qtbot.addWidget(playlist_tab)
with qtbot.waitExposed(window): with qtbot.waitExposed(window):
window.show() window.show()
row0_item2 = playlist_tab.item(0, 2) row0_item2 = playlist_tab.item(0, 2)
assert row0_item2 is not None assert row0_item2 is not None
rect = playlist_tab.visualItemRect(row0_item2) rect = playlist_tab.visualItemRect(row0_item2)
qtbot.mouseClick( qtbot.mouseClick(
playlist_tab.viewport(), Qt.LeftButton, pos=rect.center() playlist_tab.viewport(), Qt.LeftButton, pos=rect.center()
) )
qtbot.wait(10000) # qtbot.wait(10000)
qtbot.keyPress(playlist_tab.viewport(), "N", qtbot.keyPress(playlist_tab.viewport(), "N",
modifier=Qt.ControlModifier) modifier=Qt.ControlModifier)
qtbot.wait(2000) qtbot.wait(2000)
@ -223,6 +269,12 @@ def test_set_next(qtbot, session):
def test_kae(monkeypatch, session): def test_kae(monkeypatch, session):
# monkeypatch.setattr(dbconfig, "Session", session)
monkeypatch.setattr(musicmuster, "Session", session) monkeypatch.setattr(musicmuster, "Session", session)
musicmuster.Window.kae() musicmuster.Window.kae()
# monkeypatch.setattr(musicmuster, "Session", session)
# monkeypatch.setattr(dbconfig, "Session", session)
# monkeypatch.setattr(models, "Session", session)
# monkeypatch.setattr(playlists, "Session", session)