Sfoglia il codice sorgente

add initial burning code

Noah Vogt 1 anno fa
parent
commit
1434389f39
3 ha cambiato i file con 242 aggiunte e 0 eliminazioni
  1. 132 0
      burn_cd_dialog.py
  2. 108 0
      choose_cd_dialog.py
  3. 2 0
      requirements.txt

+ 132 - 0
burn_cd_dialog.py

@@ -0,0 +1,132 @@
+#!/usr/bin/env python3
+
+"""
+Copyright © 2024 Noah Vogt <noah@noahvogt.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+"""
+
+import sys
+from subprocess import Popen
+from shlex import split
+
+from PyQt5.QtWidgets import (  # pylint: disable=no-name-in-module
+    QApplication,
+    QMessageBox,
+)
+from PyQt5.QtCore import QTimer  # pylint: disable=no-name-in-module
+
+from pycdio import DRIVER_DEVICE
+from cdio import get_devices, Device, DriverUnsupportedError, DeviceException
+
+from utils import (
+    make_sure_file_exists,
+    log,
+)
+from input import validate_cd_record_config
+import config as const
+
+
+class InfoMsgBox:
+    def __init__(self, icon: QMessageBox.Icon, title: str, text: str) -> None:
+        self.app = QApplication([])
+        self.title = title
+        self.text = text
+        self.icon = icon
+        self.show_msg_box()
+        self.app.exec_()
+
+    def show_msg_box(self):
+        self.message_box = QMessageBox()
+        self.message_box.setIcon(self.icon)
+        self.message_box.setWindowTitle(self.title)
+        self.message_box.setText(self.text)
+
+        self.message_box.show()
+
+
+class CDBurnerGUI:
+    def __init__(self, drive: Device):
+        self.app = QApplication([])
+        self.drive = drive
+        self.exit_code = 1
+        self.show_burning_msg_box()
+        self.start_burn_subprocess()
+        self.app.exec_()
+
+    def burning_successful(self) -> bool:
+        if self.exit_code == 0:
+            return True
+        return False
+
+    def show_burning_msg_box(self):
+        self.message_box = QMessageBox()
+        self.message_box.setWindowTitle("Info")
+        self.message_box.setText("Burning CD...")
+        self.message_box.setInformativeText(
+            "Please wait for a few minutes. You can close this Window, as "
+            + "there will spawn another window after the operation is "
+            + "finished."
+        )
+
+        self.message_box.show()
+
+    def start_burn_subprocess(self):
+        process = Popen(["grep", "-a"])
+
+        while process.poll() is None:
+            QApplication.processEvents()
+        self.message_box.accept()
+
+        # Yeah this is hacky but it doesn't work when calling quit directly
+        QTimer.singleShot(0, self.app.quit)
+        self.exit_code = process.returncode
+
+
+def get_cd_drives() -> list:
+    cd_drives = get_devices(DRIVER_DEVICE)
+    return cd_drives
+
+
+def eject_drive(drive: Device) -> None:
+    try:
+        drive.eject_media()
+    except (DriverUnsupportedError, DeviceException):
+        log(f"Eject of CD-ROM drive {drive} failed")
+
+
+if __name__ == "__main__":
+    validate_cd_record_config()
+    make_sure_file_exists(const.CD_RECORD_CACHEFILE)
+
+    drives = get_cd_drives()
+    if not drives:
+        InfoMsgBox(
+            QMessageBox.Critical,
+            "Error",
+            "Error: Could not find a CD-ROM. Please try again",
+        )
+        sys.exit(1)
+    if len(drives) != 1:
+        # TODO: let user choose between drive slots / letters / devices
+        log("Warning: More than one cd drive found", color="yellow")
+        drives = drives[0]
+
+    BURN_SUCESS = CDBurnerGUI(drives[0]).burning_successful()
+    if BURN_SUCESS:
+        InfoMsgBox(QMessageBox.Info, "Info", "Successfully burned CD.")
+    else:
+        InfoMsgBox(QMessageBox.Critical, "Error", "Error: Failed to burn CD.")
+
+    eject_drive(drives[0])

+ 108 - 0
choose_cd_dialog.py

@@ -0,0 +1,108 @@
+#!/usr/bin/env python3
+
+"""
+Copyright © 2024 Noah Vogt <noah@noahvogt.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+"""
+
+from PyQt5.QtWidgets import (  # pylint: disable=no-name-in-module
+    QApplication,
+    QDialog,
+    QVBoxLayout,
+    QRadioButton,
+    QPushButton,
+    QMessageBox,
+    QButtonGroup,
+    QScrollArea,
+    QWidget,
+)
+
+from PyQt5.QtGui import QColor, QIcon  # pylint: disable=all
+
+from utils import (
+    get_yyyy_mm_dd_date,
+    make_sure_file_exists,
+    is_valid_cd_record_checkfile,
+    log,
+)
+from input import get_cachefile_content, validate_cd_record_config
+import config as const
+
+
+def stop_cd_recording() -> None:
+    cachefile_content = get_cachefile_content(const.CD_RECORD_CACHEFILE)
+    yyyy_mm_dd = get_yyyy_mm_dd_date()
+
+    if is_valid_cd_record_checkfile(cachefile_content, yyyy_mm_dd):
+        pass
+
+
+class RadioButtonDialog(QDialog):
+    def __init__(self):
+        super().__init__()
+        self.setWindowTitle("Choose a CD to Burn")
+
+        master_layout = QVBoxLayout(self)
+
+        scroll_area = QScrollArea()
+        scroll_area.setWidgetResizable(True)
+        master_layout.addWidget(scroll_area)
+
+        scroll_content = QWidget()
+        scroll_area.setWidget(scroll_content)
+        scroll_area_layout = QVBoxLayout(scroll_content)
+
+        self.radio_button_group = QButtonGroup(self)
+
+        self.radio_buttons = []
+        for i in range(1, 101):
+            radio_button = QRadioButton(f"Radio Button {i}")
+            if i == 1:
+                radio_button.setChecked(True)
+            self.radio_buttons.append(radio_button)
+            self.radio_button_group.addButton(radio_button)
+            scroll_area_layout.addWidget(radio_button)
+
+        ok_button = QPushButton("OK")
+        ok_button.clicked.connect(self.accept)
+        master_layout.addWidget(ok_button)
+
+    def accept(self):
+        selected_button = self.radio_button_group.checkedButton()
+        if selected_button:
+            QMessageBox.information(
+                self, "Selection", f"You selected: {selected_button.text()}"
+            )
+            super().accept()
+        else:
+            QMessageBox.warning(
+                self,
+                "No Selection",
+                "Please select an option before proceeding.",
+            )
+
+
+def main() -> None:
+    validate_cd_record_config()
+    make_sure_file_exists(const.CD_RECORD_CACHEFILE)
+
+    app = QApplication([])
+    dialog = RadioButtonDialog()
+    if dialog.exec_() == QDialog.Accepted:
+        print("Dialog accepted.")
+
+
+if __name__ == "__main__":
+    main()

+ 2 - 0
requirements.txt

@@ -2,3 +2,5 @@ wand
 termcolor
 colorama
 pyautogui
+PyQt5
+pycdio