Пример #1
0
    def Set(self, data):
        preinst = data.split(u'<<PREINST>>\n')[1].split(u'\n<</PREINST>>')[0]
        postinst = data.split(u'<<POSTINST>>\n')[1].split(
            u'\n<</POSTINST>>')[0]
        prerm = data.split(u'<<PRERM>>\n')[1].split(u'\n<</PRERM>>')[0]
        postrm = data.split(u'<<POSTRM>>\n')[1].split(u'\n<</POSTRM>>')[0]

        def format_script(script):
            return u'\n'.join(
                script.split(u'\n')[2:])  # Use '2' to remove first two lines

        if GS(preinst[0]).isnumeric():
            if int(preinst[0]):
                self.script_objects[0][0].SetValue(format_script(preinst))

        if GS(postinst[0]).isnumeric():
            if int(postinst[0]):
                self.script_objects[1][0].SetValue(format_script(postinst))

        if GS(prerm[0]).isnumeric():
            if int(prerm[0]):
                self.script_objects[2][0].SetValue(format_script(prerm))

        if GS(postrm[0]).isnumeric():
            if int(postrm[0]):
                self.script_objects[3][0].SetValue(format_script(postrm))
Пример #2
0
    def GetLauncherInfo(self):
        desktop_list = [u'[Desktop Entry]']

        name = GetField(self, inputid.NAME).GetValue()
        if not TextIsEmpty(name):
            desktop_list.append(u'Name={}'.format(name))

        desktop_list.append(u'Version=1.0')

        executable = GetField(self, inputid.EXEC).GetValue()
        if not TextIsEmpty(executable):
            desktop_list.append(u'Exec={}'.format(executable))

        comment = GetField(self, inputid.DESCR).GetValue()
        if not TextIsEmpty(comment):
            desktop_list.append(u'Comment={}'.format(comment))

        icon = GetField(self, inputid.ICON).GetValue()
        if not TextIsEmpty(icon):
            desktop_list.append(u'Icon={}'.format(icon))

        launcher_type = GetField(self, inputid.TYPE).GetValue()
        if not TextIsEmpty(launcher_type):
            desktop_list.append(u'Type={}'.format(launcher_type))

        desktop_list.append(u'Terminal={}'.format(
            GS(self.sel_term.GetSelection() == 0).lower()))

        desktop_list.append(u'StartupNotify={}'.format(
            GS(self.sel_notify.GetSelection() == 0).lower()))

        encoding = GetField(self, inputid.ENC).GetValue()
        if not TextIsEmpty(encoding):
            desktop_list.append(u'Encoding={}'.format(encoding))

        lst_categories = GetField(self, listid.CAT)
        categories = []
        cat_total = lst_categories.GetItemCount()
        count = 0
        while count < cat_total:
            C = lst_categories.GetItemText(count)
            if not TextIsEmpty(C):
                categories.append(lst_categories.GetItemText(count))

            count += 1

        # Add a final semi-colon if categories is not empty
        if categories:
            categories = u';'.join(categories)
            if categories[-1] != u';':
                categories = u'{};'.format(categories)

            desktop_list.append(u'Categories={}'.format(categories))
        '''
        other = self.ti_other.GetValue()
        if not TextIsEmpty(other):
            desktop_list.append(other)
        '''

        return u'\n'.join(desktop_list)
Пример #3
0
def GetInteger(value):
	if isinstance(value, (int, float,)):
		return int(value)

	# Will always use there very first value, even for nested items
	elif isinstance(value,(tuple, list,)):
		# Recursive check lists & tuples
		return GetInteger(value[0])

	elif value and IsString(value):
		# Convert because of unsupported methods in str class
		value = GS(value)

		if HasAlpha(value):
			return None

		# Check for negative
		if value[0] == u'-':
			if value.count(u'-') <= 1:
				value = GetInteger(value[1:])

				if value != None:
					return -value

		# Check for tuple
		elif u'.' in value:
			value = value.split(u'.')[0]
			return GetInteger(value)

		elif StringIsNumeric(value):
			return int(value)

	return None
Пример #4
0
def CreateStage():
	stage = u'/tmp'

	# Use current working directory if no write access to /tmp
	if not os.access(stage, os.W_OK):
		stage = os.getcwd()

	#suffix = u'{}{}{}_'.format(GetYear(), GetMonthInt(), GetDayInt())

	#suffix = u'_temp'
	suffix = GetDate(dtfmt.STAMP)

	stage = u'{}/{}-{}_{}'.format(stage, GS(APP_name).lower(), VERSION_string, suffix)

	if os.access(os.path.dirname(stage), os.W_OK):
		# Start with fresh directory
		if os.path.isdir(stage):
			shutil.rmtree(stage)

		elif os.path.isfile(stage):
			os.remove(stage)

		os.makedirs(stage)

		if os.path.isdir(stage):
			return stage
