pyrip/pyripgui.py

141 lines
5.1 KiB
Python

import argparse
import fstools
from gui import MainWindow, SelectionDialog
import media
import os
from PySide6.QtWidgets import QApplication, QMessageBox
import report
import sys
import task
logger = report.app_logging_config()
# TODO: Usage of QThread instead of task.delayed
# TODO: Error handling on cancelling cddb choose Dialog
MEDIA_GUI_DICT = {
MainWindow.KEY_ALBUM_ARTIST: media.KEY_ARTIST,
MainWindow.KEY_ALBUM_ALBUM: media.KEY_ALBUM,
MainWindow.KEY_ALBUM_YEAR: media.KEY_YEAR,
MainWindow.KEY_ALBUM_GENRE: media.KEY_GENRE
}
class RipMainWindow(MainWindow):
def __init__(self, basepath):
super().__init__(basepath)
self.__rip_task__ = task.delayed(0, self.__rip_it__)
def join(self):
self.__rip_task__.join
def stop(self):
self.__rip_task__.stop()
def clear(self):
self.list_widget.clear()
for key in MEDIA_GUI_DICT:
self.set_album_field(key, "")
def read_it(self):
self.set_status("Reading data from disc...")
disc_data = media.get_media_data(media.get_disc_device(), self.cddb_choose_dialog)
# disc_data = media.metadata.get_disc_data_dummy()
if disc_data is None:
msg = "Could not read disc data!"
logger.error(msg)
self.set_status(msg)
QMessageBox.critical(self, "Error!", msg)
else:
self.clear()
# Set album info to gui
for key in MEDIA_GUI_DICT:
self.set_album_field(key, str(disc_data[MEDIA_GUI_DICT[key]]))
# Set tracks to gui
for track in disc_data[media.KEY_TRACKLIST]:
self.append_title(track[media.KEY_TITLE])
# Enable rip button
self.set_status("Disc data received")
self.button_rip.setEnabled(True)
def cddb_choose_dialog(self, what: int, info: dict):
if what == media.CALLBACK_CDDB_CHOICE:
values = tuple(info.values())
keys = tuple(info.keys())
dlg = SelectionDialog(self, "Multiple CDDB entries found. Choose one.", values)
if dlg.exec():
return keys[dlg.get_selected_index()]
else:
msg = "Invalid cddb selection!"
logger.error(msg)
self.set_status(msg)
QMessageBox.critical(self, "Error!", msg)
def rip_it(self):
self.__rip_task__.run()
def __rip_it__(self):
self.button_rip.setDisabled(True)
self.button_read.setDisabled(True)
for i in range(self.list_widget.count()):
list_item = self.list_widget.item(i)
row_widget = self.list_widget.itemWidget(list_item)
track_info = {}
track_info[media.KEY_TRACK] = i + 1
for key in MEDIA_GUI_DICT:
track_info[MEDIA_GUI_DICT[key]] = self.get_album_field(key)
track_info[media.KEY_TITLE] = row_widget.text_edit.toPlainText()
wavfile = media.track_to_targetpath(self.__basepath__, track_info, 'wav')
try:
fstools.mkdir(os.path.dirname(wavfile))
except PermissionError:
msg = f"Unable to create ripping target path: {os.path.dirname(wavfile)}"
logger.exception(msg)
self.set_status(msg)
QMessageBox.critical(self, "Error!", msg)
self.button_rip.setDisabled(False)
self.button_read.setDisabled(False)
return
self.set_status("Ripping track %02d..." % (i + 1))
rv = media.disc_track_rip(i + 1, wavfile, self.progress_callback_rip)
if rv == 0:
self.set_status("Encoding track %02d..." % (i + 1))
rv = media.wav_to_mp3(wavfile, self.__basepath__, track_info, self.progress_callback_enc)
os.remove(wavfile)
if rv != 0:
msg = f"Error while ripping or encoding track {i + 1}"
logger.error(msg)
self.set_status(msg)
self.set_title_progress(i, 0)
QMessageBox.critical(self, "Error!", msg)
self.button_rip.setDisabled(False)
self.button_read.setDisabled(False)
return
self.set_status("Ripping finished!")
self.button_rip.setDisabled(False)
self.button_read.setDisabled(False)
def progress_callback_rip(self, p: float, track_num: int = None):
self.set_title_progress(track_num - 1, 50 * p)
def progress_callback_enc(self, p: float, track_num: int = None):
self.set_title_progress(track_num - 1, 50 + 50 * p)
if __name__ == "__main__":
default_baspath = os.path.join(os.getenv("HOME"), "pyrip")
parser = argparse.ArgumentParser(description='Description')
parser.add_argument('-b', '--basepath', help=f'The rip and encode basepath (default is {default_baspath})', default=default_baspath)
args = parser.parse_args()
#
app = QApplication(sys.argv)
window = RipMainWindow(args.basepath)
window.show()
try:
window.join()
finally:
window.stop()
sys.exit(app.exec())