Compare commits

...

2 Commits

Author SHA1 Message Date
Keith Edmunds
1749f0a0b8 Actually add tracks chosen from query 2025-03-13 10:41:56 +00:00
Keith Edmunds
c9ff1aa668 Improver performance loading playlists 2025-03-09 19:23:55 +00:00
8 changed files with 100 additions and 11 deletions

View File

@ -5,7 +5,7 @@ from dataclasses import dataclass
from enum import auto, Enum
import functools
import threading
from typing import NamedTuple, Optional
from typing import NamedTuple
# Third party imports
@ -97,10 +97,7 @@ class MusicMusterSignals(QObject):
"""
Class for all MusicMuster signals. See:
- https://zetcode.com/gui/pyqt5/eventssignals/
- https://stackoverflow.com/questions/62654525/
emit-a-signal-from-another-class-to-main-class
and Singleton class at
https://refactoring.guru/design-patterns/singleton/python/example#example-0
- https://stackoverflow.com/questions/62654525/emit-a-signal-from-another-class-to-main-class
"""
begin_reset_model_signal = pyqtSignal(int)

View File

@ -22,7 +22,7 @@ from sqlalchemy import (
)
from sqlalchemy.exc import IntegrityError, ProgrammingError
from sqlalchemy.orm.exc import NoResultFound
from sqlalchemy.orm import joinedload
from sqlalchemy.orm import joinedload, selectinload
from sqlalchemy.orm.session import Session
from sqlalchemy.engine.row import RowMapping
@ -48,6 +48,7 @@ cache_region = make_region().configure(
expiration_time=600 # Cache expires after 10 minutes
)
def run_sql(session: Session, sql: str) -> Sequence[RowMapping]:
"""
Run a sql string and return results
@ -519,9 +520,13 @@ class PlaylistRows(dbtables.PlaylistRowsTable):
For passed playlist, return a list of rows.
"""
plrs = session.scalars(
select(cls).where(cls.playlist_id == playlist_id).order_by(cls.row_number)
).all()
stmt = (
select(cls)
.where(cls.playlist_id == playlist_id)
.options(selectinload(cls.track))
.order_by(cls.row_number)
)
plrs = session.execute(stmt).scalars().all()
return plrs

View File

@ -6,6 +6,7 @@ from time import sleep
from typing import Optional
# Third party imports
# import line_profiler
import numpy as np
import pyqtgraph as pg # type: ignore
from sqlalchemy.orm.session import Session

View File

