preparation for reorganization function

This commit is contained in:
billypom on debian 2024-03-19 20:57:23 -04:00
parent ca5b9ad849
commit 6daadb09aa
2 changed files with 72 additions and 47 deletions

View File

@ -1,12 +1,12 @@
import DBA
from PyQt5.QtGui import QStandardItem, QStandardItemModel
from PyQt5.QtWidgets import QTableView
from PyQt5.QtCore import QTimer, Qt, pyqtSignal
from tinytag import TinyTag
from PyQt5.QtGui import QStandardItem, QStandardItemModel, QKeySequence
from PyQt5.QtWidgets import QTableView, QShortcut
from PyQt5.QtCore import Qt, pyqtSignal
from utils import add_files_to_library
from utils import get_id3_tags
from utils import get_album_art
import logging
import configparser
class MusicTable(QTableView):
@ -19,12 +19,32 @@ class MusicTable(QTableView):
self.selected_song_filepath = None
self.current_song_filepath = None
self.qapp = None
self.config = configparser.ConfigParser()
self.config.read('config.ini')
# 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
self.doubleClicked.connect(self.set_current_song_filepath)
self.enterKey.connect(self.set_current_song_filepath)
self.fetch_library()
self.setup_keyboard_shortcuts()
def setup_keyboard_shortcuts(self):
"""Setup shortcuts here"""
shortcut = QShortcut(QKeySequence("Ctrl+Shift+R"), self)
shortcut.activated.connect(self.reorganize_selected_files)
def reorganize_selected_files(self):
"""Ctrl+Shift+R = Reorganize"""
filepaths = self.get_selected_songs_filepaths()
# right now this just prints the filepaths to the songs obv.
print(f'yay: {filepaths}')
# TODO
# Get user confirmation screen (default yes, so i can press enter and go)
# Get target directory
# Copy files to new dir
# delete files from current dir
# add new files to library
def keyPressEvent(self, event):
"""Press a key. Do a thing"""
@ -51,34 +71,45 @@ class MusicTable(QTableView):
if not self.current_song_filepath:
self.set_current_song_filepath()
self.playPauseSignal.emit()
def get_selected_rows(self):
"""Returns a list of indexes for every selected row"""
rows = []
for idx in self.selectionModel().siblingAtColumn():
rows.append(idx.row())
return rows
def set_selected_song_filepath(self):
"""Sets the filepath of the currently selected song"""
self.selected_song_filepath = self.currentIndex().siblingAtColumn(self.headers.index('path')).data()
print(f'Selected song: {self.selected_song_filepath}')
def set_current_song_filepath(self):
"""Sets the filepath of the currently playing song"""
# Setting the current song filepath automatically plays that song
# self.tableView listens to this function and plays the audio file located at self.current_song_filepath
self.current_song_filepath = self.currentIndex().siblingAtColumn(self.headers.index('path')).data()
print(f'Current song: {self.current_song_filepath}')
def get_selected_rows(self):
"""Returns a list of indexes for every selected row"""
selection_model = self.selectionModel()
return [index.row() for index in selection_model.selectedRows()]
# rows = []
# for idx in self.selectionModel().siblingAtColumn():
# rows.append(idx.row())
# return rows
def get_selected_songs_filepaths(self):
"""Returns a list of the filepaths for the currently selected songs"""
selected_rows = self.get_selected_rows()
filepaths = []
for row in selected_rows:
idx = self.model.index(row, self.headers.index('path'))
filepaths.append(idx.data())
return filepaths
def get_selected_song_filepath(self):
"""Returns the selected songs filepath"""
return self.selected_song_filepath
def get_selected_song_metadata(self):
"""Returns the selected song's ID3 tags"""
return get_id3_tags(self.selected_song_filepath)
def get_current_song_filepath(self):
"""Returns the currently playing song filepath"""
return self.current_song_filepath
@ -86,12 +117,11 @@ class MusicTable(QTableView):
def get_current_song_metadata(self):
"""Returns the currently playing song's ID3 tags"""
return get_id3_tags(self.current_song_filepath)
def get_current_song_album_art(self):
"""Returns the APIC data (album art lol) for the currently playing song"""
return get_album_art(self.current_song_filepath)
def fetch_library(self):
"""Initialize the tableview model"""
self.model = QStandardItemModel()
@ -107,7 +137,7 @@ class MusicTable(QTableView):
self.setModel(self.model)
# self.update()
self.viewport().update()
def add_files(self, files):
"""When song(s) added to the library, update the tableview model
- Drag & Drop song(s) on tableView
@ -117,11 +147,9 @@ class MusicTable(QTableView):
number_of_files_added = add_files_to_library(files)
if number_of_files_added:
self.fetch_library()
def load_qapp(self, qapp):
# why was this necessary again? :thinking:
self.qapp = qapp

45
main.py
View File

@ -1,5 +1,6 @@
from ui import Ui_MainWindow
from PyQt5.QtWidgets import QMainWindow, QApplication, QGraphicsScene, QHeaderView, QGraphicsPixmapItem
from PyQt5.QtWidgets import QMainWindow, QApplication, QGraphicsScene, \
QHeaderView, QGraphicsPixmapItem
import qdarktheme
from PyQt5.QtCore import QUrl, QTimer, QEvent, Qt
from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent, QAudioProbe
@ -14,6 +15,7 @@ import configparser
# Create ui.py file from Qt Designer
# pyuic5 ui.ui -o ui.py
class ApplicationWindow(QMainWindow, Ui_MainWindow):
def __init__(self, qapp):
super(ApplicationWindow, self).__init__()
@ -29,24 +31,21 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
self.tableView.load_qapp(self.qapp)
self.config = configparser.ConfigParser()
self.config.read('config.ini')
global stopped
stopped = False
# Initialization
self.player = QMediaPlayer() # Audio player
self.probe = QAudioProbe() # Get audio data
self.timer = QTimer(self) # Audio timing things
self.player = QMediaPlayer() # Audio player
self.probe = QAudioProbe() # Get audio data
self.timer = QTimer(self) # Audio timing things
# self.model = QStandardItemModel() # Table library listing
self.audio_visualizer = AudioVisualizer(self.player)
self.current_volume = 50
self.player.setVolume(self.current_volume)
# Audio probe for processing audio signal in real time
# Provides faster updates than move_slider
self.probe.setSource(self.player)
self.probe.audioBufferProbed.connect(self.process_probe)
# Slider Timer (realtime playback feedback horizontal bar)
self.timer.start(150) # 150ms update interval solved problem with drag seeking halting playback
self.timer.timeout.connect(self.move_slider)
@ -56,7 +55,7 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
self.PlotWidget.setYRange(0,0.3,padding=0) # y axis range
self.PlotWidget.getAxis('bottom').setTicks([]) # Remove x-axis ticks
self.PlotWidget.getAxis('bottom').setLabel('') # Remove x-axis label
self.PlotWidget.setLogMode(False,False)
self.PlotWidget.setLogMode(False, False)
# Remove y-axis labels and decorations
self.PlotWidget.getAxis('left').setTicks([]) # Remove y-axis ticks
self.PlotWidget.getAxis('left').setLabel('') # Remove y-axis label
@ -80,7 +79,7 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
self.tableView.playPauseSignal.connect(self.on_play_clicked) # Spacebar toggle play/pause signal
self.tableView.viewport().installEventFilter(self) # for drag & drop functionality
# self.tableView.model.layoutChanged()
### set column widths
# set column widths
table_view_column_widths = str(self.config['table']['column_widths']).split(',')
for i in range(self.tableView.model.columnCount()):
self.tableView.setColumnWidth(i, int(table_view_column_widths[i]))
@ -88,15 +87,14 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
self.tableView.horizontalHeader().setStretchLastSection(False)
def eventFilter(self, source, event):
"""Handles events"""
# tableView (drag & drop)
if (source is self.tableView.viewport() and
(event.type() == QEvent.DragEnter or
event.type() == QEvent.DragMove or
event.type() == QEvent.Drop) and
event.mimeData().hasUrls()):
event.type() == QEvent.DragMove or
event.type() == QEvent.Drop) and
event.mimeData().hasUrls()):
files = []
if event.type() == QEvent.Drop:
for url in event.mimeData().urls():
@ -206,7 +204,7 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
self.startTimeLabel.setText(f"{int(current_minutes):02d}:{int(current_seconds):02d}")
self.endTimeLabel.setText(f"{int(duration_minutes):02d}:{int(duration_seconds):02d}")
def volume_changed(self):
"""Handles volume changes"""
try:
@ -214,7 +212,7 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
self.player.setVolume(self.current_volume)
except Exception as e:
print(f"Changing volume error: {e}")
def on_play_clicked(self):
"""Updates the Play & Pause buttons when clicked"""
if self.player.state() == QMediaPlayer.PlayingState:
@ -227,31 +225,30 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
else:
self.play_audio_file()
self.playButton.setText("⏸️")
def on_previous_clicked(self):
""""""
print('previous')
def on_next_clicked(self):
print('next')
def actionPreferencesClicked(self):
preferences_window = PreferencesWindow(self.config)
preferences_window.exec_() # Display the preferences window modally
def scan_libraries(self):
scan_for_music()
self.tableView.fetch_library()
def clear_database(self):
initialize_library_database()
self.tableView.fetch_library()
def process_probe(self, buff):
buff.startTime()
self.update_audio_visualization()
if __name__ == "__main__":
import sys