fixes and fonts and such
This commit is contained in:
parent
80dd2df74b
commit
1add0bc85a
@ -1,8 +1,5 @@
|
|||||||
from configparser import ConfigParser
|
|
||||||
from pathlib import Path
|
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from appdirs import user_config_dir
|
from dataclasses import dataclass
|
||||||
from dataclasses import dataclass, asdict
|
|
||||||
from mutagen.id3._frames import (
|
from mutagen.id3._frames import (
|
||||||
TIT2,
|
TIT2,
|
||||||
TPE1,
|
TPE1,
|
||||||
@ -80,22 +77,6 @@ mutagen_id3_tag_mapping = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class SQLiteMap:
|
|
||||||
title: str | TIT2 | None = None
|
|
||||||
artist: str | TPE1 | None = None
|
|
||||||
album: str | TALB | None = None
|
|
||||||
album_artist: str | TPE2 | None = None
|
|
||||||
track_number: str | TRCK | None = None
|
|
||||||
genre: str | TCON | None = None
|
|
||||||
length_ms: str | TLEN | None = None
|
|
||||||
album_date: str | TDRC | None = None
|
|
||||||
codec: str | None = None
|
|
||||||
filepath: str | None = None
|
|
||||||
bitrate: str | None = None
|
|
||||||
# lyrics: str | USLT | None = None
|
|
||||||
# album_art: str | APIC | None = None
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ID3Field:
|
class ID3Field:
|
||||||
db: str # e.g., "title"
|
db: str # e.g., "title"
|
||||||
@ -134,114 +115,3 @@ class HeaderTags2:
|
|||||||
def get_editable_db_list(self) -> list:
|
def get_editable_db_list(self) -> list:
|
||||||
return [f.db for f in self.headers if f.editable]
|
return [f.db for f in self.headers if f.editable]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class HeaderTags:
|
|
||||||
"""
|
|
||||||
Utility class to converting between different "standards" for tags (headers, id3, etc)
|
|
||||||
|
|
||||||
`db`: dict = "db name": "db name string"
|
|
||||||
`gui`: dict = "db name": "gui string"
|
|
||||||
`id3`: dict = "db name": "id3 tag string"
|
|
||||||
`id3_keys`: dict = "id3 tag string": "db name"
|
|
||||||
`editable_fields`: list = "list of db names that are user editable"
|
|
||||||
`user_fields`: list = "list of db headers that the user has chosen to see in gui"
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
cfg_file = (
|
|
||||||
Path(user_config_dir(appname="musicpom", appauthor="billypom"))
|
|
||||||
/ "config.ini"
|
|
||||||
)
|
|
||||||
self.config = ConfigParser()
|
|
||||||
self.config.read(cfg_file)
|
|
||||||
# print("header tag config")
|
|
||||||
# print(self.config)
|
|
||||||
self.user_fields: list = str(self.config["table"]["columns"]).split(",")
|
|
||||||
self.editable_fields: list = [
|
|
||||||
"title",
|
|
||||||
"artist",
|
|
||||||
"album_artist",
|
|
||||||
"album",
|
|
||||||
"track_number",
|
|
||||||
"genre",
|
|
||||||
"album_date",
|
|
||||||
]
|
|
||||||
self.fields = SQLiteMap()
|
|
||||||
self.headers = SQLiteMap(
|
|
||||||
title="title",
|
|
||||||
artist="artist",
|
|
||||||
album="album",
|
|
||||||
album_artist="alb artist",
|
|
||||||
track_number="track",
|
|
||||||
genre="genre",
|
|
||||||
album_date="year",
|
|
||||||
codec="codec",
|
|
||||||
length_ms="length",
|
|
||||||
filepath="path",
|
|
||||||
bitrate="bitrate",
|
|
||||||
)
|
|
||||||
# self.id3 = SQLiteMap(
|
|
||||||
# title = "TIT2",
|
|
||||||
# artist = "TPE1",
|
|
||||||
# album = "TALB",
|
|
||||||
# album_artist = "TPE2",
|
|
||||||
# track_number = "TRCK",
|
|
||||||
# genre = "TCON",
|
|
||||||
# length_seconds = "TLEN",
|
|
||||||
# album_date = "TDRC",
|
|
||||||
# codec = None,
|
|
||||||
# filepath = None
|
|
||||||
# )
|
|
||||||
self.db: dict = {
|
|
||||||
"title": "title",
|
|
||||||
"artist": "artist",
|
|
||||||
"album": "album",
|
|
||||||
"album_artist": "album_artist",
|
|
||||||
"track_number": "track_number",
|
|
||||||
"genre": "genre",
|
|
||||||
"album_date": "album_date",
|
|
||||||
"codec": "codec",
|
|
||||||
"length_seconds": "length_seconds",
|
|
||||||
"filepath": "filepath",
|
|
||||||
"bitrate": "bitrate",
|
|
||||||
}
|
|
||||||
self.gui: dict = {
|
|
||||||
"title": "title",
|
|
||||||
"artist": "artist",
|
|
||||||
"album": "album",
|
|
||||||
"album_artist": "alb artist",
|
|
||||||
"track_number": "track",
|
|
||||||
"genre": "genre",
|
|
||||||
"album_date": "year",
|
|
||||||
"codec": "codec",
|
|
||||||
"length_seconds": "length",
|
|
||||||
"filepath": "path",
|
|
||||||
"bitrate": "bitrate",
|
|
||||||
}
|
|
||||||
self.id3: dict = {
|
|
||||||
"title": "TIT2",
|
|
||||||
"artist": "TPE1",
|
|
||||||
"album_artist": "TPE2",
|
|
||||||
"album": "TALB",
|
|
||||||
"track_number": "TRCK",
|
|
||||||
"genre": "TCON",
|
|
||||||
"album_date": "TDRC",
|
|
||||||
"codec": None,
|
|
||||||
"length_seconds": "TLEN",
|
|
||||||
"filepath": None,
|
|
||||||
"bitrate": "TBIT",
|
|
||||||
}
|
|
||||||
# id3 is the key
|
|
||||||
self.id3_keys: dict = {}
|
|
||||||
for k, v in self.id3.items():
|
|
||||||
if v is not None:
|
|
||||||
self.id3_keys[v] = k
|
|
||||||
|
|
||||||
def get_user_gui_headers(self) -> list:
|
|
||||||
"""Returns a list of headers for the GUI"""
|
|
||||||
gui_headers = []
|
|
||||||
for db, gui in asdict(self.headers).items():
|
|
||||||
if db in self.user_fields:
|
|
||||||
gui_headers.append(gui)
|
|
||||||
return gui_headers
|
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import DBA
|
|||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
QColor,
|
QColor,
|
||||||
QDragMoveEvent,
|
QDragMoveEvent,
|
||||||
|
QFont,
|
||||||
QPainter,
|
QPainter,
|
||||||
QPen,
|
QPen,
|
||||||
QStandardItem,
|
QStandardItem,
|
||||||
@ -83,6 +84,10 @@ class MusicTable(QTableView):
|
|||||||
)
|
)
|
||||||
_ = self.config.read(self.cfg_file)
|
_ = self.config.read(self.cfg_file)
|
||||||
|
|
||||||
|
font: QFont = QFont()
|
||||||
|
font.setPointSize(11)
|
||||||
|
self.setFont(font)
|
||||||
|
|
||||||
# NOTE:
|
# NOTE:
|
||||||
# QTableView model2 = QSortFilterProxyModel(QStandardItemModel)
|
# QTableView model2 = QSortFilterProxyModel(QStandardItemModel)
|
||||||
#
|
#
|
||||||
@ -765,9 +770,13 @@ class MusicTable(QTableView):
|
|||||||
|
|
||||||
hint: You get a `playlist_id` from the signal emitted from PlaylistsPane as a tuple (1,)
|
hint: You get a `playlist_id` from the signal emitted from PlaylistsPane as a tuple (1,)
|
||||||
"""
|
"""
|
||||||
|
if playlist_id:
|
||||||
|
if self.selected_playlist_id == playlist_id[0]:
|
||||||
|
# Don't reload if we clicked the same item
|
||||||
|
return
|
||||||
# self.disconnect_data_changed()
|
# self.disconnect_data_changed()
|
||||||
# self.disconnect_layout_changed()
|
# self.disconnect_layout_changed()
|
||||||
self.save_scroll_position(self.current_playlist_id)
|
# self.save_scroll_position(self.current_playlist_id)
|
||||||
self.model2.clear()
|
self.model2.clear()
|
||||||
# self.model2.setHorizontalHeaderLabels(self.headers.get_user_gui_headers())
|
# self.model2.setHorizontalHeaderLabels(self.headers.get_user_gui_headers())
|
||||||
self.model2.setHorizontalHeaderLabels(self.headers.db_list)
|
self.model2.setHorizontalHeaderLabels(self.headers.db_list)
|
||||||
@ -780,10 +789,15 @@ class MusicTable(QTableView):
|
|||||||
params = ""
|
params = ""
|
||||||
is_playlist = 0
|
is_playlist = 0
|
||||||
if len(playlist_id) > 0:
|
if len(playlist_id) > 0:
|
||||||
self.selected_playlist_id = playlist_id[0]
|
if playlist_id[0] == 0:
|
||||||
is_playlist = 1
|
self.selected_playlist_id = 0
|
||||||
|
is_playlist = 0
|
||||||
|
else:
|
||||||
|
self.selected_playlist_id = playlist_id[0]
|
||||||
|
is_playlist = 1
|
||||||
else:
|
else:
|
||||||
self.selected_playlist_id = None
|
self.selected_playlist_id = 0
|
||||||
|
is_playlist = 0
|
||||||
|
|
||||||
# try:
|
# try:
|
||||||
# # Check cache for already loaded QTableView QStandardItemModel
|
# # Check cache for already loaded QTableView QStandardItemModel
|
||||||
@ -1097,13 +1111,13 @@ class MusicTable(QTableView):
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def connect_layout_changed(self):
|
# def connect_layout_changed(self):
|
||||||
"""Connects the layoutChanged signal from QTableView.model"""
|
# """Connects the layoutChanged signal from QTableView.model"""
|
||||||
try:
|
# try:
|
||||||
pass
|
# pass
|
||||||
_ = self.model2.layoutChanged.connect(self.restore_scroll_position)
|
# _ = self.model2.layoutChanged.connect(self.restore_scroll_position)
|
||||||
except Exception:
|
# except Exception:
|
||||||
pass
|
# pass
|
||||||
|
|
||||||
|
|
||||||
# QT Roles
|
# QT Roles
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
from PyQt5.QtGui import QFont
|
||||||
from PyQt5.QtWidgets import (
|
from PyQt5.QtWidgets import (
|
||||||
QAction,
|
QAction,
|
||||||
QInputDialog,
|
QInputDialog,
|
||||||
@ -42,6 +43,10 @@ class PlaylistsPane(QTreeWidget):
|
|||||||
self.customContextMenuRequested.connect(self.showContextMenu)
|
self.customContextMenuRequested.connect(self.showContextMenu)
|
||||||
self.currentItemChanged.connect(self.playlist_clicked)
|
self.currentItemChanged.connect(self.playlist_clicked)
|
||||||
self.playlist_db_id_choice: int | None = None
|
self.playlist_db_id_choice: int | None = None
|
||||||
|
font: QFont = QFont()
|
||||||
|
font.setPointSize(16)
|
||||||
|
font.setBold(True)
|
||||||
|
self.setFont(font)
|
||||||
|
|
||||||
def reload_playlists(self, progress_callback=None):
|
def reload_playlists(self, progress_callback=None):
|
||||||
"""
|
"""
|
||||||
@ -50,7 +55,7 @@ class PlaylistsPane(QTreeWidget):
|
|||||||
"""
|
"""
|
||||||
# take all children away
|
# take all children away
|
||||||
self._playlists_root.takeChildren()
|
self._playlists_root.takeChildren()
|
||||||
# NOTE: implement user sorting by adding a column to playlist db table for 'rank' or something
|
# TODO: implement user sorting by adding a column to playlist db table for 'rank' or something
|
||||||
with DBA.DBAccess() as db:
|
with DBA.DBAccess() as db:
|
||||||
playlists = db.query(
|
playlists = db.query(
|
||||||
"SELECT id, name FROM playlist ORDER BY date_created DESC;", ()
|
"SELECT id, name FROM playlist ORDER BY date_created DESC;", ()
|
||||||
@ -144,7 +149,7 @@ class PlaylistsPane(QTreeWidget):
|
|||||||
if item == self._playlists_root or item == self._library_root:
|
if item == self._playlists_root or item == self._library_root:
|
||||||
self.playlist_db_id_choice = None
|
self.playlist_db_id_choice = None
|
||||||
# self.all_songs_selected()
|
# self.all_songs_selected()
|
||||||
self.allSongsSignal.emit()
|
self.playlistChoiceSignal.emit(0)
|
||||||
elif isinstance(item, PlaylistWidgetItem):
|
elif isinstance(item, PlaylistWidgetItem):
|
||||||
# debug(f"ID: {item.id}, name: {item.text(0)}")
|
# debug(f"ID: {item.id}, name: {item.text(0)}")
|
||||||
self.playlist_db_id_choice = item.id
|
self.playlist_db_id_choice = item.id
|
||||||
@ -153,9 +158,3 @@ class PlaylistsPane(QTreeWidget):
|
|||||||
def load_qapp(self, qapp) -> None:
|
def load_qapp(self, qapp) -> None:
|
||||||
"""Necessary for using members and methods of main application window"""
|
"""Necessary for using members and methods of main application window"""
|
||||||
self.qapp = qapp
|
self.qapp = qapp
|
||||||
|
|
||||||
# def all_songs_selected(self):
|
|
||||||
# """Emits a signal to display all songs in the library"""
|
|
||||||
# # I have no idea why this has to be in its own function, but it does
|
|
||||||
# # or else it doesn't work
|
|
||||||
# self.allSongsSignal.emit()
|
|
||||||
|
|||||||
@ -11,6 +11,6 @@ from .CreatePlaylistWindow import CreatePlaylistWindow
|
|||||||
from .PlaylistsPane import PlaylistsPane
|
from .PlaylistsPane import PlaylistsPane
|
||||||
from .ExportPlaylistWindow import ExportPlaylistWindow
|
from .ExportPlaylistWindow import ExportPlaylistWindow
|
||||||
from .QuestionBoxDetails import QuestionBoxDetails
|
from .QuestionBoxDetails import QuestionBoxDetails
|
||||||
from .HeaderTags import HeaderTags, HeaderTags2
|
from .HeaderTags import HeaderTags2
|
||||||
from .MediaPlayer import MediaPlayer
|
from .MediaPlayer import MediaPlayer
|
||||||
from .SearchLineEdit import SearchLineEdit
|
from .SearchLineEdit import SearchLineEdit
|
||||||
|
|||||||
15
main.py
15
main.py
@ -157,7 +157,6 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
|
|||||||
self.actionOpenFiles.triggered.connect(self.open_files) # Open files window
|
self.actionOpenFiles.triggered.connect(self.open_files) # Open files window
|
||||||
self.actionNewPlaylist.triggered.connect(self.playlistTreeView.create_playlist)
|
self.actionNewPlaylist.triggered.connect(self.playlistTreeView.create_playlist)
|
||||||
self.actionExportPlaylist.triggered.connect(self.export_playlist)
|
self.actionExportPlaylist.triggered.connect(self.export_playlist)
|
||||||
|
|
||||||
# EDIT MENU
|
# EDIT MENU
|
||||||
self.actionPreferences.triggered.connect(self.open_preferences)
|
self.actionPreferences.triggered.connect(self.open_preferences)
|
||||||
# VIEW MENU
|
# VIEW MENU
|
||||||
@ -207,14 +206,6 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
|
|||||||
|
|
||||||
def closeEvent(self, a0: QCloseEvent | None) -> None:
|
def closeEvent(self, a0: QCloseEvent | None) -> None:
|
||||||
"""Save settings when closing the application"""
|
"""Save settings when closing the application"""
|
||||||
# MusicTable/tableView column widths
|
|
||||||
# list_of_column_widths = []
|
|
||||||
# for i in range(self.tableView.model2.columnCount()):
|
|
||||||
# list_of_column_widths.append(str(self.tableView.columnWidth(i)))
|
|
||||||
# column_widths_as_string = ",".join(list_of_column_widths)
|
|
||||||
# debug(f"saving column widths: {column_widths_as_string}")
|
|
||||||
# self.config["table"]["column_widths"] = column_widths_as_string
|
|
||||||
|
|
||||||
self.config["settings"]["volume"] = str(self.current_volume)
|
self.config["settings"]["volume"] = str(self.current_volume)
|
||||||
self.config["settings"]["window_size"] = (str(self.width()) + "," + str(self.height()))
|
self.config["settings"]["window_size"] = (str(self.width()) + "," + str(self.height()))
|
||||||
self.config['table']['column_ratios'] = ",".join(self.tableView.get_current_header_width_ratios())
|
self.config['table']['column_ratios'] = ",".join(self.tableView.get_current_header_width_ratios())
|
||||||
@ -687,8 +678,10 @@ if __name__ == "__main__":
|
|||||||
handlers=handlers,
|
handlers=handlers,
|
||||||
)
|
)
|
||||||
debug('--------- musicpom debug started')
|
debug('--------- musicpom debug started')
|
||||||
debug('---------------------| ')
|
debug('--------------------------------')
|
||||||
debug(f'----------------------> {handlers} ')
|
debug(handlers)
|
||||||
|
debug('--------------------------------')
|
||||||
|
debug('--------------------------------')
|
||||||
# Initialization
|
# Initialization
|
||||||
config: ConfigParser = update_config_file()
|
config: ConfigParser = update_config_file()
|
||||||
if not update_database_file():
|
if not update_database_file():
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user