Пример #5
0
    def Get(self, getModule=False):
        # 'install after build' is not exported to project for safety

        fields = {}
        omit_options = (self.chk_install, )

        for O in self.build_options:
            # Leave options out that should not be saved
            if O not in omit_options:
                fields[O.GetName()] = GS(O.GetValue())

        page = wx.EmptyString

        for F in fields:
            if page == wx.EmptyString:
                page = u'{}={}'.format(F, fields[F])

            else:
                page = u'{}\n{}={}'.format(page, F, fields[F])

        if page == wx.EmptyString:
            page = None

        if getModule:
            page = (
                __name__,
                page,
            )

        return page
Пример #6
0
def GetDayInt(string_value=False):
    day = GS(strftime(u'%d'))

    if not string_value:
        day = int(day)

    return day
Пример #7
0
def GetMonthInt(string_value=False):
    month = GS(strftime(u'%m'))

    if not string_value:
        month = int(month)

    return month
Пример #8
0
def GetYear(fmt=dtfmt.DEFAULT, string_value=True):
    year = GS(strftime(u'%Y'))

    if not string_value:
        year = int(year)

    return year
Пример #9
0
 def OnAddCustom(self, event=None):
     custom_label = GS(
         self.input_add_custom.GetValue()).strip(u' ').replace(u' ', u'_')
     if not TextIsEmpty(custom_label) and not self.check_list.LabelExists(
             custom_label):
         self.check_list.AddItem(custom_label, True)
         self.check_list.ScrollToEnd()
Пример #10
0
def GetTime(fmt=dtfmt.DEFAULT):
    ms = None
    current_time = None

    if fmt in (
            dtfmt.LOG,
            dtfmt.STAMP,
    ):
        ms = GS(datetime.now().strftime(u'%f'))[:3]

        if fmt == dtfmt.STAMP:
            # HHMMSSmmm
            current_time = u'{}{}'.format(GS(strftime(u'%H%M%S')), ms)

        else:
            # HH:MM:SS.mmm
            current_time = u'{}.{}'.format(GS(strftime(u'%T')), ms)

    return current_time
Пример #11
0
def CreateButton(parent,
                 btnId=wx.ID_ANY,
                 label=wx.EmptyString,
                 image=None,
                 size=32,
                 tooltip=None,
                 name=None,
                 commands=None,
                 requireAll=False):
    if not image:
        image = btnid.GetImage(btnId)

    # Use titleized version of the image name for the label
    if not label and image:
        label = image.title()

    if not name:
        name = label

    button = None

    if image:
        image = ConcatPaths(
            (PATH_bitmaps, u'button', GS(size), u'{}.png'.format(image)))

        if not os.path.isfile(image):
            Logger.Warn(
                __name__,
                u'CreateButton: Attempted to set not-existent image for button (ID {}):'
                .format(btnId),
                details=image)

        else:
            button = CustomButton(parent,
                                  image,
                                  btnId,
                                  name=name,
                                  commands=commands,
                                  requireAll=requireAll)

            if not tooltip:
                tooltip = label

            button.SetToolTipString(tooltip)

    # Use a standard button
    if not button:
        button = Button(parent,
                        btnId,
                        label,
                        name=name,
                        commands=commands,
                        requireAll=requireAll)

    return button
Пример #12
0
def GetImagePath(name, size=16, cat=None, img_type=u'png'):
    name = u'{}.{}'.format(name, img_type)

    if cat:
        paths = (PATH_bitmaps, cat, GS(size), name)

    else:
        paths = (PATH_bitmaps, GS(size), name)

    image_path = ConcatPaths(paths)

    # Attempt to use failsafe image if file does not exists
    if not os.path.isfile(image_path):
        image_path = ConcatPaths((PATH_bitmaps, GS(size), u'failsafe.png'))

    # Last resort is to retrun None if a failsafe image was not found
    if not os.path.isfile(image_path):
        return None

    return image_path
