first time run auto-config + update readme

This commit is contained in:
tsi-billypom 2024-05-30 11:34:27 -04:00
parent 5b93f81e05
commit 767ce3fa9c
6 changed files with 79 additions and 22 deletions

11
DBA.py
View File

@ -2,17 +2,16 @@ import sqlite3
import logging
from configparser import ConfigParser
class DBAccess:
def __init__(self, db_name=None):
logging.info('Instantiating DBAccess')
logging.info("Instantiating DBAccess")
config = ConfigParser()
config.read('config.ini')
config.read("config.ini")
if db_name is None:
db_name = config.get('db', 'database')
db_name = config.get("db", "database")
self._conn: sqlite3.Connection = sqlite3.connect(db_name)
logging.info(f'DBAccess | self._conn = [\n{type(self._conn)}\n{self._conn}\n]')
self._cursor: sqlite3.Cursor = self._conn.cursor()
logging.info(f'DBAccess | self._cursor = [\n{type(self._cursor)}\n{self._cursor}\n]')
def __enter__(self):
return self
@ -40,7 +39,7 @@ class DBAccess:
self.cursor.execute(sql, params or ())
def executemany(self, sql, seq_of_params):
self.cursor.executemany(sql, seq_of_params) #sqlite has execute many i guess?
self.cursor.executemany(sql, seq_of_params) # sqlite has execute many i guess?
def fetchall(self):
return self.cursor.fetchall()

View File

@ -2,6 +2,29 @@
PyQt5 music player inspired by MusicBee & iTunes
## Installation:
clone the repo
```
git clone https://github.com/billypom/musicpom
```
install system packages
```
sudo apt install ffmpeg
sudo apt install python3-pyqt5
```
create environment
```
cd musicpom
virtualenv venv
cd ..
cd musicpom
pip install -r requirements.txt
```
run the program
```
python3 main.py
```
## Todo:
- [ ] Delete songs from library (del key || right-click delete)

View File

@ -7,14 +7,23 @@ from PyQt5.QtGui import (
QDragEnterEvent,
QDropEvent,
)
from PyQt5.QtWidgets import QAction, QMenu, QTableView, QShortcut, QMessageBox, QAbstractItemView
from PyQt5.QtWidgets import (
QAction,
QMenu,
QTableView,
QShortcut,
QMessageBox,
QAbstractItemView,
)
from PyQt5.QtCore import QModelIndex, Qt, pyqtSignal, QTimer
from utils import add_files_to_library
from utils import update_song_in_library
from utils import get_id3_tags
from utils import get_album_art
from utils import set_id3_tag
from utils import delete_and_create_library_database
from subprocess import Popen
from sqlite3 import OperationalError
import logging
import configparser
import os
@ -57,8 +66,8 @@ class MusicTable(QTableView):
self.database_columns = str(self.config["table"]["columns"]).split(",")
self.vertical_scroll_position = 0
self.songChanged = None
self.selected_song_filepath = ''
self.current_song_filepath = ''
self.selected_song_filepath = ""
self.current_song_filepath = ""
# self.tableView.resizeColumnsToContents()
self.clicked.connect(self.set_selected_song_filepath)
# doubleClicked is a built in event for QTableView - we listen for this event and run set_current_song_filepath
@ -104,12 +113,12 @@ class MusicTable(QTableView):
# self.model().removeRow(index)
for file in selected_filepaths:
with DBA.DBAccess() as db:
db.execute('DELETE FROM library WHERE filepath = ?', (file,))
db.execute("DELETE FROM library WHERE filepath = ?", (file,))
def open_directory(self):
filepath = self.get_selected_song_filepath().split('/')
filepath = self.get_selected_song_filepath().split("/")
filepath.pop()
path = '/'.join(filepath)
path = "/".join(filepath)
Popen(["xdg-open", path])
def show_lyrics_menu(self):
@ -241,7 +250,7 @@ class MusicTable(QTableView):
self.playPauseSignal.emit()
def fetch_library(self):
"""Initialize the tableview model"""
"""Initializes the tableview model"""
self.vertical_scroll_position = (
self.verticalScrollBar().value()
) # Get my scroll position before clearing
@ -249,18 +258,22 @@ class MusicTable(QTableView):
self.model.clear()
self.model.setHorizontalHeaderLabels(self.table_headers)
# Fetch library data
with DBA.DBAccess() as db:
data = db.query(
"SELECT id, title, artist, album, genre, codec, album_date, filepath FROM library;",
(),
)
try:
with DBA.DBAccess() as db:
data = db.query(
"SELECT id, title, artist, album, genre, codec, album_date, filepath FROM library;",
(),
)
except Exception as e:
logging.warning(f"MusicTable.py | fetch_library | Unhandled exception: {e}")
return
# Populate the model
for row_data in data:
id, *rest_of_data = row_data
items = [QStandardItem(str(item)) for item in rest_of_data]
self.model.appendRow(items)
# store id using setData - useful for later faster db fetching
row = self.model.rowCount() - 1
# row = self.model.rowCount() - 1
for item in items:
item.setData(id, Qt.UserRole)
# Update the viewport/model

22
main.py
View File

@ -1,10 +1,13 @@
import os
import configparser
import sys
from subprocess import run
import qdarktheme
from pyqtgraph import mkBrush
from mutagen.id3 import ID3, APIC, error
from mutagen.mp3 import MP3
from configparser import ConfigParser
import DBA
from ui import Ui_MainWindow
from PyQt5.QtWidgets import (
QMainWindow,
@ -337,6 +340,25 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
if __name__ == "__main__":
# First run initialization
if not os.path.exists("config.ini"):
# Create config file from sample
run(["cp", "sample_config.ini", "config.ini"])
config = ConfigParser()
config.read("config.ini")
db_name = config.get("db", "database")
db_path = db_name.split("/")
db_path.pop()
path_as_string = "/".join(db_path)
if not os.path.exists(path_as_string):
os.makedirs(path_as_string)
# Create database on first run
with DBA.DBAccess() as db:
with open("utils/delete_and_create_library.sql", "r") as file:
lines = file.read()
for statement in lines.split(";"):
print(f"executing [{statement}]")
db.execute(statement, ())
# Allow for dynamic imports of my custom classes and utilities
project_root = os.path.abspath(os.path.dirname(__file__))
sys.path.append(project_root)

View File

@ -1,6 +1,6 @@
[db]
# The library database file
library = db/library.db
database = db/library.db
[directories]
# Useful paths to have stored