示例#1
0
    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'))
示例#2
0
    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)
示例#3
0
    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__)
示例#4
0
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
示例#5
0
    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)
示例#6
0
    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
示例#7
0
    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
示例#8
0
    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()
示例#9
0
 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)
示例#10
0
    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)
示例#11
0
	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)
示例#12
0
    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
示例#13
0
    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)
示例#14
0
 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
示例#15
0
        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)
示例#16
0
文件: tree.py 项目: carsenk/debreate
    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))
示例#17
0
文件: tree.py 项目: carsenk/debreate
    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
示例#18
0
    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)
示例#19
0
    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)
示例#20
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())
示例#21
0
    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
示例#22
0
	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)
示例#23
0
    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())
示例#24
0
    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
示例#25
0
    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
示例#26
0
文件: about.py 项目: carsenk/debreate
    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)
示例#27
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()
示例#28
0
    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
示例#29
0
    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
示例#30
0
 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()