Пример #13
0
def GetInteger(value):
    if isinstance(value, (
            int,
            float,
    )):
        return int(value)

    # Will always use there very first value, even for nested items
    elif isinstance(value, (
            tuple,
            list,
    )):
        # Recursive check lists & tuples
        return GetInteger(value[0])

    elif value and IsString(value):
        # Convert because of unsupported methods in str class
        value = GS(value)

        if HasAlpha(value):
            return None

        # Check for negative
        if value[0] == u'-':
            if value.count(u'-') <= 1:
                value = GetInteger(value[1:])

                if value != None:
                    return -value

        # Check for tuple
        elif u'.' in value:
            value = value.split(u'.')[0]
            return GetInteger(value)

        elif StringIsNumeric(value):
            return int(value)

    return None
Пример #14
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()
Пример #15
0
 def RefreshLog(self, event=None):
     if self.LogFile.IsFile():
         log_data = self.LogFile.Read()
         
         if not self.DspLog.IsEmpty():
             self.DspLog.Clear()
         
         self.DspLog.SetValue(log_data)
         
         try:
             # Yield here to make sure last line is displayed
             # FIXME: Causes delay when debug enabled
             wx.SafeYield()
             self.DspLog.ShowPosition(self.DspLog.GetLastPosition())
         
         except wx.PyDeadObjectError:
             tb_error = GS(traceback.format_exc())
             
             Logger.Warn(__name__, u'Error refreshing log window. Details below:\n\n{}'.format(tb_error))
Пример #16
0
    # FIXME: How to add 'absolute' argument with ambiguous arg count for 'tail'
    absolute = True
    if absolute and not path.startswith(u'/'):
        path = u'/' + path

    return path


# *** System paths *** #

## Directory where app is installed
#  HACK: test
#  HACK: Call os.path.dirname twice to get root directory.
#        This is necessary because this variable is
#        declared from a sub-directory.
PATH_app = GS(os.path.dirname(os.path.dirname(__file__)))

## User's home directory
#
#  Used to set config directory.
PATH_home = GS(os.getenv(u'HOME'))

## Local folder to store files such as custom templates
PATH_local = ConcatPaths((PATH_home, u'.local/share/debreate'))

## Directory where cache files are stored
PATH_cache = ConcatPaths((PATH_local, u'cache'))

## Directory where log files are stored
PATH_logs = ConcatPaths((PATH_local, u'logs'))
Пример #17
0
def GetTimeZone(fmt=dtfmt.DEFAULT):
    return GS(strftime(u'%z'))
Пример #18
0
    sys.exit(0)

if u'help' in parsed_args_s:
    if INSTALLED:
        help_output = commands.getstatusoutput(u'man debreate')

    else:
        help_output = commands.getstatusoutput(
            u'man --manpath="{}/man" debreate'.format(PATH_app))

    if help_output[0]:
        print(u'ERROR: Could not locate manpage')

        sys.exit(help_output[0])

    help_output = GS(help_output[1])
    print(u'\n'.join(help_output.split(u'\n')[2:-1]))

    sys.exit(0)

if u'log-level' in parsed_args_v:
    Logger.SetLogLevel(parsed_args_v[u'log-level'])

Logger.Info(script_name, u'Python version: {}'.format(PY_VER_STRING))
Logger.Info(script_name, u'wx.Python version: {}'.format(WX_VER_STRING))
Logger.Info(script_name, u'Debreate version: {}'.format(VERSION_string))
Logger.Info(script_name, u'Logging level: {}'.format(Logger.GetLogLevel()))

# Check for & parse existing configuration
conf_values = GetAllConfigKeys()
Пример #19
0
def WriteConfig(k_name, k_value, conf=default_config, sectLabel=None):
    conf_dir = os.path.dirname(conf)

    if not os.path.isdir(conf_dir):
        if os.path.exists(conf_dir):
            print(u'{}: {}: {}'.format(
                GT(u'Error'),
                GT(u'Cannot create config directory, file exists'), conf_dir))
            return ConfCode.ERR_WRITE

        os.makedirs(conf_dir)

    # Only write pre-defined keys
    if k_name not in default_config_values:
        print(u'{}: {}: {}'.format(GT(u'Error'),
                                   GT(u'Configuration key not found'), k_name))
        return ConfCode.KEY_NOT_DEFINED

    # Make sure we are writing the correct type
    k_value = default_config_values[k_name][0](k_value)

    if k_value == None:
        print(u'{}: {}: {}'.format(
            GT(u'Error'), GT(u'Wrong value type for configuration key'),
            k_name))
        return ConfCode.WRONG_TYPE

    # tuple is the only type we need to format
    if isinstance(k_value, tuple):
        k_value = u'{},{}'.format(GS(k_value[0]), GS(k_value[1]))

    else:
        k_value = GS(k_value)

    conf_text = wx.EmptyString

    # Save current config to buffer
    if os.path.exists(conf):
        if not os.path.isfile(conf):
            print(u'{}: {}: {}'.format(
                GT(u'Error'),
                GT(u'Cannot open config for writing, directory exists'), conf))
            return ConfCode.ERR_WRITE

        conf_text = ReadFile(conf)

        # FIXME: ReadFile returns None type if config file exists but is empty
        if conf_text == None:
            conf_text = u''

    else:
        conf_text = u'[CONFIG-{}.{}]'.format(GS(config_version[0]),
                                             GS(config_version[1]))

    conf_lines = conf_text.split(u'\n')

    key_exists = False
    for L in conf_lines:
        l_index = conf_lines.index(L)
        if u'=' in L:
            key = L.split(u'=')[0]

            if k_name == key:
                key_exists = True

                conf_lines[l_index] = u'{}={}'.format(k_name, k_value)

    if not key_exists:
        conf_lines.append(u'{}={}'.format(k_name, k_value))

    conf_text = u'\n'.join(conf_lines)

    if TextIsEmpty(conf_text):
        print(u'{}: {}'.format(GT(u'Warning'),
                               GT(u'Not writing empty text to configuration')))
        return ConfCode.ERR_WRITE

    # Actual writing to configuration
    WriteFile(conf, conf_text)

    if os.path.isfile(conf):
        return ConfCode.SUCCESS

    return ConfCode.ERR_WRITE
