def __init__(self, parent): super(PackageCreationWidget, self).__init__(parent) self.ui = Ui_PackageCreationPage() self.ui.setupUi(self) self.document = None # the push buttons to specify directories... self.ui.pbOutputDirectory.released.connect(self.__onChooseSimpleOutputDirectory) self.ui.pbOutputDirectoryCustom.released.connect(self.__onChooseCustomOutputDirectory) self.ui.pbScriptsDirectory.released.connect(self.__onChooseScriptsDirectory) self.ui.pbCreatePackage.released.connect(self.__createPackage) self.ui.gbCustom.clicked.connect(lambda x: self.__onGroupBoxSelected(True, x)) self.ui.gbSimple.clicked.connect(lambda x: self.__onGroupBoxSelected(False, x)) self.ui.lineEditPackageName.textChanged.connect(self.__fieldsValid) self.ui.lineEditOutputDirectory.textChanged.connect(self.__fieldsValid) self.ui.lineEditOutputDirectoryCustom.textChanged.connect(self.__fieldsValid) self.ui.lineEditPackageIdent.textChanged.connect(self.__fieldsValid) self.ui.lineEditPackageVersion.textChanged.connect(self.__fieldsValid) self.ui.lineEditScriptsDirectory.textChanged.connect(self.__fieldsValid) self.ui.rbPermissionsPreserve.clicked.connect(self.__fieldsValid) self.ui.rbPermissionsRecommended.clicked.connect(self.__fieldsValid) self.ui.lblProgress.linkActivated.connect(self.__onLinkActivated) self.ui.lblProgressInfo.linkActivated.connect(self.__onLinkActivated) self.__loadFields() self.__fieldsValid() self.__setProgressHidden(True)
def __init__(self, parent): super(PackageCreationWidget, self).__init__(parent) self.ui = Ui_PackageCreationPage() self.ui.setupUi(self) self.document = None # the push buttons to specify directories... self.ui.pbOutputDirectory.released.connect( self.__onChooseSimpleOutputDirectory) self.ui.pbOutputDirectoryCustom.released.connect( self.__onChooseCustomOutputDirectory) self.ui.pbScriptsDirectory.released.connect( self.__onChooseScriptsDirectory) self.ui.pbCreatePackage.released.connect(self.__createPackage) self.ui.gbCustom.clicked.connect( lambda x: self.__onGroupBoxSelected(True, x)) self.ui.gbSimple.clicked.connect( lambda x: self.__onGroupBoxSelected(False, x)) self.ui.lineEditPackageName.textChanged.connect(self.__fieldsValid) self.ui.lineEditOutputDirectory.textChanged.connect(self.__fieldsValid) self.ui.lineEditOutputDirectoryCustom.textChanged.connect( self.__fieldsValid) self.ui.lineEditPackageIdent.textChanged.connect(self.__fieldsValid) self.ui.lineEditPackageVersion.textChanged.connect(self.__fieldsValid) self.ui.lineEditScriptsDirectory.textChanged.connect( self.__fieldsValid) self.ui.rbPermissionsPreserve.clicked.connect(self.__fieldsValid) self.ui.rbPermissionsRecommended.clicked.connect(self.__fieldsValid) self.ui.lblProgress.linkActivated.connect(self.__onLinkActivated) self.ui.lblProgressInfo.linkActivated.connect(self.__onLinkActivated) self.__loadFields() self.__fieldsValid() self.__setProgressHidden(True)
class PackageCreationWidget(QWidget): def __init__(self, parent): super(PackageCreationWidget, self).__init__(parent) self.ui = Ui_PackageCreationPage() self.ui.setupUi(self) self.document = None # the push buttons to specify directories... self.ui.pbOutputDirectory.released.connect( self.__onChooseSimpleOutputDirectory) self.ui.pbOutputDirectoryCustom.released.connect( self.__onChooseCustomOutputDirectory) self.ui.pbScriptsDirectory.released.connect( self.__onChooseScriptsDirectory) self.ui.pbCreatePackage.released.connect(self.__createPackage) self.ui.gbCustom.clicked.connect( lambda x: self.__onGroupBoxSelected(True, x)) self.ui.gbSimple.clicked.connect( lambda x: self.__onGroupBoxSelected(False, x)) self.ui.lineEditPackageName.textChanged.connect(self.__fieldsValid) self.ui.lineEditOutputDirectory.textChanged.connect(self.__fieldsValid) self.ui.lineEditOutputDirectoryCustom.textChanged.connect( self.__fieldsValid) self.ui.lineEditPackageIdent.textChanged.connect(self.__fieldsValid) self.ui.lineEditPackageVersion.textChanged.connect(self.__fieldsValid) self.ui.lineEditScriptsDirectory.textChanged.connect( self.__fieldsValid) self.ui.rbPermissionsPreserve.clicked.connect(self.__fieldsValid) self.ui.rbPermissionsRecommended.clicked.connect(self.__fieldsValid) self.ui.lblProgress.linkActivated.connect(self.__onLinkActivated) self.ui.lblProgressInfo.linkActivated.connect(self.__onLinkActivated) self.__loadFields() self.__fieldsValid() self.__setProgressHidden(True) def initializePageWithDocument(self, document): self.document = document def __onGroupBoxSelected(self, isCustom, ison): self.ui.gbCustom.blockSignals(True) self.ui.gbSimple.blockSignals(True) if not isCustom: ison = not ison self.ui.gbCustom.setChecked(ison) self.ui.gbSimple.setChecked(not ison) self.__fieldsValid() self.ui.gbCustom.blockSignals(False) self.ui.gbSimple.blockSignals(False) def __onChooseSimpleOutputDirectory(self): dir_name = QFileDialog.getExistingDirectory(self, "Choose Output Directory") if len(dir_name) > 0: self.ui.lineEditOutputDirectory.setText(dir_name) self.parent().changed() def __onChooseCustomOutputDirectory(self): dir_name = QFileDialog.getExistingDirectory( self, "Choose Custom Output Directory") if len(dir_name) > 0: self.ui.lineEditOutputDirectoryCustom.setText(dir_name) self.parent().changed() def __onChooseScriptsDirectory(self): dir_name = QFileDialog.getExistingDirectory( self, "Choose Scripts Directory") if len(dir_name) > 0: self.ui.lineEditScriptsDirectory.setText(dir_name) self.parent().changed() def __enableExportControls(self, enabled): self.ui.pbCreatePackage.setEnabled(enabled) def __fieldsValid(self): res = False res3 = len(self.__userSpecifiedDSTROOT()) > 0 if self.ui.gbSimple.isChecked(): res1 = len(self.ui.lineEditPackageIdent.text()) > 0 and len( self.ui.lineEditPackageVersion.text()) > 0 res2 = len(self.ui.lineEditPackageName.text()) > 0 res = res1 and res2 and res3 else: res = res3 self.__enableExportControls(res) self.__saveFields() return res def isComplete(self): if self.document == None: return False return self.__fieldsValid() def __userSpecifiedDSTROOT(self): res = None if self.ui.gbSimple.isChecked(): res = self.ui.lineEditOutputDirectory.text() if res is None or len(res) == 0: res = self.ui.lineEditOutputDirectory.placeholderText() else: res = self.ui.lineEditOutputDirectoryCustom.text() if res is None or len(res) == 0: res = self.ui.lineEditOutputDirectoryCustom.placeholderText() return os.path.expandvars(os.path.expanduser(res)) def __createPackage(self): # get the destination directory, if it does not exist - prompt and create it dstroot = self.__userSpecifiedDSTROOT() if not os.path.exists(dstroot): opt = QMessageBox.warning( self, "Destination Doesn't Exist", "The destination directory does not exist:\r\n{}\r\n\nDo you want to create it?" .format(dstroot)) if opt != QMessageBox.StandardButton(QMessageBox.Ok): return os.makedirs(dstroot) if not os.path.exists(dstroot): QMessageBox.error( self, "Failed to Create Directory", "There was a problem creating the directory:\r\n{}".format( dstroot)) return # check if the scripts dir is specified, if it is, then it must exist scripts_dir = self.ui.lineEditScriptsDirectory.text() if len(scripts_dir) > 0: if not os.path.exists(scripts_dir): res = QMessageBox.warning(self,\ "Scripts Directory",\ "The scripts directory you specified does not exist - if you continue, the package will be created without scripting support\r\n\nDo you want to continue?",\ buttons = QMessageBox.StandardButton(QMessageBox.Ok + QMessageBox.Cancel)) if res != QMessageBox.StandardButton(QMessageBox.Ok): return total_items = self.document.countScanningResults() self.__prepareProgress("Copying data files ...", total_items) # create a new DSTROOT the_dir = os.path.join(dstroot, "DSTROOT") if not os.path.exists(the_dir): os.makedirs(the_dir) self.dstroot_path = tempfile.mkdtemp(dir=the_dir) self.package_name = self.ui.lineEditPackageName.text() # grab all the stuff we're supposed to export, and write it into a DSTROOT, then point # pkgbuild at it. # 1. construct a DSTROOT # 2. decide whether to run an analysis or create the pkg # 3. done. word = "DSTROOT creation" pkg_process = True if self.__createDSTRoot(): if self.ui.gbSimple.isChecked(): word = "creation" self.__prepareProgress("Constructing PKG...") pkg_process = self.__constructPackage() else: word = "analysis" self.__prepareProgress("Analyzing PKG...") pkg_process = self.__analyzePackage() html = "<a href='{}'>{}</href>".format(self.dstroot_path, self.dstroot_path) if pkg_process: pkg_result = "Package {} completed OK ({})".format(word, html) else: pkg_result = "Package {} failed to complete because of the packaging command failed (check logs)".format( word) else: pkg_result = "Package {} failed (check logs)".format(word) self.__finishProgress(pkg_result) def __runPackagingCommand(self, command_line): self.ui.pbCreatePackage.setEnabled(False) try: logger.info("going to run command: {0}".format(command_line)) proc = QProcess() proc.startDetached(command_line) proc.waitForFinished(-1) # note: you are looking here, probably because the PKG command failed, but it wasn't caught - I've noticed that # the waitForFinished() will always return False (the command runs too quick on analysis for example?), and exitStatus() # isn't reliable when a failure occurs anyway. Useless.... if proc.exitStatus() != QProcess.NormalExit: QMessageBox.critical( self, "Packaging Error", "The packaging process failed to finish properly") return False return True finally: self.ui.pbCreatePackage.setEnabled(True) def __analyzePackage(self): path = self.dstroot_path plist = os.path.join(os.path.dirname(path), os.path.basename(path) + ".plist") cmd_line = "/usr/bin/pkgbuild --analyze --root {} {}".format( path, plist) return self.__runPackagingCommand(cmd_line) def __constructPackage(self): path = self.dstroot_path pkg = os.path.join(os.path.dirname(path), self.package_name + ".pkg") ident = self.ui.lineEditPackageIdent.text() ver = self.ui.lineEditPackageVersion.text() scripts = self.ui.lineEditScriptsDirectory.text() if len(scripts) > 0 and os.path.exists(scripts): cmd_line = "/usr/bin/pkgbuild --identifier {} --version {} --scripts \"{}\" --root \"{}\" \"{}\"".format( ident, ver, scripts, path, pkg) else: # this one doesn't spec the scripts path cmd_line = "/usr/bin/pkgbuild --identifier {} --version {} --root \"{}\" \"{}\"".format( ident, ver, path, pkg) return self.__runPackagingCommand(cmd_line) def __createDSTRoot(self): errors = [] counter = 0 for scan_record in self.document.iterateScanningResults(): counter += 1 source_path = scan_record.abs_path # goal: remove leading '/' so that join does the right thing final_dest = os.path.join(self.dstroot_path, source_path[1:]) parent = os.path.split(final_dest)[0] if parent is not None and len(parent) > 0 and not os.path.exists( parent): os.makedirs(parent) self.__setProgress(counter, source_path) try: if os.path.islink(source_path): linkto = os.readlink(source_path) os.symlink(linkto, final_dest) elif os.path.isfile(source_path): shutil.copy2(source_path, final_dest) elif os.path.isdir(source_path): if not os.path.exists(final_dest): os.makedirs(final_dest) shutil.copystat(source_path, final_dest) except (IOError, os.error), why: errors.append((source_path, final_dest, str(why))) return len(errors) == 0
class PackageCreationWidget(QWidget): def __init__(self, parent): super(PackageCreationWidget, self).__init__(parent) self.ui = Ui_PackageCreationPage() self.ui.setupUi(self) self.document = None # the push buttons to specify directories... self.ui.pbOutputDirectory.released.connect(self.__onChooseSimpleOutputDirectory) self.ui.pbOutputDirectoryCustom.released.connect(self.__onChooseCustomOutputDirectory) self.ui.pbScriptsDirectory.released.connect(self.__onChooseScriptsDirectory) self.ui.pbCreatePackage.released.connect(self.__createPackage) self.ui.gbCustom.clicked.connect(lambda x: self.__onGroupBoxSelected(True, x)) self.ui.gbSimple.clicked.connect(lambda x: self.__onGroupBoxSelected(False, x)) self.ui.lineEditPackageName.textChanged.connect(self.__fieldsValid) self.ui.lineEditOutputDirectory.textChanged.connect(self.__fieldsValid) self.ui.lineEditOutputDirectoryCustom.textChanged.connect(self.__fieldsValid) self.ui.lineEditPackageIdent.textChanged.connect(self.__fieldsValid) self.ui.lineEditPackageVersion.textChanged.connect(self.__fieldsValid) self.ui.lineEditScriptsDirectory.textChanged.connect(self.__fieldsValid) self.ui.rbPermissionsPreserve.clicked.connect(self.__fieldsValid) self.ui.rbPermissionsRecommended.clicked.connect(self.__fieldsValid) self.ui.lblProgress.linkActivated.connect(self.__onLinkActivated) self.ui.lblProgressInfo.linkActivated.connect(self.__onLinkActivated) self.__loadFields() self.__fieldsValid() self.__setProgressHidden(True) def initializePageWithDocument(self, document): self.document = document def __onGroupBoxSelected(self, isCustom, ison): self.ui.gbCustom.blockSignals(True) self.ui.gbSimple.blockSignals(True) if not isCustom: ison = not ison self.ui.gbCustom.setChecked(ison) self.ui.gbSimple.setChecked(not ison) self.__fieldsValid() self.ui.gbCustom.blockSignals(False) self.ui.gbSimple.blockSignals(False) def __onChooseSimpleOutputDirectory(self): dir_name = QFileDialog.getExistingDirectory(self, "Choose Output Directory") if len(dir_name) > 0: self.ui.lineEditOutputDirectory.setText(dir_name) self.parent().changed() def __onChooseCustomOutputDirectory(self): dir_name = QFileDialog.getExistingDirectory(self, "Choose Custom Output Directory") if len(dir_name) > 0: self.ui.lineEditOutputDirectoryCustom.setText(dir_name) self.parent().changed() def __onChooseScriptsDirectory(self): dir_name = QFileDialog.getExistingDirectory(self, "Choose Scripts Directory") if len(dir_name) > 0: self.ui.lineEditScriptsDirectory.setText(dir_name) self.parent().changed() def __enableExportControls(self, enabled): self.ui.pbCreatePackage.setEnabled(enabled) def __fieldsValid(self): res = False res3 = len(self.__userSpecifiedDSTROOT()) > 0 if self.ui.gbSimple.isChecked(): res1 = len(self.ui.lineEditPackageIdent.text()) > 0 and len(self.ui.lineEditPackageVersion.text()) > 0 res2 = len(self.ui.lineEditPackageName.text()) > 0 res = res1 and res2 and res3 else: res = res3 self.__enableExportControls(res) self.__saveFields() return res def isComplete(self): if self.document == None: return False return self.__fieldsValid() def __userSpecifiedDSTROOT(self): res = None if self.ui.gbSimple.isChecked(): res = self.ui.lineEditOutputDirectory.text() if res is None or len(res) == 0: res = self.ui.lineEditOutputDirectory.placeholderText() else: res = self.ui.lineEditOutputDirectoryCustom.text() if res is None or len(res) == 0: res = self.ui.lineEditOutputDirectoryCustom.placeholderText() return os.path.expandvars(os.path.expanduser(res)) def __createPackage(self): # get the destination directory, if it does not exist - prompt and create it dstroot = self.__userSpecifiedDSTROOT() if not os.path.exists(dstroot): opt = QMessageBox.warning(self, "Destination Doesn't Exist", "The destination directory does not exist:\r\n{}\r\n\nDo you want to create it?".format(dstroot)) if opt != QMessageBox.StandardButton(QMessageBox.Ok): return os.makedirs(dstroot) if not os.path.exists(dstroot): QMessageBox.error(self, "Failed to Create Directory", "There was a problem creating the directory:\r\n{}".format(dstroot)) return # check if the scripts dir is specified, if it is, then it must exist scripts_dir = self.ui.lineEditScriptsDirectory.text() if len(scripts_dir) > 0: if not os.path.exists(scripts_dir): res = QMessageBox.warning(self,\ "Scripts Directory",\ "The scripts directory you specified does not exist - if you continue, the package will be created without scripting support\r\n\nDo you want to continue?",\ buttons = QMessageBox.StandardButton(QMessageBox.Ok + QMessageBox.Cancel)) if res != QMessageBox.StandardButton(QMessageBox.Ok): return total_items = self.document.countScanningResults() self.__prepareProgress("Copying data files ...", total_items) # create a new DSTROOT the_dir = os.path.join(dstroot, "DSTROOT") if not os.path.exists(the_dir): os.makedirs(the_dir) self.dstroot_path = tempfile.mkdtemp(dir=the_dir) self.package_name = self.ui.lineEditPackageName.text() # grab all the stuff we're supposed to export, and write it into a DSTROOT, then point # pkgbuild at it. # 1. construct a DSTROOT # 2. decide whether to run an analysis or create the pkg # 3. done. word = "DSTROOT creation" pkg_process = True if self.__createDSTRoot(): if self.ui.gbSimple.isChecked(): word = "creation" self.__prepareProgress("Constructing PKG...") pkg_process = self.__constructPackage() else: word = "analysis" self.__prepareProgress("Analyzing PKG...") pkg_process = self.__analyzePackage() html = "<a href='{}'>{}</href>".format(self.dstroot_path, self.dstroot_path) if pkg_process: pkg_result = "Package {} completed OK ({})".format(word, html) else: pkg_result = "Package {} failed to complete because of the packaging command failed (check logs)".format(word) else: pkg_result = "Package {} failed (check logs)".format(word) self.__finishProgress(pkg_result) def __runPackagingCommand(self, command_line): self.ui.pbCreatePackage.setEnabled(False) try: logger.info("going to run command: {0}".format(command_line)) proc = QProcess() proc.startDetached(command_line) proc.waitForFinished(-1) # note: you are looking here, probably because the PKG command failed, but it wasn't caught - I've noticed that # the waitForFinished() will always return False (the command runs too quick on analysis for example?), and exitStatus() # isn't reliable when a failure occurs anyway. Useless.... if proc.exitStatus() != QProcess.NormalExit: QMessageBox.critical(self, "Packaging Error", "The packaging process failed to finish properly") return False return True finally: self.ui.pbCreatePackage.setEnabled(True) def __analyzePackage(self): path = self.dstroot_path plist = os.path.join(os.path.dirname(path), os.path.basename(path) + ".plist") cmd_line = "/usr/bin/pkgbuild --analyze --root {} {}".format(path, plist) return self.__runPackagingCommand(cmd_line) def __constructPackage(self): path = self.dstroot_path pkg = os.path.join(os.path.dirname(path), self.package_name + ".pkg") ident = self.ui.lineEditPackageIdent.text() ver = self.ui.lineEditPackageVersion.text() scripts = self.ui.lineEditScriptsDirectory.text() if len(scripts) > 0 and os.path.exists(scripts): cmd_line = "/usr/bin/pkgbuild --identifier {} --version {} --scripts \"{}\" --root \"{}\" \"{}\"".format(ident, ver, scripts, path, pkg) else: # this one doesn't spec the scripts path cmd_line = "/usr/bin/pkgbuild --identifier {} --version {} --root \"{}\" \"{}\"".format(ident, ver, path, pkg) return self.__runPackagingCommand(cmd_line) def __createDSTRoot(self): errors = [] counter = 0 for scan_record in self.document.iterateScanningResults(): counter += 1 source_path = scan_record.abs_path # goal: remove leading '/' so that join does the right thing final_dest = os.path.join(self.dstroot_path, source_path[1:]) parent = os.path.split(final_dest)[0] if parent is not None and len(parent) > 0 and not os.path.exists(parent): os.makedirs(parent) self.__setProgress(counter, source_path) try: if os.path.islink(source_path): linkto = os.readlink(source_path) os.symlink(linkto, final_dest) elif os.path.isfile(source_path): shutil.copy2(source_path, final_dest) elif os.path.isdir(source_path): if not os.path.exists(final_dest): os.makedirs(final_dest) shutil.copystat(source_path, final_dest) except (IOError, os.error), why: errors.append((source_path, final_dest, str(why))) return len(errors) == 0