initial gui added for pyrip
This commit is contained in:
parent
893e27f417
commit
7622f1fa38
13
README.md
13
README.md
@ -1,3 +1,14 @@
|
||||
# pyrip
|
||||
|
||||
PyRip - CD ripper
|
||||
PyRip - CD ripper
|
||||
|
||||
You might want to install:
|
||||
* cdparnoia
|
||||
* lame
|
||||
|
||||
|
||||
Possibly these are also needed:
|
||||
* qt6-base-dev
|
||||
* qt6-base-devtools
|
||||
* python3-pyside6.qtwidgets
|
||||
* python3-pyqt6.qtdesigner
|
||||
|
180
gui/__init__.py
Normal file
180
gui/__init__.py
Normal file
@ -0,0 +1,180 @@
|
||||
import logging
|
||||
import media
|
||||
from PySide6.QtWidgets import (
|
||||
QMainWindow,
|
||||
QDialog,
|
||||
QDialogButtonBox,
|
||||
QWidget,
|
||||
QVBoxLayout,
|
||||
QHBoxLayout,
|
||||
QListWidget,
|
||||
QListWidgetItem,
|
||||
QLabel,
|
||||
QPlainTextEdit,
|
||||
QProgressBar,
|
||||
QPushButton,
|
||||
QLineEdit
|
||||
)
|
||||
from PySide6.QtCore import Qt
|
||||
|
||||
try:
|
||||
from config import APP_NAME as ROOT_LOGGER_NAME
|
||||
except ImportError:
|
||||
ROOT_LOGGER_NAME = 'root'
|
||||
logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__)
|
||||
|
||||
|
||||
class RowWidget(QWidget):
|
||||
"""
|
||||
Ein Widget, das eine einzelne Zeile in unserer Liste darstellt.
|
||||
Es enthält eine Nummer (QLabel), ein Textfeld (QPlainTextEdit)
|
||||
und einen Fortschrittsbalken (QProgressBar).
|
||||
"""
|
||||
|
||||
def __init__(self, number: int, parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
self.number_label = QLabel(f"{number}.")
|
||||
self.text_edit = QPlainTextEdit()
|
||||
self.progress_bar = QProgressBar()
|
||||
|
||||
self.text_edit.setFixedHeight(31)
|
||||
self.number_label.setFixedWidth(30)
|
||||
self.number_label.setAlignment(Qt.AlignmentFlag.AlignTop | Qt.AlignmentFlag.AlignRight)
|
||||
|
||||
layout = QHBoxLayout()
|
||||
layout.addWidget(self.number_label)
|
||||
layout.addWidget(self.text_edit)
|
||||
layout.addWidget(self.progress_bar)
|
||||
self.setLayout(layout)
|
||||
|
||||
|
||||
class MainWindow(QMainWindow):
|
||||
KEY_ALBUM_ARTIST = "Interpret"
|
||||
KEY_ALBUM_ALBUM = "Album"
|
||||
KEY_ALBUM_YEAR = "Jahr"
|
||||
KEY_ALBUM_GENRE = "Genre"
|
||||
FIELD_NAMES = [KEY_ALBUM_ARTIST, KEY_ALBUM_ALBUM, KEY_ALBUM_YEAR, KEY_ALBUM_GENRE]
|
||||
|
||||
def __init__(self, basepath):
|
||||
super().__init__()
|
||||
self.__basepath__ = basepath
|
||||
#
|
||||
self.setWindowTitle("PySide6 Listenanwendung")
|
||||
self.setGeometry(100, 100, 900, 600) # Fensterbreite angepasst
|
||||
self.set_status("Ready...")
|
||||
|
||||
self.__album_lines__ = []
|
||||
main_widget = QWidget()
|
||||
main_layout = QVBoxLayout(main_widget)
|
||||
self.setCentralWidget(main_widget)
|
||||
|
||||
disc_layout = QHBoxLayout()
|
||||
album_layout = QVBoxLayout()
|
||||
|
||||
# Create fields for Album Information
|
||||
for i in range(0, len(self.FIELD_NAMES)):
|
||||
# Add label
|
||||
label = QLabel(self.FIELD_NAMES[i])
|
||||
# Add title
|
||||
line_edit = QLineEdit()
|
||||
line_edit.setMaximumWidth(300)
|
||||
line_edit.setPlaceholderText("Title...")
|
||||
# Add title to list for later use
|
||||
self.__album_lines__.append(line_edit)
|
||||
|
||||
# Add both to album_layout
|
||||
album_layout.addWidget(label)
|
||||
album_layout.addWidget(line_edit)
|
||||
# Add stretch to place entries to top
|
||||
album_layout.addStretch()
|
||||
|
||||
# Add album and disc_layout
|
||||
disc_layout.addLayout(album_layout)
|
||||
main_layout.addLayout(disc_layout)
|
||||
|
||||
self.list_widget = QListWidget()
|
||||
disc_layout.addWidget(self.list_widget)
|
||||
|
||||
button_layout = QHBoxLayout()
|
||||
main_layout.addLayout(button_layout)
|
||||
|
||||
self.button_read = QPushButton("Read Disc")
|
||||
self.button_read.clicked.connect(self.read_it)
|
||||
button_layout.addWidget(self.button_read)
|
||||
|
||||
self.button_rip = QPushButton("Rip Disc")
|
||||
self.button_rip.setDisabled(True)
|
||||
self.button_rip.clicked.connect(self.rip_it)
|
||||
button_layout.addWidget(self.button_rip)
|
||||
|
||||
def set_album_field(self, key, value):
|
||||
i = self.FIELD_NAMES.index(key)
|
||||
line = self.__album_lines__[i]
|
||||
line.setText(value)
|
||||
|
||||
def get_album_field(self, key):
|
||||
i = self.FIELD_NAMES.index(key)
|
||||
if key == self.KEY_ALBUM_YEAR:
|
||||
return int(self.__album_lines__[i].text())
|
||||
else:
|
||||
return self.__album_lines__[i].text()
|
||||
|
||||
def append_title(self, value):
|
||||
num_tracks = self.list_widget.count() + 1
|
||||
row_widget = RowWidget(num_tracks)
|
||||
row_widget.text_edit.setPlainText(value)
|
||||
row_widget.progress_bar.setValue(0)
|
||||
list_item = QListWidgetItem(self.list_widget)
|
||||
list_item.setSizeHint(row_widget.sizeHint())
|
||||
self.list_widget.addItem(list_item)
|
||||
self.list_widget.setItemWidget(list_item, row_widget)
|
||||
|
||||
def set_status(self, status):
|
||||
self.statusBar().showMessage(status)
|
||||
|
||||
def set_title_progress(self, num, value):
|
||||
list_item = self.list_widget.item(num)
|
||||
row_widget = self.list_widget.itemWidget(list_item)
|
||||
row_widget.progress_bar.setValue(value)
|
||||
|
||||
def read_it(self):
|
||||
print("read_it button action not yet implemented...")
|
||||
|
||||
def rip_it(self):
|
||||
print("rip_it button action not yet implemented...")
|
||||
|
||||
|
||||
class SelectionDialog(QDialog):
|
||||
"""
|
||||
A custom dialog to select an item from a list.
|
||||
"""
|
||||
|
||||
def __init__(self, parent, title, items):
|
||||
super().__init__(parent)
|
||||
self.setWindowTitle(title)
|
||||
self.setMinimumWidth(300)
|
||||
|
||||
# Layout
|
||||
layout = QVBoxLayout(self)
|
||||
|
||||
# List widget for options
|
||||
self.list_widget = QListWidget()
|
||||
self.list_widget.addItems(items)
|
||||
if items:
|
||||
self.list_widget.setCurrentRow(0) # Select first item by default
|
||||
|
||||
# Add a double-click shortcut to accept the dialog
|
||||
self.list_widget.itemDoubleClicked.connect(self.accept)
|
||||
|
||||
layout.addWidget(self.list_widget)
|
||||
|
||||
# Standard OK and Cancel buttons
|
||||
button_box = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel)
|
||||
button_box.accepted.connect(self.accept)
|
||||
button_box.rejected.connect(self.reject)
|
||||
layout.addWidget(button_box)
|
||||
|
||||
def get_selected_index(self):
|
||||
"""Returns the index of the currently selected item."""
|
||||
return self.list_widget.currentRow()
|
2
gui/requirements.txt
Normal file
2
gui/requirements.txt
Normal file
@ -0,0 +1,2 @@
|
||||
pyside6
|
||||
|
2
media
2
media
@ -1 +1 @@
|
||||
Subproject commit 2e497e2d9e3617e5b50d50556e35cd631c36fd87
|
||||
Subproject commit f38f34e9a5f85a263ae6856d5cea7241160dea79
|
4
pyrip.py
4
pyrip.py
@ -8,7 +8,7 @@ import fstools
|
||||
logger = report.app_logging_config()
|
||||
|
||||
|
||||
def progress_callback_rip(p: float):
|
||||
def progress_callback_rip(p: float, track_num: int = None):
|
||||
bar_length = 40
|
||||
progress = int(bar_length * p)
|
||||
out = "\rRipping.... - [ "
|
||||
@ -18,7 +18,7 @@ def progress_callback_rip(p: float):
|
||||
sys.stdout.write(out)
|
||||
|
||||
|
||||
def progress_callback_enc(p: float):
|
||||
def progress_callback_enc(p: float, track_num: int = None):
|
||||
bar_length = 40
|
||||
progress = int(bar_length * p)
|
||||
out = "\rEncoding... - [ "
|
||||
|
384
pyrip.wxg
384
pyrip.wxg
@ -1,384 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- generated by wxGlade 0.7.1 on Tue Jul 12 10:30:16 2016 -->
|
||||
|
||||
<application class="" encoding="UTF-8" for_version="3.0" header_extension=".h" indent_amount="4" indent_symbol="space" is_template="0" language="python" name="" option="0" overwrite="0" path="pyrip.py" source_extension=".cpp" top_window="frame_1" use_gettext="1" use_new_namespace="1">
|
||||
<object class="MainFrame" name="frame_1" base="EditFrame">
|
||||
<title>PyRip</title>
|
||||
<size>1033, 761</size>
|
||||
<object class="wxBoxSizer" name="sizer_main" base="EditBoxSizer">
|
||||
<orient>wxVERTICAL</orient>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>1</option>
|
||||
<object class="wxNotebook" name="notebook_main" base="EditNotebook">
|
||||
<tabs>
|
||||
<tab window="notebook_main_rip">Rip</tab>
|
||||
<tab window="notebook_main_config">Config</tab>
|
||||
</tabs>
|
||||
<object class="wxPanel" name="notebook_main_rip" base="EditPanel">
|
||||
<style>wxTAB_TRAVERSAL</style>
|
||||
<object class="wxBoxSizer" name="sizer_rip" base="EditBoxSizer">
|
||||
<orient>wxVERTICAL</orient>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>1</option>
|
||||
<object class="wxBoxSizer" name="sizer_rip_cd_data" base="EditBoxSizer">
|
||||
<orient>wxHORIZONTAL</orient>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>1</option>
|
||||
<object class="wxListBox" name="track_list" base="EditListBox">
|
||||
<style>wxLB_MULTIPLE</style>
|
||||
<selection>0</selection>
|
||||
<choices>
|
||||
</choices>
|
||||
<events>
|
||||
<handler event="EVT_LISTBOX">evt_tracklist</handler>
|
||||
</events>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>1</option>
|
||||
<object class="wxBoxSizer" name="sizer_rip_track_data" base="EditBoxSizer">
|
||||
<orient>wxVERTICAL</orient>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="wxStaticBoxSizer" name="sizer_artist" base="EditStaticBoxSizer">
|
||||
<orient>wxVERTICAL</orient>
|
||||
<label>Artist</label>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="wxTextCtrl" name="text_ctrl_artist" base="EditTextCtrl">
|
||||
<events>
|
||||
<handler event="EVT_TEXT">evt_artist_changed</handler>
|
||||
</events>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="wxStaticBoxSizer" name="sizer_album" base="EditStaticBoxSizer">
|
||||
<orient>wxVERTICAL</orient>
|
||||
<label>Album</label>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="wxTextCtrl" name="text_ctrl_album" base="EditTextCtrl">
|
||||
<events>
|
||||
<handler event="EVT_TEXT">evt_album_changed</handler>
|
||||
</events>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="wxStaticBoxSizer" name="sizer_year" base="EditStaticBoxSizer">
|
||||
<orient>wxVERTICAL</orient>
|
||||
<label>Year</label>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="wxTextCtrl" name="text_ctrl_year" base="EditTextCtrl">
|
||||
<events>
|
||||
<handler event="EVT_TEXT">evt_year_changed</handler>
|
||||
</events>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="wxStaticBoxSizer" name="sizer_genre" base="EditStaticBoxSizer">
|
||||
<orient>wxVERTICAL</orient>
|
||||
<label>Genre</label>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="wxTextCtrl" name="text_ctrl_genre" base="EditTextCtrl">
|
||||
<events>
|
||||
<handler event="EVT_TEXT">evt_genre_changed</handler>
|
||||
</events>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="wxStaticBoxSizer" name="sizer_title" base="EditStaticBoxSizer">
|
||||
<orient>wxVERTICAL</orient>
|
||||
<label>Title</label>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="wxTextCtrl" name="text_ctrl_title" base="EditTextCtrl">
|
||||
<events>
|
||||
<handler event="EVT_TEXT">evt_title_changed</handler>
|
||||
</events>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="wxStaticBoxSizer" name="sizer_track_no" base="EditStaticBoxSizer">
|
||||
<orient>wxVERTICAL</orient>
|
||||
<label>Trucknumber</label>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="wxTextCtrl" name="text_ctrl_track_no" base="EditTextCtrl">
|
||||
<events>
|
||||
<handler event="EVT_TEXT">evt_track_no_changed</handler>
|
||||
</events>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="wxStaticBoxSizer" name="sizer_comment" base="EditStaticBoxSizer">
|
||||
<orient>wxVERTICAL</orient>
|
||||
<label>Comment</label>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="wxTextCtrl" name="text_ctrl_comment" base="EditTextCtrl">
|
||||
<events>
|
||||
<handler event="EVT_TEXT">evt_comment_changed</handler>
|
||||
</events>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<border>0</border>
|
||||
<option>1</option>
|
||||
<object class="spacer" name="spacer" base="EditSpacer">
|
||||
<height>20</height>
|
||||
<width>20</width>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="wxStaticBoxSizer" name="sizer_overall_progress" base="EditStaticBoxSizer">
|
||||
<orient>wxVERTICAL</orient>
|
||||
<label>Overall Progress</label>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="wxGauge" name="gauge_overall_progress" base="EditGauge">
|
||||
<range>1000</range>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="wxStaticBoxSizer" name="sizer_rip_progress" base="EditStaticBoxSizer">
|
||||
<orient>wxVERTICAL</orient>
|
||||
<label>Rip Progress</label>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="wxGauge" name="gauge_rip_progress" base="EditGauge">
|
||||
<range>1000</range>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="wxStaticBoxSizer" name="sizer_encode_progress" base="EditStaticBoxSizer">
|
||||
<orient>wxVERTICAL</orient>
|
||||
<label>Encode Progress</label>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="wxGauge" name="gauge_encode_progress" base="EditGauge">
|
||||
<range>1000</range>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="wxBoxSizer" name="sizer_rip_buttons" base="EditBoxSizer">
|
||||
<orient>wxHORIZONTAL</orient>
|
||||
<object class="sizeritem">
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="spacer" name="spacer" base="EditSpacer">
|
||||
<height>20</height>
|
||||
<width>20</width>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="wxButton" name="button_rip" base="EditButton">
|
||||
<label>Rip</label>
|
||||
<events>
|
||||
<handler event="EVT_BUTTON">evt_rip</handler>
|
||||
</events>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="spacer" name="spacer" base="EditSpacer">
|
||||
<height>20</height>
|
||||
<width>20</width>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="wxButton" name="button_read_disc" base="EditButton">
|
||||
<label>Read Disc</label>
|
||||
<events>
|
||||
<handler event="EVT_BUTTON">evt_new_disc</handler>
|
||||
</events>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="spacer" name="spacer" base="EditSpacer">
|
||||
<height>20</height>
|
||||
<width>20</width>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="wxPanel" name="notebook_main_config" base="EditPanel">
|
||||
<style>wxTAB_TRAVERSAL</style>
|
||||
<object class="wxBoxSizer" name="sizer_notebook_main_config" base="EditBoxSizer">
|
||||
<orient>wxVERTICAL</orient>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="wxStaticBoxSizer" name="sizer_target_path" base="EditStaticBoxSizer">
|
||||
<orient>wxVERTICAL</orient>
|
||||
<label>Target Path</label>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="wxTextCtrl" name="text_ctrl_target_path" base="EditTextCtrl">
|
||||
<events>
|
||||
<handler event="EVT_TEXT">evt_target_path_changed</handler>
|
||||
</events>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="wxStaticBoxSizer" name="sizer_device" base="EditStaticBoxSizer">
|
||||
<orient>wxVERTICAL</orient>
|
||||
<label>Device</label>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="wxTextCtrl" name="text_ctrl_device" base="EditTextCtrl">
|
||||
<events>
|
||||
<handler event="EVT_TEXT">evt_device_changed</handler>
|
||||
</events>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="wxStaticBoxSizer" name="sizer_default_comment" base="EditStaticBoxSizer">
|
||||
<orient>wxVERTICAL</orient>
|
||||
<label>Default Comment</label>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="wxTextCtrl" name="text_ctrl_default_comment" base="EditTextCtrl">
|
||||
<events>
|
||||
<handler event="EVT_TEXT">evt_default_comment_changed</handler>
|
||||
</events>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="wxStaticBoxSizer" name="sizer_track_list_string" base="EditStaticBoxSizer">
|
||||
<orient>wxVERTICAL</orient>
|
||||
<label>Track List Sting</label>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>0</option>
|
||||
<object class="wxTextCtrl" name="text_ctrl_track_list_string" base="EditTextCtrl">
|
||||
<events>
|
||||
<handler event="EVT_TEXT">evt_track_list_string_changed</handler>
|
||||
</events>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</application>
|
140
pyripgui.py
Normal file
140
pyripgui.py
Normal file
@ -0,0 +1,140 @@
|
||||
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())
|
Loading…
x
Reference in New Issue
Block a user