Пример #20
0
def HasAlpha(value):
    return (re.search(u'[a-zA-Z]', GS(value)) != None)
Пример #21
0
    sys.exit(0)

if u'help' in parsed_args_s:
    if INSTALLED:
        help_output = commands.getstatusoutput(u'man debreate')

    else:
        help_output = commands.getstatusoutput(
            u'man --manpath="{}/man" debreate'.format(PATH_app))

    if help_output[0]:
        print(u'ERROR: Could not locate manpage')

        sys.exit(help_output[0])

    help_output = GS(help_output[1])
    print(u'\n'.join(help_output.split(u'\n')[2:-1]))

    sys.exit(0)

if u'log-level' in parsed_args_v:
    Logger.SetLogLevel(parsed_args_v[u'log-level'])

Logger.Info(script_name, u'Python version: {}'.format(PY_VER_STRING))
Logger.Info(script_name, u'wx.Python version: {}'.format(WX_VER_STRING))
Logger.Info(script_name, u'Debreate version: {}'.format(VERSION_string))
Logger.Info(script_name, u'Logging level: {}'.format(Logger.GetLogLevel()))

# Check for & parse existing configuration
conf_values = GetAllConfigKeys()
Пример #22
0
def _digit_to_string(number):
    if number < 10:
        return GS(u'0{}'.format(number))

    return GS(number)
Пример #23
0
	def Get(self, getModule=False):
		l_lines = [u'[Desktop Entry]']
		categories = []

		id_list = (
			inputid.VERSION,
			inputid.ENC,
			inputid.NAME,
			inputid.EXEC,
			inputid.DESCR,
			inputid.ICON,
			inputid.TYPE,
			inputid.TERM,
			inputid.NOTIFY,
			inputid.MIME,
			listid.CAT,
			inputid.CAT2,
			inputid.OTHER,
			)

		for ID in id_list:
			field = GetField(self, ID)

			if field:
				if isinstance(field, ErrorTuple):
					Logger.Warn(__name__, field.GetMessage())

					continue

				if ID == inputid.OTHER:
					for INDEX in range(field.GetSectionCount()):
						section = field.GetSection(INDEX)

						if isinstance(section, CustomSection):
							key = section.GetKey().strip()
							value = section.GetValue().strip()

				elif ID in (listid.CAT, inputid.CAT2):
					if ID == inputid.CAT2:
						custom_cats = []

						for C1 in field.GetValue().split(u','):
							for C2 in C1.split(u';'):
								if not TextIsEmpty(C2):
									custom_cats.append(C2.strip())

						if GetField(self, chkid.CAT).GetValue():
							for LABEL in reversed(custom_cats):
								categories.insert(0, LABEL)

						else:
							for LABEL in custom_cats:
								categories.append(LABEL)

					else:
						for LABEL in field.GetCheckedLabels():
							categories.append(LABEL)

				else:
					if isinstance(field, OutputField):
						key = field.GetOutLabel()

					else:
						key = field.GetName()

					value = wx.EmptyString

					if isinstance(field, (wx.TextCtrl, OwnerDrawnComboBox,)):
						value = field.GetValue().strip()

					elif isinstance(field, wx.CheckBox):
						value = GS(field.GetValue()).lower()

					elif isinstance(field, (ListCtrlBase, ListCtrl,)):
						value = u';'.join(field.GetListTuple())

						if not value.endswith(u';'):
							value = u'{};'.format(value)

				if not TextIsEmpty(key) and not TextIsEmpty(value):
					l_lines.append(u'{}={}'.format(key, value))

		# FIXME: Categories should be organized manually by user
		if categories:
			categories = u';'.join(categories)
			if not categories.endswith(u';'):
				categories = u'{};'.format(categories)

			l_lines.append(u'Categories={}'.format(categories))

		l_text = u'\n'.join(l_lines)

		if getModule:
			# FIXME: 'MENU' needed?
			l_text = (__name__, l_text, u'MENU')

		return l_text
