Compare commits

...

4 Commits

Author SHA1 Message Date
Keith Edmunds
34fa0c92b2 Update packages 2022-03-14 20:11:11 +00:00
Keith Edmunds
87f9e1e81b Merge 2022-03-14 20:10:59 +00:00
Keith Edmunds
a31718d2b9 Separate db config, testing session for pytest 2022-03-14 20:10:07 +00:00
Keith Edmunds
cf4e42358e First moves to separate db config 2022-03-14 20:09:38 +00:00
9 changed files with 249 additions and 190 deletions

38
app/dbconfig.py Normal file
View File

@ -0,0 +1,38 @@
import os
import sqlalchemy
from config import Config
from sqlalchemy.orm import (sessionmaker, scoped_session)
MM_ENV = os.environ.get('MM_ENV', 'PRODUCTION')
testing = False
if MM_ENV == 'PRODUCTION':
dbname = os.environ.get('MM_PRODUCTION_DBNAME', 'musicmuster_prod')
dbuser = os.environ.get('MM_PRODUCTION_DBUSER', 'musicmuster')
dbpw = os.environ.get('MM_PRODUCTION_DBPW', 'musicmuster')
dbhost = os.environ.get('MM_PRODUCTION_DBHOST', 'localhost')
elif MM_ENV == 'TESTING':
dbname = os.environ.get('MM_TESTING_DBNAME', 'musicmuster_testing')
dbuser = os.environ.get('MM_TESTING_DBUSER', 'musicmuster_testing')
dbpw = os.environ.get('MM_TESTING_DBPW', 'musicmuster_testing')
dbhost = os.environ.get('MM_TESTING_DBHOST', 'localhost')
testing = True
elif MM_ENV == 'DEVELOPMENT':
dbname = os.environ.get('MM_DEVELOPMENT_DBNAME', 'musicmuster_dev')
dbuser = os.environ.get('MM_DEVELOPMENT_DBUSER', 'musicmuster')
dbpw = os.environ.get('MM_DEVELOPMENT_DBPW', 'musicmuster')
dbhost = os.environ.get('MM_DEVELOPMENT_DBHOST', 'localhost')
else:
raise ValueError(f"Unknown MusicMuster environment: {MM_ENV=}")
MYSQL_CONNECT = f"mysql+mysqldb://{dbuser}:{dbpw}@{dbhost}/{dbname}"
engine = sqlalchemy.create_engine(
MYSQL_CONNECT,
encoding='utf-8',
echo=Config.DISPLAY_SQL,
pool_pre_ping=True
)
session = scoped_session(sessionmaker(bind=engine))

View File

