Compare commits

...

2 Commits

Author SHA1 Message Date
Keith Edmunds
ac685426d9 Implement NoteColoursDTO 2025-04-12 11:15:54 +01:00
Keith Edmunds
38c49b32d7 WIP: rename repository.py → ds.py 2025-04-12 11:15:21 +01:00
10 changed files with 171 additions and 106 deletions

View File

@ -95,6 +95,19 @@ class PlaydatesDTO(TrackDTO):
lastplayed: dt.datetime
@dataclass
class NoteColoursDTO:
notecolour_id: int
substring: str
colour: str
enabled: bool = True
foreground: str | None = None
is_regex: bool = False
is_casesensitive: bool = False
order: int | None = None
strip_substring: bool = True
class ApplicationError(Exception):
"""
Custom exception

View File

@ -23,7 +23,7 @@ from helpers import (
get_relative_date,
ms_to_mmss,
)
import repository
import ds
class TrackInsertDialog(QDialog):
@ -94,8 +94,8 @@ class TrackInsertDialog(QDialog):
self.setLayout(layout)
self.resize(800, 600)
width = repository.get_setting("dbdialog_width") or 800
height = repository.get_setting("dbdialog_height") or 800
width = ds.get_setting("dbdialog_width") or 800
height = ds.get_setting("dbdialog_height") or 800
self.resize(width, height)
self.signals = MusicMusterSignals()
@ -107,9 +107,9 @@ class TrackInsertDialog(QDialog):
return
if text.startswith("a/") and len(text) > 2:
self.tracks = repository.tracks_by_artist(text[2:])
self.tracks = ds.tracks_by_artist(text[2:])
else:
self.tracks = repository.tracks_by_title(text)
self.tracks = ds.tracks_by_title(text)
for track in self.tracks:
duration_str = ms_to_mmss(track.duration)

View File

@ -5,6 +5,8 @@ import re
# PyQt imports
# Third party imports
from dogpile.cache import make_region
from dogpile.cache.api import NO_VALUE
from sqlalchemy import (
delete,
func,
@ -19,6 +21,7 @@ from sqlalchemy.sql.elements import BinaryExpression, ColumnElement
from classes import (
ApplicationError,
Filter,
NoteColoursDTO,
PlaydatesDTO,
PlaylistDTO,
PlaylistRowDTO,
@ -39,6 +42,13 @@ from models import (
)
# Configure the dogpile cache region
cache_region = make_region().configure(
'dogpile.cache.memory', # Use in-memory caching for now (switch to Redis if needed)
expiration_time=600 # Cache expires after 10 minutes
)
# Helper functions
@log_call
def _remove_substring_case_insensitive(parent_string: str, substring: str) -> str:
@ -68,13 +78,53 @@ def _remove_substring_case_insensitive(parent_string: str, substring: str) -> st
# Notecolour functions
def _get_colour_record(text: str) -> tuple[NoteColours | None, str]:
def _all_notecolours(session: Session) -> list[NoteColoursDTO]:
"""
Return all notecolour records
"""
cache_key = "note_colours_all"
cached_result = cache_region.get(cache_key)
if cached_result is not NO_VALUE:
return cached_result
# Query the database
records = session.scalars(
select(NoteColours)
.where(
NoteColours.enabled.is_(True),
)
.order_by(NoteColours.order)
).all()
results: list[NoteColoursDTO] = []
for record in records:
result = NoteColoursDTO(
notecolour_id=record.id,
substring=record.substring,
colour=record.colour,
enabled=record.enabled,
foreground=record.foreground,
is_regex=record.is_regex,
is_casesensitive=record.is_casesensitive,
order=record.order,
strip_substring=record.strip_substring,
)
results.append(result)
cache_region.set(cache_key, results)
return results
def _get_colour_record(text: str) -> tuple[NoteColoursDTO | None, str]:
"""
Parse text and return first matching colour record or None
"""
with db.Session() as session:
for rec in NoteColours.get_all(session):
for rec in _all_notecolours(session):
if rec.is_regex:
flags = re.UNICODE
if not rec.is_casesensitive:
@ -751,7 +801,7 @@ def copy_playlist(src_id: int, dst_id: int) -> None:
with db.Session() as session:
src_rows = session.scalars(
select(PlaylistRows).filter(PlaylistRows.playlist_id == src_id)
select(PlaylistRows).where(PlaylistRows.playlist_id == src_id)
).all()
for plr in src_rows:
@ -763,6 +813,8 @@ def copy_playlist(src_id: int, dst_id: int) -> None:
track_id=plr.track_id,
)
session.commit()
def playlist_row_count(playlist_id: int) -> int:
"""

