rhcp011235

Untitled

Jul 29th, 2025
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 20.57 KB | None | 0 0
  1.  
  2. import sys
  3. import os
  4. import subprocess
  5. from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton, QLabel, QTextEdit, QVBoxLayout, QWidget, QMessageBox
  6. from PySide6.QtGui import QColor, QDesktopServices, QIcon
  7. from PySide6.QtCore import Qt, QUrl, QRunnable, QThreadPool, Signal, QObject
  8.  
  9. class FastbootWorker(QRunnable):
  10.     """
  11.    A QRunnable subclass to execute fastboot commands in a separate thread.
  12.    Signals are used to communicate results and log messages back to the GUI thread.
  13.    """
  14.  
  15.     class Signals(QObject):
  16.         """
  17.        Defines the signals available from a running worker thread.
  18.        """
  19.         log_message = Signal(str, QColor)
  20.         process_finished = Signal(bool, str)
  21.         user_action_required = Signal()
  22.         error = Signal(str)
  23.  
  24.     def __init__(self, command_args: str, is_device_check: bool=False):
  25.         super().__init__()
  26.         self.command_args = command_args
  27.         self.is_device_check = is_device_check
  28.         self.signals = self.Signals()
  29.  
  30.     def run(self):
  31.         """
  32.        Executes the fastboot command and emits signals based on the outcome.
  33.        """
  34.         self.signals.log_message.emit(f'Executing: fastboot {self.command_args}', QColor('black'))
  35.         try:
  36.             process = subprocess.run(['fastboot', self.command_args], capture_output=True, text=True, check=False, creationflags=subprocess.CREATE_NO_WINDOW if sys.platform == 'win32' else 0)
  37.             stdout = process.stdout.strip()
  38.             stderr = process.stderr.strip()
  39.             exit_code = process.returncode
  40.             if stdout:
  41.                 self.signals.log_message.emit(f'Output: {stdout}', QColor('gray'))
  42.             if stderr:
  43.                 self.signals.log_message.emit(f'Error Output: {stderr}', QColor('red'))
  44.             success = False
  45.             if self.is_device_check:
  46.                 success = 'fastboot' in stdout.lower()
  47.             else:
  48.                 success = exit_code == 0
  49.             if not success:
  50.                 self.signals.log_message.emit(f'Command failed: fastboot {self.command_args}', QColor('red'))
  51.             self.signals.process_finished.emit(success, self.command_args)
  52.         except FileNotFoundError:
  53.             error_msg = "Error: 'fastboot' command not found. Make sure fastboot is installed and in your system's PATH."
  54.             self.signals.log_message.emit(error_msg, QColor('red'))
  55.             self.signals.error.emit(error_msg)
  56.             self.signals.process_finished.emit(False, self.command_args)
  57.         except Exception as e:
  58.             error_msg = f'An unexpected error occurred during fastboot execution: {e}'
  59.             self.signals.log_message.emit(error_msg, QColor('red'))
  60.             self.signals.error.emit(error_msg)
  61.             self.signals.process_finished.emit(False, self.command_args)
  62.  
  63. class FRPToolApp(QMainWindow):
  64.     """
  65.    Main application window for the GSMYOGESH FRP Removal Tool.
  66.    """
  67.  
  68.     def __init__(self):
  69.         super().__init__()
  70.         self.is_process_running = False
  71.         self.thread_pool = QThreadPool.globalInstance()
  72.         self._current_worker = None
  73.         self.init_ui()
  74.         self.display_welcome_message()
  75.  
  76.     def init_ui(self):
  77.         """
  78.        Initializes the user interface elements and layout.
  79.        """
  80.         self.setWindowTitle('A065 F065 FRP REMOVAL BY GSMYOGESH.COM')
  81.         self.setGeometry(100, 100, 600, 400)
  82.         central_widget = QWidget()
  83.         self.setCentralWidget(central_widget)
  84.         layout = QVBoxLayout(central_widget)
  85.         self.instruction_label = QLabel('Connect DEVICE in FASTBOOT MODE')
  86.         self.instruction_label.setObjectName('instructionLabel')
  87.         layout.addWidget(self.instruction_label)
  88.         self.log_text_edit = QTextEdit()
  89.         self.log_text_edit.setReadOnly(True)
  90.         self.log_text_edit.setObjectName('logTextEdit')
  91.         layout.addWidget(self.log_text_edit)
  92.         self.remove_frp_button = QPushButton('REMOVE FRP')
  93.         self.remove_frp_button.setObjectName('removeFRPButton')
  94.         self.remove_frp_button.clicked.connect(self.start_frp_removal)
  95.         layout.addWidget(self.remove_frp_button)
  96.         self.apply_qss()
  97.  
  98.     def apply_qss(self):
  99.         """
  100.        Applies Qt Style Sheet (QSS) to the application for styling.
  101.        Removed unsupported CSS properties like box-shadow, transition, transform.
  102.        """
  103.         qss = '\n        QMainWindow {\n            background-color: #f0f2f5; /* Light gray background */\n        }\n\n        #instructionLabel {\n            font-family: "Segoe UI", sans-serif;\n            font-size: 16px;\n            font-weight: bold;\n            color: #333;\n            padding: 10px;\n            text-align: center;\n            background-color: #e0e5ec; /* Soft background */\n            border-radius: 8px;\n            margin: 10px;\n            /* box-shadow: 2px 2px 5px rgba(0,0,0,0.1); Removed: Unsupported in QSS */\n        }\n\n        #logTextEdit {\n            font-family: "Consolas", "Monaco", monospace;\n            font-size: 13px;\n            color: #333;\n            background-color: #ffffff;\n            border: 1px solid #c0c0c0;\n            border-radius: 8px;\n            padding: 10px;\n            margin: 10px;\n            /* box-shadow: inset 1px 1px 3px rgba(0,0,0,0.1); Removed: Unsupported in QSS */\n        }\n\n        #removeFRPButton {\n            background-color: #4CAF50; /* Green */\n            color: white;\n            font-family: "Segoe UI", sans-serif;\n            font-size: 16px;\n            font-weight: bold;\n            border: none;\n            border-radius: 10px;\n            padding: 12px 24px;\n            margin: 10px;\n            min-height: 40px;\n            /* box-shadow: 3px 3px 6px rgba(0,0,0,0.2); Removed: Unsupported in QSS */\n            /* transition: background-color 0.3s ease, transform 0.1s ease; Removed: Unsupported in QSS */\n        }\n\n        #removeFRPButton:hover {\n            background-color: #45a049; /* Darker green on hover */\n            /* transform: translateY(-2px); Removed: Unsupported in QSS */\n        }\n\n        #removeFRPButton:pressed {\n            background-color: #3e8e41; /* Even darker on press */\n            /* transform: translateY(0); Removed: Unsupported in QSS */\n            /* box-shadow: 1px 1px 3px rgba(0,0,0,0.2); Removed: Unsupported in QSS */\n        }\n\n        #removeFRPButton:disabled {\n            background-color: #cccccc;\n            color: #666666;\n            /* box-shadow: none; Removed: Unsupported in QSS */\n        }\n        '
  104.         self.setStyleSheet(qss)
  105.  
  106.     def display_welcome_message(self):
  107.         """
  108.        Clears the log and displays the initial welcome messages.
  109.        """
  110.         self.log_text_edit.clear()
  111.         self.log_message('Samsung A065 - U1,U2,U3', QColor('blue'))
  112.         self.log_message('Samsung F065', QColor('blue'))
  113.         self.log_message('BY GSMYOGESH.COM', QColor('darkblue'))
  114.         self.log_message('\nEnter Device in Fastboot Mode', QColor('red'))
  115.         self.log_message('\nReady to start FRP removal process...', QColor('black'))
  116.         self.log_message('Make sure your device is connected in FASTBOOT MODE!\n', QColor('black'))
  117.  
  118.     def log_message(self, message: str, color: QColor):
  119.         """
  120.        Appends a colored message to the log text edit.
  121.        Uses HTML for rich text formatting.
  122.        """
  123.         if self.thread() != QApplication.instance().thread():
  124.             self.log_text_edit.append(f"<span style='color:{color.name()};'>{message}</span>")
  125.         else:
  126.             self.log_text_edit.append(f"<span style='color:{color.name()};'>{message}</span>")
  127.         self.log_text_edit.verticalScrollBar().setValue(self.log_text_edit.verticalScrollBar().maximum())
  128.  
  129.     def show_message_box(self, title: str, message: str, icon: QMessageBox.Icon, buttons: QMessageBox.StandardButtons):
  130.         """
  131.        Displays a custom message box (replaces C# MessageBox.Show).
  132.        """
  133.         msg_box = QMessageBox(self)
  134.         msg_box.setWindowTitle(title)
  135.         msg_box.setText(message)
  136.         msg_box.setIcon(icon)
  137.         msg_box.setStandardButtons(buttons)
  138.         msg_box.setWindowFlags(msg_box.windowFlags() + Qt.WindowStaysOnTopHint)
  139.         return msg_box.exec()
  140.  
  141.     def open_website(self, url: str):
  142.         """
  143.        Opens the specified URL in the default web browser.
  144.        """
  145.         try:
  146.             QDesktopServices.openUrl(QUrl(url))
  147.             self.log_message(f'Opened website: {url}', QColor('blue'))
  148.         except Exception as e:
  149.             self.log_message(f'Could not open website automatically: {e}', QColor('orange'))
  150.  
  151.     def start_frp_removal(self):
  152.         """
  153.        Initiates the FRP removal process.
  154.        Manages the state of the process and button.
  155.        """
  156.         if self.is_process_running:
  157.             self.show_message_box('Process Running', 'FRP removal process is already running!', QMessageBox.Icon.Warning, QMessageBox.StandardButton.Ok)
  158.             return
  159.         self.is_process_running = True
  160.         self.remove_frp_button.setEnabled(False)
  161.         self.remove_frp_button.setText('PROCESSING...')
  162.         self.log_text_edit.clear()
  163.         self._step_check_devices()
  164.  
  165.     def _step_check_devices(self):
  166.         """Step 1: Check for connected devices."""
  167.         self.log_message('Starting FRP removal process...', QColor('blue'))
  168.         self.log_message('Checking connected devices...', QColor('black'))
  169.         self._current_worker = FastbootWorker('devices', is_device_check=True)
  170.         self._current_worker.signals.log_message.connect(self.log_message)
  171.         self._current_worker.signals.process_finished.connect(self._handle_check_devices_result)
  172.         self._current_worker.signals.error.connect(self._handle_error)
  173.         self.thread_pool.start(self._current_worker)
  174.  
  175.     def _handle_check_devices_result(self, success: bool, command_args: str):
  176.         """Handles the result of the 'fastboot devices' command."""
  177.         if self._current_worker:
  178.             self._current_worker.signals.process_finished.disconnect(self._handle_check_devices_result)
  179.             self._current_worker.signals.log_message.disconnect(self.log_message)
  180.             self._current_worker.signals.error.disconnect(self._handle_error)
  181.         if not success:
  182.             self.log_message('No device found in fastboot mode!', QColor('red'))
  183.             self.show_message_box('Device Not Found', 'No device detected in fastboot mode!\nPlease connect your device in fastboot mode and try again.', QMessageBox.Icon.Critical, QMessageBox.StandardButton.Ok)
  184.             self._reset_ui_state()
  185.         else:
  186.             self.log_message('Device detected in fastboot mode.', QColor('green'))
  187.             self._step_flashing_unlock()
  188.         self._current_worker = None
  189.  
  190.     def _step_flashing_unlock(self):
  191.         """Step 2: Start flashing unlock."""
  192.         self.log_message('Preparing device...', QColor('black'))
  193.         self._current_worker = FastbootWorker('flashing unlock')
  194.         self._current_worker.signals.log_message.connect(self.log_message)
  195.         self._current_worker.signals.process_finished.connect(self._handle_flashing_unlock_result)
  196.         self._current_worker.signals.error.connect(self._handle_error)
  197.         self.thread_pool.start(self._current_worker)
  198.  
  199.     def _handle_flashing_unlock_result(self, success: bool, command_args: str):
  200.         """Handles the result of 'fastboot flashing unlock' and prompts user."""
  201.         if self._current_worker:
  202.             self._current_worker.signals.process_finished.disconnect(self._handle_flashing_unlock_result)
  203.             self._current_worker.signals.log_message.disconnect(self.log_message)
  204.             self._current_worker.signals.error.disconnect(self._handle_error)
  205.         if not success:
  206.             self.log_message('Failed to initiate flashing unlock. Check device status.', QColor('red'))
  207.             self.show_message_box('Unlock Failed', 'Failed to initiate flashing unlock. Please ensure your device is ready.', QMessageBox.Icon.Critical, QMessageBox.StandardButton.Ok)
  208.             self._reset_ui_state()
  209.             self._current_worker = None
  210.             return
  211.         reply = self.show_message_box('User Action Required', 'PRESS VOLUME UP TO CONTINUE\n\nOn your device:\n1. Use Volume UP/DOWN to navigate\n2. Press Volume UP to confirm unlock\n3. Click OK here after confirming on device', QMessageBox.Icon.Information, QMessageBox.StandardButton.Ok | QMessageBox.StandardButton.Cancel)
  212.         if reply == QMessageBox.StandardButton.Ok:
  213.             self._step_erase_persistent()
  214.         else:
  215.             self.log_message('Process cancelled by user.', QColor('red'))
  216.             self._reset_ui_state()
  217.         self._current_worker = None
  218.  
  219.     def _step_erase_persistent(self):
  220.         """Step 3: Erase persistent partition."""
  221.         self.log_message('Processing device data...', QColor('black'))
  222.         self._current_worker = FastbootWorker('erase persistent')
  223.         self._current_worker.signals.log_message.connect(self.log_message)
  224.         self._current_worker.signals.process_finished.connect(self._handle_erase_persistent_result)
  225.         self._current_worker.signals.error.connect(self._handle_error)
  226.         self.thread_pool.start(self._current_worker)
  227.  
  228.     def _handle_erase_persistent_result(self, success: bool, command_args: str):
  229.         """Handles the result of 'fastboot erase persistent'."""
  230.         if self._current_worker:
  231.             self._current_worker.signals.process_finished.disconnect(self._handle_erase_persistent_result)
  232.             self._current_worker.signals.log_message.disconnect(self.log_message)
  233.             self._current_worker.signals.error.disconnect(self._handle_error)
  234.         if not success:
  235.             self.log_message('Failed to erase persistent partition.', QColor('red'))
  236.             self.show_message_box('Erase Failed', 'Failed to erase persistent partition. Please check logs for details.', QMessageBox.Icon.Critical, QMessageBox.StandardButton.Ok)
  237.             self._reset_ui_state()
  238.         else:
  239.             self.log_message('Persistent partition erased.', QColor('green'))
  240.             self._step_erase_userdata()
  241.         self._current_worker = None
  242.  
  243.     def _step_erase_userdata(self):
  244.         """Step 4: Erase userdata partition."""
  245.         self.log_message('Clearing device memory...', QColor('black'))
  246.         self._current_worker = FastbootWorker('erase userdata')
  247.         self._current_worker.signals.log_message.connect(self.log_message)
  248.         self._current_worker.signals.process_finished.connect(self._handle_erase_userdata_result)
  249.         self._current_worker.signals.error.connect(self._handle_error)
  250.         self.thread_pool.start(self._current_worker)
  251.  
  252.     def _handle_erase_userdata_result(self, success: bool, command_args: str):
  253.         """Handles the result of 'fastboot erase userdata'."""
  254.         if self._current_worker:
  255.             self._current_worker.signals.process_finished.disconnect(self._handle_erase_userdata_result)
  256.             self._current_worker.signals.log_message.disconnect(self.log_message)
  257.             self._current_worker.signals.error.disconnect(self._handle_error)
  258.         if not success:
  259.             self.log_message('Failed to erase userdata partition.', QColor('red'))
  260.             self.show_message_box('Erase Failed', 'Failed to erase userdata partition. Please check logs for details.', QMessageBox.Icon.Critical, QMessageBox.StandardButton.Ok)
  261.             self._reset_ui_state()
  262.         else:
  263.             self.log_message('Userdata partition erased.', QColor('green'))
  264.             self._step_flash_super()
  265.         self._current_worker = None
  266.  
  267.     def _step_flash_super(self):
  268.         """Step 5: Flash super.img."""
  269.         self.log_message('Installing system files... This may take several minutes...', QColor('black'))
  270.         super_img_path = os.path.join(os.getcwd(), 'super.img')
  271.         if not os.path.exists(super_img_path):
  272.             error_msg = f'Error: super.img not found at {super_img_path}. Please ensure the file exists.'
  273.             self.log_message(error_msg, QColor('red'))
  274.             self.show_message_box('File Not Found', error_msg, QMessageBox.Icon.Critical, QMessageBox.StandardButton.Ok)
  275.             self._reset_ui_state()
  276.             return
  277.         command = f'flash super "{super_img_path}"'
  278.         self._current_worker = FastbootWorker(command)
  279.         self._current_worker.signals.log_message.connect(self.log_message)
  280.         self._current_worker.signals.process_finished.connect(self._handle_flash_super_result)
  281.         self._current_worker.signals.error.connect(self._handle_error)
  282.         self.thread_pool.start(self._current_worker)
  283.  
  284.     def _handle_flash_super_result(self, success: bool, command_args: str):
  285.         """Handles the result of 'fastboot flash super'."""
  286.         if self._current_worker:
  287.             self._current_worker.signals.process_finished.disconnect(self._handle_flash_super_result)
  288.             self._current_worker.signals.log_message.disconnect(self.log_message)
  289.             self._current_worker.signals.error.disconnect(self._handle_error)
  290.         if not success:
  291.             self.log_message('Failed to flash super.img.', QColor('red'))
  292.             self.show_message_box('Flash Failed', 'Failed to flash super.img. Please check logs for details.', QMessageBox.Icon.Critical, QMessageBox.StandardButton.Ok)
  293.             self._reset_ui_state()
  294.         else:
  295.             self.log_message('super.img flashed successfully.', QColor('green'))
  296.             self._step_reboot()
  297.         self._current_worker = None
  298.  
  299.     def _step_reboot(self):
  300.         """Step 6: Reboot the device."""
  301.         self.log_message('Finalizing process...', QColor('black'))
  302.         self._current_worker = FastbootWorker('reboot')
  303.         self._current_worker.signals.log_message.connect(self.log_message)
  304.         self._current_worker.signals.process_finished.connect(self._handle_reboot_result)
  305.         self._current_worker.signals.error.connect(self._handle_error)
  306.         self.thread_pool.start(self._current_worker)
  307.  
  308.     def _handle_reboot_result(self, success: bool, command_args: str):
  309.         """Handles the result of 'fastboot reboot' and finalizes the process."""
  310.         if self._current_worker:
  311.             self._current_worker.signals.process_finished.disconnect(self._handle_reboot_result)
  312.             self._current_worker.signals.log_message.disconnect(self.log_message)
  313.             self._current_worker.signals.error.disconnect(self._handle_error)
  314.         if not success:
  315.             self.log_message('Failed to reboot device. Please reboot manually.', QColor('orange'))
  316.         else:
  317.             self.log_message('Device rebooted successfully.', QColor('green'))
  318.         self.log_message('\nFRP REMOVAL COMPLETED!', QColor('green'))
  319.         self.log_message('\nIMPORTANT INSTRUCTIONS:', QColor('red'))
  320.         self.log_message('1. PUT PHONE TO DOWNLOAD MODE', QColor('red'))
  321.         self.log_message('2. LONG PRESS VOLUME UP BUTTON TO RELOCK BOOTLOADER', QColor('red'))
  322.         self.log_message('\nPowered By GSMYOGESH', QColor('blue'))
  323.         self.log_message('Contact: +917043259004', QColor('blue'))
  324.         self.show_message_box('Process Complete', 'FRP Removal Process Completed!\n\nNEXT STEPS:\n1. Put phone in DOWNLOAD MODE\n2. Long press VOLUME UP to relock bootloader\n\nContact: +917043259004\nWebsite: WWW.GSMYOGESH.COM', QMessageBox.Icon.Information, QMessageBox.StandardButton.Ok)
  325.         self.open_website('https://www.gsmyogesh.com')
  326.         self._reset_ui_state()
  327.         self._current_worker = None
  328.  
  329.     def _handle_error(self, error_message: str):
  330.         """Handles errors reported by worker threads."""
  331.         self.log_message(f'An error occurred: {error_message}', QColor('red'))
  332.         self.show_message_box('Error', f'An error occurred during the process: {error_message}', QMessageBox.Icon.Critical, QMessageBox.StandardButton.Ok)
  333.         self._reset_ui_state()
  334.         if self._current_worker:
  335.             self._current_worker.signals.process_finished.disconnect(self._handle_error)
  336.             self._current_worker.signals.log_message.disconnect(self.log_message)
  337.             self._current_worker.signals.error.disconnect(self._handle_error)
  338.         self._current_worker = None
  339.  
  340.     def _reset_ui_state(self):
  341.         """Resets the UI elements to their initial state after a process completes or fails."""
  342.         self.is_process_running = False
  343.         self.remove_frp_button.setEnabled(True)
  344.         self.remove_frp_button.setText('REMOVE FRP')
  345. if __name__ == '__main__':
  346.     app = QApplication(sys.argv)
  347.     window = FRPToolApp()
  348.     window.show()
  349.     sys.exit(app.exec())
Advertisement
Add Comment
Please, Sign In to add comment