Пример #24
0
if u'help' in parsed_args_s:
	if INSTALLED:
		help_output = commands.getstatusoutput(u'man debreate')

	else:
		help_output = commands.getstatusoutput(u'man --manpath="{}/man" debreate'.format(PATH_app))


	if help_output[0]:
		print(u'ERROR: Could not locate manpage')

		sys.exit(help_output[0])


	help_output = GS(help_output[1])
	print(u'\n'.join(help_output.split(u'\n')[2:-1]))

	sys.exit(0)


if u'log-level' in parsed_args_v:
	Logger.SetLogLevel(parsed_args_v[u'log-level'])


Logger.Info(script_name, u'Python version: {}'.format(PY_VER_STRING))
Logger.Info(script_name, u'wx.Python version: {}'.format(WX_VER_STRING))
Logger.Info(script_name, u'Debreate version: {}'.format(VERSION_string))
Logger.Info(script_name, u'Logging level: {}'.format(Logger.GetLogLevel()))

# Check for & parse existing configuration
Пример #25
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())
Пример #26
0
    def Get(self, getModule=False):
        l_lines = [u'[Desktop Entry]']
        categories = []

        id_list = (
            inputid.VERSION,
            inputid.ENC,
            inputid.NAME,
            inputid.EXEC,
            inputid.DESCR,
            inputid.ICON,
            inputid.TYPE,
            inputid.TERM,
            inputid.NOTIFY,
            inputid.MIME,
            listid.CAT,
            inputid.CAT2,
            inputid.OTHER,
        )

        for ID in id_list:
            field = GetField(self, ID)

            if field:
                if isinstance(field, ErrorTuple):
                    Logger.Warn(__name__, field.GetMessage())

                    continue

                if ID == inputid.OTHER:
                    for INDEX in range(field.GetSectionCount()):
                        section = field.GetSection(INDEX)

                        if isinstance(section, CustomSection):
                            key = section.GetKey().strip()
                            value = section.GetValue().strip()

                elif ID in (listid.CAT, inputid.CAT2):
                    if ID == inputid.CAT2:
                        custom_cats = []

                        for C1 in field.GetValue().split(u','):
                            for C2 in C1.split(u';'):
                                if not TextIsEmpty(C2):
                                    custom_cats.append(C2.strip())

                        if GetField(self, chkid.CAT).GetValue():
                            for LABEL in reversed(custom_cats):
                                categories.insert(0, LABEL)

                        else:
                            for LABEL in custom_cats:
                                categories.append(LABEL)

                    else:
                        for LABEL in field.GetCheckedLabels():
                            categories.append(LABEL)

                else:
                    if isinstance(field, OutputField):
                        key = field.GetOutLabel()

                    else:
                        key = field.GetName()

                    value = wx.EmptyString

                    if isinstance(field, (
                            wx.TextCtrl,
                            OwnerDrawnComboBox,
                    )):
                        value = field.GetValue().strip()

                    elif isinstance(field, wx.CheckBox):
                        value = GS(field.GetValue()).lower()

                    elif isinstance(field, (
                            ListCtrlBase,
                            ListCtrl,
                    )):
                        value = u';'.join(field.GetListTuple())

                        if not value.endswith(u';'):
                            value = u'{};'.format(value)

                if not TextIsEmpty(key) and not TextIsEmpty(value):
                    l_lines.append(u'{}={}'.format(key, value))

        # FIXME: Categories should be organized manually by user
        if categories:
            categories = u';'.join(categories)
            if not categories.endswith(u';'):
                categories = u'{};'.format(categories)

            l_lines.append(u'Categories={}'.format(categories))

        l_text = u'\n'.join(l_lines)

        if getModule:
            # FIXME: 'MENU' needed?
            l_text = (__name__, l_text, u'MENU')

        return l_text
Пример #27
0
def GT(str_value):
    return _(GS(str_value))