id3 > mp3, mutagen timestamp to sqlite db, small typing silences

This commit is contained in:
billypom on debian 2024-05-31 21:10:58 -04:00
parent 04201fcb1d
commit 3ec08d8446
5 changed files with 36 additions and 26 deletions

41
main.py
View File

@ -4,8 +4,8 @@ import sys
from subprocess import run from subprocess import run
import qdarktheme import qdarktheme
from pyqtgraph import mkBrush from pyqtgraph import mkBrush
from mutagen.id3 import ID3, APIC, error from mutagen.id3 import ID3
from mutagen.mp3 import MP3 from mutagen.id3._frames import APIC
from configparser import ConfigParser from configparser import ConfigParser
import DBA import DBA
from ui import Ui_MainWindow from ui import Ui_MainWindow
@ -18,9 +18,9 @@ from PyQt5.QtWidgets import (
QGraphicsPixmapItem, QGraphicsPixmapItem,
QMessageBox, QMessageBox,
) )
from PyQt5.QtCore import QUrl, QTimer, QEvent, Qt, QModelIndex from PyQt5.QtCore import QUrl, QTimer, Qt
from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent, QAudioProbe from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent, QAudioProbe
from PyQt5.QtGui import QPixmap, QStandardItemModel from PyQt5.QtGui import QCloseEvent, QPixmap
from utils import scan_for_music from utils import scan_for_music
from utils import delete_and_create_library_database from utils import delete_and_create_library_database
from components import PreferencesWindow, AudioVisualizer from components import PreferencesWindow, AudioVisualizer
@ -130,7 +130,7 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
self.tableView.horizontalHeader().setStretchLastSection(False) self.tableView.horizontalHeader().setStretchLastSection(False)
def closeEvent(self, event) -> None: def closeEvent(self, a0: QCloseEvent | None) -> None:
"""Save settings when closing the application""" """Save settings when closing the application"""
# MusicTable/tableView column widths # MusicTable/tableView column widths
list_of_column_widths = [] list_of_column_widths = []
@ -142,7 +142,7 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
# Save the config # Save the config
with open("config.ini", "w") as configfile: with open("config.ini", "w") as configfile:
self.config.write(configfile) self.config.write(configfile)
super().closeEvent(event) super().closeEvent(a0)
def play_audio_file(self) -> None: def play_audio_file(self) -> None:
"""Start playback of tableView.current_song_filepath track & moves playback slider""" """Start playback of tableView.current_song_filepath track & moves playback slider"""
@ -159,18 +159,17 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
self.move_slider() # mover self.move_slider() # mover
# assign metadata # assign metadata
# FIXME when i change tinytag to something else
artist = ( artist = (
self.current_song_metadata["artist"][0] self.current_song_metadata["TPE1"][0]
if "artist" in self.current_song_metadata if "artist" in self.current_song_metadata
else None else None
) )
album = ( album = (
self.current_song_metadata["album"][0] self.current_song_metadata["TALB"][0]
if "album" in self.current_song_metadata if "album" in self.current_song_metadata
else None else None
) )
title = self.current_song_metadata["title"][0] title = self.current_song_metadata["TIT2"][0]
# edit labels # edit labels
self.artistLabel.setText(artist) self.artistLabel.setText(artist)
self.albumLabel.setText(album) self.albumLabel.setText(album)
@ -226,14 +225,14 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
self, song_file_path: str, album_art_path: str self, song_file_path: str, album_art_path: str
) -> None: ) -> None:
"""Updates the ID3 tag APIC (album art) for 1 song""" """Updates the ID3 tag APIC (album art) for 1 song"""
audio = MP3(song_file_path, ID3=ID3) # audio = MP3(song_file_path, ID3=ID3)
audio = ID3(song_file_path)
# Remove existing APIC Frames (album art) # Remove existing APIC Frames (album art)
if audio.tags is not None: audio.delall("APIC")
audio.tags.delall("APIC")
# Add the album art # Add the album art
with open(album_art_path, "rb") as album_art_file: with open(album_art_path, "rb") as album_art_file:
if album_art_path.endswith(".jpg") or album_art_path.endswith(".jpeg"): if album_art_path.endswith(".jpg") or album_art_path.endswith(".jpeg"):
audio.tags.add( audio.add(
APIC( APIC(
encoding=3, # 3 = utf-8 encoding=3, # 3 = utf-8
mime="image/jpeg", mime="image/jpeg",
@ -243,7 +242,7 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
) )
) )
elif album_art_path.endswith(".png"): elif album_art_path.endswith(".png"):
audio.tags.add( audio.add(
APIC( APIC(
encoding=3, # 3 = utf-8 encoding=3, # 3 = utf-8
mime="image/png", mime="image/png",
@ -270,9 +269,9 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
def update_audio_visualization(self) -> None: def update_audio_visualization(self) -> None:
"""Handles upading points on the pyqtgraph visual""" """Handles upading points on the pyqtgraph visual"""
self.clear_audio_visualization() self.clear_audio_visualization()
self.y = self.audio_visualizer.get_amplitudes() y = self.audio_visualizer.get_amplitudes()
self.x = [i for i in range(len(self.y))] x = [i for i in range(len(y))]
self.PlotWidget.plot(self.x, self.y, fillLevel=0, fillBrush=mkBrush("b")) self.PlotWidget.plot(x, y, fillLevel=0, fillBrush=mkBrush("b"))
self.PlotWidget.show() self.PlotWidget.show()
def clear_audio_visualization(self) -> None: def clear_audio_visualization(self) -> None:
@ -284,7 +283,7 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
return return
else: else:
# Update the slider # Update the slider
if self.player.state() == QMediaPlayer.PlayingState: if self.player.state() == QMediaPlayer.State.PlayingState:
self.playbackSlider.setMinimum(0) self.playbackSlider.setMinimum(0)
self.playbackSlider.setMaximum(self.player.duration()) self.playbackSlider.setMaximum(self.player.duration())
slider_position = self.player.position() slider_position = self.player.position()
@ -310,11 +309,11 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
def on_play_clicked(self) -> None: def on_play_clicked(self) -> None:
"""Updates the Play & Pause buttons when clicked""" """Updates the Play & Pause buttons when clicked"""
if self.player.state() == QMediaPlayer.PlayingState: if self.player.state() == QMediaPlayer.State.PlayingState:
self.player.pause() self.player.pause()
self.playButton.setText("▶️") self.playButton.setText("▶️")
else: else:
if self.player.state() == QMediaPlayer.PausedState: if self.player.state() == QMediaPlayer.State.PausedState:
self.player.play() self.player.play()
self.playButton.setText("⏸️") self.playButton.setText("⏸️")
else: else:

View File

@ -1,3 +1,4 @@
from .id3_timestamp_to_datetime import id3_timestamp_to_datetime
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 from .get_id3_tags import get_id3_tags

View File

@ -1,7 +1,6 @@
import DBA import DBA
from configparser import ConfigParser from configparser import ConfigParser
from utils import get_id3_tags from utils import get_id3_tags, id3_timestamp_to_datetime, safe_get
from utils import safe_get
config = ConfigParser() config = ConfigParser()
config.read("config.ini") config.read("config.ini")
@ -40,7 +39,7 @@ def add_files_to_library(files):
except KeyError: except KeyError:
genre = "" genre = ""
try: try:
date = audio["TDRC"].text[0] date = id3_timestamp_to_datetime(audio["TDRC"].text[0])
except KeyError: except KeyError:
date = "" date = ""
try: try:

View File

@ -0,0 +1,11 @@
import datetime
from mutagen.id3._specs import ID3TimeStamp
def id3_timestamp_to_datetime(timestamp: ID3TimeStamp):
"""Turns a mutagen ID3TimeStamp into a format that SQLite can use for Date field"""
if len(timestamp.text) == 4: # If only year is provided
datetime_obj = datetime.datetime.strptime(timestamp.text, '%Y')
else:
datetime_obj = datetime.datetime.strptime(timestamp.text, '%Y-%m-%dT%H:%M:%SZ')
return datetime_obj.strftime('%Y-%m-%d')