View File

@ -45,7 +45,7 @@ from helpers import (
from log import log
from playlistrow import TrackSequence
from playlistmodel import PlaylistModel
import repository
import ds
@dataclass
@ -142,7 +142,7 @@ class FileImporter:
# Refresh list of existing tracks as they may have been updated
# by previous imports
self.existing_tracks = repository.get_all_tracks()
self.existing_tracks = ds.get_all_tracks()
for infile in [
os.path.join(Config.REPLACE_FILES_DEFAULT_SOURCE, f)
@ -465,7 +465,7 @@ class FileImporter:
# file). Check that because the path field in the database is
# unique and so adding a duplicate will give a db integrity
# error.
if repository.track_by_path(tfd.destination_path):
if ds.track_by_path(tfd.destination_path):
tfd.error = (
"Importing a new track but destination path already exists "
f"in database ({tfd.destination_path})"
@ -638,9 +638,9 @@ class DoTrackImport(QThread):
# Update databse
metadata = get_all_track_metadata(self.destination_track_path)
if self.track_id == 0:
track_dto = repository.create_track(self.destination_track_path, metadata)
track_dto = ds.create_track(self.destination_track_path, metadata)
else:
track_dto = repository.update_track(
track_dto = ds.update_track(
self.destination_track_path, self.track_id, metadata
)

View File

@ -79,7 +79,7 @@ from models import db, Playdates, PlaylistRows, Playlists, Queries, Settings, Tr
from playlistrow import PlaylistRow, TrackSequence
from playlistmodel import PlaylistModel, PlaylistProxyModel
from playlists import PlaylistTab
import repository
import ds
from querylistmodel import QuerylistModel
from ui import icons_rc # noqa F401
from ui.dlg_SelectPlaylist_ui import Ui_dlgSelectPlaylist # type: ignore
@ -472,7 +472,7 @@ class ManageQueries(ItemlistManager):
# Build a list of queries
query_list: list[ItemlistItem] = []
for query in repository.get_all_queries():
for query in ds.get_all_queries():
query_list.append(
ItemlistItem(
name=query.name, id=query.query_id, favourite=query.favourite
@ -485,7 +485,7 @@ class ManageQueries(ItemlistManager):
def delete_item(self, query_id: int) -> None:
"""delete query"""
query = repository.query_by_id(query_id)
query = ds.query_by_id(query_id)
if not query:
raise ApplicationError(
f"manage_template.delete({query_id=}) can't load query"
@ -494,7 +494,7 @@ class ManageQueries(ItemlistManager):
"Delete query",
f"Delete query '{query.name}': " "Are you sure?",
):
repository.delete_query(query_id)
ds.delete_query(query_id)
self.refresh_table()
@ -503,13 +503,13 @@ class ManageQueries(ItemlistManager):
dlg = FilterDialog(query.name, query.filter)
if dlg.exec():
repository.update_query_filter(query.query_id, dlg.filter)
repository.update_query_name(query.query_id, dlg.name_text.text())
ds.update_query_filter(query.query_id, dlg.filter)
ds.update_query_name(query.query_id, dlg.name_text.text())
def edit_item(self, query_id: int) -> None:
"""Edit query"""
query = repository.query_by_id(query_id)
query = ds.query_by_id(query_id)
if not query:
raise ApplicationError(
f"manage_template.edit_item({query_id=}) can't load query"
@ -519,7 +519,7 @@ class ManageQueries(ItemlistManager):
def toggle_favourite(self, query_id: int, favourite: bool) -> None:
"""Mark query as (not) favourite"""
repository.update_query_favourite(query_id, favourite)
ds.update_query_favourite(query_id, favourite)
def new_item(self) -> None:
"""Create new query"""
@ -528,21 +528,21 @@ class ManageQueries(ItemlistManager):
if not query_name:
return
query = repository.create_query(query_name, Filter())
query = ds.create_query(query_name, Filter())
self._edit_item(query)
self.refresh_table()
def rename_item(self, query_id: int) -> None:
"""rename query"""
query = repository.query_by_id(query_id)
query = ds.query_by_id(query_id)
if not query:
raise ApplicationError(f"Can't load query ({query_id=})")
new_name = get_name(prompt="New query name", default=query.name)
if not new_name:
return
repository.update_query_name(query_id, new_name)
ds.update_query_name(query_id, new_name)
self.change_text(query_id, new_name)
@ -567,7 +567,7 @@ class ManageTemplates(ItemlistManager):
# Build a list of templates
template_list: list[ItemlistItem] = []
for template in repository.playlists_templates():
for template in ds.playlists_templates():
template_list.append(
ItemlistItem(
name=template.name,
@ -582,7 +582,7 @@ class ManageTemplates(ItemlistManager):
def delete_item(self, template_id: int) -> None:
"""delete template"""
template = repository.playlists_template_by_id(template_id)
template = ds.playlists_template_by_id(template_id)
if not template:
raise ApplicationError(
f"manage_template.delete({template_id=}) can't load template"
@ -602,12 +602,12 @@ class ManageTemplates(ItemlistManager):
else:
self.musicmuster.playlist_section.tabPlaylist.removeTab(open_idx)
repository.delete_playlist(template.playlist_id)
ds.delete_playlist(template.playlist_id)
def edit_item(self, template_id: int) -> None:
"""Edit template"""
template = repository.playlists_template_by_id(template_id)
template = ds.playlists_template_by_id(template_id)
if not template:
raise ApplicationError(
f"manage_template.edit({template_id=}) can't load template"
@ -619,7 +619,7 @@ class ManageTemplates(ItemlistManager):
def toggle_favourite(self, template_id: int, favourite: bool) -> None:
"""Mark template as (not) favourite"""
repository.update_template_favourite(template_id, favourite)
ds.update_template_favourite(template_id, favourite)
def new_item(
self,
@ -639,7 +639,7 @@ class ManageTemplates(ItemlistManager):
return
# Create playlist for template and mark is as a template
template = repository.create_playlist(name, template_id, as_template=True)
template = ds.create_playlist(name, template_id, as_template=True)
# Open it for editing
self.musicmuster._open_playlist(template, is_template=True)
@ -647,14 +647,14 @@ class ManageTemplates(ItemlistManager):
def rename_item(self, template_id: int) -> None:
"""rename template"""
template = repository.playlist_by_id(template_id)
template = ds.playlist_by_id(template_id)
if not template:
raise ApplicationError(
f"manage_template.delete({template_id=}) can't load template"
)
new_name = self.musicmuster.get_playlist_name(template.name)
if new_name:
repository.playlist_rename(template_id, new_name)
ds.playlist_rename(template_id, new_name)
@dataclass
@ -780,7 +780,7 @@ class QueryDialog(QDialog):
self.query_list: list[tuple[str, int]] = []
self.query_list.append((Config.NO_QUERY_NAME, 0))
for query in repository.get_all_queries():
for query in ds.get_all_queries():
self.query_list.append((query.name, query.query_id))
self.setWindowTitle("Query Selector")
@ -898,7 +898,7 @@ class QueryDialog(QDialog):
querylist_y=self.y(),
)
for name, value in attributes_to_save.items():
repository.set_setting(name, value)
ds.set_setting(name, value)
header = self.table_view.horizontalHeader()
if header is None:
@ -908,7 +908,7 @@ class QueryDialog(QDialog):
return
for column_number in range(column_count - 1):
attr_name = f"querylist_col_{column_number}_width"
repository.set_setting(
ds.set_setting(
attr_name, self.table_view.columnWidth(column_number)
)
@ -939,7 +939,7 @@ class QueryDialog(QDialog):
# Get query
query_id = self.combo_box.currentData()
query = repository.query_by_id(query_id)
query = ds.query_by_id(query_id)
if not query:
return
@ -961,10 +961,10 @@ class QueryDialog(QDialog):
def set_window_size(self) -> None:
"""Set window sizes"""
x = repository.get_setting("querylist_x") or 100
y = repository.get_setting("querylist_y") or 100
width = repository.get_setting("querylist_width") or 100
height = repository.get_setting("querylist_height") or 100
x = ds.get_setting("querylist_x") or 100
y = ds.get_setting("querylist_y") or 100
width = ds.get_setting("querylist_width") or 100
height = ds.get_setting("querylist_height") or 100
self.setGeometry(x, y, width, height)
def set_column_sizes(self) -> None:
@ -980,7 +980,7 @@ class QueryDialog(QDialog):
# Last column is set to stretch so ignore it here
for column_number in range(column_count - 1):
attr_name = f"querylist_col_{column_number}_width"
width = repository.get_setting(attr_name) or Config.DEFAULT_COLUMN_WIDTH
width = ds.get_setting(attr_name) or Config.DEFAULT_COLUMN_WIDTH
self.table_view.setColumnWidth(column_number, width)
@ -997,8 +997,8 @@ class SelectPlaylistDialog(QDialog):
self.ui.buttonBox.rejected.connect(self.close)
self.playlist = None
width = repository.get_setting("select_playlist_dialog_width") or 800
height = repository.get_setting("select_playlist_dialog_height") or 800
width = ds.get_setting("select_playlist_dialog_width") or 800
height = ds.get_setting("select_playlist_dialog_height") or 800
self.resize(width, height)
for playlist in playlists:
@ -1008,8 +1008,8 @@ class SelectPlaylistDialog(QDialog):
self.ui.lstPlaylists.addItem(p)
def __del__(self): # review
repository.set_setting("select_playlist_dialog_height", self.height())
repository.set_setting("select_playlist_dialog_width", self.width())
ds.set_setting("select_playlist_dialog_height", self.height())
ds.set_setting("select_playlist_dialog_width", self.width())
def list_doubleclick(self, entry): # review
self.playlist = entry.data(Qt.ItemDataRole.UserRole)
@ -1195,7 +1195,7 @@ class Window(QMainWindow):
playlist_id_to_tab[
self.playlist_section.tabPlaylist.widget(idx).playlist_id
] = idx
repository.playlist_save_tabs(playlist_id_to_tab)
ds.playlist_save_tabs(playlist_id_to_tab)
# Save window attributes
attributes_to_save = dict(
@ -1206,7 +1206,7 @@ class Window(QMainWindow):
active_tab=self.playlist_section.tabPlaylist.currentIndex(),
)
for name, value in attributes_to_save.items():
repository.set_setting(name, value)
ds.set_setting(name, value)
event.accept()
@ -1324,7 +1324,7 @@ class Window(QMainWindow):
"separator": True,
},
]
templates = repository.playlists_templates()
templates = ds.playlists_templates()
for template in templates:
submenu_items.append(
{
@ -1357,7 +1357,7 @@ class Window(QMainWindow):
"separator": True,
},
]
queries = repository.get_all_queries(favourites_only=True)
queries = ds.get_all_queries(favourites_only=True)
for query in queries:
submenu_items.append(
{
@ -1409,7 +1409,7 @@ class Window(QMainWindow):
if template_id > 0, and return the Playlists object.
"""
return repository.create_playlist(name, template_id)
return ds.create_playlist(name, template_id)
@log_call
def _open_playlist(self, playlist: Playlists, is_template: bool = False) -> int:
@ -1432,7 +1432,7 @@ class Window(QMainWindow):
idx = self.playlist_section.tabPlaylist.addTab(playlist_tab, playlist.name)
# Mark playlist as open
repository.playlist_mark_status(playlist.playlist_id, open=True)
ds.playlist_mark_status(playlist.playlist_id, open=True)
# Switch to new tab
self.playlist_section.tabPlaylist.setCurrentIndex(idx)
@ -1458,7 +1458,7 @@ class Window(QMainWindow):
if not playlist_name:
return
_ = repository.create_playlist(playlist_name, template_id)
_ = ds.create_playlist(playlist_name, template_id)
@log_call
def delete_playlist(self, checked: bool = False) -> None:
@ -1467,21 +1467,21 @@ class Window(QMainWindow):
but unused.
"""
playlist = repository.playlist_by_id(self.current.playlist_id)
playlist = ds.playlist_by_id(self.current.playlist_id)
if playlist:
if helpers.ask_yes_no(
"Delete playlist",
f"Delete playlist '{playlist.name}': " "Are you sure?",
):
if self.close_playlist_tab():
repository.delete_playlist(self.current.playlist_id)
ds.delete_playlist(self.current.playlist_id)
else:
log.error("Failed to retrieve playlist")
def open_existing_playlist(self, checked: bool = False) -> None:
"""Open existing playlist"""
playlists = repository.playlists_closed()
playlists = ds.playlists_closed()
dlg = SelectPlaylistDialog(self, playlists=playlists)
dlg.exec()
playlist = dlg.playlist
@ -1491,7 +1491,7 @@ class Window(QMainWindow):
def save_as_template(self, checked: bool = False) -> None:
"""Save current playlist as template"""
template_names = [a.name for a in repository.playlists_templates()]
template_names = [a.name for a in ds.playlists_templates()]
while True:
# Get name for new template
@ -1509,7 +1509,7 @@ class Window(QMainWindow):
helpers.show_warning(
self, "Duplicate template", "Template name already in use"
)
repository.save_as_template(self.current.playlist_id, template_name)
ds.save_as_template(self.current.playlist_id, template_name)
helpers.show_OK("Template", "Template saved", self)
def get_playlist_name(
@ -1520,7 +1520,7 @@ class Window(QMainWindow):
dlg = QInputDialog(self)
dlg.setInputMode(QInputDialog.InputMode.TextInput)
dlg.setLabelText(prompt)
all_playlist_names = [a.name for a in repository.get_all_playlists()]
all_playlist_names = [a.name for a in ds.get_all_playlists()]
while True:
if default:
@ -1552,7 +1552,7 @@ class Window(QMainWindow):
template_name_id_list: list[tuple[str, int]] = []
template_name_id_list.append((Config.NO_TEMPLATE_NAME, 0))
for template in repository.playlists_templates():
for template in ds.playlists_templates():
template_name_id_list.append((template.name, template.playlist_id))
dlg = TemplateSelectorDialog(template_name_id_list, template_prompt)
@ -1594,7 +1594,7 @@ class Window(QMainWindow):
except subprocess.CalledProcessError as exc_info:
git_tag = str(exc_info.output)
dbname = repository.get_db_name()
dbname = ds.get_db_name()
QMessageBox.information(
self,
@ -1661,7 +1661,7 @@ class Window(QMainWindow):
return False
# Record playlist as closed
repository.playlist_mark_status(open=False)
ds.playlist_mark_status(open=False)
# Close playlist and remove tab
self.playlist_section.tabPlaylist.widget(tab_index).close()
@ -1744,7 +1744,7 @@ class Window(QMainWindow):
path += ".csv"
with open(path, "w") as f:
for playdate in repository.playdates_between_dates(start_dt):
for playdate in ds.playdates_between_dates(start_dt):
f.write(f"{playdate.artist},{playdate.title}\n")
def drop3db(self) -> None:
@ -1807,7 +1807,7 @@ class Window(QMainWindow):
playlist_id = self.current.playlist_id
playlist = repository.playlist_by_id(playlist_id)
playlist = ds.playlist_by_id(playlist_id)
if not playlist:
return
@ -1828,7 +1828,7 @@ class Window(QMainWindow):
with open(path, "w") as f:
# Required directive on first line
f.write("#EXTM3U\n")
for playlistrow in repository.get_playlist_rows(playlist_id):
for playlistrow in ds.get_playlist_rows(playlist_id):
if playlistrow.track:
f.write(
"#EXTINF:"
@ -1909,13 +1909,13 @@ class Window(QMainWindow):
"""Load the playlists that were open when app was last closed"""
playlist_ids = []
for playlist in repository.playlists_open():
for playlist in ds.playlists_open():
if playlist:
# Create tab
playlist_ids.append(self._open_playlist(playlist))
# Set active tab
value = repository.get_setting("active_tab")
value = ds.get_setting("active_tab")
if value is not None and value >= 0:
self.playlist_section.tabPlaylist.setCurrentIndex(value)
@ -1965,7 +1965,7 @@ class Window(QMainWindow):
playlists = []
source_playlist_id = self.current.playlist_id
for playlist in repository.get_all_playlists():
for playlist in ds.get_all_playlists():
if playlist.id == source_playlist_id:
continue
else:
@ -1979,7 +1979,7 @@ class Window(QMainWindow):
# Add to end of target playlist, so target row will be length of
# playlist
to_row = repository.playlist_row_count(to_playlist_id)
to_row = ds.playlist_row_count(to_playlist_id)
# Move rows
self.current.base_model.move_rows_between_playlists(
@ -2186,7 +2186,7 @@ class Window(QMainWindow):
if not track_info:
return
self.preview_manager.row_number = track_info.row_number
track = repository.track_by_id(track_info.track_id)
track = ds.track_by_id(track_info.track_id)
if not track:
raise ApplicationError(
f"musicmuster.preview: unable to retreive track {track_info.track_id=}"
@ -2236,7 +2236,7 @@ class Window(QMainWindow):
return
intro = round(self.preview_manager.get_playtime() / 100) * 100
repository.set_track_intro(track_id, intro)
ds.set_track_intro(track_id, intro)
self.preview_manager.set_intro(intro)
self.current.base_model.refresh_row(row_number)
roles = [
@ -2270,11 +2270,11 @@ class Window(QMainWindow):
Rename current playlist. checked is passed by menu but not used here
"""
playlist = repository.playlist_by_id(self.current.playlist_id)
playlist = ds.playlist_by_id(self.current.playlist_id)
if playlist:
new_name = self.get_playlist_name(playlist.name)
if new_name:
repository.playlist_rename(playlist.id, new_name)
ds.playlist_rename(playlist.id, new_name)
idx = self.tabBar.currentIndex()
self.tabBar.setTabText(idx, new_name)
@ -2415,10 +2415,10 @@ class Window(QMainWindow):
def set_main_window_size(self) -> None:
"""Set size of window from database"""
x = repository.get_setting("mainwindow_x") or 100
y = repository.get_setting("mainwindow_y") or 100
width = repository.get_setting("mainwindow_width") or 100
height = repository.get_setting("mainwindow_height") or 100
x = ds.get_setting("mainwindow_x") or 100
y = ds.get_setting("mainwindow_y") or 100
width = ds.get_setting("mainwindow_width") or 100
height = ds.get_setting("mainwindow_height") or 100
self.setGeometry(x, y, width, height)
@log_call

View File

@ -49,7 +49,7 @@ from helpers import (
)
from log import log, log_call
from playlistrow import PlaylistRow, TrackSequence
import repository
import ds
HEADER_NOTES_COLUMN = 1
@ -102,7 +102,7 @@ class PlaylistModel(QAbstractTableModel):
self.signals.signal_track_started.connect(self.track_started)
# Populate self.playlist_rows
for dto in repository.get_playlist_rows(self.playlist_id):
for dto in ds.get_playlist_rows(self.playlist_id):
self.playlist_rows[dto.row_number] = PlaylistRow(dto)
self.update_track_times()
@ -198,7 +198,7 @@ class PlaylistModel(QAbstractTableModel):
if self.is_header_row(row):
# Check for specific header colouring
if plr.row_bg is None:
plr.row_bg = repository.get_colour(plr.note)
plr.row_bg = ds.get_colour(plr.note)
if plr.row_bg:
return QBrush(QColor(plr.row_bg))
else:
@ -235,7 +235,7 @@ class PlaylistModel(QAbstractTableModel):
if column == Col.NOTE.value:
if plr.note:
if plr.note_bg is None:
plr.row_bg = repository.get_colour(plr.note)
plr.row_bg = ds.get_colour(plr.note)
if plr.note_bg:
return QBrush(QColor(plr.note_bg))
@ -296,7 +296,7 @@ class PlaylistModel(QAbstractTableModel):
self.obs_scene_change(row_number)
# Update Playdates in database
repository.update_playdates(track_id)
ds.update_playdates(track_id)
# Mark track as played in playlist
playlist_dto.played = True
@ -397,7 +397,7 @@ class PlaylistModel(QAbstractTableModel):
# Signal that rows will be removed
super().beginRemoveRows(QModelIndex(), min(row_group), max(row_group))
# Remove rows from data store
repository.remove_rows(self.playlist_id, row_group)
ds.remove_rows(self.playlist_id, row_group)
# Signal that data store has been updated
super().endRemoveRows()
@ -502,7 +502,7 @@ class PlaylistModel(QAbstractTableModel):
def _foreground_role(self, row: int, column: int, plr: PlaylistRow) -> QBrush:
"""Return header foreground colour or QBrush() if none"""
plr.row_fg = repository.get_colour(plr.note, foreground=True)
plr.row_fg = ds.get_colour(plr.note, foreground=True)
if plr.row_fg:
return QBrush(QColor(plr.row_fg))
return QBrush()
@ -713,7 +713,7 @@ class PlaylistModel(QAbstractTableModel):
super().beginInsertRows(QModelIndex(), new_row_number, new_row_number)
new_row = repository.insert_row(
new_row = ds.insert_row(
playlist_id=self.playlist_id,
row_number=new_row_number,
track_id=track_id,
@ -843,7 +843,7 @@ class PlaylistModel(QAbstractTableModel):
# Notify model going to change
self.beginResetModel()
# Update database
repository.move_rows(from_rows, self.playlist_id, to_row_number)
ds.move_rows(from_rows, self.playlist_id, to_row_number)
# Notify model changed
self.endResetModel()
@ -896,7 +896,7 @@ class PlaylistModel(QAbstractTableModel):
to_row_number + len(row_group)
)
self.signals.signal_begin_insert_rows.emit(insert_rows)
repository.move_rows(from_rows=row_group,
ds.move_rows(from_rows=row_group,
from_playlist_id=self.playlist_id,
to_row=to_row_number,
to_playlist_id=to_playlist_id)
@ -1025,7 +1025,7 @@ class PlaylistModel(QAbstractTableModel):
# build a new playlist_rows
new_playlist_rows: dict[int, PlaylistRow] = {}
for dto in repository.get_playlist_rows(self.playlist_id):
for dto in ds.get_playlist_rows(self.playlist_id):
if dto.playlistrow_id not in plrid_to_row:
new_playlist_rows[dto.row_number] = PlaylistRow(dto)
else:
@ -1040,7 +1040,7 @@ class PlaylistModel(QAbstractTableModel):
"""Populate dict for one row from database"""
plrid = self.playlist_rows[row_number].playlistrow_id
refreshed_row = repository.get_playlist_row(plrid)
refreshed_row = ds.get_playlist_row(plrid)
if not refreshed_row:
raise ApplicationError(f"Failed to retrieve row {self.playlist_id=}, {row_number=}")
@ -1067,7 +1067,7 @@ class PlaylistModel(QAbstractTableModel):
track = self.playlist_rows[row_number]
metadata = get_all_track_metadata(track.path)
_ = repository.update_track(track.path, track.track_id, metadata)
_ = ds.update_track(track.path, track.track_id, metadata)
roles = [
Qt.ItemDataRole.BackgroundRole,
@ -1107,7 +1107,7 @@ class PlaylistModel(QAbstractTableModel):
):
return
repository.remove_comments(self.playlist_id, row_numbers)
ds.remove_comments(self.playlist_id, row_numbers)
# only invalidate required roles
roles = [
@ -1166,7 +1166,7 @@ class PlaylistModel(QAbstractTableModel):
header_text = header_text[0:-1]
# Parse passed header text and remove the first colour match string
return repository.remove_colour_substring(header_text)
return ds.remove_colour_substring(header_text)
def rowCount(self, index: QModelIndex = QModelIndex()) -> int:
"""Standard function for view"""
@ -1450,7 +1450,7 @@ class PlaylistModel(QAbstractTableModel):
if not track_id:
return ""
return repository.get_last_played_dates(track_id)
return ds.get_last_played_dates(track_id)
@log_call
def update_or_insert(self, track_id: int, row_number: int) -> None:

View File

@ -22,7 +22,7 @@ from config import Config
import helpers
from log import log
from music_manager import Music
import repository
import ds
class PlaylistRow:
@ -161,10 +161,10 @@ class PlaylistRow:
if self.track_id > 0:
raise ApplicationError("Attempting to add track to row with existing track ({self=}")
repository.add_track_to_header(track_id)
ds.add_track_to_header(track_id)
# Need to update with track information
track = repository.track_by_id(track_id)
track = ds.track_by_id(track_id)
if track:
for attr, value in track.__dataclass_fields__.items():
setattr(self, attr, value)
@ -583,7 +583,7 @@ class TrackSequence:
for ts in [self.next, self.current, self.previous]:
if not ts:
continue
playlist_row_dto = repository.get_playlist_row(ts.playlistrow_id)
playlist_row_dto = ds.get_playlist_row(ts.playlistrow_id)
if not playlist_row_dto:
raise ApplicationError(f"(Can't retrieve PlaylistRows entry, {self=}")
ts = PlaylistRow(playlist_row_dto)

View File

@ -54,7 +54,7 @@ from helpers import (
from log import log, log_call
from playlistrow import TrackSequence
from playlistmodel import PlaylistModel, PlaylistProxyModel
import repository
import ds
if TYPE_CHECKING:
from musicmuster import Window
@ -688,7 +688,7 @@ class PlaylistTab(QTableView):
self.resizeRowsToContents()
# Save settings
repository.set_setting(
ds.set_setting(
f"playlist_col_{column_number}_width", self.columnWidth(column_number)
)
@ -1071,7 +1071,7 @@ class PlaylistTab(QTableView):
# Last column is set to stretch so ignore it here
for column_number in range(header.count() - 1):
attr_name = f"playlist_col_{column_number}_width"
value = repository.get_setting(attr_name)
value = ds.get_setting(attr_name)
if value is not None:
self.setColumnWidth(column_number, value)
else:

View File

@ -39,7 +39,7 @@ from helpers import (
)
from log import log, log_call
from playlistrow import PlaylistRow
import repository
import ds
@dataclass
@ -228,7 +228,7 @@ class QuerylistModel(QAbstractTableModel):
row = 0
try:
results = repository.get_filtered_tracks(self.filter)
results = ds.get_filtered_tracks(self.filter)
for result in results:
queryrow = QueryRow(
artist=result.artist,
@ -271,4 +271,4 @@ class QuerylistModel(QAbstractTableModel):
track_id = self.querylist_rows[row].track_id
if not track_id:
return QVariant()
return repository.get_last_played_dates(track_id)
return ds.get_last_played_dates(track_id)

View File

@ -12,7 +12,7 @@ from helpers import (
get_tags,
)
from log import log
import repository
import ds
def check_db() -> None:
@ -26,7 +26,7 @@ def check_db() -> None:
Check all paths in database exist
"""
db_paths = set([a.path for a in repository.get_all_tracks()])
db_paths = set([a.path for a in ds.get_all_tracks()])
os_paths_list = []
for root, _dirs, files in os.walk(Config.ROOT):
@ -51,7 +51,7 @@ def check_db() -> None:
missing_file_count += 1
track = repository.track_by_path(path)
track = ds.track_by_path(path)
if not track:
# This shouldn't happen as we're looking for paths in
# database that aren't in filesystem, but just in case...
@ -88,7 +88,7 @@ def update_bitrates() -> None:
Update bitrates on all tracks in database
"""
for track in repository.get_all_tracks():
for track in ds.get_all_tracks():
try:
t = get_tags(track.path)
# TODO this won't persist as we're updating DTO