From a41f909abe093c595f32d691acfc91ec0ed538cf Mon Sep 17 00:00:00 2001 From: tsi-billypom Date: Mon, 24 Mar 2025 11:29:31 -0400 Subject: [PATCH] XDG_CONFIG_HOME config file and put the database there i guess --- DBA.py | 8 ++++- components/ExportPlaylistWindow.py | 22 ++++++++---- components/MusicTable.py | 24 ++++++++----- components/PreferencesWindow.py | 21 ++++++++--- main.py | 56 ++++++++++++++++++++++-------- requirements.txt | 1 + utils/add_files_to_library.py | 11 ++++-- utils/scan_for_music.py | 10 ++++-- 8 files changed, 111 insertions(+), 42 deletions(-) diff --git a/DBA.py b/DBA.py index 1f32305..3ea56f5 100644 --- a/DBA.py +++ b/DBA.py @@ -1,13 +1,19 @@ import sqlite3 import logging from configparser import ConfigParser +from pathlib import Path +from appdirs import user_config_dir class DBAccess: def __init__(self, db_name=None): logging.info("Instantiating DBAccess") config = ConfigParser() - config.read("config.ini") + cfg_file = ( + Path(user_config_dir(appname="musicpom", appauthor="billypom")) + / "config.ini" + ) + config.read(cfg_file) if db_name is None: db_name = config.get("db", "database") self._conn: sqlite3.Connection = sqlite3.connect(db_name) diff --git a/components/ExportPlaylistWindow.py b/components/ExportPlaylistWindow.py index 975550f..7ebf986 100644 --- a/components/ExportPlaylistWindow.py +++ b/components/ExportPlaylistWindow.py @@ -1,4 +1,6 @@ import logging +import DBA +import os from PyQt5.QtWidgets import ( QCheckBox, QDialog, @@ -11,11 +13,11 @@ from PyQt5.QtWidgets import ( QListWidgetItem, ) from PyQt5.QtGui import QFont -from configparser import ConfigParser from utils import get_reorganize_vars from components import ErrorDialog -import DBA -import os +from configparser import ConfigParser +from pathlib import Path +from appdirs import user_config_dir class ExportPlaylistWindow(QDialog): @@ -23,10 +25,16 @@ class ExportPlaylistWindow(QDialog): super(ExportPlaylistWindow, self).__init__() self.setWindowTitle("Export playlist") self.setMinimumSize(600, 400) - config = ConfigParser() - config.read("config.ini") - self.relative_path: str = config.get("directories", "playlist_relative_path") - self.export_path: str = config.get("directories", "playlist_export_path") + self.cfg_file = ( + Path(user_config_dir(appname="musicpom", appauthor="billypom")) + / "config.ini" + ) + self.config = ConfigParser() + self.config.read(self.cfg_file) + self.relative_path: str = self.config.get( + "directories", "playlist_relative_path" + ) + self.export_path: str = self.config.get("directories", "playlist_export_path") self.selected_playlist_name: str = "my-playlist.m3u" self.current_m3u_path: str = self.export_path self.current_relative_path: str = self.relative_path diff --git a/components/MusicTable.py b/components/MusicTable.py index 729801e..56e86e4 100644 --- a/components/MusicTable.py +++ b/components/MusicTable.py @@ -44,10 +44,12 @@ from utils.get_album_art import get_album_art from utils import set_id3_tag from subprocess import Popen from logging import debug, error -import configparser import os import shutil import typing +from pathlib import Path +from appdirs import user_config_dir +from configparser import ConfigParser class MusicTable(QTableView): @@ -65,8 +67,14 @@ class MusicTable(QTableView): self.setModel(self.model2) # Config - self.config = configparser.ConfigParser() - self.config.read("config.ini") + cfg_file = ( + Path(user_config_dir(appname="musicpom", appauthor="billypom")) + / "config.ini" + ) + self.config = ConfigParser() + self.config.read(cfg_file) + + # Threads self.threadpool = QThreadPool # gui names of headers self.table_headers = [ @@ -494,7 +502,7 @@ class MusicTable(QTableView): Reorganizes files into Artist/Album/Song, based on self.config['directories'][reorganize_destination'] """ - debug('reorganizing files') + debug("reorganizing files") # Get target directory target_dir = str(self.config["directories"]["reorganize_destination"]) for filepath in filepaths: @@ -511,10 +519,10 @@ class MusicTable(QTableView): if progress_callback: progress_callback.emit(f"Organizing: {filepath}") # Create the directories if they dont exist - debug('make dirs') + debug("make dirs") os.makedirs(os.path.dirname(new_path), exist_ok=True) # Move the file to the new directory - debug(f'{filepath} > {new_path}') + debug(f"{filepath} > {new_path}") shutil.move(filepath, new_path) # Update the db with DBA.DBAccess() as db: @@ -524,9 +532,7 @@ class MusicTable(QTableView): ) debug(f"reorganize_files() | Moved: {filepath} -> {new_path}") except Exception as e: - error( - f"reorganize_files() | Error moving file: {filepath} | {e}" - ) + error(f"reorganize_files() | Error moving file: {filepath} | {e}") # Draw the rest of the owl # QMessageBox.information( # self, "Reorganization complete", "Files successfully reorganized" diff --git a/components/PreferencesWindow.py b/components/PreferencesWindow.py index 4c94840..f81b6b4 100644 --- a/components/PreferencesWindow.py +++ b/components/PreferencesWindow.py @@ -10,16 +10,26 @@ from PyQt5.QtWidgets import ( QWidget, QDial, ) +from logging import info from PyQt5.QtGui import QFont +from configparser import ConfigParser +from pathlib import Path +from appdirs import user_config_dir class PreferencesWindow(QDialog): - def __init__(self, config): + def __init__(self, reloadConfigSignal): super(PreferencesWindow, self).__init__() # Config + self.reloadConfigSignal = reloadConfigSignal self.setWindowTitle("Preferences") self.setMinimumSize(800, 800) - self.config = config + self.cfg_file = ( + Path(user_config_dir(appname="musicpom", appauthor="billypom")) + / "config.ini" + ) + self.config = ConfigParser() + self.config.read(self.cfg_file) self.current_category = "" # Widgets @@ -83,7 +93,7 @@ class PreferencesWindow(QDialog): child.widget().deleteLater() def save_preferences(self): - print('im saving') + info("im saving") # Upcate the config fields for key in self.input_fields: for category in self.config.sections(): @@ -93,6 +103,7 @@ class PreferencesWindow(QDialog): ].text() # Write the config file - with open("config.ini", "w") as configfile: + with open(self.cfg_file, "w") as configfile: self.config.write(configfile) - # self.close() + + self.reloadConfigSignal.emit() diff --git a/main.py b/main.py index 66d8532..dfc8289 100644 --- a/main.py +++ b/main.py @@ -1,15 +1,17 @@ import os import sys import logging -from subprocess import run import qdarktheme import typing +import traceback +import DBA +from subprocess import run from pyqtgraph import mkBrush from mutagen.id3 import ID3 from mutagen.id3._frames import APIC from configparser import ConfigParser -import traceback -import DBA +from pathlib import Path +from appdirs import user_config_dir from logging import debug, error, warning, basicConfig, INFO, DEBUG from ui import Ui_MainWindow from PyQt5.QtWidgets import ( @@ -132,6 +134,7 @@ class Worker(QRunnable): class ApplicationWindow(QMainWindow, Ui_MainWindow): playlistCreatedSignal = pyqtSignal() + reloadConfigSignal = pyqtSignal() def __init__(self, clipboard): super(ApplicationWindow, self).__init__() @@ -141,7 +144,7 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow): self.threadpool = QThreadPool() # UI self.setupUi(self) - self.setWindowTitle("MusicPom") + self.setWindowTitle("musicpom") self.status_bar = QStatusBar() self.permanent_status_label = QLabel("Status...") self.status_bar.addPermanentWidget(self.permanent_status_label) @@ -152,6 +155,11 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow): self.current_song_album_art: bytes | None = None self.album_art_scene: QGraphicsScene = QGraphicsScene() self.config: ConfigParser = ConfigParser() + self.cfg_file = ( + Path(user_config_dir(appname="musicpom", appauthor="billypom")) + / "config.ini" + ) + self.config.read(self.cfg_file) self.player: QMediaPlayer = QMediaPlayer() # Audio player object self.probe: QAudioProbe = QAudioProbe() # Gets audio data self.audio_visualizer: AudioVisualizer = AudioVisualizer(self.player) @@ -159,7 +167,6 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow): self.clipboard = clipboard self.tableView.load_qapp(self) self.albumGraphicsView.load_qapp(self) - self.config.read("config.ini") # Initialization self.timer = QTimer(self) # Audio timing things self.player.setVolume(self.current_volume) @@ -242,9 +249,13 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow): self.delete_album_art_for_current_song ) - def reload_config(self) -> None: + def load_config(self) -> None: """does what it says""" - self.config.read("config.ini") + cfg_loc = ( + Path(user_config_dir(appname="musicpom", appauthor="billypom")) + / "config.ini" + ) + self.config.read(cfg_loc) def get_thread_pool(self) -> QThreadPool: """Returns the threadpool instance""" @@ -265,7 +276,7 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow): self.config["table"]["column_widths"] = column_widths_as_string # Save the config - with open("config.ini", "w") as configfile: + with open(self.cfg_file, "w") as configfile: self.config.write(configfile) if a0 is not None: super().closeEvent(a0) @@ -506,10 +517,9 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow): def open_preferences(self) -> None: """Opens the preferences window""" - preferences_window = PreferencesWindow(self.config) + preferences_window = PreferencesWindow(self.reloadConfigSignal) + preferences_window.reloadConfigSignal.connect(self.load_config) preferences_window.exec_() # Display the preferences window modally - self.reload_config() - self.tableView.load_music_table() # Quick Actions @@ -568,15 +578,33 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow): if __name__ == "__main__": # Initialization - if not os.path.exists("config.ini"): + + cfg_file = ( + Path(user_config_dir(appname="musicpom", appauthor="billypom")) / "config.ini" + ) + cfg_path = str(Path(user_config_dir(appname="musicpom", appauthor="billypom"))) + + # If the config file doesn't exist, create it from the sample config + if not os.path.exists(cfg_file): # Create config file from sample - run(["cp", "sample_config.ini", "config.ini"]) + run(["cp", "sample_config.ini", cfg_file]) config = ConfigParser() - config.read("config.ini") + config.read(cfg_file) + db_filepath: str = config.get("db", "database") + + # If the database location isnt set at the config location, move it + if not db_filepath.startswith(cfg_path): + config["db"]["database"] = f"{cfg_path}/{db_filepath}" + # Save the config + with open(cfg_file, "w") as configfile: + config.write(configfile) + config.read(cfg_file) + db_filepath: str = config.get("db", "database") db_path = db_filepath.split("/") db_path.pop() db_path = "/".join(db_path) + # If the db file doesn't exist if not os.path.exists(db_filepath): # If the db directory doesn't exist diff --git a/requirements.txt b/requirements.txt index 0d22d45..b9d2ee6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,6 @@ mutagen matplotlib +appdirs pyqt5 pydub pyqtdarktheme-fork diff --git a/utils/add_files_to_library.py b/utils/add_files_to_library.py index 1e1b0df..99c7d04 100644 --- a/utils/add_files_to_library.py +++ b/utils/add_files_to_library.py @@ -1,11 +1,16 @@ import DBA -from configparser import ConfigParser -from utils import get_id3_tags, id3_timestamp_to_datetime import logging +from utils import get_id3_tags, id3_timestamp_to_datetime from PyQt5.QtCore import pyqtSignal +from configparser import ConfigParser +from pathlib import Path +from appdirs import user_config_dir config = ConfigParser() -config.read("config.ini") +cfg_file = ( + Path(user_config_dir(appname="musicpom", appauthor="billypom")) / "config.ini" +) +config.read(cfg_file) def add_files_to_library(files, progress_callback=None): diff --git a/utils/scan_for_music.py b/utils/scan_for_music.py index 255b2b4..844b576 100644 --- a/utils/scan_for_music.py +++ b/utils/scan_for_music.py @@ -1,11 +1,15 @@ import os -from configparser import ConfigParser - from PyQt5.QtCore import pyqtSignal from utils.add_files_to_library import add_files_to_library +from configparser import ConfigParser +from pathlib import Path +from appdirs import user_config_dir config = ConfigParser() -config.read("config.ini") +cfg_file = ( + Path(user_config_dir(appname="musicpom", appauthor="billypom")) / "config.ini" +) +config.read(cfg_file) def scan_for_music():