rhcp011235 icon

Untitled

rhcp011235 | PRO | 07/29/25 05:38:03 PM UTC | 0 ⭐ | 869 👁️ | Never ⏰ | []
Python |

20.57 KB

|

None

|

0 👍

/

0 👎

 
import sys
import os
import subprocess
from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton, QLabel, QTextEdit, QVBoxLayout, QWidget, QMessageBox
from PySide6.QtGui import QColor, QDesktopServices, QIcon
from PySide6.QtCore import Qt, QUrl, QRunnable, QThreadPool, Signal, QObject
 
class FastbootWorker(QRunnable):
    """
    A QRunnable subclass to execute fastboot commands in a separate thread.
    Signals are used to communicate results and log messages back to the GUI thread.
    """
 
    class Signals(QObject):
        """
        Defines the signals available from a running worker thread.
        """
        log_message = Signal(str, QColor)
        process_finished = Signal(bool, str)
        user_action_required = Signal()
        error = Signal(str)
 
    def __init__(self, command_args: str, is_device_check: bool=False):
        super().__init__()
        self.command_args = command_args
        self.is_device_check = is_device_check
        self.signals = self.Signals()
 
    def run(self):
        """
        Executes the fastboot command and emits signals based on the outcome.
        """
        self.signals.log_message.emit(f'Executing: fastboot {self.command_args}', QColor('black'))
        try:
            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)
            stdout = process.stdout.strip()
            stderr = process.stderr.strip()
            exit_code = process.returncode
            if stdout:
                self.signals.log_message.emit(f'Output: {stdout}', QColor('gray'))
            if stderr:
                self.signals.log_message.emit(f'Error Output: {stderr}', QColor('red'))
            success = False
            if self.is_device_check:
                success = 'fastboot' in stdout.lower()
            else:
                success = exit_code == 0
            if not success:
                self.signals.log_message.emit(f'Command failed: fastboot {self.command_args}', QColor('red'))
            self.signals.process_finished.emit(success, self.command_args)
        except FileNotFoundError:
            error_msg = "Error: 'fastboot' command not found. Make sure fastboot is installed and in your system's PATH."
            self.signals.log_message.emit(error_msg, QColor('red'))
            self.signals.error.emit(error_msg)
            self.signals.process_finished.emit(False, self.command_args)
        except Exception as e:
            error_msg = f'An unexpected error occurred during fastboot execution: {e}'
            self.signals.log_message.emit(error_msg, QColor('red'))
            self.signals.error.emit(error_msg)
            self.signals.process_finished.emit(False, self.command_args)
 