@ -57,6 +57,7 @@ from PyQt6.QtWidgets import (
)
# Third party imports
# import line_profiler
from pygame import mixer
from sqlalchemy.orm.session import Session
import stackprinter # type: ignore
@ -71,7 +72,7 @@ from classes import (
from config import Config
from dialogs import TrackSelectDialog
from file_importer import FileImporter
from helpers import file_is_unreadable, get_name
from helpers import ask_yes_no, file_is_unreadable, get_name
from log import log
from models import db, Playdates, PlaylistRows, Playlists, Queries, Settings, Tracks
from music_manager import RowAndTrack, track_sequence
@ -1430,7 +1431,27 @@ class Window(QMainWindow):
# Keep a reference else it will be gc'd
self.query_dialog = QueryDialog(session, query_id)
self.query_dialog.exec()
if self.query_dialog.exec():
new_row_number = self.current_row_or_end()
base_model = self.current.base_model
for track_id in self.query_dialog.selected_tracks:
# Check whether track is already in playlist
move_existing = False
existing_prd = base_model.is_track_in_playlist(track_id)
if existing_prd is not None:
if ask_yes_no(
"Duplicate row",
"Track already in playlist. " "Move to new location?",
default_yes=True,
):
move_existing = True
if move_existing and existing_prd:
base_model.move_track_add_note(new_row_number, existing_prd, note="")
else:
base_model.insert_row(new_row_number, track_id)
new_row_number += 1
# # # # # # # # # # Playlist management functions # # # # # # # # # #

View File

@ -24,6 +24,7 @@ from PyQt6.QtGui import (
)
# Third party imports
# import line_profiler
from sqlalchemy.orm.session import Session
import obswebsocket # type: ignore

View File

@ -31,6 +31,7 @@ from PyQt6.QtWidgets import (
)
# Third party imports
# import line_profiler
# App imports
from audacity_controller import AudacityController

View File

@ -32,6 +32,7 @@ dependencies = [
"audioop-lts>=0.2.1",
"types-pyyaml>=6.0.12.20241230",
"dogpile-cache>=1.3.4",
"pdbpp>=0.10.3",
]
[dependency-groups]

62
uv.lock
View File

@ -37,6 +37,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/25/8a/c46dcc25341b5bce5472c718902eb3d38600a903b14fa6aeecef3f21a46f/asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2", size = 26918 },
]
[[package]]
name = "attrs"
version = "25.1.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/49/7c/fdf464bcc51d23881d110abd74b512a42b3d5d376a55a831b44c603ae17f/attrs-25.1.0.tar.gz", hash = "sha256:1c97078a80c814273a76b2a298a932eb681c87415c11dee0a6921de7f1b02c3e", size = 810562 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/fc/30/d4986a882011f9df997a55e6becd864812ccfcd821d64aac8570ee39f719/attrs-25.1.0-py3-none-any.whl", hash = "sha256:c75a69e28a550a7e93789579c22aa26b0f5b83b75dc4e08fe092980051e1090a", size = 63152 },
]
[[package]]
name = "audioop-lts"
version = "0.2.1"
@ -199,6 +208,19 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/7b/8f/c4d9bafc34ad7ad5d8dc16dd1347ee0e507a52c3adb6bfa8887e1c6a26ba/executing-2.2.0-py2.py3-none-any.whl", hash = "sha256:11387150cad388d62750327a53d3339fad4888b39a6fe233c3afbb54ecffd3aa", size = 26702 },
]
[[package]]
name = "fancycompleter"
version = "0.9.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pyreadline", marker = "sys_platform == 'win32'" },
{ name = "pyrepl" },
]
sdist = { url = "https://files.pythonhosted.org/packages/a9/95/649d135442d8ecf8af5c7e235550c628056423c96c4bc6787348bdae9248/fancycompleter-0.9.1.tar.gz", hash = "sha256:09e0feb8ae242abdfd7ef2ba55069a46f011814a80fe5476be48f51b00247272", size = 10866 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/38/ef/c08926112034d017633f693d3afc8343393a035134a29dfc12dcd71b0375/fancycompleter-0.9.1-py3-none-any.whl", hash = "sha256:dd076bca7d9d524cc7f25ec8f35ef95388ffef9ef46def4d3d25e9b044ad7080", size = 9681 },
]
[[package]]
name = "flake8"
version = "7.1.2"
@ -467,6 +489,7 @@ dependencies = [
{ name = "mutagen" },
{ name = "mysqlclient" },
{ name = "obs-websocket-py" },
{ name = "pdbpp" },
{ name = "psutil" },
{ name = "pydub" },
{ name = "pydymenu" },
@ -511,6 +534,7 @@ requires-dist = [
{ name = "mutagen", specifier = ">=1.47.0" },
{ name = "mysqlclient", specifier = ">=2.2.5" },
{ name = "obs-websocket-py", specifier = ">=1.0" },
{ name = "pdbpp", specifier = ">=0.10.3" },
{ name = "psutil", specifier = ">=6.1.0" },
{ name = "pydub", specifier = ">=0.25.1" },
{ name = "pydymenu", specifier = ">=0.5.2" },
@ -668,6 +692,20 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/47/ac/684d71315abc7b1214d59304e23a982472967f6bf4bde5a98f1503f648dc/pbr-6.1.1-py2.py3-none-any.whl", hash = "sha256:38d4daea5d9fa63b3f626131b9d34947fd0c8be9b05a29276870580050a25a76", size = 108997 },
]
[[package]]
name = "pdbpp"
version = "0.10.3"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "fancycompleter" },
{ name = "pygments" },
{ name = "wmctrl" },
]
sdist = { url = "https://files.pythonhosted.org/packages/1f/a3/c4bd048256fd4b7d28767ca669c505e156f24d16355505c62e6fce3314df/pdbpp-0.10.3.tar.gz", hash = "sha256:d9e43f4fda388eeb365f2887f4e7b66ac09dce9b6236b76f63616530e2f669f5", size = 68116 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/93/ee/491e63a57fffa78b9de1c337b06c97d0cd0753e88c00571c7b011680332a/pdbpp-0.10.3-py2.py3-none-any.whl", hash = "sha256:79580568e33eb3d6f6b462b1187f53e10cd8e4538f7d31495c9181e2cf9665d1", size = 23961 },
]
[[package]]
name = "pexpect"
version = "4.9.0"
@ -928,6 +966,18 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/7b/34/5702b3b7cafe99be1d94b42f100e8cc5e6957b761fcb1cf5f72d492851da/pyqtgraph-0.13.7-py3-none-any.whl", hash = "sha256:7754edbefb6c367fa0dfb176e2d0610da3ada20aa7a5318516c74af5fb72bf7a", size = 1925473 },
]
[[package]]
name = "pyreadline"
version = "2.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/bc/7c/d724ef1ec3ab2125f38a1d53285745445ec4a8f19b9bb0761b4064316679/pyreadline-2.1.zip", hash = "sha256:4530592fc2e85b25b1a9f79664433da09237c1a270e4d78ea5aa3a2c7229e2d1", size = 109189 }
[[package]]
name = "pyrepl"
version = "0.9.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/05/1b/ea40363be0056080454cdbabe880773c3c5bd66d7b13f0c8b8b8c8da1e0c/pyrepl-0.9.0.tar.gz", hash = "sha256:292570f34b5502e871bbb966d639474f2b57fbfcd3373c2d6a2f3d56e681a775", size = 48744 }
[[package]]
name = "pytest"
version = "8.3.5"
@ -1231,3 +1281,15 @@ sdist = { url = "https://files.pythonhosted.org/packages/e6/30/fba0d96b4b5fbf594
wheels = [
{ url = "https://files.pythonhosted.org/packages/5a/84/44687a29792a70e111c5c477230a72c4b957d88d16141199bf9acb7537a3/websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526", size = 58826 },
]
[[package]]
name = "wmctrl"
version = "0.5"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "attrs" },
]
sdist = { url = "https://files.pythonhosted.org/packages/60/d9/6625ead93412c5ce86db1f8b4f2a70b8043e0a7c1d30099ba3c6a81641ff/wmctrl-0.5.tar.gz", hash = "sha256:7839a36b6fe9e2d6fd22304e5dc372dbced2116ba41283ea938b2da57f53e962", size = 5202 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/13/ca/723e3f8185738d7947f14ee7dc663b59415c6dee43bd71575f8c7f5cd6be/wmctrl-0.5-py2.py3-none-any.whl", hash = "sha256:ae695c1863a314c899e7cf113f07c0da02a394b968c4772e1936219d9234ddd7", size = 4268 },
]