From f3bf829ef354ad880f1c4c7cfef33d83f8879674 Mon Sep 17 00:00:00 2001 From: Keith Edmunds Date: Wed, 2 Mar 2022 09:11:52 +0000 Subject: [PATCH] Rebase dev onto v2_id --- app/models.py | 65 ++++++++++++++++++++--------------------- app/musicmuster.py | 4 +-- poetry.lock | 50 ++++++++++++++++---------------- pyproject.toml | 2 +- test_models.py | 72 ++++++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 131 insertions(+), 62 deletions(-) diff --git a/app/models.py b/app/models.py index 6ba4708..47019bc 100644 --- a/app/models.py +++ b/app/models.py @@ -31,7 +31,7 @@ Base = declarative_base() Session = scoped_session(sessionmaker()) -def dbinit(): +def db_init(): # Set up database connection global Session @@ -74,15 +74,16 @@ class NoteColours(Base): return session.query(cls).all() @classmethod - def get_by_id(cls, session, id): + def get_by_id(cls, session, note_id): """Return record identified by id, or None if not found""" - return session.query(NoteColours).filter(NoteColours.id == id).first() + return session.query(NoteColours).filter( + NoteColours.id == note_id).first() @staticmethod def get_colour(session, text): """ - Parse text and return colour string if match, else None + Parse text and return colour string if matched, else None """ for rec in ( @@ -125,7 +126,7 @@ class Notes(Base): @classmethod def add_note(cls, session, playlist_id, row, text): - "Add note" + """Add note""" DEBUG(f"add_note(playlist_id={playlist_id}, row={row}, text={text})") note = Notes() @@ -138,23 +139,23 @@ class Notes(Base): return note @staticmethod - def delete_note(session, id): - "Delete note" + def delete_note(session, note_id): + """Delete note""" - DEBUG(f"delete_note(id={id}") + DEBUG(f"delete_note(id={note_id}") - session.query(Notes).filter(Notes.id == id).delete() + session.query(Notes).filter(Notes.id == note_id).delete() session.commit() @classmethod - def update_note(cls, session, id, row, text=None): + def update_note(cls, session, note_id, row, text=None): """ Update note details. If text=None, don't change text. """ - DEBUG(f"Notes.update_note(id={id}, row={row}, text={text})") + DEBUG(f"Notes.update_note(id={note_id}, row={row}, text={text})") - note = session.query(Notes).filter(Notes.id == id).one() + note = session.query(Notes).filter(Notes.id == note_id).one() note.row = row if text: note.note = text @@ -173,7 +174,7 @@ class Playdates(Base): @classmethod def add_playdate(cls, session, track): - "Record that track was played" + """Record that track was played""" DEBUG(f"add_playdate(track={track})") pd = Playdates() @@ -187,7 +188,7 @@ class Playdates(Base): @staticmethod def last_played(session, track_id): - "Return datetime track last played or None" + """Return datetime track last played or None""" last_played = session.query(Playdates.lastplayed).filter( (Playdates.track_id == track_id) @@ -266,7 +267,7 @@ class Playlists(Base): back_populates="playlists") def __repr__(self): - return (f"") + return f"" def add_track(self, session, track, row=None): """ @@ -285,7 +286,7 @@ class Playlists(Base): session.commit() def close(self, session): - "Record playlist as no longer loaded" + """Record playlist as no longer loaded""" self.loaded = False session.add(self) @@ -293,20 +294,20 @@ class Playlists(Base): @classmethod def get_all_closed_playlists(cls, session): - "Returns a list of all playlists not currently open" + """Returns a list of all playlists not currently open""" return ( session.query(cls) .filter( (cls.loaded == False) | # noqa E712 - (cls.loaded == None) + (cls.loaded.is_(None)) ) .order_by(cls.last_used.desc()) ).all() @classmethod def get_all_playlists(cls, session): - "Returns a list of all playlists" + """Returns a list of all playlists""" return session.query(cls).all() @@ -344,7 +345,7 @@ class Playlists(Base): return playlist def open(self, session): - "Mark playlist as loaded and used now" + """Mark playlist as loaded and used now""" self.loaded = True self.last_used = datetime.now() @@ -377,7 +378,7 @@ class PlaylistTracks(Base): @staticmethod def get_track_playlists(session, track_id): - "Return all PlaylistTracks objects with this track_id" + """Return all PlaylistTracks objects with this track_id""" return session.query(PlaylistTracks).filter( PlaylistTracks.track_id == track_id).all() @@ -416,7 +417,7 @@ class PlaylistTracks(Base): @staticmethod def new_row(session, playlist_id): """ - Return row number > largest existing row number + Return row number > the largest existing row number If there are no existing rows, return 0 (ie, first row number) """ @@ -539,13 +540,13 @@ class Tracks(Base): @staticmethod def get_all_paths(session): - "Return a list of paths of all tracks" + """Return a list of paths of all tracks""" return [a[0] for a in session.query(Tracks.path).all()] @staticmethod def get_all_tracks(session): - "Return a list of all tracks" + """Return a list of all tracks""" return session.query(Tracks).all() @@ -561,12 +562,12 @@ class Tracks(Base): return track @staticmethod - def get_duration(session, id): + def get_duration(session, track_id): try: return session.query( - Tracks.duration).filter(Tracks.id == id).one()[0] + Tracks.duration).filter(Tracks.id == track_id).one()[0] except NoResultFound: - ERROR(f"Can't find track id {id}") + ERROR(f"Can't find track id {track_id}") return None @staticmethod @@ -597,7 +598,7 @@ class Tracks(Base): @staticmethod def get_path(session, track_id): - "Return path of passed track_id, or None" + """Return path of passed track_id, or None""" try: return session.query(Tracks.path).filter( @@ -608,7 +609,7 @@ class Tracks(Base): @staticmethod def get_track(session, track_id): - "Return track or None" + """Return track or None""" try: DEBUG(f"Tracks.get_track(track_id={track_id})") @@ -620,7 +621,7 @@ class Tracks(Base): @staticmethod def remove_path(session, path): - "Remove track with passed path from database" + """Remove track with passed path from database""" DEBUG(f"Tracks.remove_path({path=})") @@ -670,9 +671,9 @@ class Tracks(Base): ).all() @staticmethod - def track_from_id(session, id): + def track_from_id(session, track_id): return session.query(Tracks).filter( - Tracks.id == id).one() + Tracks.id == track_id).one() @staticmethod def update_lastplayed(session, track_id): diff --git a/app/musicmuster.py b/app/musicmuster.py index 3fec216..1044957 100755 --- a/app/musicmuster.py +++ b/app/musicmuster.py @@ -27,7 +27,7 @@ import helpers import music from config import Config -from models import (dbinit, Notes, Playdates, Playlists, PlaylistTracks, +from models import (db_init, Notes, Playdates, Playlists, PlaylistTracks, Session, Settings, Tracks) from playlists import PlaylistTab from songdb import create_track_from_file @@ -952,7 +952,7 @@ class SelectPlaylistDialog(QDialog): def main(): try: app = QApplication(sys.argv) - dbinit() + db_init() win = Window() win.show() sys.exit(app.exec()) diff --git a/poetry.lock b/poetry.lock index e32f9d5..b2ff6a2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,6 +1,6 @@ [[package]] name = "alembic" -version = "1.7.5" +version = "1.7.6" description = "A database migration tool for SQLAlchemy." category = "main" optional = false @@ -326,7 +326,7 @@ python-versions = "*" [[package]] name = "pyqt5-sip" -version = "12.9.0" +version = "12.9.1" description = "The sip module support for PyQt5" category = "main" optional = false @@ -499,8 +499,8 @@ content-hash = "0c1303cb7e23bd0c24c31b08e727cfe278bc6bdaa2ac3450a8c689c2ee7b74f2 [metadata.files] alembic = [ - {file = "alembic-1.7.5-py3-none-any.whl", hash = "sha256:a9dde941534e3d7573d9644e8ea62a2953541e27bc1793e166f60b777ae098b4"}, - {file = "alembic-1.7.5.tar.gz", hash = "sha256:7c328694a2e68f03ee971e63c3bd885846470373a5b532cf2c9f1601c413b153"}, + {file = "alembic-1.7.6-py3-none-any.whl", hash = "sha256:ad842f2c3ab5c5d4861232730779c05e33db4ba880a08b85eb505e87c01095bc"}, + {file = "alembic-1.7.6.tar.gz", hash = "sha256:6c0c05e9768a896d804387e20b299880fe01bc56484246b0dffe8075d6d3d847"}, ] appnope = [ {file = "appnope-0.1.2-py2.py3-none-any.whl", hash = "sha256:93aa393e9d6c54c5cd570ccadd8edad61ea0c4b9ea7a01409020c9aa019eb442"}, @@ -790,27 +790,27 @@ pyqt5-qt5 = [ {file = "PyQt5_Qt5-5.15.2-py3-none-win_amd64.whl", hash = "sha256:750b78e4dba6bdf1607febedc08738e318ea09e9b10aea9ff0d73073f11f6962"}, ] pyqt5-sip = [ - {file = "PyQt5_sip-12.9.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6d5bca2fc222d58e8093ee8a81a6e3437067bb22bc3f86d06ec8be721e15e90a"}, - {file = "PyQt5_sip-12.9.0-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:d59af63120d1475b2bf94fe8062610720a9be1e8940ea146c7f42bb449d49067"}, - {file = "PyQt5_sip-12.9.0-cp310-cp310-win32.whl", hash = "sha256:0fc9aefacf502696710b36cdc9fa2a61487f55ee883dbcf2c2a6477e261546f7"}, - {file = "PyQt5_sip-12.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:485972daff2fb0311013f471998f8ec8262ea381bded244f9d14edaad5f54271"}, - {file = "PyQt5_sip-12.9.0-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:d85002238b5180bce4b245c13d6face848faa1a7a9e5c6e292025004f2fd619a"}, - {file = "PyQt5_sip-12.9.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:83c3220b1ca36eb8623ba2eb3766637b19eb0ce9f42336ad8253656d32750c0a"}, - {file = "PyQt5_sip-12.9.0-cp36-cp36m-win32.whl", hash = "sha256:d8b2bdff7bbf45bc975c113a03b14fd669dc0c73e1327f02706666a7dd51a197"}, - {file = "PyQt5_sip-12.9.0-cp36-cp36m-win_amd64.whl", hash = "sha256:69a3ad4259172e2b1aa9060de211efac39ddd734a517b1924d9c6c0cc4f55f96"}, - {file = "PyQt5_sip-12.9.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:42274a501ab4806d2c31659170db14c282b8313d2255458064666d9e70d96206"}, - {file = "PyQt5_sip-12.9.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:6a8701892a01a5a2a4720872361197cc80fdd5f49c8482d488ddf38c9c84f055"}, - {file = "PyQt5_sip-12.9.0-cp37-cp37m-win32.whl", hash = "sha256:ac57d796c78117eb39edd1d1d1aea90354651efac9d3590aac67fa4983f99f1f"}, - {file = "PyQt5_sip-12.9.0-cp37-cp37m-win_amd64.whl", hash = "sha256:4347bd81d30c8e3181e553b3734f91658cfbdd8f1a19f254777f906870974e6d"}, - {file = "PyQt5_sip-12.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c446971c360a0a1030282a69375a08c78e8a61d568bfd6dab3dcc5cf8817f644"}, - {file = "PyQt5_sip-12.9.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:fc43f2d7c438517ee33e929e8ae77132749c15909afab6aeece5fcf4147ffdb5"}, - {file = "PyQt5_sip-12.9.0-cp38-cp38-win32.whl", hash = "sha256:055581c6fed44ba4302b70eeb82e979ff70400037358908f251cd85cbb3dbd93"}, - {file = "PyQt5_sip-12.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:c5216403d4d8d857ec4a61f631d3945e44fa248aa2415e9ee9369ab7c8a4d0c7"}, - {file = "PyQt5_sip-12.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a25b9843c7da6a1608f310879c38e6434331aab1dc2fe6cb65c14f1ecf33780e"}, - {file = "PyQt5_sip-12.9.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:dd05c768c2b55ffe56a9d49ce6cc77cdf3d53dbfad935258a9e347cbfd9a5850"}, - {file = "PyQt5_sip-12.9.0-cp39-cp39-win32.whl", hash = "sha256:4f8e05fe01d54275877c59018d8e82dcdd0bc5696053a8b830eecea3ce806121"}, - {file = "PyQt5_sip-12.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:b09f4cd36a4831229fb77c424d89635fa937d97765ec90685e2f257e56a2685a"}, - {file = "PyQt5_sip-12.9.0.tar.gz", hash = "sha256:d3e4489d7c2b0ece9d203ae66e573939f7f60d4d29e089c9f11daa17cfeaae32"}, + {file = "PyQt5_sip-12.9.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6b2e553e21b7ff124007a6b9168f8bb8c171fdf230d31ca0588df180f10bacbe"}, + {file = "PyQt5_sip-12.9.1-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:5740a1770d6b92a5dca8bb0bda4620baf0d7a726beb864f69c667ddac91d6f64"}, + {file = "PyQt5_sip-12.9.1-cp310-cp310-win32.whl", hash = "sha256:9699286fcdf4f75a4b91c7e4832c0f926af18d648c62a4ed72dd294c1a93705a"}, + {file = "PyQt5_sip-12.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:e2792af660da7479799f53028da88190ae8b4a0ad5acc2acbfd6c7bbfe110d58"}, + {file = "PyQt5_sip-12.9.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:7ee08ad0ebf85b935f5d8d38306f8665fff9a6026c14fc0a7d780649e889c096"}, + {file = "PyQt5_sip-12.9.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2d21420b0739df2607864e2c80ca01994bc40cb116da6ad024ea8d9f407b0356"}, + {file = "PyQt5_sip-12.9.1-cp36-cp36m-win32.whl", hash = "sha256:ffd25051962c593d1c3c30188b9fbd8589ba17acd23a0202dc987bd3552fa611"}, + {file = "PyQt5_sip-12.9.1-cp36-cp36m-win_amd64.whl", hash = "sha256:78ef8f1f41819661aa8e3117d6c1cd76fa14aef265e5bfd515dbfc64d412416b"}, + {file = "PyQt5_sip-12.9.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5e641182bfee0501267c55e687832e4efe05becdae9e555d3695d706009b6598"}, + {file = "PyQt5_sip-12.9.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:c9a977d2835a5fbf250b00d61267dc228bdec9e20c7420d4e8d54d6f20410f87"}, + {file = "PyQt5_sip-12.9.1-cp37-cp37m-win32.whl", hash = "sha256:cec6ebf0b1163b18f09bc523160c467a9528b6dca129753827ac0bc432b332ae"}, + {file = "PyQt5_sip-12.9.1-cp37-cp37m-win_amd64.whl", hash = "sha256:82c1b3080db7634fa318fddbb3cfaa30e63a67bca1001a76958c31f30b774a9d"}, + {file = "PyQt5_sip-12.9.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cfaad4a773c18b963092589b1a98153d36624601de8597a4dc287e5a295d5625"}, + {file = "PyQt5_sip-12.9.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:ce7a8b3af9db378c46b345d9809d481a74c4bfcd3129486c054fbdbc6a3503f9"}, + {file = "PyQt5_sip-12.9.1-cp38-cp38-win32.whl", hash = "sha256:8fe5b3e4bbb8b472d05631cad21028d073f9f8eda770041449514cb3824a867f"}, + {file = "PyQt5_sip-12.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:5d59c4a5e856a35c41b47f5a23e1635b38cd1672f4f0122a68ebcb6889523ff2"}, + {file = "PyQt5_sip-12.9.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b56aedf7b0a496e4a8bd6087566888cea448aa01c76126cdb8b140e3ff3f5d93"}, + {file = "PyQt5_sip-12.9.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:53e23dcc0fc3857204abd47660e383b930941bd1aeaf3c78ed59c5c12dd48010"}, + {file = "PyQt5_sip-12.9.1-cp39-cp39-win32.whl", hash = "sha256:ee188eac5fd94dfe8d9e04a9e7fbda65c3535d5709278d8b7367ebd54f00e27f"}, + {file = "PyQt5_sip-12.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:989d51c41456cc496cb96f0b341464932b957040d26561f0bb4cf5a0914d6b36"}, + {file = "PyQt5_sip-12.9.1.tar.gz", hash = "sha256:2f24f299b44c511c23796aafbbb581bfdebf78d0905657b7cee2141b4982030e"}, ] pyqtwebengine = [ {file = "PyQtWebEngine-5.15.5-cp36-abi3-macosx_10_13_x86_64.whl", hash = "sha256:5c77f71d88d871bc7400c68ef6433fadc5bd57b86d1a9c4d8094cea42f3607f1"}, diff --git a/pyproject.toml b/pyproject.toml index 1a0aa18..de1fd51 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,7 +16,7 @@ alembic = "^1.7.5" psutil = "^5.9.0" PyQtWebEngine = "^5.15.5" pydub = "^0.25.1" -PyQt5-sip = "^12.9.0" +PyQt5-sip = "^12.9.1" [tool.poetry.dev-dependencies] mypy = "^0.931" diff --git a/test_models.py b/test_models.py index a9c1657..6be5f07 100644 --- a/test_models.py +++ b/test_models.py @@ -1,3 +1,6 @@ +import time + + from app.models import ( NoteColours, Notes, @@ -70,7 +73,7 @@ def test_notes_delete_note(session): session.commit() note_text = "Here we are" - rec =Notes.add_note(session, pl.id, 1, note_text) + rec = Notes.add_note(session, pl.id, 1, note_text) Notes.delete_note(session, rec.id) @@ -127,7 +130,7 @@ def test_playdates_remove_track(session): # Need to commit because track record is updated in Playdates.add_playdate() session.commit() - playdate = Playdates.add_playdate(session, track) + Playdates.add_playdate(session, track) Playdates.remove_track(session, track.id) last_played = Playdates.last_played(session, track.id) @@ -154,3 +157,68 @@ def test_playlist_add_track(session): tracks = playlist.get_tracks() assert len(tracks) == 1 assert tracks[0].path == track_path + + +def test_playlist_close(session): + """Test closing a playlist""" + + playlist = Playlists() + playlist.name = "Test playlist one" + session.add(playlist) + session.commit() + + playlist2 = Playlists() + playlist2.name = "Test playlist two" + session.add(playlist2) + session.commit() + + apl = Playlists.get_all_playlists(session) + assert len(apl) == 2 + + cpl = Playlists.get_all_closed_playlists(session) + assert len(cpl) == 0 + + playlist2.close(session) + + cpl = Playlists.get_all_closed_playlists(session) + assert len(cpl) == 1 + + +def test_playlist_get_last_user(session): + """Test get_last_used function""" + + playlist1 = Playlists() + playlist1.name = "Test playlist one" + session.add(playlist1) + session.commit() + + playlist2 = Playlists() + playlist2.name = "Test playlist two" + session.add(playlist2) + session.commit() + + playlist3 = Playlists() + playlist3.name = "Test playlist three" + session.add(playlist3) + session.commit() + + apl = Playlists.get_all_playlists(session) + assert len(apl) == 3 + + playlist1.open(session) + playlist2.close(session) + time.sleep(1) + playlist3.open(session) + + last_used = Playlists.get_last_used(session) + assert len(last_used) == 2 + assert last_used[0].name == "Test playlist three" + + +def test_playlist_new(session): + """Test new function""" + + plname = "This is a test name" + p = Playlists.new(session, plname) + n = Playlists.get_playlist_by_id(session, p.id) + assert p.name == n.name