Seregon/PkgToolBox

Toolbox for analyzing and editing pkg application files for psp,ps3, ps4 and ps5, includes the most useful functions you might need.

Python/57.3 KB/No license
GraphicUserInterface/widgets/dump_tab.py
1"""
2Dump tab widget for PKG dumping functionality
3"""
4from PyQt5.QtWidgets import (QVBoxLayout, QHBoxLayout, QLabel, QLineEdit,
5 QPushButton, QTextEdit, QFileDialog, QMessageBox,
6 QGroupBox)
7from PyQt5.QtCore import Qt
8from .base_tab import BaseTab
9from packages import PackagePS4
10from Utilities import Logger
11 
12class DumpTab(BaseTab):
13 """Tab for PKG dump operations"""
14
15 def setup_ui(self):
16 """Setup the dump tab UI"""
17 # Output directory selection
18 output_group = QGroupBox("Output Directory")
19 output_layout = QVBoxLayout()
20
21 dir_layout = QHBoxLayout()
22 self.dump_out_entry = QLineEdit()
23 self.dump_out_entry.setPlaceholderText("Select output directory")
24 browse_button = QPushButton("Browse")
25 browse_button.clicked.connect(self.browse_output_directory)
26
27 dir_layout.addWidget(self.dump_out_entry)
28 dir_layout.addWidget(browse_button)
29 output_layout.addLayout(dir_layout)
30 output_group.setLayout(output_layout)
31
32 # Dump button
33 self.dump_button = QPushButton("Dump PKG")
34 self.dump_button.clicked.connect(self.dump_pkg)
35 self.dump_button.setStyleSheet("""
36 QPushButton {
37 background-color: #9b59b6;
38 color: white;
39 font-weight: bold;
40 padding: 12px;
41 border-radius: 6px;
42 font-size: 14px;
43 }
44 QPushButton:hover {
45 background-color: #8e44ad;
46 }
47 QPushButton:disabled {
48 background-color: #95a5a6;
49 }
50 """)
51
52 # Log display
53 log_group = QGroupBox("Dump Log")
54 log_layout = QVBoxLayout()
55 self.dump_log = QTextEdit()
56 self.dump_log.setReadOnly(True)
57 self.dump_log.setMaximumHeight(200)
58 log_layout.addWidget(self.dump_log)
59 log_group.setLayout(log_layout)
60
61 # Add to main layout
62 self.layout.addWidget(output_group)
63 self.layout.addWidget(self.dump_button)
64 self.layout.addWidget(log_group)
65 self.layout.addStretch()
66
67 def browse_output_directory(self):
68 """Browse for output directory"""
69 directory = QFileDialog.getExistingDirectory(
70 self,
71 "Select Output Directory"
72 )
73 if directory:
74 self.dump_out_entry.setText(directory)
75
76 def dump_pkg(self):
77 """Dump PKG contents"""
78 package = self.get_package()
79 if not package:
80 QMessageBox.warning(self, "Warning", "Please load a PKG file first")
81 return
82 
83 output_dir = self.dump_out_entry.text()
84 if not output_dir:
85 QMessageBox.warning(self, "Warning", "Please select an output directory")
86 return
87 
88 try:
89 self.dump_button.setEnabled(False)
90 self.dump_log.append(f"[+] Starting dump to: {output_dir}")
91
92 # For PS4 use shadPKG; fallback to dump
93 if isinstance(package, PackagePS4):
94 try:
95 result = package.extract_via_shadpkg(output_dir)
96 self.dump_log.append(f"[+] shadPKG dump: {result}")
97 except Exception as e:
98 Logger.log_warning(f"shadPKG failed from UI dump, fallback to dump: {e}")
99 self.dump_log.append(f"[-] shadPKG failed, using internal dump: {e}")
100 result = package.dump(output_dir)
101 self.dump_log.append(f"[+] Internal dump: {result}")
102 else:
103 result = package.dump(output_dir)
104 self.dump_log.append(f"[+] Dump completed: {result}")
105 
106 QMessageBox.information(self, "Success", "PKG dumped successfully")
107
108 except Exception as e:
109 error_msg = f"Failed to dump PKG: {str(e)}"
110 self.dump_log.append(f"[-] {error_msg}")
111 QMessageBox.critical(self, "Error", error_msg)
112 finally:
113 self.dump_button.setEnabled(True)
114