diff --git a/components/LyricsWindow.py b/components/LyricsWindow.py index b20f5a9..92d6331 100644 --- a/components/LyricsWindow.py +++ b/components/LyricsWindow.py @@ -7,7 +7,7 @@ from PyQt5.QtWidgets import ( ) from PyQt5.QtGui import QFont from components.ErrorDialog import ErrorDialog -from utils import set_id3_tag +from utils import set_tag from logging import debug @@ -32,7 +32,7 @@ class LyricsWindow(QDialog): def save(self): """Saves the current lyrics text to the USLT/lyrics ID3 tag""" - success = set_id3_tag( + success = set_tag( filepath=self.song_filepath, tag_name="lyrics", value=self.input_field.toPlainText(), diff --git a/components/MetadataWindow.py b/components/MetadataWindow.py index 488ddb2..a8d370c 100644 --- a/components/MetadataWindow.py +++ b/components/MetadataWindow.py @@ -12,10 +12,7 @@ from PyQt5.QtGui import QFont from PyQt5.QtCore import pyqtSignal from mutagen.id3 import ID3 from components.ErrorDialog import ErrorDialog -from utils.get_id3_tags import get_id3_tags -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 utils import set_tag, get_tag, update_song_in_database, id3_tag_mapping from logging import debug # import re @@ -65,7 +62,7 @@ class MetadataWindow(QDialog): # Get a dict of all tags for all songs # e.g., { "TIT2": ["song_title1", "song_title2"], ... } for song in self.songs: - song_data = get_id3_tags(song[0]) + song_data = get_tags(song[0]) if not song_data: QMessageBox.error( self, @@ -135,7 +132,7 @@ class MetadataWindow(QDialog): if field.has_changed(): # Update the ID3 tag if the tag is not blank, # and has been edited - success = set_id3_tag( + success = set_tag( filepath=song[0], tag_name=tag, value=field.text() ) if success: diff --git a/components/MusicTable.py b/components/MusicTable.py index 11b3cc0..4167e41 100644 --- a/components/MusicTable.py +++ b/components/MusicTable.py @@ -42,16 +42,17 @@ from components.MetadataWindow import MetadataWindow from components.QuestionBoxDetails import QuestionBoxDetails from main import Worker -from utils.batch_delete_filepaths_from_database import ( +from utils import ( 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 logging import debug, error import os @@ -91,7 +92,7 @@ class TableHeader: "artist": "TPE1", "album": "TALB", "track_number": "TRCK", - "genre": "content_type", + "genre": "TCON", "codec": None, "length_seconds": "TLEN", "album_date": "TDRC", @@ -440,7 +441,7 @@ class MusicTable(QTableView): user_input_data = topLeft.data() edited_column_name = self.database_columns[topLeft.column()] 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: # Update the library with new metadata 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() if selected_song_filepath is None: return - dic = id3_remap(get_id3_tags(selected_song_filepath)[0]) + dic = id3_remap(get_tags(selected_song_filepath)[0]) lyrics = dic["lyrics"] lyrics_window = LyricsWindow(selected_song_filepath, lyrics) lyrics_window.exec_() @@ -860,11 +861,11 @@ class MusicTable(QTableView): def get_current_song_metadata(self) -> dict: """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: """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: """Returns the APIC data (album art lol) for the currently playing song""" diff --git a/main.py b/main.py index 257d768..54719e8 100644 --- a/main.py +++ b/main.py @@ -41,7 +41,7 @@ from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent, QAudioProbe, QMediaP from PyQt5.QtGui import QClipboard, QCloseEvent, QFont, QPixmap, QResizeEvent from utils import ( delete_album_art, - get_id3_tags, + get_tags, scan_for_music, initialize_db, add_files_to_database, @@ -430,7 +430,7 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow): if not filepath: filepath = self.tableView.get_current_song_filepath() # get metadata - metadata = get_id3_tags(filepath)[0] + metadata = get_tags(filepath)[0] # read the file url = QUrl.fromLocalFile(filepath) # load the audio content diff --git a/utils/__init__.py b/utils/__init__.py index 4ade67c..ec52b89 100644 --- a/utils/__init__.py +++ b/utils/__init__.py @@ -3,9 +3,9 @@ from .convert_id3_timestamp_to_datetime import convert_id3_timestamp_to_datetime from .initialize_db import initialize_db from .safe_get import safe_get 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 .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 .batch_delete_filepaths_from_database import batch_delete_filepaths_from_database from .delete_and_create_library_database import delete_and_create_library_database diff --git a/utils/add_files_to_database.py b/utils/add_files_to_database.py index 60f25b6..84c680c 100644 --- a/utils/add_files_to_database.py +++ b/utils/add_files_to_database.py @@ -2,7 +2,7 @@ from PyQt5.QtWidgets import QMessageBox from mutagen.id3 import ID3 import DBA 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 pathlib import Path from appdirs import user_config_dir @@ -37,7 +37,7 @@ def add_files_to_database(files, progress_callback=None): progress_callback.emit(filepath) filename = filepath.split("/")[-1] - tags, details = get_id3_tags(filepath) + tags, details = get_tags(filepath) if details: failed_dict[filepath] = details continue @@ -55,6 +55,7 @@ def add_files_to_database(files, progress_callback=None): filename.split(".")[-1], audio["date"], audio["bitrate"], + audio["length"] ) ) # 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)}") with DBA.DBAccess() as db: 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 = [] # 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)}") with DBA.DBAccess() as db: 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, ) 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')) diff --git a/utils/get_reorganize_vars.py b/utils/get_reorganize_vars.py index 844c97c..8ace15a 100644 --- a/utils/get_reorganize_vars.py +++ b/utils/get_reorganize_vars.py @@ -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, 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) try: artist = str(audio["TPE1"].text[0]) diff --git a/utils/get_id3_tags.py b/utils/get_tags.py similarity index 92% rename from utils/get_id3_tags.py rename to utils/get_tags.py index 59e04f2..11a3b4a 100644 --- a/utils/get_id3_tags.py +++ b/utils/get_tags.py @@ -36,7 +36,7 @@ def get_mp3_tags(filename: str) -> tuple[MP3 | ID3 | FLAC, str]: 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 """ remap = {} @@ -59,9 +59,9 @@ def id3_remap(audio: MP3 | ID3 | FLAC) -> dict: 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: - mutagen ID3 object OR python dictionary - string reason for failure (failure = empty dict above) diff --git a/utils/set_id3_tag.py b/utils/set_tag.py similarity index 96% rename from utils/set_id3_tag.py rename to utils/set_tag.py index 96f7df3..3eba17c 100644 --- a/utils/set_id3_tag.py +++ b/utils/set_tag.py @@ -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 Args: @@ -136,6 +136,6 @@ def set_id3_tag(filepath: str, tag_name: str, value: str): audio_file.save(filepath) return True 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_() return False