def package_import(self, pack: str): """ Import opsi package file into development folder and open it, if successful :param pack: package file path """ self.logger.debug("Importing package") if self._active_project: if not self.project_close(): return self.reset_state() # extract product id from package path file = Helper.get_file_from_path(pack) product = file[:file.rfind( "_" )] # remove everything behind product name (version, file extension, etc.) project = Helper.concat_path_native(ConfigHandler.cfg.dev_dir, product) # import try: self.startup.hide_me() self.do_import(pack) except: self.logger.error("Package import unsuccessful!") else: # open try: self.project_load(project) except: self.logger.err("Imported package could not be opened!")
def package_import(self, pack: str): """ Import opsi package file into development folder and open it, if successful :param pack: package file path """ self.logger.debug("Importing package") if self._active_project: if not self.project_close(): return self.reset_state() # extract product id from package path file = Helper.get_file_from_path(pack) product = file[:file.rfind("_")] # remove everything behind product name (version, file extension, etc.) project = Helper.concat_path_native(ConfigHandler.cfg.dev_dir, product) # import try: self.startup.hide_me() self.do_import(pack) except: self.logger.error("Package import unsuccessful!") else: # open try: self.project_load(project) except: self.logger.err("Imported package could not be opened!")
def create_project_paths(self, base): for elem in oPB.BASE_FOLDERS: try: path = Path(Helper.concat_path_native(base, elem)) if not path.exists(): path.mkdir(parents=True) except OSError: raise
def __init__(self, parent=None, applangprefix=""): """ Constructor of Translator class :param parent: parent, mostly qApp :param applangprefix: application language file prefix """ if Translator.cfg is None: Translator.cfg = self Translator.cfg._parent = parent super().__init__(Translator.cfg._parent) Translator.cfg._qt_local_path = None Translator.cfg._app_locale_path = None Translator.cfg._syslocale = None Translator.cfg._current_lang = "en" Translator.cfg.applangprefix = applangprefix Translator.cfg._combobox = None Translator.cfg._dialog = None # different translators Translator.cfg.translator_qt = None Translator.cfg.translator_qtbase = None Translator.cfg.translator_qthelp = None Translator.cfg.translator_qtmm = None Translator.cfg.translator_qtwebengine = None Translator.cfg.translator_app = None pyqt_path = os.path.dirname(PyQt5.__file__) if platform.system() == "Windows": Translator.cfg._qt_locale_path = Helper.concat_path_native( pyqt_path, "Qt\\translations") else: if os.path.isdir("/usr/share/qt5/translations/"): Translator.cfg._qt_locale_path = "/usr/share/qt5/translations/" else: # we assume, that library plugin path is sibling to translations path # so let's find the plugins and construct translations path lib_dirs = qApp.libraryPaths() for d in lib_dirs: l = os.path.join(d, "../translations") if os.path.isdir(l): Translator.cfg._qt_locale_path = l break Translator.cfg._app_locale_path = ":locale/" Translator.cfg._syslocale = QtCore.QLocale().system().name()[:2]
def __init__(self, parent = None, applangprefix = ""): """ Constructor of Translator class :param parent: parent, mostly qApp :param applangprefix: application language file prefix """ if Translator.cfg is None: Translator.cfg = self Translator.cfg._parent = parent super().__init__(Translator.cfg._parent) Translator.cfg._qt_local_path = None Translator.cfg._app_locale_path = None Translator.cfg._syslocale = None Translator.cfg._current_lang = "en" Translator.cfg.applangprefix = applangprefix Translator.cfg._combobox = None Translator.cfg._dialog = None # different translators Translator.cfg.translator_qt = None Translator.cfg.translator_qtbase = None Translator.cfg.translator_qthelp = None Translator.cfg.translator_qtmm = None Translator.cfg.translator_qtwebengine = None Translator.cfg.translator_app = None pyqt_path = os.path.dirname(PyQt5.__file__) if platform.system() == "Windows": Translator.cfg._qt_locale_path = Helper.concat_path_native(pyqt_path, "Qt\\translations") else: if os.path.isdir("/usr/share/qt5/translations/"): Translator.cfg._qt_locale_path = "/usr/share/qt5/translations/" else: # we assume, that library plugin path is sibling to translations path # so let's find the plugins and construct translations path lib_dirs = qApp.libraryPaths() for d in lib_dirs: l = os.path.join(d, "../translations") if os.path.isdir(l): Translator.cfg._qt_locale_path = l break Translator.cfg._app_locale_path = ":locale/" Translator.cfg._syslocale = QtCore.QLocale().system().name()[:2]
def validate(self, p_str, p_int): """ Validator method :param p_str: script full pathname to validate :param p_int: (not used) :return: tuple(QValidator.state, p_str, p_int) """ if p_str == "": return ScriptFileValidator.Intermediate, p_str, p_int if os.path.exists(Helper.concat_path_native(self._parent.lblPacketFolder.text().replace('\\','/') + "/CLIENT_DATA/", p_str)): return ScriptFileValidator.Acceptable, p_str, p_int else: return ScriptFileValidator.Invalid, p_str, p_int
def select_keyfile(self): """SSH keyfile selector dialog""" self.logger.debug("Select SSH keyfile dialog") ext = "Private key file (" + (" ").join(["*." + x for x in oPB.KEYFILE_EXT]) + ")" # generate file extension selection string for dialog script = QFileDialog.getOpenFileName(self, translate("SettingsDialog", "Choose keyfile"), ConfigHandler.cfg.dev_dir, ext) if not script == ("", ""): self.logger.debug("Selected SSH keyfile: " + script[0]) self.inpKeyFile.setText(Helper.concat_path_native(script[0], "")) self.dataChanged.emit() else: self.logger.debug("Dialog aborted.")
def select_dev_dir(self): """Development directory selector dialog""" self.logger.debug("Select development directory") directory = QFileDialog.getExistingDirectory(self, translate("SettingsDialog", "Select development folder"), ConfigHandler.cfg.dev_dir, QFileDialog.ShowDirsOnly) if not directory == "": self.logger.info("Chosen directory: " + directory) value = Helper.concat_path_native(directory, "") if value[-1:] == "/" or value[-1:] == '\\': value = value[:-1] self.inpDevFolder.setText(value) self.inpLocalShareBase.setText(value) self.dataChanged.emit() else: self.logger.debug("Dialog aborted.")
def run_command_line(self): """Process project action via command line""" self.logger.info("Project given via command line: " + self.args.path) if os.path.isabs(self.args.path): project = self.args.path else: project = Helper.concat_path_native(ConfigHandler.cfg.dev_dir, self.args.path) # load project self.load_backend(project) # stop if something happened if oPB.EXITCODE != oPB.RET_OK: return # first, set rights if self.args.setrights is True: self.do_setrights() # wait a short moment for disk flushing sleep(0.5) # stop if something happened if oPB.EXITCODE != oPB.RET_OK: return # build project if self.args.build_mode is not None: self.logger.info("Command line: build") self.do_build() # wait a short moment for disk flushing sleep(0.5) # stop if something happened if oPB.EXITCODE != oPB.RET_OK: return # install / install+setup / uninstall try: self.logger.info("Command line: " + self.args.packetaction[0]) if self.args.packetaction[0] == "install": self.do_install(depot = ConfigHandler.cfg.opsi_server) if self.args.packetaction[0] == "instsetup": self.do_installsetup(depot = ConfigHandler.cfg.opsi_server) if self.args.packetaction[0] == "uninstall": self.do_uninstall(depot = ConfigHandler.cfg.opsi_server) except: pass
def select_dev_dir(self): """Development directory selector dialog""" self.logger.debug("Select development directory") directory = QFileDialog.getExistingDirectory( self, translate("SettingsDialog", "Select development folder"), ConfigHandler.cfg.dev_dir, QFileDialog.ShowDirsOnly) if not directory == "": self.logger.info("Chosen directory: " + directory) value = Helper.concat_path_native(directory, "") if value[-1:] == "/" or value[-1:] == '\\': value = value[:-1] self.inpDevFolder.setText(value) self.inpLocalShareBase.setText(value) self.dataChanged.emit() else: self.logger.debug("Dialog aborted.")
def validate(self, p_str, p_int): """ Validator method :param p_str: script full pathname to validate :param p_int: (not used) :return: tuple(QValidator.state, p_str, p_int) """ if p_str == "": return ScriptFileValidator.Intermediate, p_str, p_int if os.path.exists( Helper.concat_path_native( self._parent.lblPacketFolder.text().replace('\\', '/') + "/CLIENT_DATA/", p_str)): return ScriptFileValidator.Acceptable, p_str, p_int else: return ScriptFileValidator.Invalid, p_str, p_int
def select_externaleditor(self): """External editor selector dialog""" self.logger.debug("Select scripteditor dialog") if platform.system() != "Windows": ext = "Program (" + (" ").join(["*." + x for x in oPB.PRG_EXT]) + ")" # generate file extension selection string for dialog else: ext = "Any (*)" script = QFileDialog.getOpenFileName(self, translate("SettingsDialog", "Choose Scripteditor"), ConfigHandler.cfg.dev_dir, ext) if not script == ("", ""): self.logger.debug("Selected Scripeditor: " + script[0]) self.inpExternalEditor.setText(Helper.concat_path_native(script[0], "")) self.dataChanged.emit() else: self.logger.debug("Dialog aborted.")
def select_keyfile(self): """SSH keyfile selector dialog""" self.logger.debug("Select SSH keyfile dialog") ext = "Private key file (" + (" ").join([ "*." + x for x in oPB.KEYFILE_EXT ]) + ")" # generate file extension selection string for dialog script = QFileDialog.getOpenFileName( self, translate("SettingsDialog", "Choose keyfile"), ConfigHandler.cfg.dev_dir, ext) if not script == ("", ""): self.logger.debug("Selected SSH keyfile: " + script[0]) self.inpKeyFile.setText(Helper.concat_path_native(script[0], "")) self.dataChanged.emit() else: self.logger.debug("Dialog aborted.")
def load_backend(self, project_name): """Load project data.""" # itemChanged signal has to be disconnected temporarily, because # if not, dataChanged would be set after loading self.logger.info("Load project: " + project_name) self._dataLoaded = None self.controlData.load_data(Helper.concat_path_native(ConfigHandler.cfg.dev_dir, project_name)) while self._dataLoaded is None: # _dataLoaded has to be True or False pass if not self._dataLoaded: self.logger.error("Backend data could not be loaded.") self.logger.debug("Set exitcode RET_EOPEN") oPB.EXITCODE = oPB.RET_EOPEN self.msgbox(translate("baseController", "Project could not be loaded!"), oPB.MsgEnum.MS_ERR) else: self.logger.info("Backend data loaded") self.msgbox(translate("mainController", "Project loaded successfully!"), oPB.MsgEnum.MS_STAT)
def load_backend(self, project_name): """Load project data.""" # itemChanged signal has to be disconnected temporarily, because # if not, dataChanged would be set after loading self.logger.info("Load project: " + project_name) self._dataLoaded = None self.controlData.load_data(Helper.concat_path_native(ConfigHandler.cfg.dev_dir, project_name)) while self._dataLoaded is None: # _dataLoaded has to be True or False pass if not self._dataLoaded: self.logger.error("Backend data could not be loaded.") self.logger.debug("Set exitcode RET_EOPEN") oPB.EXITCODE = oPB.RET_EOPEN self.msgbox(translate("baseController", "Project could not be loaded!"), oPB.MsgEnum.MS_ERR) else: self.logger.info("Backend data loaded") self.msgbox(translate("baseController", "Project loaded successfully!"), oPB.MsgEnum.MS_STAT)
def select_externaleditor(self): """External editor selector dialog""" self.logger.debug("Select scripteditor dialog") if platform.system() != "Windows": ext = "Program (" + (" ").join([ "*." + x for x in oPB.PRG_EXT ]) + ")" # generate file extension selection string for dialog else: ext = "Any (*)" script = QFileDialog.getOpenFileName( self, translate("SettingsDialog", "Choose Scripteditor"), ConfigHandler.cfg.dev_dir, ext) if not script == ("", ""): self.logger.debug("Selected Scripeditor: " + script[0]) self.inpExternalEditor.setText( Helper.concat_path_native(script[0], "")) self.dataChanged.emit() else: self.logger.debug("Dialog aborted.")
def select_logfile(self): """Logfile selector dialog""" self.logger.debug("Select log file dialog") """ ext = "Log (*.log)" # generate file extension selection string for dialog script = QFileDialog.getOpenFileName(self, translate("SettingsDialog", "Choose folder for logfile"), ConfigHandler.cfg.log_file, ext) if not script == ("", ""): self.logger.debug("Selected Logile: " + script[0]) """ directory = QFileDialog.getExistingDirectory(self, translate("SettingsDialog", "Select logfile folder"), ConfigHandler.cfg.dev_dir, QFileDialog.ShowDirsOnly) if not directory == "": self.logger.info("Chosen directory: " + directory) self.inpLogFile.setText(Helper.concat_path_native(directory, "opb-session.log")) self.dataChanged.emit() else: self.logger.debug("Dialog aborted.")
def select_script_dialog(self, script_type, setvalue = True): """ Opens a dialog to select a script file or clear field content :param script_type: field type identifier (setup, uninstall, update, always, once, custom, userlogin) :param setvalue: set new value = True, empty field only = False """ self.logger.debug("Select script dialog") ext = "Scripts (" + " ".join(["*." + x for x in oPB.SCRIPT_EXT]) + ")" # generate file extension selection string for dialog if setvalue: if self.lblPacketFolder.text() == "": script = QFileDialog.getOpenFileName(self, translate("MainWindow", "Choose script"), ConfigHandler.cfg.dev_dir, ext) else: script = QFileDialog.getOpenFileName(self, translate("MainWindow", "Choose script"), Helper.concat_path_native(self.lblPacketFolder.text(), "CLIENT_DATA"), ext) if not script == ("", ""): self._parent.set_selected_script(script[0], script_type) else: self._parent.set_selected_script("", script_type)
def select_logfile(self): """Logfile selector dialog""" self.logger.debug("Select log file dialog") """ ext = "Log (*.log)" # generate file extension selection string for dialog script = QFileDialog.getOpenFileName(self, translate("SettingsDialog", "Choose folder for logfile"), ConfigHandler.cfg.log_file, ext) if not script == ("", ""): self.logger.debug("Selected Logile: " + script[0]) """ directory = QFileDialog.getExistingDirectory( self, translate("SettingsDialog", "Select logfile folder"), ConfigHandler.cfg.dev_dir, QFileDialog.ShowDirsOnly) if not directory == "": self.logger.info("Chosen directory: " + directory) self.inpLogFile.setText( Helper.concat_path_native(directory, "opb-session.log")) self.dataChanged.emit() else: self.logger.debug("Dialog aborted.")
def open_scripteditor(self): """Open script editor after double click on tree view item""" self.logger.debug("Start scripteditor") idx = self.treeView.currentIndex() if idx.isValid(): sibling = idx.sibling(idx.row(), idx.column() + 1) item = self.model.itemFromIndex(sibling) script = item.text() if "(External)" in script: self._parent.msgbox( translate( "MainWindow", "Sorry! You cannot edit a script outside the project folder!" ), oPB.MsgEnum.MS_ERR, self) return if ConfigHandler.cfg.editor_intern == "True": self._parent.msgbox( translate( "MainWindow", "Internal editor not available at the moment. Use external editor instead!" ), oPB.MsgEnum.MS_ALWAYS, self) self._parentUi.actionSettings.trigger() return if os.path.exists(ConfigHandler.cfg.scripteditor): path = Helper.concat_path_native( self._parentUi.lblPacketFolder.text(), "CLIENT_DATA") path = Helper.concat_path_native(path, script) self.logger.debug("Opening script: " + path) cmd = [ConfigHandler.cfg.scripteditor] if (ConfigHandler.cfg.editor_options).strip() != "": for part in (ConfigHandler.cfg.editor_options).split(): cmd.append(part) if ConfigHandler.cfg.editor_attachdirect == "True": cmd[-1] = cmd[-1] + path else: cmd.append(path) else: cmd.append(path) self.logger.debug("Executing subprocess: " + str(cmd)) proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) outs, errs = proc.communicate() self.logger.info(outs) self.logger.error(errs) if proc.returncode != 0: self._parent.msgbox( translate( "MainWindow", "Editor startup did not cleanup correctly.\n\nThe following message(s) returned:" ) + "\n\nStandard Out:\n" + outs + "\n\nStandard Err:\n" + errs, oPB.MsgEnum.MS_WARN, self) else: self._parent.msgbox( translate( "MainWindow", "Editor not found:" + " " + ConfigHandler.cfg.scripteditor), oPB.MsgEnum.MS_ERR, self)
def project_copy(self, project_folder): """ Copies current project data to new project destination :param destination: destination for copied project """ dest_data = "" val = 0 def sizeof_fmt(num, suffix='B'): for unit in ['','Ki','Mi','Gi','Ti','Pi','Ei','Zi']: if abs(num) < 1024.0: return "%3.1f%s%s" % (num, unit, suffix) num /= 1024.0 return "%.1f%s%s" % (num, 'Yi', suffix) def copy2_(src, dst): self.logger.debug("Copying to destination file: " + str(dst)) self.msgbox("CLIENT_DATA: " + str(dst).replace(dest_data, ""), oPB.MsgEnum.MS_STAT) self.progressChanged.emit(val) shutil.copy2(src,dst) def countFiles(directory): files = [] total_size = 0 if os.path.isdir(directory): for path, dirs, filenames in os.walk(directory): files.extend(filenames) for f in filenames: fp = os.path.join(path, f) total_size += os.path.getsize(fp) return len(files), total_size def copyDirectory(src, dest): self.logger.info("Copying files") self.logger.debug("Source: " + src) self.logger.debug("Destination:" + dest) if os.path.exists(dest): shutil.rmtree(dest) try: shutil.copytree(src, dest, copy_function=copy2_) # Directories are the same except shutil.Error as e: self.logger.error('Directory not copied. Error: %s' % e) # Any error saying that the directory doesn't exist except OSError as e: self.logger.error('Directory not copied. Error: %s' % e) self.logger.info("Create new project from current: " + project_folder) # create new control object as copy if os.path.exists(Helper.concat_path_native(project_folder, "CLIENT_DATA")): self.logger.error("CLIENT_DATA subdirectory in destination folder detected. This is not allowed for security reason!") self.msgbox(translate("mainController", "CLIENT_DATA subdirectory in destination folder detected. This is not allowed for security reason!"), oPB.MsgEnum.MS_ERR) return newControl = deepcopy(self.controlData) self.create_project_paths(project_folder) project_name = PurePath(project_folder).name.replace(" ","_") newControl.id = project_name newControl.projectfolder = project_folder # add changelog entry for this copy process text = "Project copied from: " + self.controlData.packagename newentry = ChangelogEntry(newControl.id) newentry.version = "(" + newControl.productversion + "-" + newControl.packageversion + ")" newentry.status = oPB.CHLOG_STATI[0] newentry.urgency = oPB.CHLOG_BLOCKMARKER + oPB.CHLOG_URGENCIES[0] newentry.text = "\n" + text + changelog_footer() newControl.changelog_append(newentry) try: self.processingStarted.emit() newControl.save_data() self.logger.debug("New control data saved.") dest_data = Helper.concat_path_native(newControl.projectfolder, "CLIENT_DATA") total, total_size = countFiles(Helper.concat_path_native(self.controlData.projectfolder, "CLIENT_DATA")) val = 100 / total reply = self.msgbox(translate("mainController", "Copy files now? This can't be canceled.") + "\n\nTotal: " + str(total) + "\n" + sizeof_fmt(total_size), oPB.MsgEnum.MS_QUEST_YESNO) if reply is True: copyDirectory(Helper.concat_path_native(self.controlData.projectfolder, "CLIENT_DATA"), Helper.concat_path_native(newControl.projectfolder, "CLIENT_DATA") ) self.logger.debug("Files copied.") self.processingEnded.emit(True) # close current project an re-open clone if not self.project_close(): return self.project_load(project_name) except: self.logger.error("Project could not be copied and re-opened.")
def project_copy(self, project_folder): """ Copies current project data to new project destination :param destination: destination for copied project """ dest_data = "" val = 0 def sizeof_fmt(num, suffix='B'): for unit in ['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi']: if abs(num) < 1024.0: return "%3.1f%s%s" % (num, unit, suffix) num /= 1024.0 return "%.1f%s%s" % (num, 'Yi', suffix) def copy2_(src, dst): self.logger.debug("Copying to destination file: " + str(dst)) self.msgbox("CLIENT_DATA: " + str(dst).replace(dest_data, ""), oPB.MsgEnum.MS_STAT) self.progressChanged.emit(val) shutil.copy2(src, dst) def countFiles(directory): files = [] total_size = 0 if os.path.isdir(directory): for path, dirs, filenames in os.walk(directory): files.extend(filenames) for f in filenames: fp = os.path.join(path, f) total_size += os.path.getsize(fp) return len(files), total_size def copyDirectory(src, dest): self.logger.info("Copying files") self.logger.debug("Source: " + src) self.logger.debug("Destination:" + dest) if os.path.exists(dest): shutil.rmtree(dest) try: shutil.copytree(src, dest, copy_function=copy2_) # Directories are the same except shutil.Error as e: self.logger.error('Directory not copied. Error: %s' % e) # Any error saying that the directory doesn't exist except OSError as e: self.logger.error('Directory not copied. Error: %s' % e) self.logger.info("Create new project from current: " + project_folder) # create new control object as copy if os.path.exists( Helper.concat_path_native(project_folder, "CLIENT_DATA")): self.logger.error( "CLIENT_DATA subdirectory in destination folder detected. This is not allowed for security reason!" ) self.msgbox( translate( "mainController", "CLIENT_DATA subdirectory in destination folder detected. This is not allowed for security reason!" ), oPB.MsgEnum.MS_ERR) return newControl = deepcopy(self.controlData) self.create_project_paths(project_folder) project_name = PurePath(project_folder).name.replace(" ", "_") newControl.id = project_name newControl.projectfolder = project_folder # add changelog entry for this copy process text = "Project copied from: " + self.controlData.packagename newentry = ChangelogEntry(newControl.id) newentry.version = "(" + newControl.productversion + "-" + newControl.packageversion + ")" newentry.status = oPB.CHLOG_STATI[0] newentry.urgency = oPB.CHLOG_BLOCKMARKER + oPB.CHLOG_URGENCIES[0] newentry.text = "\n" + text + changelog_footer() newControl.changelog_append(newentry) try: self.processingStarted.emit() newControl.save_data() self.logger.debug("New control data saved.") dest_data = Helper.concat_path_native(newControl.projectfolder, "CLIENT_DATA") total, total_size = countFiles( Helper.concat_path_native(self.controlData.projectfolder, "CLIENT_DATA")) val = 100 / total reply = self.msgbox( translate("mainController", "Copy files now? This can't be canceled.") + "\n\nTotal: " + str(total) + "\n" + sizeof_fmt(total_size), oPB.MsgEnum.MS_QUEST_YESNO) if reply is True: copyDirectory( Helper.concat_path_native(self.controlData.projectfolder, "CLIENT_DATA"), Helper.concat_path_native(newControl.projectfolder, "CLIENT_DATA")) self.logger.debug("Files copied.") self.processingEnded.emit(True) # close current project an re-open clone if not self.project_close(): return self.project_load(project_name) except: self.logger.error("Project could not be copied and re-opened.")
def create_bundle(self, prods=[]): self.logger.debug("Create bundle from selection") if prods: msg = "\n\n" + translate( "bundleController", "Chosen products:") + "\n\n" + ("\n").join( [p for p in prods]) reply = self._parent.msgbox( translate("bundleController", "Create product bundle now?") + msg, oPB.MsgEnum.MS_QUEST_YESNO) if reply is True: self.logger.debug("Selected product(s): " + str(prods)) ok = False while not ok: comment = "meta-" accept = False while comment == "" or accept == False: ( comment, accept ) = self._parent.msgbox(translate( "bundleController", "Please enter package name (allowed characters: a-z, A-Z, 0-9, ._-):" ), oPB.MsgEnum.MS_QUEST_PHRASE, parent=self.ui, preload=comment) # first test if cancel button was pressed if not accept: self._parent.msgbox(translate( "bundleController", "Package creation canceled!"), oPB.MsgEnum.MS_ALWAYS, parent=self.ui) self.logger.debug( "Package bundle creation canceled by the user." ) self._parent.startup.show_() return None if ConfigHandler.cfg.age == "True": test = re.match(oPB.OPB_PRODUCT_ID_REGEX_NEW, comment) else: test = re.match(oPB.OPB_PRODUCT_ID_REGEX_OLD, comment) if not test: self._parent.msgbox(translate( "bundleController", "Package name is no valid product id!"), oPB.MsgEnum.MS_ALWAYS, parent=self.ui) accept = False directory = Helper.concat_path_native( ConfigHandler.cfg.dev_dir, comment) self.logger.info("Chosen directory for new project: " + directory) if os.path.exists(directory): self._parent.msgbox(translate( "bundleController", "Package name already exists. Please choose another package name!" ), oPB.MsgEnum.MS_ALWAYS, parent=self.ui) else: self._parent.project_create(directory) for p in prods: self._parent.add_setup_before_dependency(p) self._parent.controlData.priority = -100 self._parent.controlData.setupScript = "dummy.opsiscript" self._parent.controlData.create_script_stub( self._parent.controlData.setupScript) self._parent.save_backend() ok = True self.logger.debug("Package bundle creation finished.") else: self.logger.debug("Nothing selected.")
def open_scripteditor(self): """ Open configured script editor. Method reaction depends on calling widget (self.sender()) """ self.logger.debug("Start scripteditor") if ConfigHandler.cfg.editor_intern == "True": self._parent.msgbox(translate("MainWindow", "Internal editor not available at the moment. Use external editor instead!"), oPB.MsgEnum.MS_ALWAYS, self) self.actionSettings.trigger() return if os.path.exists(ConfigHandler.cfg.scripteditor): path = Helper.concat_path_native(self.lblPacketFolder.text(), "CLIENT_DATA") if self.sender() == self.btnScrSetupEdit: if self.inpScrSetup.text().strip() == "": script = "setup.opsiscript" else: script = self.inpScrSetup.text() elif self.sender() == self.btnScrUninstallEdit: if self.inpScrUninstall.text().strip() == "": script = "uninstall.opsiscript" else: script = self.inpScrUninstall.text() elif self.sender() == self.btnScrUpdateEdit: if self.inpScrUpdate.text().strip() == "": script = "update.opsiscript" else: script = self.inpScrUpdate.text() elif self.sender() == self.btnScrAlwaysEdit: if self.inpScrAlways.text().strip() == "": script = "always.opsiscript" else: script = self.inpScrAlways.text() elif self.sender() == self.btnScrOnceEdit: if self.inpScrOnce.text().strip() == "": script = "once.opsiscript" else: script = self.inpScrOnce.text() elif self.sender() == self.btnScrCustomEdit: if self.inpScrCustom.text().strip() == "": script = "custom.opsiscript" else: script = self.inpScrCustom.text() elif self.sender() == self.btnScrUserLoginEdit: if self.inpScrUserLogin.text().strip() == "": script = "userlogin.opsiscript" else: script = self.inpScrUserLogin.text() elif self.sender() == self.actionScriptEditor: script = "new.opsiscript" # script editor from menu if path != "" and script != "": path = Helper.concat_path_native(path, script) self.logger.debug("Opening script: " + path) # construct calling array # first add basic scripteditor executable cmd = [ConfigHandler.cfg.scripteditor] # if there are options, split and append them if (ConfigHandler.cfg.editor_options).strip() != "": for part in (ConfigHandler.cfg.editor_options).split(): cmd.append(part) # if attach direct is true, combine last option with script file path if ConfigHandler.cfg.editor_attachdirect == "True": cmd[-1] = cmd[-1] + path # or else, append as separate value to list else: cmd.append(path) else: cmd.append(path) self.logger.debug("Executing subprocess: " + str(cmd)) proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) outs, errs = proc.communicate() self.logger.info(outs) self.logger.error(errs) if proc.returncode != 0 and proc.returncode != 555: self._parent.msgbox(translate("MainWindow", "Editor did not exit as expected.\n\nThe following message(s) returned:") + "\n\nStandard Out:\n" + outs + "\nStandard Err:\n" + errs + "\n\nReturn code: " + str(proc.returncode), oPB.MsgEnum.MS_WARN, self) else: self._parent.msgbox(translate("MainWindow", "Editor not found:" + " " + ConfigHandler.cfg.scripteditor), oPB.MsgEnum.MS_ERR, self)