@ -3,7 +3,7 @@
import os.path
import re
import sqlalchemy
from dbconfig import Session
from datetime import datetime
from typing import List, Optional
@ -25,8 +25,7 @@ from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm import (
backref,
relationship,
sessionmaker,
scoped_session, RelationshipProperty
RelationshipProperty
)
from sqlalchemy.orm.collections import attribute_mapped_collection
from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound
@ -40,28 +39,8 @@ from helpers import (
)
from log import DEBUG, ERROR
# Create session at the global level as per
# https://docs.sqlalchemy.org/en/13/orm/session_basics.html
# and make objects persistent
# https://docs.sqlalchemy.org/en/14/orm/session_state_management.html
engine = sqlalchemy.create_engine(
f"{Config.MYSQL_CONNECT}?charset=utf8",
encoding='utf-8',
echo=Config.DISPLAY_SQL,
pool_pre_ping=True)
# Create a Session factory
Session = scoped_session(sessionmaker(bind=engine))
# sm: sessionmaker = sessionmaker(bind=engine) # , expire_on_commit=False)
# Session = scoped_session(sm)
Base: DeclarativeMeta = declarative_base()
Base.metadata.create_all(engine)
def db_init():
return
# Database classes
@ -88,7 +67,7 @@ class NoteColours(Base):
self.order = order
session.add(self)
session.commit()
session.flush()
def __repr__(self) -> str:
return (
@ -160,7 +139,7 @@ class Notes(Base):
self.row = row
self.note = text
session.add(self)
session.commit()
session.flush()
def __repr__(self) -> str:
return (
@ -173,7 +152,7 @@ class Notes(Base):
DEBUG(f"delete_note({self.id=}")
session.query(Notes).filter_by(id=self.id).delete()
session.commit()
session.flush()
@classmethod
def get_by_id(cls, session: Session, note_id: int) -> Optional["Notes"]:
@ -199,7 +178,7 @@ class Notes(Base):
self.row = row
if text:
self.note = text
session.commit()
session.flush()
class Playdates(Base):
@ -220,7 +199,7 @@ class Playdates(Base):
self.track_id = track.id
track.update_lastplayed(session)
session.add(self)
session.commit()
session.flush()
@staticmethod
def last_played(session: Session, track_id: int) -> Optional[datetime]:
@ -242,9 +221,8 @@ class Playdates(Base):
"""
session.query(Playdates).filter(
Playdates.track_id == track_id,
).delete()
session.commit()
Playdates.track_id == track_id).delete()
session.flush()
class Playlists(Base):
@ -269,7 +247,7 @@ class Playlists(Base):
def __init__(self, session: Session, name: str) -> None:
self.name = name
session.add(self)
session.commit()
session.flush()
def __repr__(self) -> str:
return f"<Playlists(id={self.id}, name={self.name}>"
@ -297,7 +275,7 @@ class Playlists(Base):
self.loaded = False
session.add(self)
session.commit()
session.flush()
@classmethod
def get_all(cls, session: Session) -> List["Playlists"]:
@ -338,25 +316,38 @@ class Playlists(Base):
self.loaded = True
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:
"""
Remove all tracks from this playlist
"""
session.query(PlaylistTracks).filter(
PlaylistTracks.playlist_id == self.id,
).delete()
session.commit()
self.tracks = {}
session.flush()
def remove_track(self, session: Session, row: int) -> None:
DEBUG(f"Playlist.remove_track({self.id=}, {row=})")
session.query(PlaylistTracks).filter(
PlaylistTracks.playlist_id == self.id,
PlaylistTracks.row == row
).delete()
# Get tracks collection for this playlist
tracks_collections = self.tracks
# Tracks are a dictionary of tracks keyed on row
# number. Remove the relevant row.
del tracks_collections[row]
# Save the new tracks collection
self.tracks = tracks_collections
session.flush()
class PlaylistTracks(Base):
@ -373,7 +364,8 @@ class PlaylistTracks(Base):
backref=backref(
"playlist_tracks",
collection_class=attribute_mapped_collection("row"),
lazy="joined"
lazy="joined",
cascade="all, delete-orphan"
)
)
@ -386,45 +378,7 @@ class PlaylistTracks(Base):
self.track_id = track_id
self.row = row
session.add(self)
session.commit()
@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()
session.flush()
@staticmethod
def next_free_row(session: Session, playlist: Playlists) -> int:
@ -467,14 +421,14 @@ class Settings(Base):
int_setting.name = name
int_setting.f_int = None
session.add(int_setting)
session.commit()
session.flush()
return int_setting
def update(self, session: Session, data):
for key, value in data.items():
assert hasattr(self, key)
setattr(self, key, value)
session.commit()
session.flush()
class Tracks(Base):
@ -497,10 +451,30 @@ class Tracks(Base):
back_populates="tracks",
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.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.commit()
session.flush()
def __repr__(self) -> str:
return (
@ -589,7 +563,7 @@ class Tracks(Base):
Config.MILLISECOND_SIGFIGS) * 1000
self.start_gap = leading_silence(audio)
session.add(self)
session.commit()
session.flush()
@staticmethod
def remove_by_path(session: Session, path: str) -> None:
@ -599,7 +573,7 @@ class Tracks(Base):
try:
session.query(Tracks).filter(Tracks.path == path).delete()
session.commit()
session.flush()
except IntegrityError as exception:
ERROR(f"Can't remove track with {path=} ({exception=})")
@ -623,17 +597,17 @@ class Tracks(Base):
def update_lastplayed(self, session: Session) -> None:
self.lastplayed = datetime.now()
session.add(self)
session.commit()
session.flush()
def update_artist(self, session: Session, artist: str) -> None:
self.artist = artist
session.add(self)
session.commit()
session.flush()
def update_title(self, session: Session, title: str) -> None:
self.title = title
session.add(self)
session.commit()
session.flush()
def update_path(self, newpath: str) -> None:
self.path = newpath

View File

@ -23,11 +23,12 @@ from PyQt5.QtWidgets import (
QMainWindow,
)
import dbconfig
import helpers
import music
from config import Config
from models import (db_init, Playdates, Playlists, PlaylistTracks,
from models import (Playdates, Playlists, PlaylistTracks,
Session, Settings, Tracks)
from playlists import PlaylistTab
from utilities import create_track_from_file
@ -101,6 +102,12 @@ class Window(QMainWindow, Ui_MainWindow):
height = record.f_int or 981
self.setGeometry(x, y, width, height)
@staticmethod
def kae():
with Session() as session:
db = session.bind.engine.url.database
print(f"kae(): {db=}")
@staticmethod
def check_audacity() -> None:
"""Offer to run Audacity if not running"""
@ -973,16 +980,13 @@ class SelectPlaylistDialog(QDialog):
self.accept()
def main():
if __name__ == "__main__":
try:
Base.metadata.create_all(dbconfig.engine)
Session = dbconfig.Session
app = QApplication(sys.argv)
db_init()
win = Window()
win.show()
sys.exit(app.exec())
except Exception:
EXCEPTION("Unhandled Exception caught by musicmuster.main()")
if __name__ == "__main__":
main()

View File

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

View File

@ -53,7 +53,7 @@ def main():
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
if path already in database.
@ -100,7 +100,7 @@ def create_track_from_file(session, path, interactive=False):
track.mtime = os.path.getmtime(path)
session.commit()
if Config.NORMALISE_ON_IMPORT:
if normalise or normalise is None and Config.NORMALISE_ON_IMPORT:
if interactive:
INFO("Normalise...")
# Check type

View File

@ -2,12 +2,12 @@
import pytest
import sys
sys.path.append("app")
import models
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
sys.path.append("app")
from app.models import Base # noqa E402
@pytest.fixture(scope="session")
@ -19,25 +19,9 @@ def connection():
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")
def setup_database(connection):
from app.models import Base # noqa E402
Base.metadata.bind = connection
Base.metadata.create_all()
# seed_database()

20
poetry.lock generated
View File

@ -1,6 +1,6 @@
[[package]]
name = "alembic"
version = "1.7.6"
version = "1.7.7"
description = "A database migration tool for SQLAlchemy."
category = "main"
optional = false
@ -439,11 +439,11 @@ python-versions = "*"
[[package]]
name = "pytest"
version = "7.0.1"
version = "7.1.0"
description = "pytest: simple powerful testing with Python"
category = "dev"
optional = false
python-versions = ">=3.6"
python-versions = ">=3.7"
[package.dependencies]
atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""}
@ -551,14 +551,14 @@ tests = ["pytest", "typeguard", "pygments", "littleutils", "cython"]
[[package]]
name = "tinytag"
version = "1.8.0"
version = "1.8.1"
description = "Read music meta data and length of MP3, OGG, OPUS, MP4, M4A, FLAC, WMA and Wave files"
category = "main"
optional = false
python-versions = ">=2.7"
[package.extras]
tests = ["pytest", "pytest-cov", "coveralls", "flake8"]
tests = ["pytest", "pytest-cov", "flake8"]
[[package]]
name = "toml"
@ -610,8 +610,8 @@ content-hash = "08353ac7c54559da365ff26807f5179fefe388b62bc52884ee475a4a644e924a
[metadata.files]
alembic = [
{file = "alembic-1.7.6-py3-none-any.whl", hash = "sha256:ad842f2c3ab5c5d4861232730779c05e33db4ba880a08b85eb505e87c01095bc"},
{file = "alembic-1.7.6.tar.gz", hash = "sha256:6c0c05e9768a896d804387e20b299880fe01bc56484246b0dffe8075d6d3d847"},
{file = "alembic-1.7.7-py3-none-any.whl", hash = "sha256:29be0856ec7591c39f4e1cb10f198045d890e6e2274cf8da80cb5e721a09642b"},
{file = "alembic-1.7.7.tar.gz", hash = "sha256:4961248173ead7ce8a21efb3de378f13b8398e6630fab0eb258dc74a8af24c58"},
]
appnope = [
{file = "appnope-0.1.2-py2.py3-none-any.whl", hash = "sha256:93aa393e9d6c54c5cd570ccadd8edad61ea0c4b9ea7a01409020c9aa019eb442"},
@ -940,8 +940,8 @@ pyqtwebengine-qt5 = [
{file = "PyQtWebEngine_Qt5-5.15.2-py3-none-win_amd64.whl", hash = "sha256:24231f19e1595018779977de6722b5c69f3d03f34a5f7574ff21cd1e764ef76d"},
]
pytest = [
{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.1.0-py3-none-any.whl", hash = "sha256:b555252a95bbb2a37a97b5ac2eb050c436f7989993565f5e0c9128fcaacadd0e"},
{file = "pytest-7.1.0.tar.gz", hash = "sha256:f1089d218cfcc63a212c42896f1b7fbf096874d045e1988186861a1a87d27b47"},
]
pytest-qt = [
{file = "pytest-qt-4.0.2.tar.gz", hash = "sha256:dfc5240dec7eb43b76bcb5f9a87eecae6ef83592af49f3af5f1d5d093acaa93e"},
@ -1001,7 +1001,7 @@ stack-data = [
{file = "stack_data-0.2.0.tar.gz", hash = "sha256:45692d41bd633a9503a5195552df22b583caf16f0b27c4e58c98d88c8b648e12"},
]
tinytag = [
{file = "tinytag-1.8.0.tar.gz", hash = "sha256:e222d2fed7e2a26708963d907355ae242cf44908c1175d9d0d21c2ce51d47beb"},
{file = "tinytag-1.8.1.tar.gz", hash = "sha256:363ab3107831a5598b68aaa061aba915fb1c7b4254d770232e65d5db8487636d"},
]
toml = [
{file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},

View File

@ -126,7 +126,7 @@ def test_playdates_add_playdate(session):
assert playdate
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):
@ -274,6 +274,9 @@ def test_playlist_remove_tracks(session):
playlist1.remove_track(session, 1)
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)
assert len(playlist1.tracks) == 0
@ -330,8 +333,7 @@ def test_playlisttracks_move_track(session):
assert tracks[track2_row] == track2
# Move track2 to playlist2 and check
PlaylistTracks.move_track(
session, playlist1.id, track2_row, playlist2.id)
playlist1.move_track(session, [track2_row], playlist2)
tracks1 = playlist1.tracks
tracks2 = playlist2.tracks

View File

@ -1,15 +1,47 @@
from PyQt5.QtCore import Qt
from app.playlists import Notes, PlaylistTab, Tracks
from app.models import Playlists
from musicmuster import Window
from app import playlists
from app import models
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):
"""Just check we can create a playlist_tab"""
playlist = Playlists(session, "my playlist")
playlist_tab = PlaylistTab(None, session, playlist.id)
playlist = models.Playlists(session, "my playlist")
playlist_tab = playlists.PlaylistTab(None, session, playlist.id)
assert playlist_tab
@ -17,46 +49,51 @@ def test_save_and_restore(qtbot, session):
"""Playlist with one track, one note, save and restore"""
# Create playlist
playlist = Playlists(session, "my playlist")
playlist_tab = PlaylistTab(None, session, playlist.id)
playlist = models.Playlists(session, "my playlist")
playlist_tab = playlists.PlaylistTab(None, session, playlist.id)
# Insert a note
note_text = "my note"
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)
# Add a track
track_path = "/a/b/c"
track = Tracks(session, track_path)
track = models.Tracks(session, track_path)
playlist_tab.insert_track(session, track)
# Save playlist
playlist_tab.save_playlist(session)
# We need to commit the session before re-querying
session.commit()
# Retrieve playlist
playlists = Playlists.get_open(session)
assert len(playlists) == 1
retrieved_playlist = playlists[0]
assert track_path in [a.path for a in retrieved_playlist.tracks.values()]
assert note_text in [a.note for a in retrieved_playlist.notes]
all_playlists = playlists.Playlists.get_open(session)
assert len(all_playlists) == 1
retrieved_playlist = all_playlists[0]
paths = [a.path for a in retrieved_playlist.tracks.values()]
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):
# Create playlist
playlist = Playlists(session, "my playlist")
playlist_tab = PlaylistTab(None, session, playlist.id)
playlist = models.Playlists(session, "my playlist")
playlist_tab = playlists.PlaylistTab(None, session, playlist.id)
# Add some tracks
track1_path = "/a/b/c"
track1 = Tracks(session, track1_path)
track1 = models.Tracks(session, track1_path)
playlist_tab.insert_track(session, track1)
track2_path = "/d/e/f"
track2 = Tracks(session, track2_path)
track2 = models.Tracks(session, track2_path)
playlist_tab.insert_track(session, track2)
track3_path = "/h/i/j"
track3 = Tracks(session, track3_path)
track3 = models.Tracks(session, track3_path)
playlist_tab.insert_track(session, track3)
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):
# Create playlist
playlist = Playlists(session, "my playlist")
playlist_tab = PlaylistTab(None, session, playlist.id)
playlist = playlists.Playlists(session, "my playlist")
playlist_tab = playlists.PlaylistTab(None, session, playlist.id)
# Add some tracks
track1_path = "/a/b/c"
track1 = Tracks(session, track1_path)
track1 = models.Tracks(session, track1_path)
playlist_tab.insert_track(session, track1)
track2_path = "/d/e/f"
track2 = Tracks(session, track2_path)
track2 = models.Tracks(session, track2_path)
playlist_tab.insert_track(session, track2)
track3_path = "/h/i/j"
track3 = Tracks(session, track3_path)
track3 = models.Tracks(session, track3_path)
playlist_tab.insert_track(session, track3)
assert len(playlist_tab._get_unreadable_track_rows()) == 3
@ -99,7 +136,7 @@ def test_meta(qtbot, session):
# Add a note
note_text = "my note"
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)
assert playlist_tab._get_played_track_rows() == [0]
@ -147,15 +184,15 @@ def test_meta(qtbot, session):
def test_clear_next(qtbot, session):
# Create playlist
playlist = Playlists(session, "my playlist")
playlist_tab = PlaylistTab(None, session, playlist.id)
playlist = models.Playlists(session, "my playlist")
playlist_tab = playlists.PlaylistTab(None, session, playlist.id)
# Add some tracks
track1_path = "/a/b/c"
track1 = Tracks(session, track1_path)
track1 = models.Tracks(session, track1_path)
playlist_tab.insert_track(session, track1)
track2_path = "/d/e/f"
track2 = Tracks(session, track2_path)
track2 = models.Tracks(session, track2_path)
playlist_tab.insert_track(session, track2)
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
def test_get_selected_row(qtbot, session):
def test_get_selected_row(qtbot, monkeypatch, session):
# Create playlist
playlist = Playlists(session, "test playlist")
playlist_tab = PlaylistTab(None, session, playlist.id)
monkeypatch.setattr(musicmuster, "Session", session)
monkeypatch.setattr(playlists, "Session", session)
# 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
track1_path = "/a/b/c"
track1 = Tracks(session, track1_path)
track1 = models.Tracks(session, track1_path)
playlist_tab.insert_track(session, track1)
track2_path = "/d/e/f"
track2 = Tracks(session, track2_path)
track2 = models.Tracks(session, track2_path)
playlist_tab.insert_track(session, track2)
window = Window()
qtbot.addWidget(playlist_tab)
with qtbot.waitExposed(window):
window.show()
@ -191,32 +231,50 @@ 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
playlist = Playlists(session, "test playlist")
playlist_tab = PlaylistTab(None, session, playlist.id)
window = musicmuster.Window()
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
track1_path = "testdata/isa.mp3"
track1 = Tracks(session, track1_path)
track1 = models.Tracks.get_from_filename(session, "isa.mp3")
playlist_tab.insert_track(session, track1)
track2_path = "mom.mp3"
track2 = Tracks(session, track2_path)
track2 = models.Tracks.get_from_filename(session, "mom.mp3")
playlist_tab.insert_track(session, track2)
window = Window()
qtbot.addWidget(playlist_tab)
with qtbot.waitExposed(window):
window.show()
row0_item2 = playlist_tab.item(0, 2)
assert row0_item2 is not None
rect = playlist_tab.visualItemRect(row0_item2)
qtbot.mouseClick(
playlist_tab.viewport(), Qt.LeftButton, pos=rect.center()
)
qtbot.wait(10000)
# qtbot.wait(10000)
qtbot.keyPress(playlist_tab.viewport(), "N",
modifier=Qt.ControlModifier)
qtbot.wait(2000)
pass
def test_kae(monkeypatch, session):
# monkeypatch.setattr(dbconfig, "Session", session)
monkeypatch.setattr(musicmuster, "Session", session)
musicmuster.Window.kae()
# monkeypatch.setattr(musicmuster, "Session", session)
# monkeypatch.setattr(dbconfig, "Session", session)
# monkeypatch.setattr(models, "Session", session)
# monkeypatch.setattr(playlists, "Session", session)