class FRPToolApp(QMainWindow):
    """
    Main application window for the GSMYOGESH FRP Removal Tool.
    """
 
    def __init__(self):
        super().__init__()
        self.is_process_running = False
        self.thread_pool = QThreadPool.globalInstance()
        self._current_worker = None
        self.init_ui()
        self.display_welcome_message()
 
    def init_ui(self):
        """
        Initializes the user interface elements and layout.
        """
        self.setWindowTitle('A065 F065 FRP REMOVAL BY GSMYOGESH.COM')
        self.setGeometry(100, 100, 600, 400)
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        layout = QVBoxLayout(central_widget)
        self.instruction_label = QLabel('Connect DEVICE in FASTBOOT MODE')
        self.instruction_label.setObjectName('instructionLabel')
        layout.addWidget(self.instruction_label)
        self.log_text_edit = QTextEdit()
        self.log_text_edit.setReadOnly(True)
        self.log_text_edit.setObjectName('logTextEdit')
        layout.addWidget(self.log_text_edit)
        self.remove_frp_button = QPushButton('REMOVE FRP')
        self.remove_frp_button.setObjectName('removeFRPButton')
        self.remove_frp_button.clicked.connect(self.start_frp_removal)
        layout.addWidget(self.remove_frp_button)
        self.apply_qss()
 
    def apply_qss(self):
        """
        Applies Qt Style Sheet (QSS) to the application for styling.
        Removed unsupported CSS properties like box-shadow, transition, transform.
        """
        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        '
        self.setStyleSheet(qss)
 
    def display_welcome_message(self):
        """
        Clears the log and displays the initial welcome messages.
        """
        self.log_text_edit.clear()
        self.log_message('Samsung A065 - U1,U2,U3', QColor('blue'))
        self.log_message('Samsung F065', QColor('blue'))
        self.log_message('BY GSMYOGESH.COM', QColor('darkblue'))
        self.log_message('\nEnter Device in Fastboot Mode', QColor('red'))
        self.log_message('\nReady to start FRP removal process...', QColor('black'))
        self.log_message('Make sure your device is connected in FASTBOOT MODE!\n', QColor('black'))
 
    def log_message(self, message: str, color: QColor):
        """
        Appends a colored message to the log text edit.
        Uses HTML for rich text formatting.
        """
        if self.thread() != QApplication.instance().thread():
            self.log_text_edit.append(f"<span style='color:{color.name()};'>{message}</span>")
        else:
            self.log_text_edit.append(f"<span style='color:{color.name()};'>{message}</span>")
        self.log_text_edit.verticalScrollBar().setValue(self.log_text_edit.verticalScrollBar().maximum())
 
    def show_message_box(self, title: str, message: str, icon: QMessageBox.Icon, buttons: QMessageBox.StandardButtons):
        """
        Displays a custom message box (replaces C# MessageBox.Show).
        """
        msg_box = QMessageBox(self)
        msg_box.setWindowTitle(title)
        msg_box.setText(message)
        msg_box.setIcon(icon)
        msg_box.setStandardButtons(buttons)
        msg_box.setWindowFlags(msg_box.windowFlags() + Qt.WindowStaysOnTopHint)
        return msg_box.exec()
 
    def open_website(self, url: str):
        """
        Opens the specified URL in the default web browser.
        """
        try:
            QDesktopServices.openUrl(QUrl(url))
            self.log_message(f'Opened website: {url}', QColor('blue'))
        except Exception as e:
            self.log_message(f'Could not open website automatically: {e}', QColor('orange'))
 
    def start_frp_removal(self):
        """
        Initiates the FRP removal process.
        Manages the state of the process and button.
        """
        if self.is_process_running:
            self.show_message_box('Process Running', 'FRP removal process is already running!', QMessageBox.Icon.Warning, QMessageBox.StandardButton.Ok)
            return
        self.is_process_running = True
        self.remove_frp_button.setEnabled(False)
        self.remove_frp_button.setText('PROCESSING...')
        self.log_text_edit.clear()
        self._step_check_devices()
 
    def _step_check_devices(self):
        """Step 1: Check for connected devices."""
        self.log_message('Starting FRP removal process...', QColor('blue'))
        self.log_message('Checking connected devices...', QColor('black'))
        self._current_worker = FastbootWorker('devices', is_device_check=True)
        self._current_worker.signals.log_message.connect(self.log_message)
        self._current_worker.signals.process_finished.connect(self._handle_check_devices_result)
        self._current_worker.signals.error.connect(self._handle_error)
        self.thread_pool.start(self._current_worker)
 
    def _handle_check_devices_result(self, success: bool, command_args: str):
        """Handles the result of the 'fastboot devices' command."""
        if self._current_worker:
            self._current_worker.signals.process_finished.disconnect(self._handle_check_devices_result)
            self._current_worker.signals.log_message.disconnect(self.log_message)
            self._current_worker.signals.error.disconnect(self._handle_error)
        if not success:
            self.log_message('No device found in fastboot mode!', QColor('red'))
            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)
            self._reset_ui_state()
        else:
            self.log_message('Device detected in fastboot mode.', QColor('green'))
            self._step_flashing_unlock()
        self._current_worker = None
 
    def _step_flashing_unlock(self):
        """Step 2: Start flashing unlock."""
        self.log_message('Preparing device...', QColor('black'))
        self._current_worker = FastbootWorker('flashing unlock')
        self._current_worker.signals.log_message.connect(self.log_message)
        self._current_worker.signals.process_finished.connect(self._handle_flashing_unlock_result)
        self._current_worker.signals.error.connect(self._handle_error)
        self.thread_pool.start(self._current_worker)
 
    def _handle_flashing_unlock_result(self, success: bool, command_args: str):
        """Handles the result of 'fastboot flashing unlock' and prompts user."""
        if self._current_worker:
            self._current_worker.signals.process_finished.disconnect(self._handle_flashing_unlock_result)
            self._current_worker.signals.log_message.disconnect(self.log_message)
            self._current_worker.signals.error.disconnect(self._handle_error)
        if not success:
            self.log_message('Failed to initiate flashing unlock. Check device status.', QColor('red'))
            self.show_message_box('Unlock Failed', 'Failed to initiate flashing unlock. Please ensure your device is ready.', QMessageBox.Icon.Critical, QMessageBox.StandardButton.Ok)
            self._reset_ui_state()
            self._current_worker = None
            return
        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)
        if reply == QMessageBox.StandardButton.Ok:
            self._step_erase_persistent()
        else:
            self.log_message('Process cancelled by user.', QColor('red'))
            self._reset_ui_state()
        self._current_worker = None
 
    def _step_erase_persistent(self):
        """Step 3: Erase persistent partition."""
        self.log_message('Processing device data...', QColor('black'))
        self._current_worker = FastbootWorker('erase persistent')
        self._current_worker.signals.log_message.connect(self.log_message)
        self._current_worker.signals.process_finished.connect(self._handle_erase_persistent_result)
        self._current_worker.signals.error.connect(self._handle_error)
        self.thread_pool.start(self._current_worker)
 
    def _handle_erase_persistent_result(self, success: bool, command_args: str):
        """Handles the result of 'fastboot erase persistent'."""
        if self._current_worker:
            self._current_worker.signals.process_finished.disconnect(self._handle_erase_persistent_result)
            self._current_worker.signals.log_message.disconnect(self.log_message)
            self._current_worker.signals.error.disconnect(self._handle_error)
        if not success:
            self.log_message('Failed to erase persistent partition.', QColor('red'))
            self.show_message_box('Erase Failed', 'Failed to erase persistent partition. Please check logs for details.', QMessageBox.Icon.Critical, QMessageBox.StandardButton.Ok)
            self._reset_ui_state()
        else:
            self.log_message('Persistent partition erased.', QColor('green'))
            self._step_erase_userdata()
        self._current_worker = None
 
    def _step_erase_userdata(self):
        """Step 4: Erase userdata partition."""
        self.log_message('Clearing device memory...', QColor('black'))
        self._current_worker = FastbootWorker('erase userdata')
        self._current_worker.signals.log_message.connect(self.log_message)
        self._current_worker.signals.process_finished.connect(self._handle_erase_userdata_result)
        self._current_worker.signals.error.connect(self._handle_error)
        self.thread_pool.start(self._current_worker)
 
    def _handle_erase_userdata_result(self, success: bool, command_args: str):
        """Handles the result of 'fastboot erase userdata'."""
        if self._current_worker:
            self._current_worker.signals.process_finished.disconnect(self._handle_erase_userdata_result)
            self._current_worker.signals.log_message.disconnect(self.log_message)
            self._current_worker.signals.error.disconnect(self._handle_error)
        if not success:
            self.log_message('Failed to erase userdata partition.', QColor('red'))
            self.show_message_box('Erase Failed', 'Failed to erase userdata partition. Please check logs for details.', QMessageBox.Icon.Critical, QMessageBox.StandardButton.Ok)
            self._reset_ui_state()
        else:
            self.log_message('Userdata partition erased.', QColor('green'))
            self._step_flash_super()
        self._current_worker = None
 
    def _step_flash_super(self):
        """Step 5: Flash super.img."""
        self.log_message('Installing system files... This may take several minutes...', QColor('black'))
        super_img_path = os.path.join(os.getcwd(), 'super.img')
        if not os.path.exists(super_img_path):
            error_msg = f'Error: super.img not found at {super_img_path}. Please ensure the file exists.'
            self.log_message(error_msg, QColor('red'))
            self.show_message_box('File Not Found', error_msg, QMessageBox.Icon.Critical, QMessageBox.StandardButton.Ok)
            self._reset_ui_state()
            return
        command = f'flash super "{super_img_path}"'
        self._current_worker = FastbootWorker(command)
        self._current_worker.signals.log_message.connect(self.log_message)
        self._current_worker.signals.process_finished.connect(self._handle_flash_super_result)
        self._current_worker.signals.error.connect(self._handle_error)
        self.thread_pool.start(self._current_worker)
 
    def _handle_flash_super_result(self, success: bool, command_args: str):
        """Handles the result of 'fastboot flash super'."""
        if self._current_worker:
            self._current_worker.signals.process_finished.disconnect(self._handle_flash_super_result)
            self._current_worker.signals.log_message.disconnect(self.log_message)
            self._current_worker.signals.error.disconnect(self._handle_error)
        if not success:
            self.log_message('Failed to flash super.img.', QColor('red'))
            self.show_message_box('Flash Failed', 'Failed to flash super.img. Please check logs for details.', QMessageBox.Icon.Critical, QMessageBox.StandardButton.Ok)
            self._reset_ui_state()
        else:
            self.log_message('super.img flashed successfully.', QColor('green'))
            self._step_reboot()
        self._current_worker = None
 
    def _step_reboot(self):
        """Step 6: Reboot the device."""
        self.log_message('Finalizing process...', QColor('black'))
        self._current_worker = FastbootWorker('reboot')
        self._current_worker.signals.log_message.connect(self.log_message)
        self._current_worker.signals.process_finished.connect(self._handle_reboot_result)
        self._current_worker.signals.error.connect(self._handle_error)
        self.thread_pool.start(self._current_worker)
 
    def _handle_reboot_result(self, success: bool, command_args: str):
        """Handles the result of 'fastboot reboot' and finalizes the process."""
        if self._current_worker:
            self._current_worker.signals.process_finished.disconnect(self._handle_reboot_result)
            self._current_worker.signals.log_message.disconnect(self.log_message)
            self._current_worker.signals.error.disconnect(self._handle_error)
        if not success:
            self.log_message('Failed to reboot device. Please reboot manually.', QColor('orange'))
        else:
            self.log_message('Device rebooted successfully.', QColor('green'))
        self.log_message('\nFRP REMOVAL COMPLETED!', QColor('green'))
        self.log_message('\nIMPORTANT INSTRUCTIONS:', QColor('red'))
        self.log_message('1. PUT PHONE TO DOWNLOAD MODE', QColor('red'))
        self.log_message('2. LONG PRESS VOLUME UP BUTTON TO RELOCK BOOTLOADER', QColor('red'))
        self.log_message('\nPowered By GSMYOGESH', QColor('blue'))
        self.log_message('Contact: +917043259004', QColor('blue'))
        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)
        self.open_website('https://www.gsmyogesh.com')
        self._reset_ui_state()
        self._current_worker = None
 
    def _handle_error(self, error_message: str):
        """Handles errors reported by worker threads."""
        self.log_message(f'An error occurred: {error_message}', QColor('red'))
        self.show_message_box('Error', f'An error occurred during the process: {error_message}', QMessageBox.Icon.Critical, QMessageBox.StandardButton.Ok)
        self._reset_ui_state()
        if self._current_worker:
            self._current_worker.signals.process_finished.disconnect(self._handle_error)
            self._current_worker.signals.log_message.disconnect(self.log_message)
            self._current_worker.signals.error.disconnect(self._handle_error)
        self._current_worker = None
 
    def _reset_ui_state(self):
        """Resets the UI elements to their initial state after a process completes or fails."""
        self.is_process_running = False
        self.remove_frp_button.setEnabled(True)
        self.remove_frp_button.setText('REMOVE FRP')
if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = FRPToolApp()
    window.show()
    sys.exit(app.exec())

Comments

  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎

    
        
  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎

    
        
  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎

    
        
  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎

    
        
  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎

    
        
  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