def OnBuild(self, event=None): # Build preparation ret_code, build_prep = self.BuildPrep() if ret_code == dbrerrno.ECNCLD: return if ret_code == dbrerrno.FEMPTY: err_dia = DetailedMessageDialog( GetMainWindow(), GT(u'Cannot Continue'), ICON_EXCLAMATION, text=u'{}\n{}'.format( GT(u'One of the required fields is empty:'), build_prep)) err_dia.ShowModal() err_dia.Destroy() return if ret_code == dbrerrno.SUCCESS: task_list, build_path, filename = build_prep # Actual build ret_code, result = self.Build(task_list, build_path, filename) # FIXME: Check .deb package timestamp to confirm build success if ret_code == dbrerrno.SUCCESS: DetailedMessageDialog( GetMainWindow(), GT(u'Success'), ICON_INFORMATION, text=GT(u'Package created successfully')).ShowModal() # Installing the package if FieldEnabled( self.chk_install) and self.chk_install.GetValue(): self.InstallPackage(result) return if result: ShowErrorDialog(GT(u'Package build failed'), result) else: ShowErrorDialog(GT(u'Package build failed with unknown error')) return if build_prep: ShowErrorDialog(GT(u'Build preparation failed'), build_prep) else: ShowErrorDialog(GT(u'Build preparation failed with unknown error'))
def AddPage(self, page): err_msg = None err_det = None if not isinstance(page, WizardPage): try: pagemod = u'wizbin.{}'.format(page) page = mimport(pagemod).Page(self) except ImportError: err_msg = u'module does not exist' err_det = traceback.format_exc() lyt_main = self.GetSizer() if not err_msg: # Must already be child if not isinstance(page, WizardPage): err_msg = u'not WizardPage instance' elif page not in self.GetChildren(): err_msg = u'not child of wizard' elif page in lyt_main.GetChildWindows(): err_msg = u'page is already added to wizard' if err_msg: err_msg = u'Cannot add page, {}'.format(err_msg) if err_det: ShowErrorDialog(err_msg, err_det) else: ShowErrorDialog(err_msg) return main_window = GetMainWindow() lyt_main.Add(page, 1, wx.EXPAND) self.Pages.append(page) # Add to page menu page_menu = GetMenu(menuid.PAGE) page_menu.AppendItem( wx.MenuItem(page_menu, page.Id, page.GetTitle(), kind=wx.ITEM_RADIO)) # Bind menu event to ID wx.EVT_MENU(main_window, page.Id, main_window.OnMenuChangePage)
def OnTimerStop(self, event=None): Logger.Debug(__name__, u'OnTimerStop') if not self.timer.IsRunning(): Logger.Debug(__name__, GT(u'Timer is stopped')) else: Logger.Debug(__name__, GT(u'Timer is running')) if self.build_error: error_lines = self.build_error[:-1] error_output = self.build_error[-1] ShowErrorDialog(error_lines, error_output, self) # Needs to be reset or error dialog will successively show self.build_error = None return msg_lines = ( GT(u'Quick build complete'), self.input_target.GetValue(), ) ShowMessageDialog(msg_lines, GT(u'Build Complete'), module=__name__)
def LaunchFirstRun(debreate_app): FR_dialog = FirstRun() debreate_app.SetTopWindow(FR_dialog) FR_dialog.ShowModal() init_conf_code = InitializeConfig() Logger.Debug( __name__, u'Configuration initialized: {}'.format( init_conf_code == ConfCode.SUCCESS)) if (init_conf_code != ConfCode.SUCCESS) or (not os.path.isfile(default_config)): msg_l1 = GT( u'An error occurred trying to create the configuration file:') msg_l2 = GT(u'Please report this error to Debreate\'s developers') ShowErrorDialog(u'{} {}\n\n{}'.format(msg_l1, default_config, msg_l2)) return init_conf_code FR_dialog.Destroy() # Delete first run dialog from memory del (FR_dialog) return init_conf_code
def OnExportLauncher(self, event=None): Logger.Debug(__name__, u'Export launcher ...') export = GetFileSaveDialog(GetMainWindow(), GT(u'Save Launcher')) if ShowDialog(export): target = export.GetPath() # Create a backup file # FIXME: Create backup files in WriteFile function? overwrite = False if os.path.isfile(target): backup = u'{}.backup'.format(target) shutil.copy(target, backup) overwrite = True try: self.ExportToFile(target) if overwrite: os.remove(backup) except UnicodeEncodeError: detail1 = GT( u'Unfortunately Debreate does not support unicode yet.') detail2 = GT( u'Remove any non-ASCII characters from your project.') ShowErrorDialog(GT(u'Save failed'), u'{}\n{}'.format(detail1, detail2), title=GT(u'Unicode Error')) os.remove(target) # Restore from backup shutil.move(backup, target)
def InstallPackage(self, package): system_installer = GetSystemInstaller() if not system_installer: ShowErrorDialog( GT(u'Cannot install package'), GT(u'A compatible package manager could not be found on the system' ), __name__, warn=True) return Logger.Info(__name__, GT(u'Attempting to install package: {}').format(package)) Logger.Info(__name__, GT(u'Installing with {}').format(system_installer)) install_cmd = ( system_installer, package, ) wx.Yield() # FIXME: Use ExecuteCommand here install_output = subprocess.Popen(install_cmd) # Command appears to not have been executed correctly if install_output == None: ShowErrorDialog(GT(u'Could not install package: {}'), GT(u'An unknown error occurred'), __name__) return # Command executed but did not return success code if install_output.returncode: err_details = ( GT(u'Process returned code {}').format( install_output.returncode), GT(u'Command executed: {}').format(u' '.join(install_cmd)), ) ShowErrorDialog(GT(u'An error occurred during installation'), u'\n'.join(err_details), __name__) return
def CheckErrors(self): if self.error_message: ShowErrorDialog(self.error_message, parent=self, linewrap=410) # Clear error message & return self.error_message = None return True return False
def OnCheckUpdate(self, event=None): #@UnusedVariable update_test = u'update-fail' in GetTestList() if UsingDevelopmentVersion() and not update_test: DetailedMessageDialog( self, GT(u'Update'), text=GT(u'Update checking is disabled in development versions' )).ShowModal() return wx.SafeYield() if update_test: # Set a bad url to force error current = GetCurrentVersion(u'http://dummyurl.blah/') else: current = GetCurrentVersion() Logger.Debug(__name__, GT(u'URL request result: {}').format(current)) error_remote = GT( u'An error occurred attempting to contact remote website') if isinstance(current, (URLError, HTTPError)): current = GS(current) ShowErrorDialog(error_remote, current) elif isinstance(current, tuple) and current > VERSION_tuple: current = u'{}.{}.{}'.format(current[0], current[1], current[2]) l1 = GT(u'Version {} is available!').format(current) l2 = GT(u'Would you like to go to Debreate\'s website?') if ConfirmationDialog(self, GT(u'Update'), u'{}\n\n{}'.format(l1, l2)).Confirmed(): wx.LaunchDefaultBrowser(APP_homepage) elif isinstance(current, (unicode, str)): ShowErrorDialog(error_remote, current) else: DetailedMessageDialog( self, GT(u'Debreate'), text=GT(u'Debreate is up to date!')).ShowModal()
def OnOpenLogFile(self, event=None): log_select = GetFileOpenDialog(self, GT(u'Open Log'), directory=PATH_logs) if ShowDialog(log_select): logFile = log_select.GetPath() if os.path.isfile(logFile): self.SetLogFile(logFile) return ShowErrorDialog(u'{}: {}'.format(GT(u'File does not exist'), logFile), parent=self)
def SetTabName(self, index=-1, rename=False, checkBox=None, checked=False): getname = TextEntryDialog(GetMainWindow(), GT(u'Name for new page')) new_name = None if not rename and checkBox: check_box = CheckBox(getname, label=checkBox) check_box.SetValue(checked) sizer = getname.GetSizer() insert_point = len(sizer.GetChildren()) - 1 sizer.InsertSpacer(insert_point, 5) sizer.Insert(insert_point + 1, check_box, 0, wx.LEFT, 16) getname.SetSize(sizer.GetMinSize()) getname.Fit() getname.CenterOnParent() valid_name = False while not valid_name: if new_name and TextIsEmpty(new_name): getname.Clear() # User cancelled if not ShowDialog(getname): return False else: new_name = getname.GetValue() valid_name = self._title_is_ok(new_name) if valid_name: break ShowErrorDialog(GT(u'Page name cannot contain whitespace'), warn=True) if rename: if index < 0: return False return self.Tabs.SetPageText(index, new_name) if checkBox: return self.AddPage(new_name, checkBox=check_box) return self.AddPage(new_name)
def ImportFromFile(self, filename): Logger.Debug(__name__, GT(u'Importing file: {}'.format(filename))) if not os.path.isfile(filename): ShowErrorDialog(GT(u'File does not exist: {}'.format(filename)), linewrap=600) return dbrerrno.ENOENT file_text = ReadFile(filename) page_depends = GetPage(pgid.DEPENDS) # Reset fields to default before opening self.Reset() page_depends.Reset() depends_data = self.Set(file_text) page_depends.Set(depends_data)
def ProjectOpenArchive(self, filename, file_type): Logger.Debug(__name__, GT(u'Compressed project archive detected')) if file_type not in compression_mimetypes: Logger.Error( __name__, GT(u'Cannot open project with compression mime type "{}"'. format(file_type))) return dbrerrno.EBADFT compression_id = compression_mimetypes[file_type] z_format = compression_formats[compression_id] if z_format in (u'tar', u'zip'): z_format = u'r' else: z_format = u'r:{}'.format(z_format) Logger.Debug( __name__, GT(u'Opening compressed project with "{}" format').format( z_format)) stage = CreateStage() p_archive = CompressionHandler(compression_id) ret_code = p_archive.Uncompress(filename, stage) if isinstance(ret_code, tuple) and ret_code[0]: ShowErrorDialog(u'{}: {}'.format(GT(u'Project load error'), ret_code[1]), ret_code[0], parent=self) return dbrerrno.EBADFT self.Wizard.ImportPagesInfo(stage) RemoveStage(stage) # Mark project as loaded return dbrerrno.SUCCESS
def GetObject(self, section_name=None, multiline=False, static=False, expand=False, removable=False): if static: try: self.sect_name = wx.StaticText(self.Parent, label=section_name) except TypeError: err_l1 = GT(u'Could not remove section') err_l2 = GT(u'Please report this problem to the developers') ShowErrorDialog(u'{}\n\n{}'.format(err_l1, err_l2), traceback.format_exc()) return None else: self.sect_name = Choice(self.Parent, choices=self.sections) if multiline: value = TextAreaPanel(self.Parent) FLAG_VALUE = wx.EXPAND | wx.LEFT FLAG_LABEL = wx.ALIGN_TOP else: value = TextArea(self.Parent) FLAG_VALUE = wx.ALIGN_CENTER_VERTICAL | wx.LEFT FLAG_LABEL = wx.ALIGN_CENTER_VERTICAL self.lyt_main.Add(self.sect_name, (0, 0), flag=FLAG_LABEL) self.lyt_main.Add(value, (0, 1), flag=FLAG_VALUE, border=5) if expand: self.lyt_main.AddGrowableCol(1) if removable: self.btn_remove = CreateButton(self.Parent, btnid.REMOVE) self.lyt_main.Add(self.btn_remove, (0, 2), flag=wx.RIGHT, border=5) return ManSectBase.GetObject(self)
def OnOpenPath(self, event=None): CMD_open = GetExecutable(u'xdg-open') if CMD_open: path = self.GetLicensePath() if not path: ShowErrorDialog(GT(u'Error retrieving template path: {}').format(self.GetSelectedName())) return False path = os.path.dirname(path) if os.path.isdir(path): ExecuteCommand(CMD_open, (path,)) return True return False
def SaveIt(path): # Gather data from different pages data = ( GetPage(pgid.CONTROL).GetSaveData(), GetPage(pgid.FILES).GetSaveData(), GetPage(pgid.SCRIPTS).GetSaveData(), GetPage(pgid.CHANGELOG).GetSaveData(), GetPage(pgid.COPYRIGHT).GetSaveData(), GetPage(pgid.MENU).GetSaveData(), GetPage(pgid.BUILD).GetSaveData(), ) # Create a backup of the project overwrite = False if os.path.isfile(path): backup = u'{}.backup'.format(path) shutil.copy(path, backup) overwrite = True # This try statement can be removed when unicode support is enabled try: WriteFile( path, u'[DEBREATE-{}]\n{}'.format(VERSION_string, u'\n'.join(data))) if overwrite: os.remove(backup) except UnicodeEncodeError: detail1 = GT( u'Unfortunately Debreate does not support unicode yet.') detail2 = GT( u'Remove any non-ASCII characters from your project.') ShowErrorDialog(GT(u'Save failed'), u'{}\n{}'.format(detail1, detail2), title=GT(u'Unicode Error')) if overwrite: os.remove(path) # Restore project backup shutil.move(backup, path)
def OnEndLabelEdit(self, event=None): if event: if event.IsEditCancelled(): Logger.Debug(__name__, u'Vetoing due to cancelled edit') event.Veto() return item = event.GetItem() for I in self.item_list: if I.GetBaseItem() == item: item = I break new_label = event.GetLabel() item_dir = os.path.dirname(item.Path) new_path = ConcatPaths((item_dir, new_label)) try: if os.path.exists(new_path): msg_l1 = GT(u'Name already exists:') ShowErrorDialog(u'{}\n\n{}'.format(msg_l1, new_path)) event.Veto() return os.rename(item.Path, new_path) ## ???: Another way to test if rename was successful? if os.path.exists(new_path): # Items path must be updated I.Path = new_path except OSError: Logger.Debug( __name__, u'Item not renamed, traceback details below:\n\n{}'.format( traceback.format_exc())) event.Veto() Logger.Debug(__name__, u'New item path: {}'.format(item.Path))
def SendToTrash(self, item_list): path_list = [] for I in item_list: if not os.access(I.Path, os.W_OK): ShowErrorDialog( GT(u'Cannot move "{}" to trash, no write access').format( I.Path), warn=True) return False path_list.append(I.Path) msg_l1 = GT(u'Move the following items to trash?') msg_l2 = u'\n'.join(path_list) if ConfirmationDialog(GetMainWindow(), GT(u'Delete'), u'{}\n\n{}'.format(msg_l1, msg_l2)).Confirmed(): arg_list = list(path_list) # Use 'force' argument to avoid crash on non-existing paths arg_list.insert(0, u'-f') ExecuteCommand(GetExecutable(u'gvfs-trash'), arg_list) Logger.Debug(__name__, u'Paths deleted') self.DeleteItems(item_list) Logger.Debug(__name__, u'Items deleted') # Confirm that paths were removed for P in path_list: if os.path.exists(P): Logger.Debug(__name__, u'Failed to remove "{}"'.format(P)) return False Logger.Debug(__name__, u'Items successfully moved to trash') return True return False
def OnExportLauncher(self, event=None): Logger.Debug(__name__, u'Export launcher ...') # Get data to write to control file menu_data = self.GetLauncherInfo().encode(u'utf-8') dia = wx.FileDialog(GetMainWindow(), GT(u'Save Launcher'), os.getcwd(), style=wx.FD_SAVE | wx.FD_CHANGE_DIR | wx.FD_OVERWRITE_PROMPT) if ShowDialog(dia): path = dia.GetPath() # Create a backup file overwrite = False if os.path.isfile(path): backup = u'{}.backup'.format(path) shutil.copy(path, backup) overwrite = True try: WriteFile(path, menu_data) if overwrite: os.remove(backup) except UnicodeEncodeError: detail1 = GT( u'Unfortunately Debreate does not support unicode yet.') detail2 = GT( u'Remove any non-ASCII characters from your project.') ShowErrorDialog(GT(u'Save failed'), u'{}\n{}'.format(detail1, detail2), title=GT(u'Unicode Error')) os.remove(path) # Restore from backup shutil.move(backup, path)
def SetChangelog(self): ## Defines where the changelog is located # # By default it is located in the folder 'doc' # under the applications root directory. The # install script or Makefile should change this # to reflect installed path. CHANGELOG = u'{}/docs/changelog'.format(PATH_app) if os.path.isfile(CHANGELOG): changelog_mimetype = GetFileMimeType(CHANGELOG) Logger.Debug( __name__, GT(u'Changelog mimetype: {}').format(changelog_mimetype)) # Set log text in case of read error log_text = GT(u'Error reading changelog: {}\n\t').format(CHANGELOG) log_text = u'{}{}'.format( log_text, GT(u'Cannot decode, unrecognized mimetype: {}').format( changelog_mimetype)) if changelog_mimetype == u'text/plain': log_text = ReadFile(CHANGELOG) else: ShowErrorDialog(log_text, parent=self) else: log_text = GT( u'ERROR: Could not locate changelog file:\n\t\'{}\' not found'. format(CHANGELOG)) self.changelog.SetValue(log_text) self.changelog.SetInsertionPoint(0)
def Build(self, task_list, build_path, filename): # Declare this here in case of error before progress dialog created build_progress = None try: # Other mandatory tasks that will be processed mandatory_tasks = ( u'stage', u'install_size', u'control', u'build', ) # Add other mandatory tasks for T in mandatory_tasks: task_list[T] = None task_count = len(task_list) # Add each file for updating progress dialog if u'files' in task_list: task_count += len(task_list[u'files']) # Add each script for updating progress dialog if u'scripts' in task_list: task_count += len(task_list[u'scripts']) if DebugEnabled(): task_msg = GT(u'Total tasks: {}').format(task_count) print(u'DEBUG: [{}] {}'.format(__name__, task_msg)) for T in task_list: print(u'\t{}'.format(T)) create_changelog = u'changelog' in task_list create_copyright = u'copyright' in task_list pg_control = GetPage(pgid.CONTROL) pg_menu = GetPage(pgid.MENU) stage_dir = u'{}/{}__dbp__'.format(build_path, filename) if os.path.isdir(u'{}/DEBIAN'.format(stage_dir)): try: shutil.rmtree(stage_dir) except OSError: ShowErrorDialog( GT(u'Could not free stage directory: {}').format( stage_dir), title=GT(u'Cannot Continue')) return (dbrerrno.EEXIST, None) # Actual path to new .deb deb = u'"{}/{}.deb"'.format(build_path, filename) progress = 0 task_msg = GT(u'Preparing build tree') Logger.Debug(__name__, task_msg) wx.Yield() build_progress = ProgressDialog( GetMainWindow(), GT(u'Building'), task_msg, maximum=task_count, style=PD_DEFAULT_STYLE | wx.PD_ELAPSED_TIME | wx.PD_ESTIMATED_TIME | wx.PD_CAN_ABORT) DIR_debian = ConcatPaths((stage_dir, u'DEBIAN')) # Make a fresh build tree os.makedirs(DIR_debian) progress += 1 if build_progress.WasCancelled(): build_progress.Destroy() return (dbrerrno.ECNCLD, None) def UpdateProgress(current_task, message=None): task_eval = u'{} / {}'.format(current_task, task_count) if message: Logger.Debug(__name__, u'{} ({})'.format(message, task_eval)) wx.Yield() build_progress.Update(current_task, message) return wx.Yield() build_progress.Update(current_task) # *** Files *** # if u'files' in task_list: UpdateProgress(progress, GT(u'Copying files')) no_follow_link = GetField(GetPage(pgid.FILES), chkid.SYMLINK).IsChecked() # TODO: move this into a file functions module def _copy(f_src, f_tgt, exe=False): # NOTE: Python 3 appears to have follow_symlinks option for shutil.copy # FIXME: copying nested symbolic link may not work if os.path.isdir(f_src): if os.path.islink(f_src) and no_follow_link: Logger.Debug( __name__, u'Adding directory symbolic link to stage: {}'. format(f_tgt)) os.symlink(os.readlink(f_src), f_tgt) else: Logger.Debug( __name__, u'Adding directory to stage: {}'.format(f_tgt)) shutil.copytree(f_src, f_tgt) os.chmod(f_tgt, 0o0755) elif os.path.isfile(f_src): if os.path.islink(f_src) and no_follow_link: Logger.Debug( __name__, u'Adding file symbolic link to stage: {}'. format(f_tgt)) os.symlink(os.readlink(f_src), f_tgt) else: if exe: Logger.Debug( __name__, u'Adding executable to stage: {}'.format( f_tgt)) else: Logger.Debug( __name__, u'Adding file to stage: {}'.format(f_tgt)) shutil.copy(f_src, f_tgt) # Set FILE permissions if exe: os.chmod(f_tgt, 0o0755) else: os.chmod(f_tgt, 0o0644) files_data = task_list[u'files'] for FILE in files_data: file_defs = FILE.split(u' -> ') source_file = file_defs[0] target_file = u'{}{}/{}'.format(stage_dir, file_defs[2], file_defs[1]) target_dir = os.path.dirname(target_file) if not os.path.isdir(target_dir): os.makedirs(target_dir) # Remove asteriks from exectuables exe = False if source_file[-1] == u'*': exe = True source_file = source_file[:-1] _copy( source_file, u'{}/{}'.format(target_dir, os.path.basename(source_file)), exe) # Individual files progress += 1 UpdateProgress(progress) # Entire file task progress += 1 if build_progress.WasCancelled(): build_progress.Destroy() return (dbrerrno.ECNCLD, None) # *** Strip files ***# # FIXME: Needs only be run if 'files' step is used if u'strip' in task_list: UpdateProgress(progress, GT(u'Stripping binaries')) for ROOT, DIRS, FILES in os.walk(stage_dir): #@UnusedVariable for F in FILES: # Don't check files in DEBIAN directory if ROOT != DIR_debian: F = ConcatPaths((ROOT, F)) if FileUnstripped(F): Logger.Debug(__name__, u'Unstripped file: {}'.format(F)) # FIXME: Strip command should be set as class member? ExecuteCommand(GetExecutable(u'strip'), F) progress += 1 if build_progress.WasCancelled(): build_progress.Destroy() return (dbrerrno.ECNCLD, None) package = GetField(pg_control, inputid.PACKAGE).GetValue() # Make sure that the directory is available in which to place documentation if create_changelog or create_copyright: doc_dir = u'{}/usr/share/doc/{}'.format(stage_dir, package) if not os.path.isdir(doc_dir): os.makedirs(doc_dir) # *** Changelog *** # if create_changelog: UpdateProgress(progress, GT(u'Creating changelog')) # If changelog will be installed to default directory changelog_target = task_list[u'changelog'][0] if changelog_target == u'STANDARD': changelog_target = ConcatPaths( (u'{}/usr/share/doc'.format(stage_dir), package)) else: changelog_target = ConcatPaths( (stage_dir, changelog_target)) if not os.path.isdir(changelog_target): os.makedirs(changelog_target) WriteFile(u'{}/changelog'.format(changelog_target), task_list[u'changelog'][1]) CMD_gzip = GetExecutable(u'gzip') if CMD_gzip: UpdateProgress(progress, GT(u'Compressing changelog')) c = u'{} -n --best "{}/changelog"'.format( CMD_gzip, changelog_target) clog_status = commands.getstatusoutput(c.encode(u'utf-8')) if clog_status[0]: ShowErrorDialog(GT(u'Could not compress changelog'), clog_status[1], warn=True, title=GT(u'Warning')) progress += 1 if build_progress.WasCancelled(): build_progress.Destroy() return (dbrerrno.ECNCLD, None) # *** Copyright *** # if create_copyright: UpdateProgress(progress, GT(u'Creating copyright')) WriteFile( u'{}/usr/share/doc/{}/copyright'.format( stage_dir, package), task_list[u'copyright']) progress += 1 if build_progress.WasCancelled(): build_progress.Destroy() return (dbrerrno.ECNCLD, None) # Characters that should not be in filenames invalid_chars = (u' ', u'/') # *** Menu launcher *** # if u'launcher' in task_list: UpdateProgress(progress, GT(u'Creating menu launcher')) # This might be changed later to set a custom directory menu_dir = u'{}/usr/share/applications'.format(stage_dir) menu_filename = pg_menu.GetOutputFilename() # Remove invalid characters from filename for char in invalid_chars: menu_filename = menu_filename.replace(char, u'_') if not os.path.isdir(menu_dir): os.makedirs(menu_dir) WriteFile(u'{}/{}.desktop'.format(menu_dir, menu_filename), task_list[u'launcher']) progress += 1 if build_progress.WasCancelled(): build_progress.Destroy() return (dbrerrno.ECNCLD, None) # *** md5sums file *** # # Good practice to create hashes before populating DEBIAN directory if u'md5sums' in task_list: UpdateProgress(progress, GT(u'Creating md5sums')) if not WriteMD5(stage_dir, parent=build_progress): # Couldn't call md5sum command build_progress.Cancel() progress += 1 if build_progress.WasCancelled(): build_progress.Destroy() return (dbrerrno.ECNCLD, None) # *** Scripts *** # if u'scripts' in task_list: UpdateProgress(progress, GT(u'Creating scripts')) scripts = task_list[u'scripts'] for SCRIPT in scripts: script_name = SCRIPT script_text = scripts[SCRIPT] script_filename = ConcatPaths( (stage_dir, u'DEBIAN', script_name)) WriteFile(script_filename, script_text) # Make sure scipt path is wrapped in quotes to avoid whitespace errors os.chmod(script_filename, 0755) os.system((u'chmod +x "{}"'.format(script_filename))) # Individual scripts progress += 1 UpdateProgress(progress) # Entire script task progress += 1 if build_progress.WasCancelled(): build_progress.Destroy() return (dbrerrno.ECNCLD, None) # *** Control file *** # UpdateProgress(progress, GT(u'Getting installed size')) # Get installed-size installed_size = os.popen( (u'du -hsk "{}"'.format(stage_dir))).readlines() installed_size = installed_size[0].split(u'\t') installed_size = installed_size[0] # Insert Installed-Size into control file control_data = pg_control.Get().split(u'\n') control_data.insert(2, u'Installed-Size: {}'.format(installed_size)) progress += 1 if build_progress.WasCancelled(): build_progress.Destroy() return (dbrerrno.ECNCLD, None) # Create final control file UpdateProgress(progress, GT(u'Creating control file')) # dpkg fails if there is no newline at end of file control_data = u'\n'.join(control_data).strip(u'\n') # Ensure there is only one empty trailing newline # Two '\n' to show physical empty line, but not required # Perhaps because string is not null terminated??? control_data = u'{}\n\n'.format(control_data) WriteFile(u'{}/DEBIAN/control'.format(stage_dir), control_data, noStrip=u'\n') progress += 1 if build_progress.WasCancelled(): build_progress.Destroy() return (dbrerrno.ECNCLD, None) # *** Final build *** # UpdateProgress(progress, GT(u'Running dpkg')) working_dir = os.path.split(stage_dir)[0] c_tree = os.path.split(stage_dir)[1] deb_package = u'{}.deb'.format(filename) # Move the working directory becuase dpkg seems to have problems with spaces in path os.chdir(working_dir) # HACK to fix file/dir permissions for ROOT, DIRS, FILES in os.walk(stage_dir): for D in DIRS: D = u'{}/{}'.format(ROOT, D) os.chmod(D, 0o0755) for F in FILES: F = u'{}/{}'.format(ROOT, F) if os.access(F, os.X_OK): os.chmod(F, 0o0755) else: os.chmod(F, 0o0644) # FIXME: Should check for working fakeroot & dpkg-deb executables build_status = commands.getstatusoutput( (u'{} {} -b "{}" "{}"'.format(GetExecutable(u'fakeroot'), GetExecutable(u'dpkg-deb'), c_tree, deb_package))) progress += 1 if build_progress.WasCancelled(): build_progress.Destroy() return (dbrerrno.ECNCLD, None) # *** Delete staged directory *** # if u'rmstage' in task_list: UpdateProgress(progress, GT(u'Removing temp directory')) try: shutil.rmtree(stage_dir) except OSError: ShowErrorDialog(GT( u'An error occurred when trying to delete the build tree' ), parent=build_progress) progress += 1 if build_progress.WasCancelled(): build_progress.Destroy() return (dbrerrno.ECNCLD, None) # *** ERROR CHECK if u'lintian' in task_list: UpdateProgress(progress, GT(u'Checking package for errors')) # FIXME: Should be set as class memeber? CMD_lintian = GetExecutable(u'lintian') errors = commands.getoutput((u'{} {}'.format(CMD_lintian, deb))) if errors != wx.EmptyString: e1 = GT(u'Lintian found some issues with the package.') e2 = GT(u'Details saved to {}').format(filename) WriteFile(u'{}/{}.lintian'.format(build_path, filename), errors) DetailedMessageDialog(build_progress, GT(u'Lintian Errors'), ICON_INFORMATION, u'{}\n{}.lintian'.format(e1, e2), errors).ShowModal() progress += 1 # Close progress dialog wx.Yield() build_progress.Update(progress) build_progress.Destroy() # Build completed successfullly if not build_status[0]: return (dbrerrno.SUCCESS, deb_package) if PY_VER_MAJ <= 2: # Unicode decoder has trouble with certain characters. Replace any # non-decodable characters with � (0xFFFD). build_output = list(build_status[1]) # String & unicode string incompatibilities index = 0 for C in build_output: try: GS(C) except UnicodeDecodeError: build_output[index] = u'�' index += 1 build_status = (build_status[0], u''.join(build_output)) # Build failed return (build_status[0], build_status[1]) except: if build_progress: build_progress.Destroy() return (dbrerrno.EUNKNOWN, traceback.format_exc())
def OnUpdateCache(self, event=None): try: # Timer must be started before executing new thread self.timer.Start(100) if not self.timer.IsRunning(): self.error_message = GT( u'Could not start progress dialog timer') self.CheckErrors() return False self.Disable() # Start new thread for updating cache in background Thread(self.UpdateCache, None).Start() # Create the progress dialog & start timer # NOTE: Progress dialog is reset by timer stop event self.progress = ProgressDialog( self, message=GT(u'Contacting remote sites'), style=wx.PD_APP_MODAL | wx.PD_AUTO_HIDE) # Use ShowModal to wait for timer to stop before continuing self.progress.ShowModal() self.Enable() if self.CheckErrors(): return False # FIXME: Should check timestamps to make sure file was updated cache_updated = os.path.isfile(FILE_distnames) if cache_updated: distname_input = GetField(pgid.CHANGELOG, inputid.DIST) if isinstance(distname_input, OwnerDrawnComboBox): distname_input.Set(GetOSDistNames()) else: ShowMessageDialog(GT( u'The distribution names cache has been updated but Debreate needs to restart to reflect the changes on the changelog page' ), parent=self, linewrap=410) self.btn_preview.Enable(cache_updated) return cache_updated except: # Make sure dialog is re-enabled self.Enable() # Make sure progress dialog & background thread instances are reset to None if self.progress: self.progress.EndModal(0) self.progress = None cache_exists = os.path.isfile(FILE_distnames) err_msg = GT( u'An error occurred when trying to update the distribution names cache' ) err_msg2 = GT( u'The cache file exists but may not have been updated') if cache_exists: err_msg = u'{}\n\n{}'.format(err_msg, err_msg2) ShowErrorDialog(err_msg, traceback.format_exc(), self) self.btn_preview.Enable(cache_exists) return False
def LoadPaths(self, pathsList): if isinstance(pathsList, tuple): pathsList = list(pathsList) if not pathsList or not isinstance(pathsList, list): return False file_list = [] dir_list = {} prep = ProgressDialog(GetMainWindow(), GT(u'Processing Files'), GT(u'Scanning files ...'), style=wx.PD_APP_MODAL|wx.PD_AUTO_HIDE|wx.PD_CAN_ABORT) # Only update the gauge every N files (hack until I figure out timer) update_interval = 450 count = 0 prep.Show() if not self.chk_preserve_top.GetValue(): for INDEX in reversed(range(len(pathsList))): path = pathsList[INDEX] if os.path.isdir(path): # Remove top-level directory from list pathsList.pop(INDEX) insert_index = INDEX for P in os.listdir(path): pathsList.insert(insert_index, ConcatPaths((path, P))) insert_index += 1 try: for P in pathsList: if prep.WasCancelled(): prep.Destroy() return False count += 1 if count >= update_interval: wx.Yield() prep.Pulse() count = 0 if not self.chk_individuals.GetValue() or os.path.isfile(P): file_list.append(P) continue if os.path.isdir(P): parent_dir = os.path.dirname(P) if parent_dir not in dir_list: dir_list[parent_dir] = [] for ROOT, DIRS, FILES in os.walk(P): if prep.WasCancelled(): prep.Destroy() return False wx.Yield() prep.SetMessage(GT(u'Scanning directory {} ...').format(ROOT)) count += 1 if count >= update_interval: wx.Yield() prep.Pulse() count = 0 for F in FILES: if prep.WasCancelled(): prep.Destroy() return False count += 1 if count >= update_interval: wx.Yield() prep.Pulse() count = 0 # os.path.dirname preserves top level directory ROOT = ROOT.replace(os.path.dirname(P), u'').strip(u'/') F = u'{}/{}'.format(ROOT, F).strip(u'/') if F not in dir_list[parent_dir]: dir_list[parent_dir].append(F) except: prep.Destroy() ShowErrorDialog(GT(u'Could not retrieve file list'), traceback.format_exc()) return False wx.Yield() prep.Pulse(GT(u'Counting Files')) file_count = len(file_list) count = 0 for D in dir_list: for F in dir_list[D]: file_count += 1 count += 1 if count >= update_interval: wx.Yield() prep.Pulse() count = 0 prep.Destroy() # Add files to directory list for F in file_list: f_name = os.path.basename(F) f_dir = os.path.dirname(F) if f_dir not in dir_list: dir_list[f_dir] = [] dir_list[f_dir].append(f_name) if file_count > warning_threshhold: count_warnmsg = GT(u'Importing {} files'.format(file_count)) count_warnmsg = u'{}. {}.'.format(count_warnmsg, GT(u'This could take a VERY long time')) count_warnmsg = u'{}\n{}'.format(count_warnmsg, GT(u'Are you sure you want to continue?')) if not ConfirmationDialog(GetMainWindow(), text=count_warnmsg).Confirmed(): return False return self.AddPaths(dir_list, file_count, showDialog=file_count >= efficiency_threshold)
def OnBuild(self, event=None): if event: event.Skip() # Show control file preview for editing if UsingTest(u'alpha') and self.chk_editctrl.GetValue(): self.EditControl() wizard = GetWizard() pg_control = wizard.GetPage(pgid.CONTROL) pg_files = wizard.GetPage(pgid.FILES) pg_launcher = wizard.GetPage(pgid.LAUNCHERS) required_fields = { GT(u'Control'): pg_control.GetRequiredFields(), } # Check if launchers are enabled for build if pg_launcher.GetLaunchersCount(): required_fields[GT( u'Menu Launcher')] = pg_launcher.GetRequiredFields() # FIXME: Old code won't work with multiple launchers for RF in required_fields[GT(u'Menu Launcher')]: Logger.Debug( __name__, GT(u'Required field (Menu Launcher): {}').format( RF.GetName())) for p_name in required_fields: Logger.Debug(__name__, GT(u'Page name: {}').format(p_name)) for F in required_fields[p_name]: if not isinstance(F, wx.StaticText) and TextIsEmpty( F.GetValue()): f_name = F.GetName() msg_l1 = GT(u'One of the required fields is empty:') msg_full = u'{}: {} ➜ {}'.format(msg_l1, p_name, f_name) Logger.Warn(__name__, msg_full) DetailedMessageDialog(GetMainWindow(), GT(u'Cannot Continue'), ICON_EXCLAMATION, text=msg_full).ShowModal() for P in wizard.GetAllPages(): if P.GetTitle() == p_name: Logger.Debug( __name__, GT(u'Showing page with required field: {}'). format(p_name)) wizard.ShowPage(P.GetId()) return if GetField(pg_files, inputid.LIST).MissingFiles(): ShowErrorDialog(GT(u'Files are missing in file list'), warn=True, title=GT(u'Warning')) wizard.ShowPage(pgid.FILES) return ttype = GT(u'Debian Packages') save_dialog = GetFileSaveDialog(GetMainWindow(), GT(u'Build Package'), u'{} (*.deb)|*.deb'.format(ttype), u'deb') package = GetFieldValue(pg_control, inputid.PACKAGE) version = GetFieldValue(pg_control, inputid.VERSION) arch = GetFieldValue(pg_control, inputid.ARCH) save_dialog.SetFilename(u'{}_{}_{}.deb'.format(package, version, arch)) if ShowDialog(save_dialog): self.Build(save_dialog.GetPath())
def BuildPrep(self): wizard = GetWizard() prep_ids = [] pages = wizard.GetAllPages() for P in pages: if P.prebuild_check: Logger.Debug( __name__, GT(u'Pre-build check for page "{}"'.format(P.GetName()))) prep_ids.append(P.GetId()) try: main_window = GetMainWindow() # List of page IDs to process during build pg_build_ids = [] steps_count = len(prep_ids) current_step = 0 msg_label1 = GT(u'Prepping page "{}"') msg_label2 = GT(u'Step {}/{}') msg_label = u'{} ({})'.format(msg_label1, msg_label2) prep_progress = ProgressDialog( main_window, GT(u'Preparing Build'), msg_label2.format(current_step, steps_count), maximum=steps_count, style=PD_DEFAULT_STYLE | wx.PD_CAN_ABORT) for P in pages: if prep_progress.WasCancelled(): break p_id = P.GetId() p_label = P.GetTitle() if p_id in prep_ids: Logger.Debug( __name__, msg_label.format(p_label, current_step + 1, steps_count)) wx.Yield() prep_progress.Update( current_step, msg_label.format(p_label, current_step + 1, steps_count)) if P.IsOkay(): pg_build_ids.append(p_id) current_step += 1 if not prep_progress.WasCancelled(): wx.Yield() prep_progress.Update(current_step, GT(u'Prepping finished')) # Show finished dialog for short period time.sleep(1) prep_progress.Destroy() return pg_build_ids except: prep_progress.Destroy() ShowErrorDialog(GT(u'Error occurred during pre-build'), traceback.format_exc()) return None
def Build(self, outFile): def log_message(msg, current_step, total_steps): return u'{} ({}/{})'.format(msg, current_step, total_steps) wizard = GetWizard() pages_build_ids = self.BuildPrep() if pages_build_ids != None: main_window = GetMainWindow() # Reported at the end of build build_summary = [] steps_count = len(pages_build_ids) current_step = 0 # Steps from build page for chk in self.chk_md5, self.chk_lint, self.chk_rmstage: if chk.IsChecked(): steps_count += 1 # Control file & .deb build step steps_count += 2 stage = CreateStage() log_msg = GT(u'Starting build') wx.YieldIfNeeded() # FIXME: Enable PD_CAN_ABORT build_progress = ProgressDialog(main_window, GT(u'Building'), log_msg, maximum=steps_count) build_summary.append(u'{}:'.format(log_msg)) try: for P in wizard.GetAllPages(): if build_progress.WasCancelled(): break if P.GetId() in pages_build_ids: p_label = P.GetTitle() log_msg = log_message( GT(u'Processing page "{}"').format(p_label), current_step + 1, steps_count) # FIXME: Progress bar not updating??? wx.YieldIfNeeded() build_progress.Update(current_step, log_msg) ret_code, ret_value = P.ExportBuild(stage) build_summary.append(u'\n{}:\n{}'.format( log_msg, ret_value)) if ret_code > 0: build_progress.Destroy() ShowErrorDialog(GT(u'Error occurred during build'), ret_value) return current_step += 1 # *** Control File *** # if not build_progress.WasCancelled(): wx.YieldIfNeeded() log_msg = log_message(GT(u'Creating control file'), current_step + 1, steps_count) build_progress.Update(current_step, log_msg) Logger.Debug(__name__, log_msg) # Retrieve control page pg_control = wizard.GetPage(pgid.CONTROL) if not pg_control: build_progress.Destroy() ShowErrorDialog( GT(u'Could not retrieve control page'), GT(u'Please contact the developer: {}').format( AUTHOR_email), title=u'Fatal Error') return installed_size = self.OnBuildGetInstallSize(stage) Logger.Debug( __name__, GT(u'Installed size: {}').format(installed_size)) build_summary.append(u'\n{}:'.format(log_msg)) build_summary.append( pg_control.ExportBuild( u'{}/DEBIAN'.format(stage).replace(u'//', u'/'), installed_size)) current_step += 1 # *** MD5 Checksum *** # if not build_progress.WasCancelled(): if self.chk_md5.GetValue() and GetExecutable(u'md5sum'): log_msg = log_message(GT(u'Creating MD5 checksum'), current_step + 1, steps_count) #log_msg = GT(u'Creating MD5 checksum') #step = u'{}/{}'.format(current_step+1, steps_count) Logger.Debug(__name__, log_msg) wx.YieldIfNeeded() build_progress.Update(current_step, log_msg) build_summary.append(u'\n{}:'.format(log_msg)) build_summary.append(self.OnBuildMD5Sum(stage)) current_step += 1 # *** Create .deb from Stage *** # if not build_progress.WasCancelled(): log_msg = log_message(GT(u'Creating .deb package'), current_step + 1, steps_count) wx.YieldIfNeeded() build_progress.Update(current_step, log_msg) build_summary.append(u'\n{}:'.format(log_msg)) build_summary.append( self.OnBuildCreatePackage(stage, outFile)) current_step += 1 # *** Lintian *** # if not build_progress.WasCancelled(): if self.chk_lint.IsChecked(): log_msg = log_message( GT(u'Checking package with lintian'), current_step + 1, steps_count) wx.YieldIfNeeded() build_progress.Update(current_step, log_msg) build_summary.append(u'\n{}:'.format(log_msg)) build_summary.append(self.OnBuildCheckPackage(outFile)) current_step += 1 # *** Delete Stage *** # if not build_progress.WasCancelled(): if self.chk_rmstage.IsChecked(): log_msg = log_message( GT(u'Removing staged build tree'), current_step + 1, steps_count) wx.YieldIfNeeded() build_progress.Update(current_step, log_msg) build_summary.append(u'\n{}:'.format(log_msg)) RemoveStage(stage) if not os.path.isdir(stage): build_summary.append( GT(u'Staged build tree removed successfully')) else: build_summary.append( GT(u'Failed to remove staged build tree')) current_step += 1 # *** Show Completion Status *** # wx.YieldIfNeeded() build_progress.Update(steps_count, GT(u'Build completed')) # Show finished dialog for short moment time.sleep(1) # TODO: Add error count to build summary build_progress.Destroy() build_summary = u'\n'.join(build_summary) summary_dialog = DetailedMessageDialog(main_window, GT(u'Build Summary'), ICON_INFORMATION, GT(u'Build completed'), build_summary) summary_dialog.ShowModal() except: build_progress.Destroy() ShowErrorDialog(GT(u'Error occurred during build'), traceback.format_exc()) return
def SetChangelog(self): ## Defines where the changelog is located # # By default it is located in the folder 'doc' # under the applications root directory. The # install script or Makefile should change this # to reflect installed path. if INSTALLED: # FIXME: Read compressed .gz changelog CHANGELOG = u'{}/share/doc/debreate/changelog.gz'.format(PREFIX) else: CHANGELOG = u'{}/docs/changelog'.format(PREFIX) if os.path.isfile(CHANGELOG): changelog_mimetype = GetFileMimeType(CHANGELOG) Logger.Debug( __name__, GT(u'Changelog mimetype: {}').format(changelog_mimetype)) # Set log text in case of read error log_text = GT(u'Error reading changelog: {}\n\t').format(CHANGELOG) log_text = u'{}{}'.format( log_text, GT(u'Cannot decode, unrecognized mimetype: {}').format( changelog_mimetype)) if changelog_mimetype == u'application/gzip': temp_dir = CreateStage() shutil.copy(CHANGELOG, temp_dir) CMD_gzip = GetExecutable(u'gzip') if CMD_gzip: prev_dir = os.getcwd() os.chdir(temp_dir) gzip_output = commands.getstatusoutput(u'{} -fd {}'.format( CMD_gzip, os.path.basename(CHANGELOG))) Logger.Debug( __name__, GT(u'gzip decompress; Code: {}, Output: {}').format( gzip_output[0], gzip_output[1])) os.chdir(prev_dir) changelog_file = os.path.basename(CHANGELOG).split(u'.')[0] changelog_file = u'{}/{}'.format(temp_dir, changelog_file) if os.path.isfile(changelog_file): log_text = ReadFile(changelog_file) RemoveStage(temp_dir) elif changelog_mimetype == u'text/plain': log_text = ReadFile(CHANGELOG) else: ShowErrorDialog(log_text, parent=self) else: log_text = GT( u'ERROR: Could not locate changelog file:\n\t\'{}\' not found'. format(CHANGELOG)) self.changelog.SetValue(log_text) self.changelog.SetInsertionPoint(0)
def OnBuild(self, event=None): stage = self.input_stage.GetValue() target = self.input_target.GetValue().rstrip(u'/') # Attempt to use DEBIAN/control file to set output filename. This is normally # done automatically by the dpkg command, but we need to set it manually to # check for overwriting a file. if os.path.isdir(target): control_file = ConcatPaths((stage, u'DEBIAN/control')) if os.path.isfile(control_file): control_lines = ReadFile(control_file, split=True) name = None version = None arch = None for LINE in control_lines: if LINE.startswith(u'Package:'): name = LINE.replace(u'Package: ', u'').strip() elif LINE.startswith(u'Version:'): version = LINE.replace(u'Version: ', u'').strip() elif LINE.startswith(u'Architecture:'): arch = LINE.replace(u'Architecture: ', u'').strip() if name and version and arch: target = ConcatPaths((target, u'{}.deb'.format(u'_'.join(( name, version, arch, ))))) # Automatically add .deb filename extension if not present elif not target.lower().endswith(u'.deb'): target = u'{}.deb'.format(target) if not os.path.isdir(stage): ShowErrorDialog(GT(u'Stage directory does not exist'), stage, self, True) return target_path = os.path.dirname(target) if not os.path.isdir(target_path): ShowErrorDialog(GT(u'Target directory does not exist'), target_path, self, True) return elif not os.access(target_path, os.W_OK): ShowErrorDialog(GT(u'No write access to target directory'), target_path, self, True) return # Update the text input if target altered if target != self.input_target.GetValue(): self.input_target.SetValue(target) # Check for pre-existing file if os.path.isfile(target): if not OverwriteDialog(self, target).Confirmed(): return self.SetTitle(u'{} ({})'.format(self.title, GT(u'in progress'))) # Don't allow dialog to be closed while build in progress self.Disable() self.timer.Start(100) # Start new thread for background process Thread(self.Build, stage, target).Start()
def ProjectOpen(self, project_file=None): Logger.Debug(__name__, u'Opening project: {}'.format(project_file)) # Need to show file open dialog because no project file was specified if not project_file: wc_z = GetDialogWildcards(ID_PROJ_Z) wc_l = GetDialogWildcards(ID_PROJ_L) wc_a = GetDialogWildcards(ID_PROJ_A) wc_t = GetDialogWildcards(ID_PROJ_T) wildcards = ( wc_a[0], wc_a[1], wc_z[0], wc_z[1], wc_t[0], wc_t[1], wc_l[0], wc_l[1], ) open_dialog = GetFileOpenDialog(self, GT(u'Open Debreate Project'), wildcards) if not ShowDialog(open_dialog): return dbrerrno.ECNCLD # Get the path and set the saved project project_file = open_dialog.GetPath() # Failsafe check that file exists if not os.path.isfile(project_file): err_l1 = GT(u'Cannot open project:') err_details = GT(u'File does not exist') ShowErrorDialog(u'{} {}'.format(err_l1, project_file), err_details) return dbrerrno.ENOENT # Check for unsaved changes & reset project to defaults if not self.ProjectClose(): return dbrerrno.ECNCLD mime_type = GetFileMimeType(project_file) Logger.Debug(__name__, GT(u'Project mime type: {}').format(mime_type)) opened = None if mime_type == u'text/plain': p_text = ReadFile(project_file) filename = os.path.split(project_file)[1] # Legacy projects should return None since we can't save in that format opened = self.ProjectOpenLegacy(p_text, filename) else: opened = self.ProjectOpenArchive(project_file, mime_type) Logger.Debug( __name__, GT(u'Project loaded before OnProjectOpen: {}').format( self.ProjectIsLoaded())) if opened == dbrerrno.SUCCESS: self.LoadedProject = project_file # Set project 'unmodified' for newly opened project self.ProjectSetDirty(False) Logger.Debug( __name__, GT(u'Project loaded after OnOpenPreject: {}').format( self.ProjectIsLoaded())) if DebugEnabled() and self.ProjectIsLoaded(): Logger.Debug(__name__, GT(u'Loaded project: {}').format(self.LoadedProject)) return opened
def OpenProject(self, project_file): Logger.Debug(__name__, u'Opening project: {}'.format(project_file)) if not os.path.isfile(project_file): ShowErrorDialog( GT(u'Could not open project file'), GT(u'File does not exist or is not a regular file: {}').format( project_file)) return False data = ReadFile(project_file) lines = data.split(u'\n') # FIXME: Need a better way to determine valid project app = lines[0].lstrip(u'[') if not app.startswith(u'DEBREATE'): ShowErrorDialog( GT(u'Could not open project file'), GT(u'Not a valid Debreate project: {}').format(project_file)) return False if self.LoadedProject and not self.ResetPages(): return False # *** Get Control Data *** # control_data = data.split(u'<<CTRL>>\n')[1].split(u'\n<</CTRL>>')[0] depends_data = self.Wizard.GetPage(pgid.CONTROL).Set(control_data) self.Wizard.GetPage(pgid.DEPENDS).Set(depends_data) # *** Get Files Data *** # files_data = data.split(u'<<FILES>>\n')[1].split(u'\n<</FILES>>')[0] opened = self.Wizard.GetPage(pgid.FILES).Set(files_data) # *** Get Scripts Data *** # scripts_data = data.split(u'<<SCRIPTS>>\n')[1].split( u'\n<</SCRIPTS>>')[0] self.Wizard.GetPage(pgid.SCRIPTS).Set(scripts_data) # *** Get Changelog Data *** # clog_data = data.split(u'<<CHANGELOG>>\n')[1].split( u'\n<</CHANGELOG>>')[0] self.Wizard.GetPage(pgid.CHANGELOG).Set(clog_data) # *** Get Copyright Data *** # try: cpright_data = data.split(u'<<COPYRIGHT>>\n')[1].split( u'\n<</COPYRIGHT')[0] self.Wizard.GetPage(pgid.COPYRIGHT).Set(cpright_data) except IndexError: pass # *** Get Menu Data *** # m_data = data.split(u'<<MENU>>\n')[1].split(u'\n<</MENU>>')[0] self.Wizard.GetPage(pgid.MENU).SetLauncherData(m_data, enabled=True) # Get Build Data build_data = data.split(u'<<BUILD>>\n')[1].split(u'\n<</BUILD')[ 0] #.split(u'\n') self.Wizard.GetPage(pgid.BUILD).Set(build_data) return opened
def OnTemplateFull(self, event=None): selected_template = self.sel_templates.GetStringSelection() template_file = self.GetLicensePath(selected_template) if self.DestroyLicenseText(): if not template_file or not os.path.isfile(template_file): ShowErrorDialog(GT(u'Could not locate license file: {}').format(self.GetSelectedName())) return Logger.Debug(__name__, u'Copying license {}'.format(template_file)) license_text = ReadFile(template_file, noStrip=u' ') # Number defines how many empty lines to add after the copyright header # Boolean/Integer defines whether copyright header should be centered/offset add_header = { u'Artistic': (1, True), u'BSD': (0, False), } template_name = os.path.basename(template_file) if template_name in add_header: license_text = license_text.split(u'\n') empty_lines = add_header[template_name][0] for L in range(empty_lines): license_text.insert(0, wx.EmptyString) header = copyright_header.format(GetYear()) center_header = add_header[template_name][1] if center_header: Logger.Debug(__name__, u'Centering header...') offset = 0 # Don't use isinstance() here because boolean is an instance of integer if type(center_header) == int: offset = center_header else: # Use the longest line found in the text to center the header longest_line = GetLongestLine(license_text) Logger.Debug(__name__, u'Longest line: {}'.format(longest_line)) header_length = len(header) if header_length < longest_line: offset = (longest_line - header_length) / 2 if offset: Logger.Debug(__name__, u'Offset: {}'.format(offset)) header = u'{}{}'.format(u' ' * offset, header) # Special changes for BSD license if template_name == u'BSD': line_index = 0 for LI in license_text: if u'copyright (c)' in LI.lower(): license_text[line_index] = header break line_index += 1 else: license_text.insert(0, header) license_text = u'\n'.join(license_text) if not license_text: ShowErrorDialog(GT(u'License template is empty')) return self.dsp_copyright.SetValue(license_text) self.dsp_copyright.SetInsertionPoint(0) self.dsp_copyright.SetFocus()