V4 WIP: mostly Black formatting

This commit is contained in:
Keith Edmunds 2024-04-05 09:42:51 +01:00
parent 3821a7061b
commit c380d37cf9
18 changed files with 496 additions and 296 deletions

View File

@ -53,7 +53,6 @@ class MyTableWidget(QTableView):
class MyModel(QAbstractTableModel): class MyModel(QAbstractTableModel):
def columnCount(self, index): def columnCount(self, index):
return 2 return 2
@ -71,7 +70,11 @@ class MyModel(QAbstractTableModel):
return QVariant() return QVariant()
def flags(self, index): def flags(self, index):
return Qt.ItemFlag.ItemIsEnabled | Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEditable return (
Qt.ItemFlag.ItemIsEnabled
| Qt.ItemFlag.ItemIsSelectable
| Qt.ItemFlag.ItemIsEditable
)
class MainWindow(QMainWindow): class MainWindow(QMainWindow):

View File

@ -66,7 +66,9 @@ class PlaydatesTable(Model):
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
lastplayed: Mapped[dt.datetime] = mapped_column(index=True) lastplayed: Mapped[dt.datetime] = mapped_column(index=True)
track_id: Mapped[int] = mapped_column(ForeignKey("tracks.id")) track_id: Mapped[int] = mapped_column(ForeignKey("tracks.id"))
track: Mapped["TracksTable"] = relationship("TracksTable", back_populates="playdates") track: Mapped["TracksTable"] = relationship(
"TracksTable", back_populates="playdates"
)
def __repr__(self) -> str: def __repr__(self) -> str:
return ( return (

View File

@ -111,7 +111,9 @@ class TrackSelectDialog(QDialog):
if self.add_to_header: if self.add_to_header:
if move_existing and existing_prd: # "and existing_prd" for mypy's benefit if move_existing and existing_prd: # "and existing_prd" for mypy's benefit
self.source_model.move_track_to_header(self.new_row_number, existing_prd, note) self.source_model.move_track_to_header(
self.new_row_number, existing_prd, note
)
else: else:
self.source_model.add_track_to_header(self.new_row_number, track_id) self.source_model.add_track_to_header(self.new_row_number, track_id)
# Close dialog - we can only add one track to a header # Close dialog - we can only add one track to a header
@ -119,7 +121,9 @@ class TrackSelectDialog(QDialog):
else: else:
# Adding a new track row # Adding a new track row
if move_existing and existing_prd: # "and existing_prd" for mypy's benefit if move_existing and existing_prd: # "and existing_prd" for mypy's benefit
self.source_model.move_track_add_note(self.new_row_number, existing_prd, note) self.source_model.move_track_add_note(
self.new_row_number, existing_prd, note
)
else: else:
self.source_model.insert_row(self.new_row_number, track_id, note) self.source_model.insert_row(self.new_row_number, track_id, note)

View File

@ -31,14 +31,13 @@ from log import log
ALCHEMICAL_DATABASE_URI = os.environ.get("ALCHEMICAL_DATABASE_URI") ALCHEMICAL_DATABASE_URI = os.environ.get("ALCHEMICAL_DATABASE_URI")
if ALCHEMICAL_DATABASE_URI is None: if ALCHEMICAL_DATABASE_URI is None:
raise ValueError("ALCHEMICAL_DATABASE_URI is undefined") raise ValueError("ALCHEMICAL_DATABASE_URI is undefined")
if 'unittest' in sys.modules and 'sqlite' not in ALCHEMICAL_DATABASE_URI: if "unittest" in sys.modules and "sqlite" not in ALCHEMICAL_DATABASE_URI:
raise ValueError("Unit tests running on non-Sqlite database") raise ValueError("Unit tests running on non-Sqlite database")
db = Alchemical(ALCHEMICAL_DATABASE_URI) db = Alchemical(ALCHEMICAL_DATABASE_URI)
# Database classes # Database classes
class Carts(dbtables.CartsTable): class Carts(dbtables.CartsTable):
def __init__( def __init__(
self, self,
session: Session, session: Session,
@ -61,7 +60,6 @@ class Carts(dbtables.CartsTable):
class NoteColours(dbtables.NoteColoursTable): class NoteColours(dbtables.NoteColoursTable):
def __init__( def __init__(
self, self,
session: Session, session: Session,
@ -123,7 +121,6 @@ class NoteColours(dbtables.NoteColoursTable):
class Playdates(dbtables.PlaydatesTable): class Playdates(dbtables.PlaydatesTable):
def __init__(self, session: Session, track_id: int) -> None: def __init__(self, session: Session, track_id: int) -> None:
"""Record that track was played""" """Record that track was played"""
@ -162,7 +159,6 @@ class Playdates(dbtables.PlaydatesTable):
class Playlists(dbtables.PlaylistsTable): class Playlists(dbtables.PlaylistsTable):
def __init__(self, session: Session, name: str): def __init__(self, session: Session, name: str):
self.name = name self.name = name
session.add(self) session.add(self)
@ -175,11 +171,7 @@ class Playlists(dbtables.PlaylistsTable):
""" """
session.execute( session.execute(
update(Playlists) update(Playlists).where((Playlists.id.in_(playlist_ids))).values(tab=None)
.where(
(Playlists.id.in_(playlist_ids))
)
.values(tab=None)
) )
def close(self) -> None: def close(self) -> None:
@ -295,7 +287,6 @@ class Playlists(dbtables.PlaylistsTable):
class PlaylistRows(dbtables.PlaylistRowsTable): class PlaylistRows(dbtables.PlaylistRowsTable):
def __init__( def __init__(
self, self,
session: Session, session: Session,
@ -361,9 +352,7 @@ class PlaylistRows(dbtables.PlaylistRowsTable):
return session.execute(stmt).unique().scalar_one() return session.execute(stmt).unique().scalar_one()
@classmethod @classmethod
def deep_rows( def deep_rows(cls, session: Session, playlist_id: int) -> Sequence["PlaylistRows"]:
cls, session: Session, playlist_id: int
) -> Sequence["PlaylistRows"]:
""" """
Return a list of playlist rows that include full track and lastplayed data for Return a list of playlist rows that include full track and lastplayed data for
given playlist_id., Sequence given playlist_id., Sequence
@ -380,9 +369,7 @@ class PlaylistRows(dbtables.PlaylistRowsTable):
return session.scalars(stmt).unique().all() return session.scalars(stmt).unique().all()
@staticmethod @staticmethod
def delete_higher_rows( def delete_higher_rows(session: Session, playlist_id: int, maxrow: int) -> None:
session: Session, playlist_id: int, maxrow: int
) -> None:
""" """
Delete rows in given playlist that have a higher row number Delete rows in given playlist that have a higher row number
than 'maxrow' than 'maxrow'
@ -527,10 +514,21 @@ class PlaylistRows(dbtables.PlaylistRowsTable):
@classmethod @classmethod
def insert_row( def insert_row(
cls, session: Session, playlist_id: int, new_row_number: int cls,
session: Session,
playlist_id: int,
new_row_number: int,
note: str = "",
track_id: Optional[int] = None,
) -> "PlaylistRows": ) -> "PlaylistRows":
cls.move_rows_down(session, playlist_id, new_row_number, 1) cls.move_rows_down(session, playlist_id, new_row_number, 1)
return cls(session, playlist_id, new_row_number) return cls(
session,
playlist_id=playlist_id,
row_number=new_row_number,
note=note,
track_id=track_id,
)
@staticmethod @staticmethod
def move_rows_down( def move_rows_down(
@ -574,7 +572,6 @@ class PlaylistRows(dbtables.PlaylistRowsTable):
class Settings(dbtables.SettingsTable): class Settings(dbtables.SettingsTable):
def __init__(self, session: Session, name: str): def __init__(self, session: Session, name: str):
self.name = name self.name = name
session.add(self) session.add(self)
@ -612,7 +609,6 @@ class Settings(dbtables.SettingsTable):
class Tracks(dbtables.TracksTable): class Tracks(dbtables.TracksTable):
def __repr__(self) -> str: def __repr__(self) -> str:
return ( return (
f"<Track(id={self.id}, title={self.title}, " f"<Track(id={self.id}, title={self.title}, "

View File

@ -81,22 +81,22 @@ import argparse
if sys.version_info[0] < 3: if sys.version_info[0] < 3:
raise RuntimeError('PipeClient Error: Python 3.x required') raise RuntimeError("PipeClient Error: Python 3.x required")
# Platform specific constants # Platform specific constants
if sys.platform == 'win32': if sys.platform == "win32":
WRITE_NAME: str = '\\\\.\\pipe\\ToSrvPipe' WRITE_NAME: str = "\\\\.\\pipe\\ToSrvPipe"
READ_NAME: str = '\\\\.\\pipe\\FromSrvPipe' READ_NAME: str = "\\\\.\\pipe\\FromSrvPipe"
EOL: str = '\r\n\0' EOL: str = "\r\n\0"
else: else:
# Linux or Mac # Linux or Mac
PIPE_BASE: str = '/tmp/audacity_script_pipe.' PIPE_BASE: str = "/tmp/audacity_script_pipe."
WRITE_NAME: str = PIPE_BASE + 'to.' + str(os.getuid()) WRITE_NAME: str = PIPE_BASE + "to." + str(os.getuid())
READ_NAME: str = PIPE_BASE + 'from.' + str(os.getuid()) READ_NAME: str = PIPE_BASE + "from." + str(os.getuid())
EOL: str = '\n' EOL: str = "\n"
class PipeClient(): class PipeClient:
"""Write / read client access to Audacity via named pipes. """Write / read client access to Audacity via named pipes.
Normally there should be just one instance of this class. If Normally there should be just one instance of this class. If
@ -141,7 +141,7 @@ class PipeClient():
self.timer: bool = False # type: ignore self.timer: bool = False # type: ignore
self._start_time: float = 0 # type: ignore self._start_time: float = 0 # type: ignore
self._write_pipe = None self._write_pipe = None
self.reply: str = '' # type: ignore self.reply: str = "" # type: ignore
if not self._write_pipe: if not self._write_pipe:
self._write_thread_start() self._write_thread_start()
self._read_thread_start() self._read_thread_start()
@ -156,7 +156,7 @@ class PipeClient():
# Allow a little time for connection to be made. # Allow a little time for connection to be made.
time.sleep(0.1) time.sleep(0.1)
if not self._write_pipe: if not self._write_pipe:
raise RuntimeError('PipeClientError: Write pipe cannot be opened.') raise RuntimeError("PipeClientError: Write pipe cannot be opened.")
def _write_pipe_open(self) -> None: def _write_pipe_open(self) -> None:
"""Open _write_pipe.""" """Open _write_pipe."""
@ -187,16 +187,16 @@ class PipeClient():
self._write_pipe.write(command + EOL) self._write_pipe.write(command + EOL)
# Check that read pipe is alive # Check that read pipe is alive
if PipeClient.reader_pipe_broken.is_set(): if PipeClient.reader_pipe_broken.is_set():
raise RuntimeError('PipeClient: Read-pipe error.') raise RuntimeError("PipeClient: Read-pipe error.")
try: try:
self._write_pipe.flush() self._write_pipe.flush()
if self.timer: if self.timer:
self._start_time = time.time() self._start_time = time.time()
self.reply = '' self.reply = ""
PipeClient.reply_ready.clear() PipeClient.reply_ready.clear()
except IOError as err: except IOError as err:
if err.errno == errno.EPIPE: if err.errno == errno.EPIPE:
raise RuntimeError('PipeClient: Write-pipe error.') raise RuntimeError("PipeClient: Write-pipe error.")
else: else:
raise raise
@ -211,20 +211,20 @@ class PipeClient():
line = read_pipe.readline() line = read_pipe.readline()
# Stop timer as soon as we get first line of response. # Stop timer as soon as we get first line of response.
stop_time = time.time() stop_time = time.time()
while pipe_ok and line != '\n': while pipe_ok and line != "\n":
message += line message += line
line = read_pipe.readline() line = read_pipe.readline()
if line == '': if line == "":
# No data in read_pipe indicates that the pipe # No data in read_pipe indicates that the pipe
# is broken (Audacity may have crashed). # is broken (Audacity may have crashed).
PipeClient.reader_pipe_broken.set() PipeClient.reader_pipe_broken.set()
pipe_ok = False pipe_ok = False
if self.timer: if self.timer:
xtime = (stop_time - self._start_time) * 1000 xtime = (stop_time - self._start_time) * 1000
message += f'Execution time: {xtime:.2f}ms' message += f"Execution time: {xtime:.2f}ms"
self.reply = message self.reply = message
PipeClient.reply_ready.set() PipeClient.reply_ready.set()
message = '' message = ""
def read(self) -> str: def read(self) -> str:
"""Read Audacity's reply from pipe. """Read Audacity's reply from pipe.
@ -238,31 +238,45 @@ class PipeClient():
""" """
if not PipeClient.reply_ready.is_set(): if not PipeClient.reply_ready.is_set():
return '' return ""
return self.reply return self.reply
def bool_from_string(strval) -> bool: def bool_from_string(strval) -> bool:
"""Return boolean value from string""" """Return boolean value from string"""
if strval.lower() in ('true', 't', '1', 'yes', 'y'): if strval.lower() in ("true", "t", "1", "yes", "y"):
return True return True
if strval.lower() in ('false', 'f', '0', 'no', 'n'): if strval.lower() in ("false", "f", "0", "no", "n"):
return False return False
raise argparse.ArgumentTypeError('Boolean value expected.') raise argparse.ArgumentTypeError("Boolean value expected.")
def main() -> None: def main() -> None:
"""Interactive command-line for PipeClient""" """Interactive command-line for PipeClient"""
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument('-t', '--timeout', type=float, metavar='', default=10, parser.add_argument(
help="timeout for reply in seconds (default: 10") "-t",
parser.add_argument('-s', '--show-time', metavar='True/False', "--timeout",
nargs='?', type=bool_from_string, type=float,
const='t', default='t', dest='show', metavar="",
help='show command execution time (default: True)') default=10,
parser.add_argument('-d', '--docs', action='store_true', help="timeout for reply in seconds (default: 10",
help='show documentation and exit') )
parser.add_argument(
"-s",
"--show-time",
metavar="True/False",
nargs="?",
type=bool_from_string,
const="t",
default="t",
dest="show",
help="show command execution time (default: True)",
)
parser.add_argument(
"-d", "--docs", action="store_true", help="show documentation and exit"
)
args = parser.parse_args() args = parser.parse_args()
if args.docs: if args.docs:
@ -271,23 +285,23 @@ def main() -> None:
client: PipeClient = PipeClient() client: PipeClient = PipeClient()
while True: while True:
reply: str = '' reply: str = ""
message: str = input("\nEnter command or 'Q' to quit: ") message: str = input("\nEnter command or 'Q' to quit: ")
start = time.time() start = time.time()
if message.upper() == 'Q': if message.upper() == "Q":
sys.exit(0) sys.exit(0)
elif message == '': elif message == "":
pass pass
else: else:
client.write(message, timer=args.show) client.write(message, timer=args.show)
while reply == '': while reply == "":
time.sleep(0.1) # allow time for reply time.sleep(0.1) # allow time for reply
if time.time() - start > args.timeout: if time.time() - start > args.timeout:
reply = 'PipeClient: Reply timed-out.' reply = "PipeClient: Reply timed-out."
else: else:
reply = client.read() reply = client.read()
print(reply) print(reply)
if __name__ == '__main__': if __name__ == "__main__":
main() main()

View File

@ -27,6 +27,7 @@ from PyQt6.QtGui import (
# Third party imports # Third party imports
import obsws_python as obs # type: ignore import obsws_python as obs # type: ignore
# import snoop # type: ignore # import snoop # type: ignore
# App imports # App imports
@ -689,8 +690,9 @@ class PlaylistModel(QAbstractTableModel):
< prd.plr_rownum < prd.plr_rownum
) )
): ):
section_end_time = track_sequence.now.end_time + dt.timedelta( section_end_time = (
milliseconds=duration track_sequence.now.end_time
+ dt.timedelta(milliseconds=duration)
) )
end_time_str = ( end_time_str = (
", section end time " ", section end time "
@ -745,7 +747,7 @@ class PlaylistModel(QAbstractTableModel):
self, self,
proposed_row_number: Optional[int], proposed_row_number: Optional[int],
track_id: Optional[int] = None, track_id: Optional[int] = None,
note: Optional[str] = None, note: str = "",
) -> None: ) -> None:
""" """
Insert a row. Insert a row.
@ -757,11 +759,13 @@ class PlaylistModel(QAbstractTableModel):
with db.Session() as session: with db.Session() as session:
super().beginInsertRows(QModelIndex(), new_row_number, new_row_number) super().beginInsertRows(QModelIndex(), new_row_number, new_row_number)
plr = PlaylistRows.insert_row(session, self.playlist_id, new_row_number) _ = PlaylistRows.insert_row(
session=session,
plr.track_id = track_id playlist_id=self.playlist_id,
if note: new_row_number=new_row_number,
plr.note = note note=note,
track_id=track_id,
)
self.refresh_data(session) self.refresh_data(session)
super().endInsertRows() super().endInsertRows()

View File

@ -47,6 +47,7 @@ from helpers import (
from log import log from log import log
from models import Settings from models import Settings
from playlistmodel import PlaylistModel, PlaylistProxyModel from playlistmodel import PlaylistModel, PlaylistProxyModel
if TYPE_CHECKING: if TYPE_CHECKING:
from musicmuster import Window from musicmuster import Window

View File

@ -15,7 +15,11 @@ class Ui_MainWindow(object):
MainWindow.resize(1280, 857) MainWindow.resize(1280, 857)
MainWindow.setMinimumSize(QtCore.QSize(1280, 0)) MainWindow.setMinimumSize(QtCore.QSize(1280, 0))
icon = QtGui.QIcon() icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(":/icons/musicmuster"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) icon.addPixmap(
QtGui.QPixmap(":/icons/musicmuster"),
QtGui.QIcon.Mode.Normal,
QtGui.QIcon.State.Off,
)
MainWindow.setWindowIcon(icon) MainWindow.setWindowIcon(icon)
MainWindow.setStyleSheet("") MainWindow.setStyleSheet("")
self.centralwidget = QtWidgets.QWidget(parent=MainWindow) self.centralwidget = QtWidgets.QWidget(parent=MainWindow)
@ -27,39 +31,62 @@ class Ui_MainWindow(object):
self.verticalLayout_3 = QtWidgets.QVBoxLayout() self.verticalLayout_3 = QtWidgets.QVBoxLayout()
self.verticalLayout_3.setObjectName("verticalLayout_3") self.verticalLayout_3.setObjectName("verticalLayout_3")
self.previous_track_2 = QtWidgets.QLabel(parent=self.centralwidget) self.previous_track_2 = QtWidgets.QLabel(parent=self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred) sizePolicy = QtWidgets.QSizePolicy(
QtWidgets.QSizePolicy.Policy.Preferred,
QtWidgets.QSizePolicy.Policy.Preferred,
)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.previous_track_2.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(
self.previous_track_2.sizePolicy().hasHeightForWidth()
)
self.previous_track_2.setSizePolicy(sizePolicy) self.previous_track_2.setSizePolicy(sizePolicy)
self.previous_track_2.setMaximumSize(QtCore.QSize(230, 16777215)) self.previous_track_2.setMaximumSize(QtCore.QSize(230, 16777215))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily("Sans") font.setFamily("Sans")
font.setPointSize(20) font.setPointSize(20)
self.previous_track_2.setFont(font) self.previous_track_2.setFont(font)
self.previous_track_2.setStyleSheet("background-color: #f8d7da;\n" self.previous_track_2.setStyleSheet(
"border: 1px solid rgb(85, 87, 83);") "background-color: #f8d7da;\n" "border: 1px solid rgb(85, 87, 83);"
self.previous_track_2.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight|QtCore.Qt.AlignmentFlag.AlignTrailing|QtCore.Qt.AlignmentFlag.AlignVCenter) )
self.previous_track_2.setAlignment(
QtCore.Qt.AlignmentFlag.AlignRight
| QtCore.Qt.AlignmentFlag.AlignTrailing
| QtCore.Qt.AlignmentFlag.AlignVCenter
)
self.previous_track_2.setObjectName("previous_track_2") self.previous_track_2.setObjectName("previous_track_2")
self.verticalLayout_3.addWidget(self.previous_track_2) self.verticalLayout_3.addWidget(self.previous_track_2)
self.current_track_2 = QtWidgets.QLabel(parent=self.centralwidget) self.current_track_2 = QtWidgets.QLabel(parent=self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred) sizePolicy = QtWidgets.QSizePolicy(
QtWidgets.QSizePolicy.Policy.Preferred,
QtWidgets.QSizePolicy.Policy.Preferred,
)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.current_track_2.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(
self.current_track_2.sizePolicy().hasHeightForWidth()
)
self.current_track_2.setSizePolicy(sizePolicy) self.current_track_2.setSizePolicy(sizePolicy)
self.current_track_2.setMaximumSize(QtCore.QSize(230, 16777215)) self.current_track_2.setMaximumSize(QtCore.QSize(230, 16777215))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily("Sans") font.setFamily("Sans")
font.setPointSize(20) font.setPointSize(20)
self.current_track_2.setFont(font) self.current_track_2.setFont(font)
self.current_track_2.setStyleSheet("background-color: #d4edda;\n" self.current_track_2.setStyleSheet(
"border: 1px solid rgb(85, 87, 83);") "background-color: #d4edda;\n" "border: 1px solid rgb(85, 87, 83);"
self.current_track_2.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight|QtCore.Qt.AlignmentFlag.AlignTrailing|QtCore.Qt.AlignmentFlag.AlignVCenter) )
self.current_track_2.setAlignment(
QtCore.Qt.AlignmentFlag.AlignRight
| QtCore.Qt.AlignmentFlag.AlignTrailing
| QtCore.Qt.AlignmentFlag.AlignVCenter
)
self.current_track_2.setObjectName("current_track_2") self.current_track_2.setObjectName("current_track_2")
self.verticalLayout_3.addWidget(self.current_track_2) self.verticalLayout_3.addWidget(self.current_track_2)
self.next_track_2 = QtWidgets.QLabel(parent=self.centralwidget) self.next_track_2 = QtWidgets.QLabel(parent=self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred) sizePolicy = QtWidgets.QSizePolicy(
QtWidgets.QSizePolicy.Policy.Preferred,
QtWidgets.QSizePolicy.Policy.Preferred,
)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.next_track_2.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(self.next_track_2.sizePolicy().hasHeightForWidth())
@ -69,19 +96,29 @@ class Ui_MainWindow(object):
font.setFamily("Sans") font.setFamily("Sans")
font.setPointSize(20) font.setPointSize(20)
self.next_track_2.setFont(font) self.next_track_2.setFont(font)
self.next_track_2.setStyleSheet("background-color: #fff3cd;\n" self.next_track_2.setStyleSheet(
"border: 1px solid rgb(85, 87, 83);") "background-color: #fff3cd;\n" "border: 1px solid rgb(85, 87, 83);"
self.next_track_2.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight|QtCore.Qt.AlignmentFlag.AlignTrailing|QtCore.Qt.AlignmentFlag.AlignVCenter) )
self.next_track_2.setAlignment(
QtCore.Qt.AlignmentFlag.AlignRight
| QtCore.Qt.AlignmentFlag.AlignTrailing
| QtCore.Qt.AlignmentFlag.AlignVCenter
)
self.next_track_2.setObjectName("next_track_2") self.next_track_2.setObjectName("next_track_2")
self.verticalLayout_3.addWidget(self.next_track_2) self.verticalLayout_3.addWidget(self.next_track_2)
self.horizontalLayout_3.addLayout(self.verticalLayout_3) self.horizontalLayout_3.addLayout(self.verticalLayout_3)
self.verticalLayout = QtWidgets.QVBoxLayout() self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayout.setObjectName("verticalLayout") self.verticalLayout.setObjectName("verticalLayout")
self.hdrPreviousTrack = QtWidgets.QLabel(parent=self.centralwidget) self.hdrPreviousTrack = QtWidgets.QLabel(parent=self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred) sizePolicy = QtWidgets.QSizePolicy(
QtWidgets.QSizePolicy.Policy.Preferred,
QtWidgets.QSizePolicy.Policy.Preferred,
)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.hdrPreviousTrack.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(
self.hdrPreviousTrack.sizePolicy().hasHeightForWidth()
)
self.hdrPreviousTrack.setSizePolicy(sizePolicy) self.hdrPreviousTrack.setSizePolicy(sizePolicy)
self.hdrPreviousTrack.setMinimumSize(QtCore.QSize(0, 0)) self.hdrPreviousTrack.setMinimumSize(QtCore.QSize(0, 0))
self.hdrPreviousTrack.setMaximumSize(QtCore.QSize(16777215, 16777215)) self.hdrPreviousTrack.setMaximumSize(QtCore.QSize(16777215, 16777215))
@ -89,32 +126,43 @@ class Ui_MainWindow(object):
font.setFamily("Sans") font.setFamily("Sans")
font.setPointSize(20) font.setPointSize(20)
self.hdrPreviousTrack.setFont(font) self.hdrPreviousTrack.setFont(font)
self.hdrPreviousTrack.setStyleSheet("background-color: #f8d7da;\n" self.hdrPreviousTrack.setStyleSheet(
"border: 1px solid rgb(85, 87, 83);") "background-color: #f8d7da;\n" "border: 1px solid rgb(85, 87, 83);"
)
self.hdrPreviousTrack.setText("") self.hdrPreviousTrack.setText("")
self.hdrPreviousTrack.setWordWrap(False) self.hdrPreviousTrack.setWordWrap(False)
self.hdrPreviousTrack.setObjectName("hdrPreviousTrack") self.hdrPreviousTrack.setObjectName("hdrPreviousTrack")
self.verticalLayout.addWidget(self.hdrPreviousTrack) self.verticalLayout.addWidget(self.hdrPreviousTrack)
self.hdrCurrentTrack = QtWidgets.QPushButton(parent=self.centralwidget) self.hdrCurrentTrack = QtWidgets.QPushButton(parent=self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred) sizePolicy = QtWidgets.QSizePolicy(
QtWidgets.QSizePolicy.Policy.Preferred,
QtWidgets.QSizePolicy.Policy.Preferred,
)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.hdrCurrentTrack.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(
self.hdrCurrentTrack.sizePolicy().hasHeightForWidth()
)
self.hdrCurrentTrack.setSizePolicy(sizePolicy) self.hdrCurrentTrack.setSizePolicy(sizePolicy)
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(20) font.setPointSize(20)
self.hdrCurrentTrack.setFont(font) self.hdrCurrentTrack.setFont(font)
self.hdrCurrentTrack.setStyleSheet("background-color: #d4edda;\n" self.hdrCurrentTrack.setStyleSheet(
"background-color: #d4edda;\n"
"border: 1px solid rgb(85, 87, 83);\n" "border: 1px solid rgb(85, 87, 83);\n"
"text-align: left;\n" "text-align: left;\n"
"padding-left: 8px;\n" "padding-left: 8px;\n"
"") ""
)
self.hdrCurrentTrack.setText("") self.hdrCurrentTrack.setText("")
self.hdrCurrentTrack.setFlat(True) self.hdrCurrentTrack.setFlat(True)
self.hdrCurrentTrack.setObjectName("hdrCurrentTrack") self.hdrCurrentTrack.setObjectName("hdrCurrentTrack")
self.verticalLayout.addWidget(self.hdrCurrentTrack) self.verticalLayout.addWidget(self.hdrCurrentTrack)
self.hdrNextTrack = QtWidgets.QPushButton(parent=self.centralwidget) self.hdrNextTrack = QtWidgets.QPushButton(parent=self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred) sizePolicy = QtWidgets.QSizePolicy(
QtWidgets.QSizePolicy.Policy.Preferred,
QtWidgets.QSizePolicy.Policy.Preferred,
)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.hdrNextTrack.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(self.hdrNextTrack.sizePolicy().hasHeightForWidth())
@ -122,10 +170,12 @@ class Ui_MainWindow(object):
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(20) font.setPointSize(20)
self.hdrNextTrack.setFont(font) self.hdrNextTrack.setFont(font)
self.hdrNextTrack.setStyleSheet("background-color: #fff3cd;\n" self.hdrNextTrack.setStyleSheet(
"background-color: #fff3cd;\n"
"border: 1px solid rgb(85, 87, 83);\n" "border: 1px solid rgb(85, 87, 83);\n"
"text-align: left;\n" "text-align: left;\n"
"padding-left: 8px;") "padding-left: 8px;"
)
self.hdrNextTrack.setText("") self.hdrNextTrack.setText("")
self.hdrNextTrack.setFlat(True) self.hdrNextTrack.setFlat(True)
self.hdrNextTrack.setObjectName("hdrNextTrack") self.hdrNextTrack.setObjectName("hdrNextTrack")
@ -160,7 +210,12 @@ class Ui_MainWindow(object):
self.cartsWidget.setObjectName("cartsWidget") self.cartsWidget.setObjectName("cartsWidget")
self.horizontalLayout_Carts = QtWidgets.QHBoxLayout(self.cartsWidget) self.horizontalLayout_Carts = QtWidgets.QHBoxLayout(self.cartsWidget)
self.horizontalLayout_Carts.setObjectName("horizontalLayout_Carts") self.horizontalLayout_Carts.setObjectName("horizontalLayout_Carts")
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) spacerItem = QtWidgets.QSpacerItem(
40,
20,
QtWidgets.QSizePolicy.Policy.Expanding,
QtWidgets.QSizePolicy.Policy.Minimum,
)
self.horizontalLayout_Carts.addItem(spacerItem) self.horizontalLayout_Carts.addItem(spacerItem)
self.gridLayout_4.addWidget(self.cartsWidget, 2, 0, 1, 1) self.gridLayout_4.addWidget(self.cartsWidget, 2, 0, 1, 1)
self.frame_6 = QtWidgets.QFrame(parent=self.centralwidget) self.frame_6 = QtWidgets.QFrame(parent=self.centralwidget)
@ -205,7 +260,11 @@ class Ui_MainWindow(object):
self.btnPreview = QtWidgets.QPushButton(parent=self.FadeStopInfoFrame) self.btnPreview = QtWidgets.QPushButton(parent=self.FadeStopInfoFrame)
self.btnPreview.setMinimumSize(QtCore.QSize(132, 41)) self.btnPreview.setMinimumSize(QtCore.QSize(132, 41))
icon1 = QtGui.QIcon() icon1 = QtGui.QIcon()
icon1.addPixmap(QtGui.QPixmap(":/icons/headphones"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) icon1.addPixmap(
QtGui.QPixmap(":/icons/headphones"),
QtGui.QIcon.Mode.Normal,
QtGui.QIcon.State.Off,
)
self.btnPreview.setIcon(icon1) self.btnPreview.setIcon(icon1)
self.btnPreview.setIconSize(QtCore.QSize(30, 30)) self.btnPreview.setIconSize(QtCore.QSize(30, 30))
self.btnPreview.setCheckable(True) self.btnPreview.setCheckable(True)
@ -289,10 +348,15 @@ class Ui_MainWindow(object):
self.label_silent_timer.setObjectName("label_silent_timer") self.label_silent_timer.setObjectName("label_silent_timer")
self.horizontalLayout.addWidget(self.frame_silent) self.horizontalLayout.addWidget(self.frame_silent)
self.widgetFadeVolume = PlotWidget(parent=self.InfoFooterFrame) self.widgetFadeVolume = PlotWidget(parent=self.InfoFooterFrame)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred) sizePolicy = QtWidgets.QSizePolicy(
QtWidgets.QSizePolicy.Policy.Preferred,
QtWidgets.QSizePolicy.Policy.Preferred,
)
sizePolicy.setHorizontalStretch(1) sizePolicy.setHorizontalStretch(1)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.widgetFadeVolume.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(
self.widgetFadeVolume.sizePolicy().hasHeightForWidth()
)
self.widgetFadeVolume.setSizePolicy(sizePolicy) self.widgetFadeVolume.setSizePolicy(sizePolicy)
self.widgetFadeVolume.setMinimumSize(QtCore.QSize(0, 0)) self.widgetFadeVolume.setMinimumSize(QtCore.QSize(0, 0))
self.widgetFadeVolume.setObjectName("widgetFadeVolume") self.widgetFadeVolume.setObjectName("widgetFadeVolume")
@ -309,7 +373,11 @@ class Ui_MainWindow(object):
self.btnFade.setMinimumSize(QtCore.QSize(132, 32)) self.btnFade.setMinimumSize(QtCore.QSize(132, 32))
self.btnFade.setMaximumSize(QtCore.QSize(164, 16777215)) self.btnFade.setMaximumSize(QtCore.QSize(164, 16777215))
icon2 = QtGui.QIcon() icon2 = QtGui.QIcon()
icon2.addPixmap(QtGui.QPixmap(":/icons/fade"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) icon2.addPixmap(
QtGui.QPixmap(":/icons/fade"),
QtGui.QIcon.Mode.Normal,
QtGui.QIcon.State.Off,
)
self.btnFade.setIcon(icon2) self.btnFade.setIcon(icon2)
self.btnFade.setIconSize(QtCore.QSize(30, 30)) self.btnFade.setIconSize(QtCore.QSize(30, 30))
self.btnFade.setObjectName("btnFade") self.btnFade.setObjectName("btnFade")
@ -317,7 +385,11 @@ class Ui_MainWindow(object):
self.btnStop = QtWidgets.QPushButton(parent=self.frame) self.btnStop = QtWidgets.QPushButton(parent=self.frame)
self.btnStop.setMinimumSize(QtCore.QSize(0, 36)) self.btnStop.setMinimumSize(QtCore.QSize(0, 36))
icon3 = QtGui.QIcon() icon3 = QtGui.QIcon()
icon3.addPixmap(QtGui.QPixmap(":/icons/stopsign"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) icon3.addPixmap(
QtGui.QPixmap(":/icons/stopsign"),
QtGui.QIcon.Mode.Normal,
QtGui.QIcon.State.Off,
)
self.btnStop.setIcon(icon3) self.btnStop.setIcon(icon3)
self.btnStop.setObjectName("btnStop") self.btnStop.setObjectName("btnStop")
self.verticalLayout_5.addWidget(self.btnStop) self.verticalLayout_5.addWidget(self.btnStop)
@ -343,39 +415,69 @@ class Ui_MainWindow(object):
MainWindow.setStatusBar(self.statusbar) MainWindow.setStatusBar(self.statusbar)
self.actionPlay_next = QtGui.QAction(parent=MainWindow) self.actionPlay_next = QtGui.QAction(parent=MainWindow)
icon4 = QtGui.QIcon() icon4 = QtGui.QIcon()
icon4.addPixmap(QtGui.QPixmap("app/ui/../../../../.designer/backup/icon-play.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) icon4.addPixmap(
QtGui.QPixmap("app/ui/../../../../.designer/backup/icon-play.png"),
QtGui.QIcon.Mode.Normal,
QtGui.QIcon.State.Off,
)
self.actionPlay_next.setIcon(icon4) self.actionPlay_next.setIcon(icon4)
self.actionPlay_next.setObjectName("actionPlay_next") self.actionPlay_next.setObjectName("actionPlay_next")
self.actionSkipToNext = QtGui.QAction(parent=MainWindow) self.actionSkipToNext = QtGui.QAction(parent=MainWindow)
icon5 = QtGui.QIcon() icon5 = QtGui.QIcon()
icon5.addPixmap(QtGui.QPixmap(":/icons/next"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) icon5.addPixmap(
QtGui.QPixmap(":/icons/next"),
QtGui.QIcon.Mode.Normal,
QtGui.QIcon.State.Off,
)
self.actionSkipToNext.setIcon(icon5) self.actionSkipToNext.setIcon(icon5)
self.actionSkipToNext.setObjectName("actionSkipToNext") self.actionSkipToNext.setObjectName("actionSkipToNext")
self.actionInsertTrack = QtGui.QAction(parent=MainWindow) self.actionInsertTrack = QtGui.QAction(parent=MainWindow)
icon6 = QtGui.QIcon() icon6 = QtGui.QIcon()
icon6.addPixmap(QtGui.QPixmap("app/ui/../../../../.designer/backup/icon_search_database.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) icon6.addPixmap(
QtGui.QPixmap(
"app/ui/../../../../.designer/backup/icon_search_database.png"
),
QtGui.QIcon.Mode.Normal,
QtGui.QIcon.State.Off,
)
self.actionInsertTrack.setIcon(icon6) self.actionInsertTrack.setIcon(icon6)
self.actionInsertTrack.setObjectName("actionInsertTrack") self.actionInsertTrack.setObjectName("actionInsertTrack")
self.actionAdd_file = QtGui.QAction(parent=MainWindow) self.actionAdd_file = QtGui.QAction(parent=MainWindow)
icon7 = QtGui.QIcon() icon7 = QtGui.QIcon()
icon7.addPixmap(QtGui.QPixmap("app/ui/../../../../.designer/backup/icon_open_file.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) icon7.addPixmap(
QtGui.QPixmap("app/ui/../../../../.designer/backup/icon_open_file.png"),
QtGui.QIcon.Mode.Normal,
QtGui.QIcon.State.Off,
)
self.actionAdd_file.setIcon(icon7) self.actionAdd_file.setIcon(icon7)
self.actionAdd_file.setObjectName("actionAdd_file") self.actionAdd_file.setObjectName("actionAdd_file")
self.actionFade = QtGui.QAction(parent=MainWindow) self.actionFade = QtGui.QAction(parent=MainWindow)
icon8 = QtGui.QIcon() icon8 = QtGui.QIcon()
icon8.addPixmap(QtGui.QPixmap("app/ui/../../../../.designer/backup/icon-fade.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) icon8.addPixmap(
QtGui.QPixmap("app/ui/../../../../.designer/backup/icon-fade.png"),
QtGui.QIcon.Mode.Normal,
QtGui.QIcon.State.Off,
)
self.actionFade.setIcon(icon8) self.actionFade.setIcon(icon8)
self.actionFade.setObjectName("actionFade") self.actionFade.setObjectName("actionFade")
self.actionStop = QtGui.QAction(parent=MainWindow) self.actionStop = QtGui.QAction(parent=MainWindow)
icon9 = QtGui.QIcon() icon9 = QtGui.QIcon()
icon9.addPixmap(QtGui.QPixmap(":/icons/stop"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) icon9.addPixmap(
QtGui.QPixmap(":/icons/stop"),
QtGui.QIcon.Mode.Normal,
QtGui.QIcon.State.Off,
)
self.actionStop.setIcon(icon9) self.actionStop.setIcon(icon9)
self.actionStop.setObjectName("actionStop") self.actionStop.setObjectName("actionStop")
self.action_Clear_selection = QtGui.QAction(parent=MainWindow) self.action_Clear_selection = QtGui.QAction(parent=MainWindow)
self.action_Clear_selection.setObjectName("action_Clear_selection") self.action_Clear_selection.setObjectName("action_Clear_selection")
self.action_Resume_previous = QtGui.QAction(parent=MainWindow) self.action_Resume_previous = QtGui.QAction(parent=MainWindow)
icon10 = QtGui.QIcon() icon10 = QtGui.QIcon()
icon10.addPixmap(QtGui.QPixmap(":/icons/previous"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) icon10.addPixmap(
QtGui.QPixmap(":/icons/previous"),
QtGui.QIcon.Mode.Normal,
QtGui.QIcon.State.Off,
)
self.action_Resume_previous.setIcon(icon10) self.action_Resume_previous.setIcon(icon10)
self.action_Resume_previous.setObjectName("action_Resume_previous") self.action_Resume_previous.setObjectName("action_Resume_previous")
self.actionE_xit = QtGui.QAction(parent=MainWindow) self.actionE_xit = QtGui.QAction(parent=MainWindow)
@ -422,7 +524,9 @@ class Ui_MainWindow(object):
self.actionImport = QtGui.QAction(parent=MainWindow) self.actionImport = QtGui.QAction(parent=MainWindow)
self.actionImport.setObjectName("actionImport") self.actionImport.setObjectName("actionImport")
self.actionDownload_CSV_of_played_tracks = QtGui.QAction(parent=MainWindow) self.actionDownload_CSV_of_played_tracks = QtGui.QAction(parent=MainWindow)
self.actionDownload_CSV_of_played_tracks.setObjectName("actionDownload_CSV_of_played_tracks") self.actionDownload_CSV_of_played_tracks.setObjectName(
"actionDownload_CSV_of_played_tracks"
)
self.actionSearch = QtGui.QAction(parent=MainWindow) self.actionSearch = QtGui.QAction(parent=MainWindow)
self.actionSearch.setObjectName("actionSearch") self.actionSearch.setObjectName("actionSearch")
self.actionInsertSectionHeader = QtGui.QAction(parent=MainWindow) self.actionInsertSectionHeader = QtGui.QAction(parent=MainWindow)
@ -450,9 +554,13 @@ class Ui_MainWindow(object):
self.actionResume = QtGui.QAction(parent=MainWindow) self.actionResume = QtGui.QAction(parent=MainWindow)
self.actionResume.setObjectName("actionResume") self.actionResume.setObjectName("actionResume")
self.actionSearch_title_in_Wikipedia = QtGui.QAction(parent=MainWindow) self.actionSearch_title_in_Wikipedia = QtGui.QAction(parent=MainWindow)
self.actionSearch_title_in_Wikipedia.setObjectName("actionSearch_title_in_Wikipedia") self.actionSearch_title_in_Wikipedia.setObjectName(
"actionSearch_title_in_Wikipedia"
)
self.actionSearch_title_in_Songfacts = QtGui.QAction(parent=MainWindow) self.actionSearch_title_in_Songfacts = QtGui.QAction(parent=MainWindow)
self.actionSearch_title_in_Songfacts.setObjectName("actionSearch_title_in_Songfacts") self.actionSearch_title_in_Songfacts.setObjectName(
"actionSearch_title_in_Songfacts"
)
self.actionSelect_duplicate_rows = QtGui.QAction(parent=MainWindow) self.actionSelect_duplicate_rows = QtGui.QAction(parent=MainWindow)
self.actionSelect_duplicate_rows.setObjectName("actionSelect_duplicate_rows") self.actionSelect_duplicate_rows.setObjectName("actionSelect_duplicate_rows")
self.menuFile.addAction(self.actionNewPlaylist) self.menuFile.addAction(self.actionNewPlaylist)
@ -539,38 +647,58 @@ class Ui_MainWindow(object):
self.actionFade.setShortcut(_translate("MainWindow", "Ctrl+Z")) self.actionFade.setShortcut(_translate("MainWindow", "Ctrl+Z"))
self.actionStop.setText(_translate("MainWindow", "S&top")) self.actionStop.setText(_translate("MainWindow", "S&top"))
self.actionStop.setShortcut(_translate("MainWindow", "Ctrl+Alt+S")) self.actionStop.setShortcut(_translate("MainWindow", "Ctrl+Alt+S"))
self.action_Clear_selection.setText(_translate("MainWindow", "Clear &selection")) self.action_Clear_selection.setText(
_translate("MainWindow", "Clear &selection")
)
self.action_Clear_selection.setShortcut(_translate("MainWindow", "Esc")) self.action_Clear_selection.setShortcut(_translate("MainWindow", "Esc"))
self.action_Resume_previous.setText(_translate("MainWindow", "&Resume previous")) self.action_Resume_previous.setText(
_translate("MainWindow", "&Resume previous")
)
self.actionE_xit.setText(_translate("MainWindow", "E&xit")) self.actionE_xit.setText(_translate("MainWindow", "E&xit"))
self.actionTest.setText(_translate("MainWindow", "&Test")) self.actionTest.setText(_translate("MainWindow", "&Test"))
self.actionOpenPlaylist.setText(_translate("MainWindow", "O&pen...")) self.actionOpenPlaylist.setText(_translate("MainWindow", "O&pen..."))
self.actionNewPlaylist.setText(_translate("MainWindow", "&New...")) self.actionNewPlaylist.setText(_translate("MainWindow", "&New..."))
self.actionTestFunction.setText(_translate("MainWindow", "&Test function")) self.actionTestFunction.setText(_translate("MainWindow", "&Test function"))
self.actionSkipToFade.setText(_translate("MainWindow", "&Skip to start of fade")) self.actionSkipToFade.setText(
_translate("MainWindow", "&Skip to start of fade")
)
self.actionSkipToEnd.setText(_translate("MainWindow", "Skip to &end of track")) self.actionSkipToEnd.setText(_translate("MainWindow", "Skip to &end of track"))
self.actionClosePlaylist.setText(_translate("MainWindow", "&Close")) self.actionClosePlaylist.setText(_translate("MainWindow", "&Close"))
self.actionRenamePlaylist.setText(_translate("MainWindow", "&Rename...")) self.actionRenamePlaylist.setText(_translate("MainWindow", "&Rename..."))
self.actionDeletePlaylist.setText(_translate("MainWindow", "Dele&te...")) self.actionDeletePlaylist.setText(_translate("MainWindow", "Dele&te..."))
self.actionMoveSelected.setText(_translate("MainWindow", "Mo&ve selected tracks to...")) self.actionMoveSelected.setText(
_translate("MainWindow", "Mo&ve selected tracks to...")
)
self.actionExport_playlist.setText(_translate("MainWindow", "E&xport...")) self.actionExport_playlist.setText(_translate("MainWindow", "E&xport..."))
self.actionSetNext.setText(_translate("MainWindow", "Set &next")) self.actionSetNext.setText(_translate("MainWindow", "Set &next"))
self.actionSetNext.setShortcut(_translate("MainWindow", "Ctrl+N")) self.actionSetNext.setShortcut(_translate("MainWindow", "Ctrl+N"))
self.actionSelect_next_track.setText(_translate("MainWindow", "Select next track")) self.actionSelect_next_track.setText(
_translate("MainWindow", "Select next track")
)
self.actionSelect_next_track.setShortcut(_translate("MainWindow", "J")) self.actionSelect_next_track.setShortcut(_translate("MainWindow", "J"))
self.actionSelect_previous_track.setText(_translate("MainWindow", "Select previous track")) self.actionSelect_previous_track.setText(
_translate("MainWindow", "Select previous track")
)
self.actionSelect_previous_track.setShortcut(_translate("MainWindow", "K")) self.actionSelect_previous_track.setShortcut(_translate("MainWindow", "K"))
self.actionSelect_played_tracks.setText(_translate("MainWindow", "Select played tracks")) self.actionSelect_played_tracks.setText(
self.actionMoveUnplayed.setText(_translate("MainWindow", "Move &unplayed tracks to...")) _translate("MainWindow", "Select played tracks")
)
self.actionMoveUnplayed.setText(
_translate("MainWindow", "Move &unplayed tracks to...")
)
self.actionAdd_note.setText(_translate("MainWindow", "Add note...")) self.actionAdd_note.setText(_translate("MainWindow", "Add note..."))
self.actionAdd_note.setShortcut(_translate("MainWindow", "Ctrl+T")) self.actionAdd_note.setShortcut(_translate("MainWindow", "Ctrl+T"))
self.actionEnable_controls.setText(_translate("MainWindow", "Enable controls")) self.actionEnable_controls.setText(_translate("MainWindow", "Enable controls"))
self.actionImport.setText(_translate("MainWindow", "Import track...")) self.actionImport.setText(_translate("MainWindow", "Import track..."))
self.actionImport.setShortcut(_translate("MainWindow", "Ctrl+Shift+I")) self.actionImport.setShortcut(_translate("MainWindow", "Ctrl+Shift+I"))
self.actionDownload_CSV_of_played_tracks.setText(_translate("MainWindow", "Download CSV of played tracks...")) self.actionDownload_CSV_of_played_tracks.setText(
_translate("MainWindow", "Download CSV of played tracks...")
)
self.actionSearch.setText(_translate("MainWindow", "Search...")) self.actionSearch.setText(_translate("MainWindow", "Search..."))
self.actionSearch.setShortcut(_translate("MainWindow", "/")) self.actionSearch.setShortcut(_translate("MainWindow", "/"))
self.actionInsertSectionHeader.setText(_translate("MainWindow", "Insert &section header...")) self.actionInsertSectionHeader.setText(
_translate("MainWindow", "Insert &section header...")
)
self.actionInsertSectionHeader.setShortcut(_translate("MainWindow", "Ctrl+H")) self.actionInsertSectionHeader.setShortcut(_translate("MainWindow", "Ctrl+H"))
self.actionRemove.setText(_translate("MainWindow", "&Remove track")) self.actionRemove.setText(_translate("MainWindow", "&Remove track"))
self.actionFind_next.setText(_translate("MainWindow", "Find next")) self.actionFind_next.setText(_translate("MainWindow", "Find next"))
@ -578,8 +706,12 @@ class Ui_MainWindow(object):
self.actionFind_previous.setText(_translate("MainWindow", "Find previous")) self.actionFind_previous.setText(_translate("MainWindow", "Find previous"))
self.actionFind_previous.setShortcut(_translate("MainWindow", "P")) self.actionFind_previous.setShortcut(_translate("MainWindow", "P"))
self.action_About.setText(_translate("MainWindow", "&About")) self.action_About.setText(_translate("MainWindow", "&About"))
self.actionSave_as_template.setText(_translate("MainWindow", "Save as template...")) self.actionSave_as_template.setText(
self.actionNew_from_template.setText(_translate("MainWindow", "New from template...")) _translate("MainWindow", "Save as template...")
)
self.actionNew_from_template.setText(
_translate("MainWindow", "New from template...")
)
self.actionDebug.setText(_translate("MainWindow", "Debug")) self.actionDebug.setText(_translate("MainWindow", "Debug"))
self.actionAdd_cart.setText(_translate("MainWindow", "Edit cart &1...")) self.actionAdd_cart.setText(_translate("MainWindow", "Edit cart &1..."))
self.actionMark_for_moving.setText(_translate("MainWindow", "Mark for moving")) self.actionMark_for_moving.setText(_translate("MainWindow", "Mark for moving"))
@ -588,10 +720,22 @@ class Ui_MainWindow(object):
self.actionPaste.setShortcut(_translate("MainWindow", "Ctrl+V")) self.actionPaste.setShortcut(_translate("MainWindow", "Ctrl+V"))
self.actionResume.setText(_translate("MainWindow", "Resume")) self.actionResume.setText(_translate("MainWindow", "Resume"))
self.actionResume.setShortcut(_translate("MainWindow", "Ctrl+R")) self.actionResume.setShortcut(_translate("MainWindow", "Ctrl+R"))
self.actionSearch_title_in_Wikipedia.setText(_translate("MainWindow", "Search title in Wikipedia")) self.actionSearch_title_in_Wikipedia.setText(
self.actionSearch_title_in_Wikipedia.setShortcut(_translate("MainWindow", "Ctrl+W")) _translate("MainWindow", "Search title in Wikipedia")
self.actionSearch_title_in_Songfacts.setText(_translate("MainWindow", "Search title in Songfacts")) )
self.actionSearch_title_in_Songfacts.setShortcut(_translate("MainWindow", "Ctrl+S")) self.actionSearch_title_in_Wikipedia.setShortcut(
self.actionSelect_duplicate_rows.setText(_translate("MainWindow", "Select duplicate rows...")) _translate("MainWindow", "Ctrl+W")
)
self.actionSearch_title_in_Songfacts.setText(
_translate("MainWindow", "Search title in Songfacts")
)
self.actionSearch_title_in_Songfacts.setShortcut(
_translate("MainWindow", "Ctrl+S")
)
self.actionSelect_duplicate_rows.setText(
_translate("MainWindow", "Select duplicate rows...")
)
from infotabs import InfoTabs from infotabs import InfoTabs
from pyqtgraph import PlotWidget from pyqtgraph import PlotWidget

View File

@ -49,9 +49,9 @@ def leading_silence(audio_segment, silence_threshold=-50.0, chunk_size=10):
trim_ms = 0 # ms trim_ms = 0 # ms
assert chunk_size > 0 # to avoid infinite loop assert chunk_size > 0 # to avoid infinite loop
while ( while audio_segment[
audio_segment[trim_ms:trim_ms + chunk_size].dBFS < silence_threshold trim_ms : trim_ms + chunk_size
and trim_ms < len(audio_segment)): ].dBFS < silence_threshold and trim_ms < len(audio_segment):
trim_ms += chunk_size trim_ms += chunk_size
# if there is no end it should return the length of the segment # if there is no end it should return the length of the segment
@ -73,7 +73,8 @@ def significant_fade(audio_segment, fade_threshold=-20.0, chunk_size=10):
trim_ms = segment_length - chunk_size trim_ms = segment_length - chunk_size
while ( while (
audio_segment[trim_ms : trim_ms + chunk_size].dBFS < fade_threshold audio_segment[trim_ms : trim_ms + chunk_size].dBFS < fade_threshold
and trim_ms > 0): and trim_ms > 0
):
trim_ms -= chunk_size trim_ms -= chunk_size
# if there is no trailing silence, return lenght of track (it's less # if there is no trailing silence, return lenght of track (it's less
@ -95,7 +96,8 @@ def trailing_silence(audio_segment, silence_threshold=-50.0, chunk_size=10):
trim_ms = segment_length - chunk_size trim_ms = segment_length - chunk_size
while ( while (
audio_segment[trim_ms : trim_ms + chunk_size].dBFS < silence_threshold audio_segment[trim_ms : trim_ms + chunk_size].dBFS < silence_threshold
and trim_ms > 0): and trim_ms > 0
):
trim_ms -= chunk_size trim_ms -= chunk_size
# if there is no trailing silence, return lenght of track (it's less # if there is no trailing silence, return lenght of track (it's less
@ -124,15 +126,17 @@ def update_progress(player, talk_at, silent_at):
remaining_time = total_time - elapsed_time remaining_time = total_time - elapsed_time
talk_time = remaining_time - (total_time - talk_at) talk_time = remaining_time - (total_time - talk_at)
silent_time = remaining_time - (total_time - silent_at) silent_time = remaining_time - (total_time - silent_at)
end_time = (dt.datetime.now() + timedelta( end_time = (dt.datetime.now() + timedelta(milliseconds=remaining_time)).strftime(
milliseconds=remaining_time)).strftime("%H:%M:%S") "%H:%M:%S"
)
print( print(
f"\t{ms_to_mmss(elapsed_time)}/" f"\t{ms_to_mmss(elapsed_time)}/"
f"{ms_to_mmss(total_time)}\t\t" f"{ms_to_mmss(total_time)}\t\t"
f"Talk in: {ms_to_mmss(talk_time)} " f"Talk in: {ms_to_mmss(talk_time)} "
f"Silent in: {ms_to_mmss(silent_time)} " f"Silent in: {ms_to_mmss(silent_time)} "
f"Ends at: {end_time} [{ms_to_mmss(remaining_time)}]" f"Ends at: {end_time} [{ms_to_mmss(remaining_time)}]",
, end="\r") end="\r",
)
# Print name of current song, print name of next song. Play current when # Print name of current song, print name of next song. Play current when

View File

@ -1,5 +1,3 @@
# tl = Timeloop() # tl = Timeloop()
# #
# #

View File

@ -7,7 +7,7 @@ from PyQt5.QtCore import Qt
qt_creator_file = "mainwindow.ui" qt_creator_file = "mainwindow.ui"
Ui_MainWindow, QtBaseClass = uic.loadUiType(qt_creator_file) Ui_MainWindow, QtBaseClass = uic.loadUiType(qt_creator_file)
tick = QtGui.QImage('tick.png') tick = QtGui.QImage("tick.png")
class TodoModel(QtCore.QAbstractListModel): class TodoModel(QtCore.QAbstractListModel):
@ -56,7 +56,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
self.model.todos.append((False, text)) self.model.todos.append((False, text))
# Trigger refresh. # Trigger refresh.
self.model.layoutChanged.emit() self.model.layoutChanged.emit()
# Empty the input # Empty the input
self.todoEdit.setText("") self.todoEdit.setText("")
self.save() self.save()
@ -88,13 +88,13 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def load(self): def load(self):
try: try:
with open('data.db', 'r') as f: with open("data.db", "r") as f:
self.model.todos = json.load(f) self.model.todos = json.load(f)
except Exception: except Exception:
pass pass
def save(self): def save(self):
with open('data.db', 'w') as f: with open("data.db", "w") as f:
data = json.dump(self.model.todos, f) data = json.dump(self.model.todos, f)
@ -102,5 +102,3 @@ app = QtWidgets.QApplication(sys.argv)
window = MainWindow() window = MainWindow()
window.show() window.show()
app.exec_() app.exec_()

View File

@ -10,23 +10,23 @@ import sqlalchemy as sa
from sqlalchemy.dialects import mysql from sqlalchemy.dialects import mysql
# revision identifiers, used by Alembic. # revision identifiers, used by Alembic.
revision = '0c604bf490f8' revision = "0c604bf490f8"
down_revision = '29c0d7ffc741' down_revision = "29c0d7ffc741"
branch_labels = None branch_labels = None
depends_on = None depends_on = None
def upgrade(): def upgrade():
# ### commands auto generated by Alembic - please adjust! ### # ### commands auto generated by Alembic - please adjust! ###
op.add_column('playlist_rows', sa.Column('played', sa.Boolean(), nullable=False)) op.add_column("playlist_rows", sa.Column("played", sa.Boolean(), nullable=False))
op.drop_index('ix_tracks_lastplayed', table_name='tracks') op.drop_index("ix_tracks_lastplayed", table_name="tracks")
op.drop_column('tracks', 'lastplayed') op.drop_column("tracks", "lastplayed")
# ### end Alembic commands ### # ### end Alembic commands ###
def downgrade(): def downgrade():
# ### commands auto generated by Alembic - please adjust! ### # ### commands auto generated by Alembic - please adjust! ###
op.add_column('tracks', sa.Column('lastplayed', mysql.DATETIME(), nullable=True)) op.add_column("tracks", sa.Column("lastplayed", mysql.DATETIME(), nullable=True))
op.create_index('ix_tracks_lastplayed', 'tracks', ['lastplayed'], unique=False) op.create_index("ix_tracks_lastplayed", "tracks", ["lastplayed"], unique=False)
op.drop_column('playlist_rows', 'played') op.drop_column("playlist_rows", "played")
# ### end Alembic commands ### # ### end Alembic commands ###

View File

@ -10,21 +10,21 @@ import sqlalchemy as sa
# revision identifiers, used by Alembic. # revision identifiers, used by Alembic.
revision = '2cc37d3cf07f' revision = "2cc37d3cf07f"
down_revision = 'e3b04db5506f' down_revision = "e3b04db5506f"
branch_labels = None branch_labels = None
depends_on = None depends_on = None
def upgrade(): def upgrade():
# ### commands auto generated by Alembic - please adjust! ### # ### commands auto generated by Alembic - please adjust! ###
op.add_column('playlists', sa.Column('last_used', sa.DateTime(), nullable=True)) op.add_column("playlists", sa.Column("last_used", sa.DateTime(), nullable=True))
op.add_column('playlists', sa.Column('loaded', sa.Boolean(), nullable=True)) op.add_column("playlists", sa.Column("loaded", sa.Boolean(), nullable=True))
# ### end Alembic commands ### # ### end Alembic commands ###
def downgrade(): def downgrade():
# ### commands auto generated by Alembic - please adjust! ### # ### commands auto generated by Alembic - please adjust! ###
op.drop_column('playlists', 'loaded') op.drop_column("playlists", "loaded")
op.drop_column('playlists', 'last_used') op.drop_column("playlists", "last_used")
# ### end Alembic commands ### # ### end Alembic commands ###

View File

@ -10,27 +10,28 @@ import sqlalchemy as sa
# revision identifiers, used by Alembic. # revision identifiers, used by Alembic.
revision = 'b0983648595e' revision = "b0983648595e"
down_revision = '1bc727e5e87f' down_revision = "1bc727e5e87f"
branch_labels = None branch_labels = None
depends_on = None depends_on = None
def upgrade(): def upgrade():
# ### commands auto generated by Alembic - please adjust! ### # ### commands auto generated by Alembic - please adjust! ###
op.create_table('settings', op.create_table(
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False), "settings",
sa.Column('name', sa.String(length=32), nullable=False), sa.Column("id", sa.Integer(), autoincrement=True, nullable=False),
sa.Column('f_datetime', sa.DateTime(), nullable=True), sa.Column("name", sa.String(length=32), nullable=False),
sa.Column('f_int', sa.Integer(), nullable=True), sa.Column("f_datetime", sa.DateTime(), nullable=True),
sa.Column('f_string', sa.String(length=128), nullable=True), sa.Column("f_int", sa.Integer(), nullable=True),
sa.PrimaryKeyConstraint('id'), sa.Column("f_string", sa.String(length=128), nullable=True),
sa.UniqueConstraint('name') sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint("name"),
) )
# ### end Alembic commands ### # ### end Alembic commands ###
def downgrade(): def downgrade():
# ### commands auto generated by Alembic - please adjust! ### # ### commands auto generated by Alembic - please adjust! ###
op.drop_table('settings') op.drop_table("settings")
# ### end Alembic commands ### # ### end Alembic commands ###

View File

@ -10,43 +10,54 @@ import sqlalchemy as sa
# revision identifiers, used by Alembic. # revision identifiers, used by Alembic.
revision = 'f07b96a5e60f' revision = "f07b96a5e60f"
down_revision = 'b0983648595e' down_revision = "b0983648595e"
branch_labels = None branch_labels = None
depends_on = None depends_on = None
def upgrade(): def upgrade():
# ### commands auto generated by Alembic - please adjust! ### # ### commands auto generated by Alembic - please adjust! ###
op.create_table('playdates', op.create_table(
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False), "playdates",
sa.Column('lastplayed', sa.DateTime(), nullable=True), sa.Column("id", sa.Integer(), autoincrement=True, nullable=False),
sa.PrimaryKeyConstraint('id') sa.Column("lastplayed", sa.DateTime(), nullable=True),
sa.PrimaryKeyConstraint("id"),
) )
op.create_index(op.f('ix_playdates_lastplayed'), 'playdates', ['lastplayed'], unique=False) op.create_index(
op.create_table('playlists', op.f("ix_playdates_lastplayed"), "playdates", ["lastplayed"], unique=False
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('name', sa.String(length=32), nullable=False),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('name')
) )
op.create_table('playlistracks', op.create_table(
sa.Column('playlist_id', sa.Integer(), nullable=True), "playlists",
sa.Column('track_id', sa.Integer(), nullable=True), sa.Column("id", sa.Integer(), autoincrement=True, nullable=False),
sa.ForeignKeyConstraint(['playlist_id'], ['playlists.id'], ), sa.Column("name", sa.String(length=32), nullable=False),
sa.ForeignKeyConstraint(['track_id'], ['tracks.id'], ) sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint("name"),
) )
op.add_column('tracks', sa.Column('playdates_id', sa.Integer(), nullable=True)) op.create_table(
op.create_foreign_key(None, 'tracks', 'playdates', ['playdates_id'], ['id']) "playlistracks",
sa.Column("playlist_id", sa.Integer(), nullable=True),
sa.Column("track_id", sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(
["playlist_id"],
["playlists.id"],
),
sa.ForeignKeyConstraint(
["track_id"],
["tracks.id"],
),
)
op.add_column("tracks", sa.Column("playdates_id", sa.Integer(), nullable=True))
op.create_foreign_key(None, "tracks", "playdates", ["playdates_id"], ["id"])
# ### end Alembic commands ### # ### end Alembic commands ###
def downgrade(): def downgrade():
# ### commands auto generated by Alembic - please adjust! ### # ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint(None, 'tracks', type_='foreignkey') op.drop_constraint(None, "tracks", type_="foreignkey")
op.drop_column('tracks', 'playdates_id') op.drop_column("tracks", "playdates_id")
op.drop_table('playlistracks') op.drop_table("playlistracks")
op.drop_table('playlists') op.drop_table("playlists")
op.drop_index(op.f('ix_playdates_lastplayed'), table_name='playdates') op.drop_index(op.f("ix_playdates_lastplayed"), table_name="playdates")
op.drop_table('playdates') op.drop_table("playdates")
# ### end Alembic commands ### # ### end Alembic commands ###

View File

@ -12,10 +12,10 @@ import pytest
# Mark subsequent lines to ignore E402, imports not at top of file # Mark subsequent lines to ignore E402, imports not at top of file
# Set up test database before importing db # Set up test database before importing db
# Mark subsequent lines to ignore E402, imports not at top of file # Mark subsequent lines to ignore E402, imports not at top of file
DB_FILE = '/tmp/mm.db' 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 models import db, Settings # noqa: E402 from models import db, Settings # noqa: E402

View File

@ -12,10 +12,10 @@ from app import helpers
# Set up test database before importing db # Set up test database before importing db
# Mark subsequent lines to ignore E402, imports not at top of file # Mark subsequent lines to ignore E402, imports not at top of file
DB_FILE = '/tmp/mm.db' 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.models import ( # noqa: E402 from app.models import ( # noqa: E402
db, db,
Carts, Carts,

View File

@ -12,12 +12,13 @@ from sqlalchemy.orm.session import Session
# App imports # App imports
from app.log import log from app.log import log
from app.helpers import get_file_metadata from app.helpers import get_file_metadata
# Set up test database before importing db # Set up test database before importing db
# Mark subsequent lines to ignore E402, imports not at top of file # Mark subsequent lines to ignore E402, imports not at top of file
DB_FILE = '/tmp/mm.db' 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 # noqa: E402 from app import playlistmodel # noqa: E402
from app.models import ( # noqa: E402 from app.models import ( # noqa: E402
db, db,
@ -27,64 +28,83 @@ from app.models import ( # noqa: E402
) )
class TestMMMisc(unittest.TestCase): # class TestMMMiscTracks(unittest.TestCase):
# def setUp(self):
# PLAYLIST_NAME = "tracks playlist"
# self.test_tracks = [
# "testdata/isa.mp3",
# "testdata/isa_with_gap.mp3",
# "testdata/loser.mp3",
# "testdata/lovecats-10seconds.mp3",
# "testdata/lovecats.mp3",
# "testdata/mom.mp3",
# "testdata/sitting.mp3",
# ]
# db.create_all()
# # Create a playlist and model
# with db.Session() as session:
# self.playlist = Playlists(session, PLAYLIST_NAME)
# self.model = playlistmodel.PlaylistModel(self.playlist.id)
# for row in range(len(self.test_tracks)):
# track_path = self.test_tracks[row % len(self.test_tracks)]
# metadata = get_file_metadata(track_path)
# track = Tracks(session, **metadata)
# self.model.insert_row(
# proposed_row_number=row, track_id=track.id, note=f"{row=}"
# )
# session.commit()
# def tearDown(self):
# db.drop_all()
# def test_7_row_playlist(self):
# # Test auto-created playlist
# assert self.model.rowCount() == 7
# assert max(self.model.playlist_rows.keys()) == 6
# for row in range(self.model.rowCount()):
# assert row in self.model.playlist_rows
# assert self.model.playlist_rows[row].plr_rownum == row
class TestMMMiscRowMove(unittest.TestCase):
def setUp(self): def setUp(self):
PLAYLIST_NAME = "test playlist" PLAYLIST_NAME = "rowmove playlist"
self.test_tracks = [ ROWS_TO_CREATE = 11
"testdata/isa.mp3",
"testdata/isa_with_gap.mp3",
"testdata/loser.mp3",
"testdata/lovecats-10seconds.mp3",
"testdata/lovecats.mp3",
"testdata/mom.mp3",
"testdata/sitting.mp3",
]
db.create_all() db.create_all()
# Create a playlist and model
with db.Session() as session: with db.Session() as session:
self.playlist = Playlists(session, PLAYLIST_NAME) self.playlist = Playlists(session, PLAYLIST_NAME)
self.model = playlistmodel.PlaylistModel(self.playlist.id) self.model = playlistmodel.PlaylistModel(self.playlist.id)
for row in range(ROWS_TO_CREATE):
for row in range(len(self.test_tracks)): print(f"{row=}")
track_path = self.test_tracks[row % len(self.test_tracks)] self.model.insert_row(proposed_row_number=row, note=str(row))
metadata = get_file_metadata(track_path)
track = Tracks(session, **metadata)
self.model.insert_row(proposed_row_number=row, track_id=track.id, note=f"{row=}")
session.commit() session.commit()
def tearDown(self): def tearDown(self):
db.drop_all() db.drop_all()
def test_7_row_playlist(self): def test_move_rows_test2(self):
# Test auto-created playlist # move row 3 to row 5
self.model.move_rows([3], 5)
assert self.model.rowCount() == 7 # Check we have all rows and plr_rownums are correct
assert max(self.model.playlist_rows.keys()) == 6
for row in range(self.model.rowCount()): for row in range(self.model.rowCount()):
assert row in self.model.playlist_rows assert row in self.model.playlist_rows
assert self.model.playlist_rows[row].plr_rownum == row assert self.model.playlist_rows[row].plr_rownum == row
if row not in [3, 4, 5]:
assert self.model.playlist_rows[row].note == str(row)
# def test_move_rows_test2(monkeypatch, session): elif row == 3:
# # move row 3 to row 5 assert self.model.playlist_rows[row].note == str(4)
# monkeypatch.setattr(playlistmodel, "Session", session) elif row == 4:
# model = create_model_with_playlist_rows(session, 11) assert self.model.playlist_rows[row].note == str(5)
# model.move_rows([3], 5) elif row == 5:
# # Check we have all rows and plr_rownums are correct assert self.model.playlist_rows[row].note == str(3)
# for row in range(model.rowCount()):
# assert row in model.playlist_rows
# assert model.playlist_rows[row].plr_rownum == row
# if row not in [3, 4, 5]:
# assert model.playlist_rows[row].note == str(row)
# elif row == 3:
# assert model.playlist_rows[row].note == str(4)
# elif row == 4:
# assert model.playlist_rows[row].note == str(5)
# elif row == 5:
# assert model.playlist_rows[row].note == str(3)
# def test_move_rows_test3(monkeypatch, session): # def test_move_rows_test3(monkeypatch, session):