def transferPoints(self, other): params = parameters.instance current_data = self.current_data items = self.selectedItems() if len(items) == 0: items = [it for it in self.points.values() if it.arrow is None and it.link is None] new_pt_ids = [] new_pt_pos = [] move_pt_ids = [] move_pt_new_pos = [] if params.estimate: progress = QProgressDialog("Estimating position of the points...", "Abort", 0, len(items), self.parent()) progress.setMinimumDuration(1) size = (params.filter_size, params.filter_size) im1 = image_cache.cache.numpy_array(self.image_path, size) im2 = image_cache.cache.numpy_array(other.image_path, size) for i, it in enumerate(items): pos = self.findPoint(im1, im2, other, it) id = it.pt_id if id in other.points: move_pt_ids.append(id) move_pt_new_pos.append(pos) else: new_pt_ids.append(id) new_pt_pos.append(pos) progress.setValue(i+1) if progress.wasCanceled(): progress.hide() break else: for it in items: id = it.pt_id pos = current_data[id] if id in other.points: move_pt_ids.append(id) move_pt_new_pos.append(pos) else: new_pt_ids.append(id) new_pt_pos.append(pos) if new_pt_ids or move_pt_ids: self.undo_stack.beginMacro("Transfer point(s) from %s to %s" % (self.image_name, other.image_name)) if new_pt_ids: other.planAddPoints(new_pt_ids, new_pt_pos) if move_pt_ids: other.planMovePoints(move_pt_ids, move_pt_new_pos) self.undo_stack.endMacro()
def redo(self): keys = self.receiver.sourceList.elements.keys() progress = QProgressDialog("Storing DataSource elements", QString(), 0, len(keys), self.receiver.sourceList) progress.setWindowTitle("Store All DataSources") progress.setWindowModality(Qt.WindowModal) progress.show() for i in range(len(keys)): ids = keys[i] ds = self.receiver.sourceList.elements[ids] if ds.instance is None: dsEdit = DataSource.DataSource(self.receiver.sourceList) dsEdit.id = ds.id dsEdit.directory = self.receiver.sourceList.directory dsEdit.name = \ self.receiver.sourceList.elements[ds.id].name ds.instance = dsEdit logger.debug("Store %s" % ds.instance.name) try: xml = ds.instance.get() if not self.receiver.configServer.connected: QMessageBox.information( self.receiver, "Connecting to Configuration Server", "Connecting to %s on %s:%s" % (self.receiver.configServer.device, self.receiver.configServer.host, self.receiver.configServer.port)) self.receiver.configServer.connect() self.receiver.disableServer(False) if ds.instance.name: self.receiver.configServer.storeDataSource( ds.instance.dataSourceName, xml) else: self.receiver.configServer.storeDataSource( ds.instance.name, xml) ds.instance.savedXML = xml ds.savedName = ds.name except Exception, e: QMessageBox.warning(self.receiver, "Error in datasource storing", unicode(e)) progress.setValue(i)
def redo(self): keys = self.receiver.componentList.elements.keys() progress = QProgressDialog("Storing Component elements", QString(), 0, len(keys), self.receiver.componentList) progress.setWindowTitle("Store All Components") progress.setWindowModality(Qt.WindowModal) progress.show() for i in range(len(keys)): icp = keys[i] cp = self.receiver.componentList.elements[icp] if cp.instance is None: # self._cpEdit = FieldWg() cpEdit = Component(self.receiver.componentList) cpEdit.id = cp.id cpEdit.directory = self.receiver.componentList.directory cpEdit.name = self.receiver.componentList.elements[cp.id].name cpEdit.createGUI() cpEdit.addContextMenu(self.receiver.contextMenuActions) cpEdit.createHeader() cpEdit.dialog.setWindowTitle("%s [Component]" % cp.name) cp.instance = cpEdit try: cp.instance.merge(False) xml = cp.instance.get() if not self.receiver.configServer.connected: QMessageBox.information( self.receiver, "Connecting to Configuration Server", "Connecting to %s on %s:%s" % (self.receiver.configServer.device, self.receiver.configServer.host, self.receiver.configServer.port)) self.receiver.configServer.connect() self.receiver.disableServer(False) self.receiver.configServer.storeComponent( cp.instance.name, xml) cp.instance.savedXML = xml cp.savedName = cp.name except Exception, e: QMessageBox.warning(self.receiver, "Error in storing the component", unicode(e)) progress.setValue(i)
def generate_font(self): progress = QProgressDialog("", QtCore.QString(), 0, 0, self) progress.setWindowModality(Qt.Qt.WindowModal) progress.setWindowTitle("Generating font...") progress.setLabelText("Generating font...") progress.setMinimumDuration(0) progress.setAutoClose(False) # Thread this because it's slow as hell and we don't want to lock up the GUI. thread = threading.Thread(target=self.__generate_font__) thread.start() while thread.isAlive(): thread.join(THREAD_TIMEOUT) # It has to change by some amount or it won't update and the UI will lock up. progress.setValue(progress.value() - 1) progress.close()
def progress_dialog(progress=0, title='CQFS Progress', label='Running...'): dialog = QProgressDialog() dialog.setWindowTitle(title) dialog.setLabelText(label) dialog.setAutoClose(True) bar = QProgressBar(dialog) bar.setTextVisible(True) bar.setValue(progress) bar.setMaximum(100) dialog.setBar(bar) dialog.setMinimumWidth(300) dialog.show() if int(progress) == 0: bar.setValue(0) return dialog, bar
def start(self): """ To start the rebuild """ snap_util = self.__iface.mapCanvas().snappingUtils() extent = self.__iface.mapCanvas().extent() self.__progressDialog = QProgressDialog() self.__progressDialog.setWindowTitle( QCoreApplication.translate("VDLTools", "Rebuild Index...")) self.__progressDialog.setLabelText( QCoreApplication.translate("VDLTools", "Percentage of indexed layers")) progressBar = QProgressBar(self.__progressDialog) progressBar.setTextVisible(True) cancelButton = QPushButton() cancelButton.setText(QCoreApplication.translate("VDLTools", "Cancel")) cancelButton.clicked.connect(self.kill) self.__progressDialog.setBar(progressBar) self.__progressDialog.setCancelButton(cancelButton) self.__progressDialog.setMinimumWidth(300) self.__progressDialog.show() lcs_list = snap_util.layers() step = 0 self.killed = False for lc in lcs_list: if self.killed: break locator = snap_util.locatorForLayer(lc.layer) if locator.extent() is not None: txt = locator.extent().toString() else: txt = "None" print("old extent : " + txt) print("new extent : " + extent.toString()) locator.setExtent(extent) if not locator.hasIndex(): locator.init() else: locator.rebuildIndex() locator.setExtent(None) progressBar.setValue(100 * step / len(lcs_list)) step += 1 self.__progressDialog.close()
def __init__(self, parent=None, iface=None): """Constructor for import dialog. :param parent: Optional widget to use as parent :type parent: QWidget :param iface: An instance of QGisInterface :type iface: QGisInterface """ QDialog.__init__(self, parent) self.parent = parent self.setupUi(self) self.setWindowTitle(self.tr('InaSAFE OpenStreetMap Downloader')) self.iface = iface self.buildings_url = "http://osm.linfiniti.com/buildings-shp" self.roads_url = "http://osm.linfiniti.com/roads-shp" self.help_context = 'openstreetmap_downloader' # creating progress dialog for download self.progress_dialog = QProgressDialog(self) self.progress_dialog.setAutoClose(False) title = self.tr("InaSAFE OpenStreetMap Downloader") self.progress_dialog.setWindowTitle(title) # Set up context help help_button = self.button_box.button(QtGui.QDialogButtonBox.Help) help_button.clicked.connect(self.show_help) self.show_info() # set up the validator for the file name prefix expression = QRegExp('^[A-Za-z0-9-_]*$') validator = QRegExpValidator(expression, self.filename_prefix) self.filename_prefix.setValidator(validator) # Set Proxy in webpage proxy = get_proxy() self.network_manager = QNetworkAccessManager(self) if proxy is not None: self.network_manager.setProxy(proxy) self.restore_state() self.update_extent()
def dump_script(self): to_dump = self.get_checked([ self.ui.treeFileList.topLevelItem(i) for i in range(self.ui.treeFileList.topLevelItemCount()) ]) if not to_dump: QtGui.QMessageBox.warning( self, "No Selection", "No folders have beens selected to dump.") return out_file = get_save_file(self, self.last_file, "Text files (*.txt)") if out_file == "": return translated = not self.ui.chkUntranslated.isChecked() strip_clt = self.ui.chkStripClt.isChecked() only_voiced = self.ui.chkOnlyVoiced.isChecked() line_numbers = self.ui.chkLineNumbers.isChecked() progress = QProgressDialog("Dumping...", QtCore.QString(), 0, len(to_dump), self) progress.setWindowTitle("Dumping...") progress.setWindowModality(Qt.Qt.WindowModal) progress.setValue(0) progress.setAutoClose(False) progress.setMinimumDuration(0) # print out_file with open(out_file, "wb") as f: for dir in to_dump: progress.setLabelText("Dumping %s..." % dir) f.write( script_to_text(dir, translated, strip_clt, only_voiced, line_numbers).encode("UTF-8")) progress.setValue(progress.value() + 1) progress.close() self.last_file = out_file
def addMediaFile(self): path = '.' filename = self.labeltool.getCurrentFilename() if (filename is not None) and (len(filename) > 0): path = QFileInfo(filename).path() image_types = [ '*.jpg', '*.bmp', '*.png', '*.pgm', '*.ppm', '*.tiff', '*.tif', '*.gif' ] video_types = ['*.mp4', '*.mpg', '*.mpeg', '*.avi', '*.mov', '*.vob'] format_str = ' '.join(image_types + video_types) fnames = QFileDialog.getOpenFileNames( self, "%s - Add Media File" % APP_NAME, path, "Media files (%s)" % (format_str, )) item = None numFiles = len(fnames) progress_bar = QProgressDialog('Importing files...', 'Cancel import', 0, numFiles, self) for fname, c in zip(fnames, range(numFiles)): if len(str(fname)) == 0: continue fname = str(fname) if os.path.isabs(fname): fname = os.path.relpath(fname, str(path)) for pattern in image_types: if fnmatch.fnmatch(fname.lower(), pattern): item = self.labeltool.addImageFile(fname) progress_bar.setValue(c) if item is None: return self.labeltool.addVideoFile(fname) progress_bar.close() return item
def process(self): dirs = sorted(glob.glob(self.rootDir + '\\*_mask*')) total2Proc = 100 progress = QProgressDialog("Tracking leaves...", "Abort", 0, total2Proc, self) progress.setWindowTitle("Batch Process") progress.setWindowModality(QtCore.Qt.WindowModal) try: self.particleTracker(dirs, progressBar=progress) progress.setValue(total2Proc) qm = QtGui.QMessageBox qm.information(self, 'Completed', 'Leaf labels were changed.') except Exception as e: progress.cancel() qm = QtGui.QMessageBox qm.information(self, 'Error', '{}'.format(e)) raise e
def run(self): """Run a thread""" i = 0 progressDialog = QProgressDialog(QString(), QString(), 0, 100) #progressDialog.setLabelText(self.__message) #progressDialog.setWindowTitle("Wait...") #progressDialog.setRange(0, 10000) #print 'Max',progressDialog.maximum() sleepingTime = 0 #gLogger.info('Thread run') while (not self.__stoped): i = i + 1 if i == progressDialog.maximum(): sleepingTime = 1 i = 0 #progressDialog.setLabelText(self.tr(self.__message)) progressDialog.setValue(i) #QCoreApplication.processEvents() #qApp.processEvents() time.sleep(sleepingTime) self.__stoped = False
def progress(data, *args): """ A very pythonic progress dialog. Iterate over progress(iterator) instead of iterator. That’s pretty much it. """ # found at http://lateral.netmanagers.com.ar/weblog/posts/BB917.html # © 2000-2012 Roberto Alsina # Creative Commons Attribution-NonCommercial-ShareAlike 2.5 licence # http://creativecommons.org/licenses/by-nc-sa/2.5/ it = iter(data) widget = QProgressDialog(*args + (0, it.__length_hint__())) c = 0 for v in it: QCoreApplication.instance().processEvents() if widget.wasCanceled(): raise StopIteration c += 1 widget.setValue(c) yield (v)
def __init__(self, iface): """Constructor.""" QtGui.QDialog.__init__(self) # Set up the user interface from Designer. # After setupUI you can access any designer object by doing # self.<objectname>, and you can use autoconnect slots - see # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.setupUi(self) self.iface = iface if len(config.srv_list['servers']) > 0: self.btnEdit_Serv.setEnabled(True) self.btnDelete_Serv.setEnabled(True) self.updateServerListing() self.myWCPS = WCPSUtil() # creating progress dialog for download self.progress_dialog = QProgressDialog(self) self.progress_dialog.setAutoClose(True) # False # was set originally title = self.tr("WCPS Client 1.0") self.progress_dialog.setWindowTitle(title) self.tabWidget_WCPSClient.setCurrentIndex(0)
def do_update_with_gui(self, limit): from PyQt4.QtGui import QProgressDialog, QApplication from PyQt4.QtCore import Qt from guidata import qapplication dlg = QProgressDialog("pubchem update", "Cancel", 0, 100) dlg.setWindowModality(Qt.WindowModal) dlg.show() dlg.setValue(0) QApplication.processEvents() class Callback(object): def __init__(self): self.abort = False def __call__(self, i, imax): if dlg.wasCanceled(): raise Exception("aborted") dlg.setValue(int(i * 100 / imax)) QApplication.processEvents() self.do_update(500, Callback())
def write_data_to_file(self, open_mode): progressDialog = QProgressDialog() progressDialog.setModal(True) progressDialog.setLabelText(self.tr('Guardando...')) progressDialog.setMaximum(8) progressDialog.setCancelButton(None) progressDialog.show() try: # File is closed automatically even on error with open(unicode(self.filename), open_mode) as file_obj: for count, elem_edit in enumerate(self.lineEdits_list, 1): file_obj.write(''.join([str(elem_edit[0].text()), '\n'])) file_obj.write(''.join([str(elem_edit[1].text()), '\n'])) file_obj.write(''.join([str(elem_edit[2].text()), '\n'])) file_obj.write(''.join([str(elem_edit[3].text()), '\n'])) file_obj.write(''.join([str(elem_edit[4].text()), '\n'])) file_obj.write(''.join([str(elem_edit[5].text()), '\n'])) file_obj.write(''.join([str(elem_edit[6].text()), '\n'])) file_obj.write(''.join([str(elem_edit[7].text()), '\n'])) file_obj.write(''.join([str(elem_edit[8].text()), '\n'])) file_obj.write(''.join([str(elem_edit[9].text()), '\n'])) file_obj.write(''.join([str(elem_edit[10].text()), '\n'])) file_obj.write(''.join([str(elem_edit[11].text()), '\n'])) progressDialog.setValue(count) except (IOError, OSError): progressDialog.close() messageBox = QMessageBox(self) messageBox.setStyleSheet( 'QMessageBox QLabel {font: bold 14pt "Cantarell";}') messageBox.setWindowTitle(self.tr('Error')) messageBox.setText(self.tr('Error al guardar')) messageBox.setStandardButtons(QMessageBox.Ok) messageBox.setIcon(QMessageBox.Critical) messageBox.exec_() else: self.statusBar1.showMessage(self.tr('Guardado'), 3000)
def __init__(self, parent=None, iface=None): """Constructor for import dialog. .. versionadded: 3.3 :param parent: Optional widget to use as parent :type parent: QWidget :param iface: An instance of QGisInterface :type iface: QGisInterface """ QDialog.__init__(self, parent) self.parent = parent self.setupUi(self) self.setWindowTitle(self.tr('PetaJakarta Downloader')) self.iface = iface # creating progress dialog for download self.progress_dialog = QProgressDialog(self) self.progress_dialog.setAutoClose(False) title = self.tr('PetaJakarta Downloader') self.progress_dialog.setWindowTitle(title) # Set up things for context help self.help_button = self.button_box.button(QtGui.QDialogButtonBox.Help) # Allow toggling the help button self.help_button.setCheckable(True) self.help_button.toggled.connect(self.help_toggled) self.main_stacked_widget.setCurrentIndex(1) # set up the validator for the file name prefix expression = QRegExp('^[A-Za-z0-9-_]*$') validator = QRegExpValidator(expression, self.filename_prefix) self.filename_prefix.setValidator(validator) self.time_stamp = None self.restore_state()
def menu_file_save_stack(self): "Processes the entire current stack, and saves as a new name" name = QtGui.QInputDialog.getText( None, "Enter Filename", "Enter an output filename for the entire processed particle stack (not just the displayed images)." ) if not name[1]: return # canceled allfilt = " ".join([i.getAsProc() for i in self.processorlist]) n = EMUtil.get_image_count(self.datafile) from PyQt4.QtGui import QProgressDialog progressdialog = QProgressDialog("Processing Images", "Abort", 0, n, self) progressdialog.setMinimumDuration(1000) e = E2init( ["e2proc2d.py", self.datafile, str(name[0]), allfilt] ) # we don't actually run this program, since we couldn't have a progress dialog easo;y then pp = [i.processorParms() for i in self.processorlist] for i in xrange(n): im = EMData(self.datafile, i) QtGui.qApp.processEvents() for p in pp: im.process_inplace(p[0], p[1]) im.write_image(str(name[0]), i) progressdialog.setValue(i + 1) if progressdialog.wasCanceled(): print("Processing Cancelled") break progressdialog.setValue(n) E2end(e)
def doExport(self, model, filter): # print model.rowCount() if model.rowCount() < 1: QMessageBox.warning(self, 'warning', "导出内容为空") return fileName = QFileDialog.getSaveFileName(self, self.tr('Save Contents'), '', u"csv文件 (*.csv)") if not fileName: return if platform.system() == 'Windows': fileName = str(fileName.toUtf8()).decode('utf-8').encode('gbk') else: fileName = str(fileName.toUtf8()) if filter is not None: totalCount = len(filter) else: totalCount = model.rowCount() self.progressDialog = QProgressDialog( u"正在导出 (%d/%d)" % (0, totalCount), u"取消", 0, totalCount, self) thread = threading.Thread(target=self.exportThreadFunc, args=(model, filter, fileName)) thread.setDaemon(True) thread.start()
def __init__(self, parent=None, iface=None): """Constructor.""" QDialog.__init__(self, parent) # Set up the user interface from Designer. # After setupUI you can access any designer object by doing # self.<objectname>, and you can use autoconnect slots - see # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.parent = parent self.iface = iface self.setupUi(self) # Setting up progress window self.progress_dialog = QProgressDialog(self) self.progress_dialog.setAutoClose(False) title = self.tr('Progress') self.progress_dialog.setWindowTitle(title) self.restore_state() self.canvas = iface.mapCanvas()
def __init__(self, parent=None, **kwargs): super().__init__(parent, **kwargs) self.setLayout(QVBoxLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self.addonwidget = AddonManagerWidget() self.layout().addWidget(self.addonwidget) buttons = QDialogButtonBox(orientation=Qt.Horizontal, standardButtons=QDialogButtonBox.Ok | QDialogButtonBox.Cancel) buttons.accepted.connect(self.__accepted) buttons.rejected.connect(self.reject) self.layout().addWidget(buttons) self._executor = concurrent.futures.ThreadPoolExecutor(max_workers=1) if AddonManagerDialog._packages is None: self._f_pypi_addons = self._executor.submit(list_pypi_addons) else: self._f_pypi_addons = concurrent.futures.Future() self._f_pypi_addons.set_result(AddonManagerDialog._packages) self._f_pypi_addons.add_done_callback( method_queued(self._set_packages, (object, ))) self.__progress = QProgressDialog( self, Qt.Sheet, minimum=0, maximum=0, labelText=self.tr("Retrieving package list"), sizeGripEnabled=False, ) self.__progress.rejected.connect(self.reject) self.__thread = None self.__installer = None
def addScanNumbers(self): result = self.range_dialog.exec_() if result == QDialog.Accepted: text = self.range_ui.range_edit.text() if text: not_found = [] numbers = mythen.parse_range_list(text) year, visit = self.getYearAndVisit() progress = QProgressDialog( "Locating scan files from numbers...", "Stop", 0, len(numbers), self) progress.setWindowModality(Qt.WindowModal) progress.forceShow() progress.setValue(0) for n in numbers: progress.setValue(progress.value() + 1) if progress.wasCanceled(): break files = mythen.find_mythen_files( n, visit=visit, year=year) # FIXME needs to be in separate thread(!) if files: files = [f for f in files if f not in self.scans] self.scans.extend(files) self.scans_model.setStringList(self.scans) else: not_found.append(n) progress.setValue(progress.maximum()) if not_found: error = QErrorMessage(self) msg = "The following numbers were not found: " for n in not_found: msg = msg + str(n) + ", " error.showMessage(msg[:-2])
def processScans(self): base = self.getBaseDirectory(True, self.scans) out_file, _selectedfilter = getsavefilename( caption= "Choose file for summary output - the directory is also used for rebinned and/or summed scans", basedir=path.join(base, 'summary.txt')) if not out_file: return progress = QProgressDialog("Process scans...", "Stop", 0, 2 * len(self.scans), self) progress.setWindowModality(Qt.WindowModal) progress.forceShow() progress.setValue(0) from mythen import load_all, process_and_save, report_processing data, files = load_all(self.scans, None, None, progress=progress) summed = True rebinned = True if self.rebin_rb.isChecked(): summed = False elif self.sum_rb.isChecked(): rebinned = False process_and_save(data, self.angle_spinbox.value(), self.delta_spinbox.value(), rebinned, summed, files, out_file, progress=progress, weights=self.weight_cb.isChecked(), ext='.xye') report_processing(files, out_file, self.angle_spinbox.value(), [self.delta_spinbox.value()]) progress.setValue(progress.maximum())
def __init__(self, parent=None, iface=None): """Constructor for import dialog. :param parent: Optional widget to use as parent :type parent: QWidget :param iface: An instance of QGisInterface :type iface: QGisInterface """ QDialog.__init__(self, parent) self.parent = parent self.setupUi(self) self.setWindowTitle(self.tr('InaSAFE OpenStreetMap Downloader')) self.iface = iface self.url = "http://osm.linfiniti.com/buildings-shp" # creating progress dialog for download self.progressDialog = QProgressDialog(self) self.progressDialog.setAutoClose(False) myTitle = self.tr("InaSAFE OpenStreetMap Downloader") self.progressDialog.setWindowTitle(myTitle) # Set up context help helpButton = self.buttonBox.button(QtGui.QDialogButtonBox.Help) QtCore.QObject.connect(helpButton, QtCore.SIGNAL('clicked()'), self.show_help) self.show_info() # Set Proxy in webpage proxy = get_proxy() self.network_manager = QNetworkAccessManager(self) if not proxy is None: self.network_manager.setProxy(proxy) self.restore_state() self.update_extent()
def import_umdimage(src, dst, convert_png=True, propogate=True, parent=None): src = os.path.abspath(src) dst = os.path.abspath(dst) if os.path.normcase(src) == os.path.normcase(dst): raise ValueError( "Cannot import %s. Source and destination directories are the same." % src) answer = QtGui.QMessageBox.question( parent, "Import Directory", "Importing directory:\n\n" + src + "\n\n" + "into directory:\n\n" + dst + "\n\n" + "Any affected files will be backed up. Proceed?", buttons=QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, defaultButton=QtGui.QMessageBox.No) if answer == QtGui.QMessageBox.No: return progress = QProgressDialog("Finding files...", "Cancel", 0, 1, parent) progress.setWindowTitle("Importing...") progress.setWindowModality(Qt.Qt.WindowModal) progress.setValue(0) progress.setAutoClose(False) progress.setMinimumDuration(0) if parent: width = parent.width() height = parent.height() x = parent.x() y = parent.y() else: width = 1920 height = 1080 x = 0 y = 0 progress.setMaximum(0) progress.setValue(0) # The raw list of files we're importing. files = [] # A list of lists, including all dupes of the files being imported, too. affected_files = [] file_count = 0 dupe_base = "umdimage" tmp = tempfile.mkdtemp(prefix="sdse-") seen_groups = [] count = 0 last_update = time.time() for file in list_all_files(src): if progress.wasCanceled(): break # Strip our base directory, so we have just a relative file list. file = os.path.normpath(os.path.normcase(file[len(src) + 1:])) files.append(file) count += 1 if time.time() - last_update > MIN_INTERVAL or count % 25 == 0: last_update = time.time() progress.setLabelText("Finding files...\n" + file) # progress.setValue(count) progress.setValue(progress.value() ^ 1) # Re-center the dialog. progress_w = progress.geometry().width() progress_h = progress.geometry().height() new_x = x + ((width - progress_w) / 2) new_y = y + ((height - progress_h) / 2) progress.move(new_x, new_y) affected_files.append([]) if os.path.splitext( file)[1] == ".png" and convert_png and file not in SKIP_CONV: file = os.path.splitext(file)[0] + ".gim" if propogate: file_group = _DUPE_DB.group_from_file(os.path.join( dupe_base, file)) else: file_group = None if file_group in seen_groups: continue # If there are no dupes, just add this file. if file_group == None: affected_files[-1].append(file) file_count += 1 continue seen_groups.append(file_group) for dupe in _DUPE_DB.files_in_group(file_group): # Minus the "umdimage" part dupe = dupe[len(dupe_base) + 1:] affected_files[-1].append(dupe) file_count += 1 progress.setValue(0) progress.setMaximum(file_count) # Make a backup first. backup_dir = None count = 0 for file_set in affected_files: if progress.wasCanceled(): break for file in file_set: if progress.wasCanceled(): break count += 1 if time.time() - last_update > MIN_INTERVAL or count % 25 == 0: last_update = time.time() progress.setLabelText("Backing up...\n" + file) progress.setValue(count) # Re-center the dialog. progress_w = progress.geometry().width() progress_h = progress.geometry().height() new_x = x + ((width - progress_w) / 2) new_y = y + ((height - progress_h) / 2) progress.move(new_x, new_y) # It's perfectly possible we want to import some files that # don't already exist. Such as when importing a directory # with added lines. if not os.path.isfile(os.path.join(dst, file)): continue backup_dir = backup_files(dst, [file], suffix="_IMPORT", backup_dir=backup_dir) progress.setValue(0) # And now do our importing. import_all_new = False skip_all_new = False count = 0 for index, src_file in enumerate(files): if progress.wasCanceled(): break if os.path.splitext(src_file)[ 1] == ".png" and convert_png and src_file not in SKIP_CONV: tmp_src_file = os.path.join(tmp, os.path.basename(src_file)) tmp_src_file = os.path.splitext(tmp_src_file)[0] + ".gim" quantize = QuantizeType.auto for regex, q in FORCE_QUANTIZE: if not regex.search(src_file) == None: quantize = q break _CONV.png_to_gim(os.path.join(src, src_file), tmp_src_file, quantize) src_file = tmp_src_file else: src_file = os.path.join(src, src_file) for file in affected_files[index]: if progress.wasCanceled(): break dst_file = os.path.join(dst, file) count += 1 # if count % 25 == 0: if time.time() - last_update > MIN_INTERVAL or count % 25 == 0: last_update = time.time() progress.setLabelText("Importing...\n" + file) progress.setValue(count) # Re-center the dialog. progress_w = progress.geometry().width() progress_h = progress.geometry().height() new_x = x + ((width - progress_w) / 2) new_y = y + ((height - progress_h) / 2) progress.move(new_x, new_y) # We may be allowed to import files that don't exist, but we're # going to ask them about it anyway. if not os.path.isfile(dst_file): if skip_all_new: continue if not import_all_new: answer = QtGui.QMessageBox.question( parent, "File Not Found", "File:\n\n" + file + "\n\n" + "does not exist in the target directory. Import anyway?", buttons=QtGui.QMessageBox.Yes | QtGui.QMessageBox.YesToAll | QtGui.QMessageBox.No | QtGui.QMessageBox.NoToAll, defaultButton=QtGui.QMessageBox.No) if answer == QtGui.QMessageBox.YesToAll: import_all_new = True skip_all_new = False elif answer == QtGui.QMessageBox.NoToAll: skip_all_new = True import_all_new = False continue elif answer == QtGui.QMessageBox.No: continue basedir = os.path.dirname(dst_file) if not os.path.isdir(basedir): os.makedirs(basedir) shutil.copy2(src_file, dst_file) shutil.rmtree(tmp) progress.close()
def export_umdimage2(src, dst, convert_gim=True, unique=False, parent=None): src = os.path.abspath(src) dst = os.path.abspath(dst) if os.path.normcase(src) == os.path.normcase(dst): raise ValueError( "Cannot export %s. Source and destination directories are the same." % src) answer = QtGui.QMessageBox.question( parent, "Export Directory", "Exporting directory:\n\n" + src + "\n\n" + "into directory:\n\n" + dst + "\n\n" + "Proceed?", buttons=QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, defaultButton=QtGui.QMessageBox.No) if answer == QtGui.QMessageBox.No: return progress = QProgressDialog("Exporting...", "Cancel", 0, 0, parent) progress.setWindowTitle("Exporting...") progress.setWindowModality(Qt.Qt.WindowModal) progress.setValue(0) progress.setAutoClose(False) progress.setMinimumDuration(0) if unique: tmp_dst = tempfile.mkdtemp(prefix="sdse-") else: tmp_dst = dst seen_groups = [] for pak in glob.iglob(os.path.join(src, "bg_*.pak")): if progress.wasCanceled(): break pak_name = os.path.basename(pak) out_dir = os.path.join(tmp_dst, pak_name) progress.setLabelText("Extracting:\n" + pak) thread = threading.Thread(target=extract_model_pak, args=(pak, out_dir, convert_gim)) thread.start() while thread.isAlive(): thread.join(MIN_INTERVAL) progress.setValue(progress.value() ^ 1) if progress.wasCanceled(): progress.setLabelText("Canceling...") if progress.wasCanceled(): break if unique: for img in list_all_files(out_dir): img_base = img[len(tmp_dst) + 1:] dupe_name = os.path.splitext(img_base)[0] + ".gim" dupe_name = os.path.join("umdimage2", dupe_name) dupe_name = os.path.normpath(os.path.normcase(dupe_name)) group = _DUPE_DB.group_from_file(dupe_name) if group in seen_groups: continue if not group == None: seen_groups.append(group) dst_file = os.path.join(dst, img_base) dst_dir = os.path.dirname(dst_file) try: os.makedirs(dst_dir) except: pass shutil.copy2(img, dst_file) shutil.rmtree(out_dir) if unique: shutil.rmtree(tmp_dst) progress.close()
def export_umdimage(src, dst, convert_gim=True, unique=False, parent=None): src = os.path.abspath(src) dst = os.path.abspath(dst) if os.path.normcase(src) == os.path.normcase(dst): raise ValueError( "Cannot export %s. Source and destination directories are the same." % src) answer = QtGui.QMessageBox.question( parent, "Export Directory", "Exporting directory:\n\n" + src + "\n\n" + "into directory:\n\n" + dst + "\n\n" + "Proceed?", buttons=QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, defaultButton=QtGui.QMessageBox.No) if answer == QtGui.QMessageBox.No: return progress = QProgressDialog("Exporting...", "Cancel", 0, 0, parent) progress.setWindowTitle("Exporting...") progress.setWindowModality(Qt.Qt.WindowModal) progress.setValue(0) progress.setAutoClose(False) progress.setMinimumDuration(0) if parent: width = parent.width() height = parent.height() x = parent.x() y = parent.y() else: width = 1920 height = 1080 x = 0 y = 0 seen_groups = [] count = 0 last_update = time.time() progress.setMaximum(60000) for filename in list_all_files(src): if progress.wasCanceled(): break count += 1 if time.time() - last_update > MIN_INTERVAL or count % 25 == 0: last_update = time.time() progress.setLabelText("Exporting...\n" + filename) progress.setValue(count) # Re-center the dialog. progress_w = progress.geometry().width() progress_h = progress.geometry().height() new_x = x + ((width - progress_w) / 2) new_y = y + ((height - progress_h) / 2) progress.move(new_x, new_y) base_name = filename[len(src) + 1:] if unique: dupe_name = os.path.join("umdimage", base_name) dupe_name = os.path.normpath(os.path.normcase(dupe_name)) group = _DUPE_DB.group_from_file(dupe_name) if group in seen_groups: continue if not group == None: seen_groups.append(group) dst_file = os.path.join(dst, base_name) dst_dir = os.path.dirname(dst_file) ext = os.path.splitext(dst_file)[1].lower() try: os.makedirs(dst_dir) except: pass if ext == ".gim" and convert_gim: dst_file = os.path.splitext(dst_file)[0] + ".png" _CONV.gim_to_png(filename, dst_file) else: shutil.copy2(filename, dst_file) progress.close()
def import_umdimage2(src, dst, convert_png=True, propogate=True, parent=None): src = os.path.abspath(src) dst = os.path.abspath(dst) if os.path.normcase(src) == os.path.normcase(dst): raise ValueError( "Cannot import %s. Source and destination directories are the same." % src) answer = QtGui.QMessageBox.question( parent, "Import Directory", "Importing directory:\n\n" + src + "\n\n" + "into directory:\n\n" + dst + "\n\n" + "Any affected files will be backed up. Proceed?", buttons=QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, defaultButton=QtGui.QMessageBox.No) if answer == QtGui.QMessageBox.No: return progress = QProgressDialog("Importing...", "Cancel", 0, 0, parent) progress.setWindowTitle("Importing...") progress.setWindowModality(Qt.Qt.WindowModal) progress.setValue(0) progress.setAutoClose(False) progress.setMinimumDuration(0) tmp_dst = tempfile.mkdtemp(prefix="sdse-") backup_dir = None for pak in glob.iglob(os.path.join(src, "bg_*.pak")): if progress.wasCanceled(): break pak_name = os.path.basename(pak) backup_dir = backup_files(dst, [pak_name], suffix="_IMPORT", backup_dir=backup_dir) # If we have a regular file with the bg_*.pak name, then just drop it in. if os.path.isfile(pak): progress.setLabelText("Importing:\n" + pak_name) progress.setValue(progress.value() ^ 1) shutil.copy2(pak, os.path.join(dst, pak_name)) # Otherwise, if it's a directory, insert all the textures we find # into the target bg_*.pak file. elif os.path.isdir(pak): for image in list_all_files(pak): if progress.wasCanceled(): break ext = os.path.splitext(image)[1].lower() if ext == ".png" and not convert_png: continue base_name = image[len(src) + 1:] dst_files = [] if propogate: dupe_name = os.path.splitext(base_name)[0] + ".gim" dupe_name = os.path.join("umdimage2", dupe_name) dupe_name = os.path.normpath(os.path.normcase(dupe_name)) dupes = _DUPE_DB.files_in_same_group(dupe_name) if dupes == None: dupes = [dupe_name] for dupe in dupes: dst_file = dupe[10:] # chop off the "umdimage2/" dst_file = os.path.splitext( dst_file)[0] + ext # original extension dst_file = os.path.join(tmp_dst, dst_file) dst_files.append(dst_file) else: dst_files = [os.path.join(tmp_dst, base_name)] for dst_file in dst_files: try: os.makedirs(os.path.dirname(dst_file)) except: pass shutil.copy(image, dst_file) if progress.wasCanceled(): break progress.setLabelText("Inserting textures into:\n" + pak_name) progress.setValue(progress.value() ^ 1) pak_dir = os.path.join(tmp_dst, pak_name) pak_file = os.path.join(dst, pak_name) # If we didn't copy anything over, just move on. if not os.path.isdir(pak_dir): continue thread = threading.Thread(target=insert_textures, args=(pak_dir, pak_file)) thread.start() while thread.isAlive(): thread.join(MIN_INTERVAL) progress.setValue(progress.value() ^ 1) if progress.wasCanceled(): progress.setLabelText("Canceling...") shutil.rmtree(tmp_dst) progress.close()
def import_labeling_layer(labelLayer, labelingSlots, parent_widget=None): """ Prompt the user for layer import settings, and perform the layer import. :param labelLayer: The top label layer source :param labelingSlots: An instance of LabelingGui.LabelingSlots :param parent_widget: The Qt GUI parent object """ writeSeeds = labelingSlots.labelInput assert isinstance( writeSeeds, lazyflow.graph.Slot), "slot is of type %r" % (type(writeSeeds)) opLabels = writeSeeds.getRealOperator() assert isinstance(opLabels, lazyflow.graph.Operator ), "slot's operator is of type %r" % (type(opLabels)) recentlyImported = PreferencesManager().get('labeling', 'recently imported') mostRecentProjectPath = PreferencesManager().get('shell', 'recently opened') mostRecentImageFile = PreferencesManager().get('DataSelection', 'recent image') if recentlyImported: defaultDirectory = os.path.split(recentlyImported)[0] elif mostRecentProjectPath: defaultDirectory = os.path.split(mostRecentProjectPath)[0] elif mostRecentImageFile: defaultDirectory = os.path.split(mostRecentImageFile)[0] else: defaultDirectory = os.path.expanduser('~') fileNames = DataSelectionGui.getImageFileNamesToOpen( parent_widget, defaultDirectory) fileNames = map(str, fileNames) if not fileNames: return PreferencesManager().set('labeling', 'recently imported', fileNames[0]) try: # Initialize operators opImport = OpInputDataReader(parent=opLabels.parent) opCache = OpArrayCache(parent=opLabels.parent) opMetadataInjector = OpMetadataInjector(parent=opLabels.parent) opReorderAxes = OpReorderAxes(parent=opLabels.parent) # Set up the pipeline as follows: # # opImport --> opCache --> opMetadataInjector --------> opReorderAxes --(inject via setInSlot)--> labelInput # / / # User-specified axisorder labelInput.meta.axistags opImport.WorkingDirectory.setValue(defaultDirectory) opImport.FilePath.setValue(fileNames[0] if len(fileNames) == 1 else os.path.pathsep.join(fileNames)) assert opImport.Output.ready() opCache.blockShape.setValue(opImport.Output.meta.shape) opCache.Input.connect(opImport.Output) assert opCache.Output.ready() opMetadataInjector.Input.connect(opCache.Output) metadata = opCache.Output.meta.copy() opMetadataInjector.Metadata.setValue(metadata) opReorderAxes.Input.connect(opMetadataInjector.Output) # Transpose the axes for assignment to the labeling operator. opReorderAxes.AxisOrder.setValue(writeSeeds.meta.getAxisKeys()) # We'll show a little window with a busy indicator while the data is loading busy_dlg = QProgressDialog(parent=parent_widget) busy_dlg.setLabelText("Importing Label Data...") busy_dlg.setCancelButton(None) busy_dlg.setMinimum(100) busy_dlg.setMaximum(100) def close_busy_dlg(*args): QApplication.postEvent(busy_dlg, QCloseEvent()) # Load the data from file into our cache # When it's done loading, close the progress dialog. req = opCache.Output[:] req.notify_finished(close_busy_dlg) req.notify_failed(close_busy_dlg) req.submit() busy_dlg.exec_() readData = req.result maxLabels = len(labelingSlots.labelNames.value) # Can't use return_counts feature because that requires numpy >= 1.9 #unique_read_labels, readLabelCounts = numpy.unique(readData, return_counts=True) # This does the same as the above, albeit slower, and probably with more ram. unique_read_labels = numpy.unique(readData) readLabelCounts = numpy.bincount(readData.flat)[unique_read_labels] labelInfo = (maxLabels, (unique_read_labels, readLabelCounts)) del readData # Ask the user how to interpret the data. settingsDlg = LabelImportOptionsDlg(parent_widget, fileNames, opMetadataInjector.Output, labelingSlots.labelInput, labelInfo) def handle_updated_axes(): # The user is specifying a new interpretation of the file's axes updated_axisorder = str(settingsDlg.axesEdit.text()) metadata = opMetadataInjector.Metadata.value.copy() metadata.axistags = vigra.defaultAxistags(updated_axisorder) opMetadataInjector.Metadata.setValue(metadata) settingsDlg.axesEdit.editingFinished.connect(handle_updated_axes) dlg_result = settingsDlg.exec_() if dlg_result != LabelImportOptionsDlg.Accepted: return # Get user's chosen label mapping from dlg labelMapping = settingsDlg.labelMapping # Get user's chosen offsets. # Offsets in dlg only include the file axes, not the 5D axes expected by the label input, # so expand them to full 5D axes_5d = opReorderAxes.Output.meta.getAxisKeys() tagged_offsets = collections.OrderedDict( zip(axes_5d, [0] * len(axes_5d))) tagged_offsets.update( dict( zip(opMetadataInjector.Output.meta.getAxisKeys(), settingsDlg.imageOffsets))) imageOffsets = tagged_offsets.values() # Optimization if mapping is identity if labelMapping.keys() == labelMapping.values(): labelMapping = None # This will be fast (it's already cached) label_data = opReorderAxes.Output[:].wait() # Map input labels to output labels if labelMapping: # There are other ways to do a relabeling (e.g skimage.segmentation.relabel_sequential) # But this supports potentially huge values of unique_read_labels (in the billions), # without needing GB of RAM. mapping_indexes = numpy.searchsorted(unique_read_labels, label_data) new_labels = numpy.array( [labelMapping[x] for x in unique_read_labels]) label_data[:] = new_labels[mapping_indexes] label_roi = numpy.array(roiFromShape(opReorderAxes.Output.meta.shape)) label_roi += imageOffsets label_slice = roiToSlice(*label_roi) writeSeeds[label_slice] = label_data finally: opReorderAxes.cleanUp() opMetadataInjector.cleanUp() opCache.cleanUp() opImport.cleanUp()
def copy_gfx(self): gfx_dir = os.path.join(self.editor_data_dir, "gfx") if os.path.isdir(gfx_dir): shutil.rmtree(gfx_dir) os.makedirs(gfx_dir) progress = QProgressDialog("", "Abort", 0, 0, self) progress.setWindowTitle("Copying GFX...") progress.setWindowModality(Qt.Qt.WindowModal) progress.setMinimumDuration(0) progress.setValue(0) progress.setAutoClose(False) progress.setLabelText("Setting up GFX dir.") progress.setMaximum(5) progress.setValue(0) # Extract the images we can't just take directly from the game's data. gfx_bin = zipfile.ZipFile("data/gfx_base.bin", "r") progress.setValue(1) gfx_enc = gfx_bin.open("gfx_base.bin") progress.setValue(2) gfx_dec = cStringIO.StringIO() base64.decode(gfx_enc, gfx_dec) progress.setValue(3) gfx_base = zipfile.ZipFile(gfx_dec, "r") progress.setValue(4) gfx_base.extractall(gfx_dir) progress.setValue(5) gfx_base.close() gfx_dec.close() gfx_enc.close() gfx_bin.close() # We can mostly loop this. gfx_data = [ ("ammo", "kotodama_icn_???.gim"), ("bgd", "bgd_???.gim"), ("cutin", "cutin_icn_???.gim"), ("events", "gallery_icn_???.gim"), ("movies", "bin_movie_gallery_l.pak/0000/000[1789].gim"), ("movies", "bin_movie_gallery_l.pak/0000/00[123]?.gim"), ("nametags", "tex_system.pak/00[12]?.gim"), ("nametags", "tex_system.pak/003[0123456].gim"), ("presents", "present_icn_???.gim"), ("sprites", "bustup_??_??.gim"), ("sprites", "stand_??_??.gmo"), ] for (dir, file_glob) in gfx_data: out_dir = os.path.join(gfx_dir, dir) files = glob.glob(os.path.join(self.umdimage_dir, file_glob)) progress.setLabelText("Copying %s." % dir) progress.setMaximum(len(files)) progress.setValue(0) if not os.path.isdir(out_dir): os.makedirs(out_dir) for i, image in enumerate(files): if i % 10 == 0: progress.setValue(i) if progress.wasCanceled(): return src = image dest = os.path.join(out_dir, os.path.basename(src)) shutil.copy(src, dest) progress.setValue(len(files)) progress.setLabelText("Copying font.") progress.setMaximum(4) progress.setValue(0) # The font we have to get from umdimage2. font_dir = os.path.join(gfx_dir, "font") if not os.path.isdir(font_dir): os.makedirs(font_dir) progress.setValue(1) # And convert to PNG with an alpha channel so our editor can use it. font1 = font_bmp_to_alpha(os.path.join(self.umdimage2_dir, "font.pak", "0000.bmp")) progress.setValue(2) font2 = font_bmp_to_alpha(os.path.join(self.umdimage2_dir, "font.pak", "0002.bmp")) progress.setValue(3) font1.save(os.path.join(font_dir, "Font01.png")) font2.save(os.path.join(font_dir, "Font02.png")) shutil.copy(os.path.join(self.umdimage2_dir, "font.pak", "0001.font"), os.path.join(font_dir, "Font01.font")) shutil.copy(os.path.join(self.umdimage2_dir, "font.pak", "0003.font"), os.path.join(font_dir, "Font02.font")) progress.setValue(4) # And then the flash files. This'll be fun. flash_dir = os.path.join(gfx_dir, "flash") if not os.path.isdir(flash_dir): os.makedirs(flash_dir) # Because there's so many in so many different places, I just stored a list # of the flash files we need in the gfx_base archive. So let's load that. with open(os.path.join(gfx_dir, "fla.txt"), "rb") as fla: fla_list = fla.readlines() progress.setLabelText("Copying flash.") progress.setMaximum(len(fla_list)) progress.setValue(0) for i, flash in enumerate(fla_list): if i % 10 == 0: progress.setValue(i) if progress.wasCanceled(): return flash = flash.strip() fla_name = flash[:7] # fla_### src = os.path.join(self.umdimage_dir, flash) dest = os.path.join(flash_dir, "%s.gim" % fla_name) shutil.copy(src, dest) progress.setValue(len(fla_list)) # We have a couple sets of files that aren't named the way we want them to # be, just because of how they're stored in umdimage. progress.setLabelText("Renaming files.") to_rename = [ ("movies", "movie_%03d.gim", range(32)), ("nametags", "%02d.gim", range(23) + [24, 25, 30, 31]), ] for (folder, pattern, nums) in to_rename: folder = os.path.join(gfx_dir, folder) files = glob.glob(os.path.join(folder, "*.gim")) progress.setMaximum(len(files)) progress.setValue(0) for i, image in enumerate(files): if i % 10 == 0: progress.setValue(i) if progress.wasCanceled(): return src = image dest = os.path.join(folder, pattern % nums[i]) if os.path.isfile(dest): os.remove(dest) shutil.move(src, dest) sprite_dir = os.path.join(gfx_dir, "sprites") gmo_files = glob.glob(os.path.join(sprite_dir, "*.gmo")) progress.setLabelText("Extracting GMO files.") progress.setValue(0) progress.setMaximum(len(gmo_files)) for i, gmo_file in enumerate(gmo_files): if i % 10 == 0: progress.setValue(i) if progress.wasCanceled(): return name, ext = os.path.splitext(os.path.basename(gmo_file)) gim_file = os.path.join(sprite_dir, name + ".gim") gmo = GmoFile(filename = gmo_file) # Once we've loaded it, we're all done with it, so make it go away. os.remove(gmo_file) if gmo.gim_count() == 0: continue gim = gmo.get_gim(0) with open(gim_file, "wb") as f: gim.tofile(f) if self.ui.chkGimToPng.isChecked(): gim_files = glob.glob(os.path.join(gfx_dir, "*", "*.gim")) progress.setLabelText("Converting GIM to PNG.") progress.setValue(0) progress.setMaximum(len(gim_files)) converter = GimConverter() for i, gim_file in enumerate(gim_files): progress.setValue(i) if progress.wasCanceled(): return converter.gim_to_png(gim_file) os.remove(gim_file) progress.close() self.gfx_dir = gfx_dir self.ui.grpStep5.setEnabled(False) self.ui.grpStep6.setEnabled(True)
def setup_workspace(self): umdimage = os.path.join(self.iso_dir, UMDIMAGE_DAT) umdimage2 = os.path.join(self.iso_dir, UMDIMAGE2_DAT) voice = os.path.join(self.iso_dir, VOICE_PAK) self.generate_directories() progress = QProgressDialog("", QtCore.QString(), 0, 11000, self) progress.setWindowTitle("Setting up workspace...") progress.setWindowModality(Qt.Qt.WindowModal) progress.setMinimumDuration(0) progress.setValue(0) progress.setAutoClose(False) progress.setAutoReset(False) progress.setLabelText("Creating directories...") # Do the easy stuff first. if not os.path.isdir(self.changes_dir): os.makedirs(self.changes_dir) progress.setValue(progress.value() + 1) if not os.path.isdir(self.backup_dir): os.makedirs(self.backup_dir) progress.setValue(progress.value() + 1) if not os.path.isdir(self.editor_data_dir): os.makedirs(self.editor_data_dir) progress.setValue(progress.value() + 1) thread_fns = [ {"target": extract_umdimage, "kwargs": {"filename": umdimage, "out_dir": self.umdimage_dir, "eboot": self.eboot_path, "umdimage": UMDIMAGES.umdimage}}, {"target": extract_umdimage, "kwargs": {"filename": umdimage2, "out_dir": self.umdimage2_dir, "eboot": self.eboot_path, "umdimage": UMDIMAGES.umdimage2}}, {"target": extract_pak, "kwargs": {"filename": voice, "out_dir": self.voice_dir}}, ] # Going to capture stdout because I don't feel like # rewriting the extract functions to play nice with GUI. stdout = sys.stdout sys.stdout = cStringIO.StringIO() for thread_fn in thread_fns: thread = threading.Thread(**thread_fn) thread.start() while thread.isAlive(): thread.join(THREAD_TIMEOUT) output = [line for line in sys.stdout.getvalue().split('\n') if len(line) > 0] progress.setValue(progress.value() + len(output)) if len(output) > 0: progress.setLabelText("Extracting %s..." % output[-1]) sys.stdout = cStringIO.StringIO() sys.stdout = stdout # Give us an ISO directory for the editor to place modified files in. progress.setLabelText("Copying ISO files...") # ISO directory needs to not exist for copytree. if os.path.isdir(self.edited_iso_dir): shutil.rmtree(self.edited_iso_dir) # One more thing we want threaded so it doesn't lock up the GUI. thread = threading.Thread(target = shutil.copytree, kwargs = {"src": self.iso_dir, "dst": self.edited_iso_dir}) thread.start() while thread.isAlive(): thread.join(THREAD_TIMEOUT) progress.setLabelText("Copying ISO files...") # It has to increase by some amount or it won't update and the UI will lock up. progress.setValue(progress.value() + 1) # shutil.copytree(self.iso_dir, self.edited_iso_dir) progress.setValue(progress.value() + 1) # Files we want to make blank, because they're unnecessary. blank_files = [ os.path.join(self.edited_iso_dir, "PSP_GAME", "INSDIR", "UMDIMAGE.DAT"), os.path.join(self.edited_iso_dir, "PSP_GAME", "SYSDIR", "UPDATE", "DATA.BIN"), os.path.join(self.edited_iso_dir, "PSP_GAME", "SYSDIR", "UPDATE", "EBOOT.BIN"), os.path.join(self.edited_iso_dir, "PSP_GAME", "SYSDIR", "UPDATE", "PARAM.SFO"), ] for blank in blank_files: with open(blank, "wb") as f: pass # Copy the decrypted EBOOT into the ISO folder and apply our hacks to it. progress.setLabelText("Hacking EBOOT...") progress.setValue(progress.value() + 1) hacked_eboot = BitStream(filename = self.eboot_path) hacked_eboot, offset = apply_eboot_patches(hacked_eboot) with open(os.path.join(self.edited_iso_dir, "PSP_GAME", "SYSDIR", "EBOOT.BIN"), "wb") as f: hacked_eboot.tofile(f) # shutil.copy(self.eboot_path, os.path.join(self.edited_iso_dir, "PSP_GAME", "SYSDIR", "EBOOT.BIN")) progress.setLabelText("Extracting editor data...") progress.setValue(progress.value() + 1) # Extract the editor data. editor_data = zipfile.ZipFile("data/editor_data.zip", "r") editor_data.extractall(self.editor_data_dir) editor_data.close() progress.setValue(progress.maximum()) progress.close() self.ui.grpStep4.setEnabled(False) self.ui.grpStep5.setEnabled(True)