dataclass swag

This commit is contained in:
billypom on debian 2025-04-19 22:45:02 -04:00
parent 466b38ce2e
commit 491e134d94
5 changed files with 62 additions and 25 deletions

View File

@ -1,9 +1,18 @@
from configparser import ConfigParser
from pathlib import Path
from appdirs import user_config_dir
from dataclasses import dataclass, asdict
from typing import Optional
@dataclass
class SQLiteMap():
title: str
artist: str
album: Optional[str] = None
class HeaderTags:
class HeaderTags():
"""
Utility class to converting between different "standards" for tags (headers, id3, etc)
@ -22,7 +31,7 @@ class HeaderTags:
)
self.config = ConfigParser()
self.config.read(cfg_file)
self.user_headers = str(self.config["table"]["columns"]).split(",")
self.user_headers: list = str(self.config["table"]["columns"]).split(",")
self.db: dict = {
"title": "title",
"artist": "artist",

View File

@ -342,12 +342,12 @@ class MusicTable(QTableView):
def on_sort(self):
debug("on_sort")
search_col_num = list(self.headers.gui.values()).index("path")
search_col_num = self.headers.user_headers.index("filepath")
selected_qmodel_index = self.find_qmodel_index_by_value(
self.model2, search_col_num, self.selected_song_filepath
self.proxymodel, search_col_num, self.selected_song_filepath
)
current_qmodel_index = self.find_qmodel_index_by_value(
self.model2, search_col_num, self.current_song_filepath
self.proxymodel, search_col_num, self.current_song_filepath
)
# Update the 2 QModelIndexes that we track
self.set_selected_song_qmodel_index(selected_qmodel_index)
@ -360,7 +360,7 @@ class MusicTable(QTableView):
When a cell is clicked, do some stuff :)
- this func also runs when double click happens, fyi
"""
print(index.row(), index.column())
# print(index.row(), index.column())
self.set_selected_song_filepath()
self.set_selected_song_qmodel_index()
self.viewport().update() # type: ignore
@ -407,7 +407,8 @@ class MusicTable(QTableView):
filepath = self.model2.data(filepath_index)
# update the ID3 information
user_input_data = topLeft.data()
edited_column_name = self.database_columns[topLeft.column()]
# edited_column_name = self.database_columns[topLeft.column()]
edited_column_name = self.headers.user_headers[topLeft.column()]
debug(f"on_cell_data_changed | edited column name: {edited_column_name}")
response = set_tag(filepath, edited_column_name, user_input_data)
if response:
@ -545,6 +546,8 @@ class MusicTable(QTableView):
"""Moves screen to the currently playing song, then selects the row"""
debug("jump_to_current_song")
# get the proxy model index
debug(self.current_song_filepath)
debug(self.current_song_qmodel_index)
proxy_index = self.proxymodel.mapFromSource(self.current_song_qmodel_index)
self.scrollTo(proxy_index)
self.selectRow(proxy_index.row())
@ -724,6 +727,18 @@ class MusicTable(QTableView):
item.setData(id, Qt.ItemDataRole.UserRole)
self.model2.appendRow(items)
# reloading the model destroys and makes new indexes
# so we look for the new index of the current song on load
current_song_filepath = self.get_current_song_filepath()
print(f'load music table current filepath: {current_song_filepath}')
for row in range(self.model2.rowCount()):
real_index = self.model2.index(row, self.headers.user_headers.index("filepath"))
if real_index.data() == current_song_filepath:
print('is it true?')
print(f'{real_index.data()} == {current_song_filepath}')
print('load music table real index:')
print(real_index)
self.current_song_qmodel_index = real_index
self.model2.layoutChanged.emit() # emits a signal that the view should be updated
self.playlistStatsSignal.emit(f"Songs: {row_count} | Total time: {total_time}")
self.loadMusicTableSignal.emit()
@ -871,11 +886,11 @@ class MusicTable(QTableView):
from the current selected row index
"""
# update the filepath
self.current_song_filepath: str = (
self.current_song_qmodel_index.siblingAtColumn(
list(self.headers.gui.values()).index("path")
).data()
)
if not filepath:
path = self.current_song_qmodel_index.siblingAtColumn(self.headers.user_headers.index("filepath")).data()
self.current_song_filepath: str = path
else:
self.current_song_filepath = filepath
def set_current_song_qmodel_index(self, index=None):
"""
@ -886,8 +901,8 @@ class MusicTable(QTableView):
if index is None:
index = self.currentIndex()
# map proxy (sortable) model to the original model (used for interactions)
model_index: QModelIndex = self.proxymodel.mapToSource(index)
self.current_song_qmodel_index: QModelIndex = model_index
real_index: QModelIndex = self.proxymodel.mapToSource(index)
self.current_song_qmodel_index: QModelIndex = real_index
def set_selected_song_qmodel_index(self, index=None):
"""
@ -898,8 +913,8 @@ class MusicTable(QTableView):
if index is None:
index = self.currentIndex()
# map proxy (sortable) model to the original model (used for interactions)
model_index: QModelIndex = self.proxymodel.mapToSource(index)
self.selected_song_qmodel_index: QModelIndex = model_index
real_index: QModelIndex = self.proxymodel.mapToSource(index)
self.selected_song_qmodel_index: QModelIndex = real_index
def load_qapp(self, qapp) -> None:
"""Necessary for using members and methods of main application window"""

23
main.py
View File

@ -328,7 +328,7 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
file_url = media.canonicalUrl().toLocalFile()
metadata = id3_remap(get_tags(file_url)[0])
if metadata is not None:
self.set_ui_metadata(metadata["title"], metadata["artist"], metadata["album"])
self.set_ui_metadata(metadata["title"], metadata["artist"], metadata["album"], file_url)
def on_volume_changed(self) -> None:
"""Handles volume changes"""
@ -368,26 +368,39 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
def on_prev_clicked(self) -> None:
"""click previous - go to previous song"""
current_real_index = self.tableView.current_song_qmodel_index
index = self.tableView.proxymodel.mapFromSource(current_real_index)
try:
index = self.tableView.proxymodel.mapFromSource(current_real_index)
except:
return
row: int = index.row()
prev_row: int = row - 1
prev_index: QModelIndex = self.tableView.proxymodel.index(prev_row, index.column())
prev_filepath = prev_index.siblingAtColumn(self.headers.user_headers.index("filepath")).data()
if prev_filepath is None:
return
self.play_audio_file(prev_filepath)
self.tableView.set_current_song_qmodel_index(prev_index)
self.tableView.set_current_song_filepath(prev_filepath)
def on_next_clicked(self) -> None:
"""click next (or song ended) - go to next song"""
current_real_index = self.tableView.current_song_qmodel_index
index = self.tableView.proxymodel.mapFromSource(current_real_index)
try:
# FIXME: seg fault here but only sometimes???
# when playing song in lib, switch to playlist, back to lib, next song
index = self.tableView.proxymodel.mapFromSource(current_real_index)
except:
return
row: int = index.row()
next_row: int = row + 1
next_index: QModelIndex = self.tableView.proxymodel.index(next_row, index.column())
next_filepath = next_index.siblingAtColumn(self.headers.user_headers.index("filepath")).data()
if next_filepath is None:
return
self.play_audio_file(next_filepath)
self.tableView.set_current_song_qmodel_index(next_index)
self.tableView.set_current_song_filepath(next_filepath)
# ____________________
# | |
@ -458,9 +471,9 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
filepath default value = `tableView.current_song_filepath`
"""
print('play audio file')
if not filepath:
filepath = self.tableView.get_selected_song_filepath()
file_url = QUrl.fromLocalFile(filepath)
metadata = id3_remap(get_tags(filepath)[0])
# read the file
url = QUrl.fromLocalFile(filepath)

View File

@ -9,7 +9,6 @@ def get_album_art(file: str | None) -> bytes:
# Returns
bytes for album art or placeholder artwork
"""
debug(f'try album art: {file}')
default_image_path = "./assets/default_album_art.jpg"
if file:
try:
@ -23,5 +22,5 @@ def get_album_art(file: str | None) -> bytes:
error(f"Error retrieving album art: {e}")
return bytes()
with open(default_image_path, "rb") as f:
debug("loading placeholder album art")
# debug("loading placeholder album art")
return f.read()

View File

@ -1,5 +1,6 @@
from logging import debug, error
from components import ErrorDialog, HeaderTags
from components import ErrorDialog
from components.HeaderTags import HeaderTags
# from utils import convert_date_str_to_tyer_tdat_id3_tag
from mutagen.id3 import ID3
@ -120,7 +121,7 @@ def set_tag(filepath: str, tag_name: str, value: str):
return True
# Convert any ID3 tag or nice name (that i chose) into into the Mutagen Frame object
if tag_name in list(headers.id3_keys.values()):
tag_nice_name = headers.id3_keys[tag_name]
tag_nice_name = headers.id3[tag_name]
else:
tag_nice_name = tag_name
# Other