This commit is contained in:
billypom on debian 2025-04-17 22:43:32 -04:00
parent 0f459d3216
commit 8bfc269f42
9 changed files with 35 additions and 45 deletions

View File

@ -7,7 +7,7 @@ from PyQt5.QtWidgets import (
) )
from PyQt5.QtGui import QFont from PyQt5.QtGui import QFont
from components.ErrorDialog import ErrorDialog from components.ErrorDialog import ErrorDialog
from utils import set_id3_tag from utils import set_tag
from logging import debug from logging import debug
@ -32,7 +32,7 @@ class LyricsWindow(QDialog):
def save(self): def save(self):
"""Saves the current lyrics text to the USLT/lyrics ID3 tag""" """Saves the current lyrics text to the USLT/lyrics ID3 tag"""
success = set_id3_tag( success = set_tag(
filepath=self.song_filepath, filepath=self.song_filepath,
tag_name="lyrics", tag_name="lyrics",
value=self.input_field.toPlainText(), value=self.input_field.toPlainText(),

View File

@ -12,10 +12,7 @@ from PyQt5.QtGui import QFont
from PyQt5.QtCore import pyqtSignal from PyQt5.QtCore import pyqtSignal
from mutagen.id3 import ID3 from mutagen.id3 import ID3
from components.ErrorDialog import ErrorDialog from components.ErrorDialog import ErrorDialog
from utils.get_id3_tags import get_id3_tags from utils import set_tag, get_tag, update_song_in_database, id3_tag_mapping
from utils.set_id3_tag import set_id3_tag
from utils.update_song_in_database import update_song_in_database
from utils.id3_tag_mapping import id3_tag_mapping
from logging import debug from logging import debug
# import re # import re
@ -65,7 +62,7 @@ class MetadataWindow(QDialog):
# Get a dict of all tags for all songs # Get a dict of all tags for all songs
# e.g., { "TIT2": ["song_title1", "song_title2"], ... } # e.g., { "TIT2": ["song_title1", "song_title2"], ... }
for song in self.songs: for song in self.songs:
song_data = get_id3_tags(song[0]) song_data = get_tags(song[0])
if not song_data: if not song_data:
QMessageBox.error( QMessageBox.error(
self, self,
@ -135,7 +132,7 @@ class MetadataWindow(QDialog):
if field.has_changed(): if field.has_changed():
# Update the ID3 tag if the tag is not blank, # Update the ID3 tag if the tag is not blank,
# and has been edited # and has been edited
success = set_id3_tag( success = set_tag(
filepath=song[0], tag_name=tag, value=field.text() filepath=song[0], tag_name=tag, value=field.text()
) )
if success: if success:

View File

@ -42,16 +42,17 @@ from components.MetadataWindow import MetadataWindow
from components.QuestionBoxDetails import QuestionBoxDetails from components.QuestionBoxDetails import QuestionBoxDetails
from main import Worker from main import Worker
from utils.batch_delete_filepaths_from_database import ( from utils import (
batch_delete_filepaths_from_database, batch_delete_filepaths_from_database,
delete_song_id_from_database,
add_files_to_database,
get_reorganize_vars,
update_song_in_database,
get_album_art,
id3_remap,
get_tags,
set_tag
) )
from utils.delete_song_id_from_database import delete_song_id_from_database
from utils.add_files_to_database import add_files_to_database
from utils.get_reorganize_vars import get_reorganize_vars
from utils.update_song_in_database import update_song_in_database
from utils.get_id3_tags import get_id3_tags, id3_remap
from utils.get_album_art import get_album_art
from utils import set_id3_tag
from subprocess import Popen from subprocess import Popen
from logging import debug, error from logging import debug, error
import os import os
@ -91,7 +92,7 @@ class TableHeader:
"artist": "TPE1", "artist": "TPE1",
"album": "TALB", "album": "TALB",
"track_number": "TRCK", "track_number": "TRCK",
"genre": "content_type", "genre": "TCON",
"codec": None, "codec": None,
"length_seconds": "TLEN", "length_seconds": "TLEN",
"album_date": "TDRC", "album_date": "TDRC",
@ -440,7 +441,7 @@ class MusicTable(QTableView):
user_input_data = topLeft.data() user_input_data = topLeft.data()
edited_column_name = self.database_columns[topLeft.column()] edited_column_name = self.database_columns[topLeft.column()]
debug(f"on_cell_data_changed | edited column name: {edited_column_name}") debug(f"on_cell_data_changed | edited column name: {edited_column_name}")
response = set_id3_tag(filepath, edited_column_name, user_input_data) response = set_tag(filepath, edited_column_name, user_input_data)
if response: if response:
# Update the library with new metadata # Update the library with new metadata
update_song_in_database(song_id, edited_column_name, user_input_data) update_song_in_database(song_id, edited_column_name, user_input_data)
@ -600,7 +601,7 @@ class MusicTable(QTableView):
selected_song_filepath = self.get_selected_song_filepath() selected_song_filepath = self.get_selected_song_filepath()
if selected_song_filepath is None: if selected_song_filepath is None:
return return
dic = id3_remap(get_id3_tags(selected_song_filepath)[0]) dic = id3_remap(get_tags(selected_song_filepath)[0])
lyrics = dic["lyrics"] lyrics = dic["lyrics"]
lyrics_window = LyricsWindow(selected_song_filepath, lyrics) lyrics_window = LyricsWindow(selected_song_filepath, lyrics)
lyrics_window.exec_() lyrics_window.exec_()
@ -860,11 +861,11 @@ class MusicTable(QTableView):
def get_current_song_metadata(self) -> dict: def get_current_song_metadata(self) -> dict:
"""Returns the currently playing song's ID3 tags""" """Returns the currently playing song's ID3 tags"""
return id3_remap(get_id3_tags(self.current_song_filepath)[0]) return id3_remap(get_tags(self.current_song_filepath)[0])
def get_selected_song_metadata(self) -> dict: def get_selected_song_metadata(self) -> dict:
"""Returns the selected song's ID3 tags""" """Returns the selected song's ID3 tags"""
return id3_remap(get_id3_tags(self.selected_song_filepath)[0]) return id3_remap(get_tags(self.selected_song_filepath)[0])
def get_current_song_album_art(self) -> bytes: def get_current_song_album_art(self) -> bytes:
"""Returns the APIC data (album art lol) for the currently playing song""" """Returns the APIC data (album art lol) for the currently playing song"""

View File

@ -41,7 +41,7 @@ from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent, QAudioProbe, QMediaP
from PyQt5.QtGui import QClipboard, QCloseEvent, QFont, QPixmap, QResizeEvent from PyQt5.QtGui import QClipboard, QCloseEvent, QFont, QPixmap, QResizeEvent
from utils import ( from utils import (
delete_album_art, delete_album_art,
get_id3_tags, get_tags,
scan_for_music, scan_for_music,
initialize_db, initialize_db,
add_files_to_database, add_files_to_database,
@ -430,7 +430,7 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
if not filepath: if not filepath:
filepath = self.tableView.get_current_song_filepath() filepath = self.tableView.get_current_song_filepath()
# get metadata # get metadata
metadata = get_id3_tags(filepath)[0] metadata = get_tags(filepath)[0]
# read the file # read the file
url = QUrl.fromLocalFile(filepath) url = QUrl.fromLocalFile(filepath)
# load the audio content # load the audio content

View File

@ -3,9 +3,9 @@ from .convert_id3_timestamp_to_datetime import convert_id3_timestamp_to_datetime
from .initialize_db import initialize_db from .initialize_db import initialize_db
from .safe_get import safe_get from .safe_get import safe_get
from .get_album_art import get_album_art from .get_album_art import get_album_art
from .get_id3_tags import get_id3_tags, id3_remap from .get_tags import get_tags, id3_remap
from .get_reorganize_vars import get_reorganize_vars from .get_reorganize_vars import get_reorganize_vars
from .set_id3_tag import set_id3_tag from .set_tag import set_tag
from .delete_song_id_from_database import delete_song_id_from_database from .delete_song_id_from_database import delete_song_id_from_database
from .batch_delete_filepaths_from_database import batch_delete_filepaths_from_database from .batch_delete_filepaths_from_database import batch_delete_filepaths_from_database
from .delete_and_create_library_database import delete_and_create_library_database from .delete_and_create_library_database import delete_and_create_library_database

View File

@ -2,7 +2,7 @@ from PyQt5.QtWidgets import QMessageBox
from mutagen.id3 import ID3 from mutagen.id3 import ID3
import DBA import DBA
from logging import debug from logging import debug
from utils import get_id3_tags, convert_id3_timestamp_to_datetime, id3_remap from utils import get_tags, convert_id3_timestamp_to_datetime, id3_remap
from configparser import ConfigParser from configparser import ConfigParser
from pathlib import Path from pathlib import Path
from appdirs import user_config_dir from appdirs import user_config_dir
@ -37,7 +37,7 @@ def add_files_to_database(files, progress_callback=None):
progress_callback.emit(filepath) progress_callback.emit(filepath)
filename = filepath.split("/")[-1] filename = filepath.split("/")[-1]
tags, details = get_id3_tags(filepath) tags, details = get_tags(filepath)
if details: if details:
failed_dict[filepath] = details failed_dict[filepath] = details
continue continue
@ -55,6 +55,7 @@ def add_files_to_database(files, progress_callback=None):
filename.split(".")[-1], filename.split(".")[-1],
audio["date"], audio["date"],
audio["bitrate"], audio["bitrate"],
audio["length"]
) )
) )
# Check if batch size is reached # Check if batch size is reached
@ -62,7 +63,7 @@ def add_files_to_database(files, progress_callback=None):
debug(f"inserting a LOT of songs: {len(insert_data)}") debug(f"inserting a LOT of songs: {len(insert_data)}")
with DBA.DBAccess() as db: with DBA.DBAccess() as db:
db.executemany( db.executemany(
"INSERT OR IGNORE INTO song (filepath, title, album, artist, track_number, genre, codec, album_date, bitrate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", "INSERT OR IGNORE INTO song (filepath, title, album, artist, track_number, genre, codec, album_date, bitrate, length_seconds) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
insert_data, insert_data,
) )
insert_data = [] # Reset the insert_data list insert_data = [] # Reset the insert_data list
@ -75,20 +76,9 @@ def add_files_to_database(files, progress_callback=None):
debug(f"inserting some songs: {len(insert_data)}") debug(f"inserting some songs: {len(insert_data)}")
with DBA.DBAccess() as db: with DBA.DBAccess() as db:
db.executemany( db.executemany(
"INSERT OR IGNORE INTO song (filepath, title, album, artist, track_number, genre, codec, album_date, bitrate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", "INSERT OR IGNORE INTO song (filepath, title, album, artist, track_number, genre, codec, album_date, bitrate, length_seconds) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
insert_data, insert_data,
) )
return True, failed_dict return True, failed_dict
# id int unsigned auto_increment,
# title varchar(255),
# album varchar(255),
# artist varchar(255),
# genre varchar(255),
# codec varchar(15),
# album_date date,
# bitrate int unsigned,
# date_added TIMESTAMP default CURRENT_TIMESTAMP,
# scan_for_music(config.get('directories', 'library1'))

View File

@ -9,6 +9,8 @@ def get_reorganize_vars(filepath: str) -> tuple[str, str]:
if no artist or album or ID3 tags at all are found, if no artist or album or ID3 tags at all are found,
function will return ("Unknown Artist", "Unknown Album") function will return ("Unknown Artist", "Unknown Album")
""" """
# TODO: fix this func. id3_remap(get_tags())
# or is what i have less memory so more better? :shrug:
audio = ID3(filepath) audio = ID3(filepath)
try: try:
artist = str(audio["TPE1"].text[0]) artist = str(audio["TPE1"].text[0])

View File

@ -36,7 +36,7 @@ def get_mp3_tags(filename: str) -> tuple[MP3 | ID3 | FLAC, str]:
def id3_remap(audio: MP3 | ID3 | FLAC) -> dict: def id3_remap(audio: MP3 | ID3 | FLAC) -> dict:
""" """
Turns an ID3 dict into a normal dict that I, the human, can use. Turns the ID3 dict of an audio file into a normal dict that I, the human, can use.
Add extra fields too :D yahooo Add extra fields too :D yahooo
""" """
remap = {} remap = {}
@ -59,9 +59,9 @@ def id3_remap(audio: MP3 | ID3 | FLAC) -> dict:
return remap return remap
def get_id3_tags(filename: str) -> tuple[MP3 | ID3 | FLAC, str]: def get_tags(filename: str) -> tuple[MP3 | ID3 | FLAC, str]:
""" """
Get the ID3 tags for an audio file Get the "ID3" tags for an audio file
Returns a tuple of: Returns a tuple of:
- mutagen ID3 object OR python dictionary - mutagen ID3 object OR python dictionary
- string reason for failure (failure = empty dict above) - string reason for failure (failure = empty dict above)

View File

@ -82,7 +82,7 @@ mutagen_id3_tag_mapping = {
} }
def set_id3_tag(filepath: str, tag_name: str, value: str): def set_tag(filepath: str, tag_name: str, value: str):
"""Sets the ID3 tag for a file given a filepath, tag_name, and a value for the tag """Sets the ID3 tag for a file given a filepath, tag_name, and a value for the tag
Args: Args:
@ -136,6 +136,6 @@ def set_id3_tag(filepath: str, tag_name: str, value: str):
audio_file.save(filepath) audio_file.save(filepath)
return True return True
except Exception as e: except Exception as e:
dialog = ErrorDialog(f"set_id3_tag.py | An unhandled exception occurred:\n{e}") dialog = ErrorDialog(f"set_tag.py | An unhandled exception occurred:\n{e}")
dialog.exec_() dialog.exec_()
return False return False