Compare commits
No commits in common. "35438f59fb7fd3d6be5c9905522a3b95885f63c5" and "5f1682c0c675122ca890916243ca0737af75abb9" have entirely different histories.
35438f59fb
...
5f1682c0c6
@ -116,7 +116,6 @@ class PlaylistTrack:
|
|||||||
self.end_time: Optional[dt.datetime] = None
|
self.end_time: Optional[dt.datetime] = None
|
||||||
self.fade_at: Optional[int] = None
|
self.fade_at: Optional[int] = None
|
||||||
self.fade_graph: Optional[FadeCurve] = None
|
self.fade_graph: Optional[FadeCurve] = None
|
||||||
self.fade_graph_start_updates: Optional[dt.datetime] = None
|
|
||||||
self.fade_length: Optional[int] = None
|
self.fade_length: Optional[int] = None
|
||||||
self.path: Optional[str] = None
|
self.path: Optional[str] = None
|
||||||
self.playlist_id: Optional[int] = None
|
self.playlist_id: Optional[int] = None
|
||||||
@ -183,20 +182,10 @@ class PlaylistTrack:
|
|||||||
Called when track starts playing
|
Called when track starts playing
|
||||||
"""
|
"""
|
||||||
|
|
||||||
now = dt.datetime.now()
|
self.start_time = dt.datetime.now()
|
||||||
self.start_time = now
|
|
||||||
if self.duration:
|
if self.duration:
|
||||||
self.end_time = self.start_time + dt.timedelta(milliseconds=self.duration)
|
self.end_time = self.start_time + dt.timedelta(milliseconds=self.duration)
|
||||||
|
|
||||||
# Calculate time fade_graph should start updating
|
|
||||||
if self.fade_at:
|
|
||||||
update_graph_at_ms = max(
|
|
||||||
0, self.fade_at - Config.FADE_CURVE_MS_BEFORE_FADE - 1
|
|
||||||
)
|
|
||||||
self.fade_graph_start_updates = now + dt.timedelta(
|
|
||||||
milliseconds=update_graph_at_ms
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class AddFadeCurve(QObject):
|
class AddFadeCurve(QObject):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -1,11 +1,13 @@
|
|||||||
# Standard library imports
|
# Standard library imports
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
import datetime as dt
|
import datetime as dt
|
||||||
|
|
||||||
# PyQt imports
|
# PyQt imports
|
||||||
|
|
||||||
# Third party imports
|
# Third party imports
|
||||||
from alchemical import Model # type: ignore
|
from alchemical import Alchemical, Model # type: ignore
|
||||||
from sqlalchemy import (
|
from sqlalchemy import (
|
||||||
Boolean,
|
Boolean,
|
||||||
DateTime,
|
DateTime,
|
||||||
|
|||||||
@ -1,15 +1,17 @@
|
|||||||
# Standard library imports
|
# Standard library imports
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
# PyQt imports
|
# PyQt imports
|
||||||
|
|
||||||
|
# Third party imports
|
||||||
|
|
||||||
|
# App imports
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
from PyQt6.QtCore import QEvent, Qt
|
from PyQt6.QtCore import QEvent, Qt
|
||||||
from PyQt6.QtWidgets import QDialog, QListWidgetItem
|
from PyQt6.QtWidgets import QDialog, QListWidgetItem
|
||||||
|
|
||||||
# Third party imports
|
|
||||||
from sqlalchemy.orm.session import Session
|
|
||||||
|
|
||||||
# App imports
|
|
||||||
from classes import MusicMusterSignals
|
from classes import MusicMusterSignals
|
||||||
|
from sqlalchemy.orm import scoped_session
|
||||||
from helpers import (
|
from helpers import (
|
||||||
ask_yes_no,
|
ask_yes_no,
|
||||||
get_relative_date,
|
get_relative_date,
|
||||||
@ -26,7 +28,7 @@ class TrackSelectDialog(QDialog):
|
|||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
session: Session,
|
session: scoped_session,
|
||||||
new_row_number: int,
|
new_row_number: int,
|
||||||
source_model: PlaylistModel,
|
source_model: PlaylistModel,
|
||||||
add_to_header: Optional[bool] = False,
|
add_to_header: Optional[bool] = False,
|
||||||
|
|||||||
@ -44,7 +44,7 @@ class FadeTrack(QRunnable):
|
|||||||
sleep(1 / Config.FADEOUT_STEPS_PER_SECOND)
|
sleep(1 / Config.FADEOUT_STEPS_PER_SECOND)
|
||||||
|
|
||||||
self.player.stop()
|
self.player.stop()
|
||||||
log.debug(f"Releasing player {self.player=}")
|
log.error(f"Releasing player {self.player=}")
|
||||||
self.player.release()
|
self.player.release()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -48,7 +48,7 @@ from PyQt6.QtWidgets import (
|
|||||||
# Third party imports
|
# Third party imports
|
||||||
from pygame import mixer
|
from pygame import mixer
|
||||||
import pipeclient
|
import pipeclient
|
||||||
from sqlalchemy.orm.session import Session
|
from sqlalchemy.orm import scoped_session
|
||||||
import stackprinter # type: ignore
|
import stackprinter # type: ignore
|
||||||
|
|
||||||
# App imports
|
# App imports
|
||||||
@ -562,7 +562,7 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
self.timer1000.timeout.connect(self.tick_1000ms)
|
self.timer1000.timeout.connect(self.tick_1000ms)
|
||||||
|
|
||||||
def create_playlist(
|
def create_playlist(
|
||||||
self, session: Session, playlist_name: Optional[str] = None
|
self, session: scoped_session, playlist_name: Optional[str] = None
|
||||||
) -> Optional[Playlists]:
|
) -> Optional[Playlists]:
|
||||||
"""Create new playlist"""
|
"""Create new playlist"""
|
||||||
|
|
||||||
@ -1140,25 +1140,34 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
break
|
break
|
||||||
sleep(0.1)
|
sleep(0.1)
|
||||||
|
|
||||||
|
# TODO: remove sleep() calls - used to try to isolate bug #223
|
||||||
# Show closing volume graph
|
# Show closing volume graph
|
||||||
|
sleep(1)
|
||||||
if track_sequence.now.fade_graph:
|
if track_sequence.now.fade_graph:
|
||||||
track_sequence.now.fade_graph.plot()
|
track_sequence.now.fade_graph.plot()
|
||||||
else:
|
else:
|
||||||
log.error("No fade_graph")
|
log.error("No fade_graph")
|
||||||
|
|
||||||
# Note that track is playing
|
# Note that track is playing
|
||||||
log.debug("set track_sequence")
|
sleep(1)
|
||||||
|
log.error("set track_sequence")
|
||||||
track_sequence.now.start()
|
track_sequence.now.start()
|
||||||
self.playing = True
|
self.playing = True
|
||||||
|
|
||||||
# Disable play next controls
|
# Disable play next controls
|
||||||
|
sleep(1)
|
||||||
|
log.error("catch return key")
|
||||||
self.catch_return_key = True
|
self.catch_return_key = True
|
||||||
self.show_status_message("Play controls: Disabled", 0)
|
self.show_status_message("Play controls: Disabled", 0)
|
||||||
|
|
||||||
# Notify model
|
# Notify model
|
||||||
|
sleep(1)
|
||||||
|
log.error("active_proxy_model().current_track_started()")
|
||||||
self.active_proxy_model().current_track_started()
|
self.active_proxy_model().current_track_started()
|
||||||
|
|
||||||
# Update headers
|
# Update headers
|
||||||
|
sleep(1)
|
||||||
|
log.error("update headers")
|
||||||
self.update_headers()
|
self.update_headers()
|
||||||
|
|
||||||
def preview(self) -> None:
|
def preview(self) -> None:
|
||||||
@ -1404,7 +1413,7 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
self.tabPlaylist.currentWidget().scroll_to_top(display_row)
|
self.tabPlaylist.currentWidget().scroll_to_top(display_row)
|
||||||
|
|
||||||
def solicit_playlist_name(
|
def solicit_playlist_name(
|
||||||
self, session: Session, default: str = ""
|
self, session: scoped_session, default: str = ""
|
||||||
) -> Optional[str]:
|
) -> Optional[str]:
|
||||||
"""Get name of new playlist from user"""
|
"""Get name of new playlist from user"""
|
||||||
|
|
||||||
@ -1505,12 +1514,6 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# Update volume fade curve
|
# Update volume fade curve
|
||||||
if (
|
|
||||||
track_sequence.now.fade_graph_start_updates is None
|
|
||||||
or track_sequence.now.fade_graph_start_updates > dt.datetime.now()
|
|
||||||
):
|
|
||||||
return
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
track_sequence.now.track_id
|
track_sequence.now.track_id
|
||||||
and track_sequence.now.fade_graph
|
and track_sequence.now.fade_graph
|
||||||
@ -1639,7 +1642,7 @@ class CartDialog(QDialog):
|
|||||||
"""Edit cart details"""
|
"""Edit cart details"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, musicmuster: Window, session: Session, cart: Carts, *args, **kwargs
|
self, musicmuster: Window, session: scoped_session, cart: Carts, *args, **kwargs
|
||||||
) -> None:
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Manage carts
|
Manage carts
|
||||||
|
|||||||
@ -160,7 +160,7 @@ class PipeClient:
|
|||||||
|
|
||||||
def _write_pipe_open(self) -> None:
|
def _write_pipe_open(self) -> None:
|
||||||
"""Open _write_pipe."""
|
"""Open _write_pipe."""
|
||||||
self._write_pipe = open(WRITE_NAME, "w")
|
self._write_pipe = open(WRITE_NAME, 'w')
|
||||||
|
|
||||||
def _read_thread_start(self) -> None:
|
def _read_thread_start(self) -> None:
|
||||||
"""Start read_pipe thread."""
|
"""Start read_pipe thread."""
|
||||||
@ -204,8 +204,8 @@ class PipeClient:
|
|||||||
"""Read FIFO in worker thread."""
|
"""Read FIFO in worker thread."""
|
||||||
# Thread will wait at this read until it connects.
|
# Thread will wait at this read until it connects.
|
||||||
# Connection should occur as soon as _write_pipe has connected.
|
# Connection should occur as soon as _write_pipe has connected.
|
||||||
with open(READ_NAME, "r") as read_pipe:
|
with open(READ_NAME, 'r') as read_pipe:
|
||||||
message = ""
|
message = ''
|
||||||
pipe_ok = True
|
pipe_ok = True
|
||||||
while pipe_ok:
|
while pipe_ok:
|
||||||
line = read_pipe.readline()
|
line = read_pipe.readline()
|
||||||
|
|||||||
@ -279,16 +279,21 @@ class PlaylistModel(QAbstractTableModel):
|
|||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
log.debug("Call OBS scene change")
|
# TODO: remove sleep/log calls, used to debug #223
|
||||||
|
# Check for OBS scene change
|
||||||
|
sleep(1)
|
||||||
|
log.error("Call OBS scene change")
|
||||||
self.obs_scene_change(row_number)
|
self.obs_scene_change(row_number)
|
||||||
|
|
||||||
with db.Session() as session:
|
with db.Session() as session:
|
||||||
# Update Playdates in database
|
# Update Playdates in database
|
||||||
log.debug("update playdates")
|
sleep(1)
|
||||||
|
log.error("update playdates")
|
||||||
Playdates(session, track_sequence.now.track_id)
|
Playdates(session, track_sequence.now.track_id)
|
||||||
|
|
||||||
# Mark track as played in playlist
|
# Mark track as played in playlist
|
||||||
log.debug("Mark track as played")
|
sleep(1)
|
||||||
|
log.error("Mark track as played")
|
||||||
plr = session.get(PlaylistRows, track_sequence.now.plr_id)
|
plr = session.get(PlaylistRows, track_sequence.now.plr_id)
|
||||||
if plr:
|
if plr:
|
||||||
plr.played = True
|
plr.played = True
|
||||||
@ -297,7 +302,8 @@ class PlaylistModel(QAbstractTableModel):
|
|||||||
log.error(f"Can't retrieve plr, {track_sequence.now.plr_id=}")
|
log.error(f"Can't retrieve plr, {track_sequence.now.plr_id=}")
|
||||||
|
|
||||||
# Update track times
|
# Update track times
|
||||||
log.debug("Update track times")
|
sleep(1)
|
||||||
|
log.error("Update track times")
|
||||||
if prd:
|
if prd:
|
||||||
prd.start_time = track_sequence.now.start_time
|
prd.start_time = track_sequence.now.start_time
|
||||||
prd.end_time = track_sequence.now.end_time
|
prd.end_time = track_sequence.now.end_time
|
||||||
@ -314,7 +320,8 @@ class PlaylistModel(QAbstractTableModel):
|
|||||||
|
|
||||||
# Find next track
|
# Find next track
|
||||||
# Get all unplayed track rows
|
# Get all unplayed track rows
|
||||||
log.debug("Find next track")
|
sleep(1)
|
||||||
|
log.error("Find next track")
|
||||||
next_row = None
|
next_row = None
|
||||||
unplayed_rows = self.get_unplayed_rows()
|
unplayed_rows = self.get_unplayed_rows()
|
||||||
if unplayed_rows:
|
if unplayed_rows:
|
||||||
@ -1215,7 +1222,7 @@ class PlaylistModel(QAbstractTableModel):
|
|||||||
self.signals.next_track_changed_signal.emit()
|
self.signals.next_track_changed_signal.emit()
|
||||||
return
|
return
|
||||||
|
|
||||||
# Update track_sequence
|
# Update playing_track
|
||||||
with db.Session() as session:
|
with db.Session() as session:
|
||||||
track_sequence.next = PlaylistTrack()
|
track_sequence.next = PlaylistTrack()
|
||||||
try:
|
try:
|
||||||
@ -1569,7 +1576,7 @@ class PlaylistProxyModel(QSortFilterProxyModel):
|
|||||||
self,
|
self,
|
||||||
proposed_row_number: Optional[int],
|
proposed_row_number: Optional[int],
|
||||||
track_id: Optional[int] = None,
|
track_id: Optional[int] = None,
|
||||||
note: str = "",
|
note: Optional[str] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
return self.source_model.insert_row(proposed_row_number, track_id, note)
|
return self.source_model.insert_row(proposed_row_number, track_id, note)
|
||||||
|
|
||||||
|
|||||||
@ -4,25 +4,20 @@
|
|||||||
# the current directory contains a "better" version of the file than the
|
# the current directory contains a "better" version of the file than the
|
||||||
# parent (eg, bettet bitrate).
|
# parent (eg, bettet bitrate).
|
||||||
|
|
||||||
# Standard library imports
|
|
||||||
import os
|
import os
|
||||||
|
import pydymenu # type: ignore
|
||||||
import shutil
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
from typing import List
|
|
||||||
|
|
||||||
# PyQt imports
|
|
||||||
|
|
||||||
# Third party imports
|
|
||||||
import pydymenu # type: ignore
|
|
||||||
from sqlalchemy.exc import IntegrityError
|
|
||||||
from sqlalchemy.orm.session import Session
|
|
||||||
|
|
||||||
# App imports
|
|
||||||
from helpers import (
|
from helpers import (
|
||||||
get_tags,
|
get_tags,
|
||||||
set_track_metadata,
|
set_track_metadata,
|
||||||
)
|
)
|
||||||
from models import db, Tracks
|
|
||||||
|
from models import Tracks
|
||||||
|
from dbconfig import Session
|
||||||
|
from sqlalchemy.exc import IntegrityError
|
||||||
|
from typing import List
|
||||||
|
|
||||||
# ###################### SETTINGS #########################
|
# ###################### SETTINGS #########################
|
||||||
process_name_and_tags_matches = True
|
process_name_and_tags_matches = True
|
||||||
@ -47,7 +42,7 @@ def main():
|
|||||||
# We only want to run this against the production database because
|
# We only want to run this against the production database because
|
||||||
# we will affect files in the common pool of tracks used by all
|
# we will affect files in the common pool of tracks used by all
|
||||||
# databases
|
# databases
|
||||||
if "musicmuster_prod" not in os.environ.get("ALCHEMICAL_DATABASE_URI"):
|
if "musicmuster_prod" not in os.environ.get("MM_DB"):
|
||||||
response = input("Not on production database - c to continue: ")
|
response = input("Not on production database - c to continue: ")
|
||||||
if response != "c":
|
if response != "c":
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
@ -56,7 +51,7 @@ def main():
|
|||||||
assert source_dir != parent_dir
|
assert source_dir != parent_dir
|
||||||
|
|
||||||
# Scan parent directory
|
# Scan parent directory
|
||||||
with db.Session() as session:
|
with Session() as session:
|
||||||
all_tracks = Tracks.get_all(session)
|
all_tracks = Tracks.get_all(session)
|
||||||
parent_tracks = [a for a in all_tracks if parent_dir in a.path]
|
parent_tracks = [a for a in all_tracks if parent_dir in a.path]
|
||||||
parent_fnames = [os.path.basename(a.path) for a in parent_tracks]
|
parent_fnames = [os.path.basename(a.path) for a in parent_tracks]
|
||||||
@ -244,7 +239,7 @@ def process_track(src, dst, title, artist, bitrate):
|
|||||||
if not do_processing:
|
if not do_processing:
|
||||||
return
|
return
|
||||||
|
|
||||||
with db.Session() as session:
|
with Session() as session:
|
||||||
track = Tracks.get_by_path(session, dst)
|
track = Tracks.get_by_path(session, dst)
|
||||||
if track:
|
if track:
|
||||||
# Update path, but workaround MariaDB bug
|
# Update path, but workaround MariaDB bug
|
||||||
|
|||||||
@ -59,7 +59,7 @@ explicit_package_bases = true
|
|||||||
[tool.pytest.ini_options]
|
[tool.pytest.ini_options]
|
||||||
addopts = "--exitfirst --showlocals --capture=no"
|
addopts = "--exitfirst --showlocals --capture=no"
|
||||||
pythonpath = [".", "app"]
|
pythonpath = [".", "app"]
|
||||||
filterwarnings = ["ignore:'audioop' is deprecated", "ignore:pkg_resources"]
|
filterwarnings = "ignore:'audioop' is deprecated"
|
||||||
|
|
||||||
[tool.vulture]
|
[tool.vulture]
|
||||||
exclude = ["migrations", "app/ui", "archive"]
|
exclude = ["migrations", "app/ui", "archive"]
|
||||||
|
|||||||
@ -79,13 +79,12 @@ class TestMMMiscTracks(unittest.TestCase):
|
|||||||
self.model.insert_row(proposed_row_number=END_ROW, note="-")
|
self.model.insert_row(proposed_row_number=END_ROW, note="-")
|
||||||
|
|
||||||
prd = self.model.playlist_rows[START_ROW]
|
prd = self.model.playlist_rows[START_ROW]
|
||||||
qv_value = self.model.display_role(
|
qv_value = self.model.display_role(START_ROW, playlistmodel.HEADER_NOTES_COLUMN, prd)
|
||||||
START_ROW, playlistmodel.HEADER_NOTES_COLUMN, prd
|
|
||||||
)
|
|
||||||
assert qv_value.value() == "start [1 tracks, 4:23 unplayed]"
|
assert qv_value.value() == "start [1 tracks, 4:23 unplayed]"
|
||||||
|
|
||||||
|
|
||||||
class TestMMMiscNoPlaylist(unittest.TestCase):
|
class TestMMMiscNoPlaylist(unittest.TestCase):
|
||||||
|
|
||||||
PLAYLIST_NAME = "tracks playlist"
|
PLAYLIST_NAME = "tracks playlist"
|
||||||
test_tracks = [
|
test_tracks = [
|
||||||
"testdata/isa.mp3",
|
"testdata/isa.mp3",
|
||||||
@ -122,13 +121,10 @@ class TestMMMiscNoPlaylist(unittest.TestCase):
|
|||||||
_ = str(prd)
|
_ = str(prd)
|
||||||
|
|
||||||
assert (
|
assert (
|
||||||
model.edit_role(
|
model.edit_role(model.rowCount() - 1, playlistmodel.Col.TITLE.value, prd)
|
||||||
model.rowCount() - 1, playlistmodel.Col.TITLE.value, prd
|
|
||||||
)
|
|
||||||
== metadata["title"]
|
== metadata["title"]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestMMMiscRowMove(unittest.TestCase):
|
class TestMMMiscRowMove(unittest.TestCase):
|
||||||
PLAYLIST_NAME = "rowmove playlist"
|
PLAYLIST_NAME = "rowmove playlist"
|
||||||
ROWS_TO_CREATE = 11
|
ROWS_TO_CREATE = 11
|
||||||
@ -296,6 +292,7 @@ class TestMMMiscRowMove(unittest.TestCase):
|
|||||||
self.model.add_track_to_header(insert_row, prd.track_id)
|
self.model.add_track_to_header(insert_row, prd.track_id)
|
||||||
|
|
||||||
def test_reverse_row_groups_one_row(self):
|
def test_reverse_row_groups_one_row(self):
|
||||||
|
|
||||||
rows_to_move = [3]
|
rows_to_move = [3]
|
||||||
|
|
||||||
result = self.model._reversed_contiguous_row_groups(rows_to_move)
|
result = self.model._reversed_contiguous_row_groups(rows_to_move)
|
||||||
@ -304,6 +301,7 @@ class TestMMMiscRowMove(unittest.TestCase):
|
|||||||
assert result[0] == [3]
|
assert result[0] == [3]
|
||||||
|
|
||||||
def test_reverse_row_groups_multiple_row(self):
|
def test_reverse_row_groups_multiple_row(self):
|
||||||
|
|
||||||
rows_to_move = [2, 3, 4, 5, 7, 9, 10, 13, 17, 20, 21]
|
rows_to_move = [2, 3, 4, 5, 7, 9, 10, 13, 17, 20, 21]
|
||||||
|
|
||||||
result = self.model._reversed_contiguous_row_groups(rows_to_move)
|
result = self.model._reversed_contiguous_row_groups(rows_to_move)
|
||||||
@ -359,6 +357,7 @@ class TestMMMiscRowMove(unittest.TestCase):
|
|||||||
assert [int(a) for a in row_notes] == [0, 1, 3, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
assert [int(a) for a in row_notes] == [0, 1, 3, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
||||||
|
|
||||||
def test_move_multiple_rows_between_playlists_to_end(self):
|
def test_move_multiple_rows_between_playlists_to_end(self):
|
||||||
|
|
||||||
from_rows = [1, 3, 4]
|
from_rows = [1, 3, 4]
|
||||||
to_row = 2
|
to_row = 2
|
||||||
destination_playlist = "destination"
|
destination_playlist = "destination"
|
||||||
@ -383,22 +382,7 @@ class TestMMMiscRowMove(unittest.TestCase):
|
|||||||
|
|
||||||
assert len(model_src.playlist_rows) == self.ROWS_TO_CREATE - len(from_rows)
|
assert len(model_src.playlist_rows) == self.ROWS_TO_CREATE - len(from_rows)
|
||||||
assert len(model_dst.playlist_rows) == self.ROWS_TO_CREATE + len(from_rows)
|
assert len(model_dst.playlist_rows) == self.ROWS_TO_CREATE + len(from_rows)
|
||||||
assert [int(a) for a in row_notes] == [
|
assert [int(a) for a in row_notes] == [0, 1, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
||||||
0,
|
|
||||||
1,
|
|
||||||
3,
|
|
||||||
4,
|
|
||||||
1,
|
|
||||||
2,
|
|
||||||
3,
|
|
||||||
4,
|
|
||||||
5,
|
|
||||||
6,
|
|
||||||
7,
|
|
||||||
8,
|
|
||||||
9,
|
|
||||||
10,
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
# # def test_edit_header(monkeypatch, session): # edit header row in middle of playlist
|
# # def test_edit_header(monkeypatch, session): # edit header row in middle of playlist
|
||||||
|
|||||||
@ -18,7 +18,6 @@ DB_FILE = "/tmp/mm.db"
|
|||||||
if os.path.exists(DB_FILE):
|
if os.path.exists(DB_FILE):
|
||||||
os.unlink(DB_FILE)
|
os.unlink(DB_FILE)
|
||||||
os.environ["ALCHEMICAL_DATABASE_URI"] = "sqlite:///" + DB_FILE
|
os.environ["ALCHEMICAL_DATABASE_URI"] = "sqlite:///" + DB_FILE
|
||||||
from app import playlistmodel, utilities
|
|
||||||
from app.models import ( # noqa: E402
|
from app.models import ( # noqa: E402
|
||||||
db,
|
db,
|
||||||
Carts,
|
Carts,
|
||||||
@ -42,14 +41,13 @@ def qtbot_adapter(qapp, request):
|
|||||||
# Wrapper to handle setup/teardown operations
|
# Wrapper to handle setup/teardown operations
|
||||||
def with_updown(function):
|
def with_updown(function):
|
||||||
def test_wrapper(self, *args, **kwargs):
|
def test_wrapper(self, *args, **kwargs):
|
||||||
if callable(getattr(self, "up", None)):
|
if callable(getattr(self, 'up', None)):
|
||||||
self.up()
|
self.up()
|
||||||
try:
|
try:
|
||||||
function(self, *args, **kwargs)
|
function(self, *args, **kwargs)
|
||||||
finally:
|
finally:
|
||||||
if callable(getattr(self, "down", None)):
|
if callable(getattr(self, 'down', None)):
|
||||||
self.down()
|
self.down()
|
||||||
|
|
||||||
test_wrapper.__doc__ = function.__doc__
|
test_wrapper.__doc__ = function.__doc__
|
||||||
return test_wrapper
|
return test_wrapper
|
||||||
|
|
||||||
@ -60,41 +58,7 @@ class MyTestCase(unittest.TestCase):
|
|||||||
def up(self):
|
def up(self):
|
||||||
db.create_all()
|
db.create_all()
|
||||||
self.widget = musicmuster.Window()
|
self.widget = musicmuster.Window()
|
||||||
# self.widget.show()
|
self.widget.show()
|
||||||
|
|
||||||
# Add two tracks to database
|
|
||||||
self.tracks = {
|
|
||||||
1: {
|
|
||||||
"path": "testdata/isa.mp3",
|
|
||||||
"title": "I'm so afraid",
|
|
||||||
"artist": "Fleetwood Mac",
|
|
||||||
"bitrate": 64,
|
|
||||||
"duration": 263000,
|
|
||||||
"start_gap": 60,
|
|
||||||
"fade_at": 236263,
|
|
||||||
"silence_at": 260343,
|
|
||||||
"mtime": 371900000,
|
|
||||||
},
|
|
||||||
2: {
|
|
||||||
"path": "testdata/mom.mp3",
|
|
||||||
"title": "Man of Mystery",
|
|
||||||
"artist": "The Shadows",
|
|
||||||
"bitrate": 64,
|
|
||||||
"duration": 120000,
|
|
||||||
"start_gap": 70,
|
|
||||||
"fade_at": 115000,
|
|
||||||
"silence_at": 118000,
|
|
||||||
"mtime": 1642760000,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
with db.Session() as session:
|
|
||||||
for track in self.tracks.values():
|
|
||||||
db_track = Tracks(session=session, **track)
|
|
||||||
session.add(db_track)
|
|
||||||
track['id'] = db_track.id
|
|
||||||
|
|
||||||
session.commit()
|
|
||||||
|
|
||||||
def down(self):
|
def down(self):
|
||||||
db.drop_all()
|
db.drop_all()
|
||||||
@ -103,52 +67,81 @@ class MyTestCase(unittest.TestCase):
|
|||||||
def test_init(self):
|
def test_init(self):
|
||||||
"""Just check we can create a playlist_tab"""
|
"""Just check we can create a playlist_tab"""
|
||||||
|
|
||||||
playlist_name = "test_init playlist"
|
|
||||||
|
|
||||||
with db.Session() as session:
|
with db.Session() as session:
|
||||||
playlist = Playlists(session, playlist_name)
|
playlist = Playlists(session, "test playlist")
|
||||||
|
# playlist_tab = playlists.PlaylistTab(self.widget, playlist.id)
|
||||||
|
|
||||||
self.widget.create_playlist_tab(playlist)
|
self.widget.create_playlist_tab(playlist)
|
||||||
with self.qtbot.waitExposed(self.widget):
|
with self.qtbot.waitExposed(self.widget):
|
||||||
|
# window.show()
|
||||||
|
# with self.qtbot.waitSignal(self.widget.my_signal, timeout=300):
|
||||||
|
# with qtbot.waitExposed(window):
|
||||||
self.widget.show()
|
self.widget.show()
|
||||||
|
|
||||||
@with_updown
|
|
||||||
def test_save_and_restore(self):
|
|
||||||
"""Playlist with one track, one note, save and restore"""
|
|
||||||
|
|
||||||
note_text = "my note"
|
# def seed2tracks(session):
|
||||||
playlist_name = "test_save_and_restore playlist"
|
# 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,
|
||||||
|
# },
|
||||||
|
# ]
|
||||||
|
|
||||||
with db.Session() as session:
|
# for track in tracks:
|
||||||
playlist = Playlists(session, playlist_name)
|
# db_track = models.Tracks(session=session, **track)
|
||||||
model = playlistmodel.PlaylistModel(playlist.id)
|
# session.add(db_track)
|
||||||
|
|
||||||
# Add a track with a note
|
# session.commit()
|
||||||
model.insert_row(proposed_row_number=0, track_id=self.tracks[1]['id'], note=note_text)
|
|
||||||
|
|
||||||
# We need to commit the session before re-querying
|
|
||||||
session.commit()
|
|
||||||
|
|
||||||
# Retrieve playlist
|
|
||||||
all_playlists = Playlists.get_all(session)
|
|
||||||
assert len(all_playlists) == 1
|
|
||||||
retrieved_playlist = all_playlists[0]
|
|
||||||
assert len(retrieved_playlist.rows) == 1
|
|
||||||
paths = [a.track.path for a in retrieved_playlist.rows]
|
|
||||||
assert self.tracks[1]['path'] in paths
|
|
||||||
notes = [a.note for a in retrieved_playlist.rows]
|
|
||||||
assert note_text in notes
|
|
||||||
|
|
||||||
@with_updown
|
# def test_save_and_restore(qtbot, session):
|
||||||
def test_utilities(self):
|
# """Playlist with one track, one note, save and restore"""
|
||||||
"""Test check_db utility"""
|
|
||||||
|
|
||||||
from config import Config
|
# # Create playlist
|
||||||
|
# playlist = models.Playlists(session, "my playlist")
|
||||||
|
# playlist_tab = playlists.PlaylistTab(None, session, playlist.id)
|
||||||
|
|
||||||
Config.ROOT = os.path.join(os.path.dirname(__file__), 'testdata')
|
# # Insert a note
|
||||||
|
# note_text = "my note"
|
||||||
|
# note_row = 7
|
||||||
|
# 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 = models.Tracks(session, track_path)
|
||||||
|
# # Inserting the track will also save the playlist
|
||||||
|
# playlist_tab.insert_track(session, track)
|
||||||
|
|
||||||
|
# # We need to commit the session before re-querying
|
||||||
|
# session.commit()
|
||||||
|
|
||||||
|
# # Retrieve playlist
|
||||||
|
# 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
|
||||||
|
|
||||||
with db.Session() as session:
|
|
||||||
utilities.check_db(session)
|
|
||||||
utilities.update_bitrates(session)
|
|
||||||
|
|
||||||
# def test_meta_all_clear(qtbot, session):
|
# def test_meta_all_clear(qtbot, session):
|
||||||
# # Create playlist
|
# # Create playlist
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user