示例#1
0
    def unpack_cmg(self, cmg_path, location):
        try:
            cmg_path = os.path.expanduser(cmg_path)
            cmg_path = os.path.expandvars(cmg_path)
            cmg_path = os.path.abspath(cmg_path)

            if not location:
                location = os.path.splitext(cmg_path)[0]
            print location

            location = os.path.expanduser(location)
            location = os.path.expandvars(location)
            location = os.path.abspath(location)

            if not os.path.exists(location):
                print "Extract to : " + location
                ex = KlikExecute(self)
                ex.extract_all(KlikCmg(self, cmg_path), location)
            else:
                print "Sorry %s already exists" % location
        except Exception, inst:
            if isinstance(inst, ExecuteException):
                print "Error occured : " + str(inst)
            else:
                traceback.print_exc()
示例#2
0
    def load_items(self, desktop_files):
        self.item_store.clear()

        for item in desktop_files:

            cmg = KlikCmg(self.klik, item.get("X-CMG"))
            name = item.get("Name").strip()
            if item.get("Comment") != None:
                name = xml.sax.saxutils.escape(
                    name) + '\n<small><i>' + xml.sax.saxutils.escape(
                        item.get("Comment").strip()) + '</i></small>'
            else:
                name = xml.sax.saxutils.escape(
                    name) + '\n<small><i></i></small>'

            icon = cmg.scan_cmg_icons(item)[0]

            if icon[0] == "/":
                temp_path = tempfile.mktemp()
                cmg.extract_file(icon, temp_path)
                icon = temp_path

            pixbuf = utils.getIcon(icon)

            if pixbuf == None:
                pixbuf = utils.getIcon("application-default-icon")

            if name != '':
                self.item_store.append((pixbuf, name, item))

        self.window.show()

        gtk.main()

        return self.result
示例#3
0
 def cmg_is_not_registered(cmg_path):
     # Returns: True if there are NO .desktop files registered
     #          that correspond with `cmg_path`
     # TODO: overkill, speed up not creating objects
     cmg = KlikCmg(self.base, cmg_path)
     return not glob.glob(
         os.path.join(self.base.xdg.get_xdg_apps_path(),
                      cmg.get_unique_id()) + "*")
示例#4
0
    def unregister(self, cmg_list):

        apps_to_notify = set()

        cmg_list = filter(self.__is_valid_cmg_name, cmg_list)

        for cmg_path in cmg_list:

            # Make sure CMG path is absolute
            if cmg_path[0] != "/":
                cmg_path = os.path.abspath(cmg_path)

            print _("Unregistering %s") % cmg_path

            cmg = KlikCmg(self.base, cmg_path)
            package_id_prefix = cmg.get_unique_id()

            # Look for .desktop files owned by the CMG, and xdg-uninstall them
            menu_entries = glob.glob(
                os.path.join(self.base.xdg.get_xdg_apps_path(),
                             package_id_prefix + "*"))

            if menu_entries:
                (old_paths,
                 old_versions) = self.__get_collision_status(menu_entries[0])

                for file in menu_entries:
                    self.base.xdg.desktop_uninstall(file, noupdate=True)
                    apps_to_notify.add(" - " + self.__get_app_name(file))

                # If unregistering this package ends with a collision situation,
                # remove extra info from the menu entry that is left.

                (paths, versions,
                 colliding_entries) = self.__check_already_registered(cmg_path)
                if old_paths and not paths:
                    map(self.__del_path, colliding_entries)
                if old_versions and not versions:
                    map(self.__del_version, colliding_entries)

            # Look for icons owned by the CMG, and xdg-uninstall them

            self.base.xdg.icon_uninstall(package_id_prefix, uninstall_all=True)

        self.base.xdg.desktop_update()

        # Notification
        self.notify_event(
            _("The following menu items have been removed:") + "\n\n%s",
            apps_to_notify)
示例#5
0
        def register_icon(icon_path):
            # Tries to register the given icon, considering the different possible natures of icons:
            #   1.- Themed
            #   2.- Inside CMG
            #   3.- Already in the filesystem

            # If path is not in a filesystem, icon is themed: skip processing
            if icon_path[0] != "/":
                return True

            # icon_path[2:] to avoid `extension = .DirIcon`
            extension = os.path.splitext(icon_path[2:])[1]
            temp_icon_path = os.path.join(build_path, package_id + extension)

            # Try to extract icon from CMG
            cmg = KlikCmg(self.base, cmg_path)
            if cmg.extract_file(icon_path, temp_icon_path):
                if not extension:
                    # Guess image type
                    extension = "." + klik.utils.images.guess_type(
                        temp_icon_path)
                    shutil.move(temp_icon_path, temp_icon_path + extension)
                    temp_icon_path += extension

            # If image was not in CMG, try to get it from filesystem
            else:
                try:
                    shutil.copy(icon_path, temp_icon_path)
                except IOError:
                    return False

            # Try to guess icon size and theme
            regexp_result = regexp_icon.search(icon_path)
            if not temp_icon_path.endswith(
                    ".svg"):  # FIXME: xdg-utils do not support SVG icons
                if regexp_result:
                    theme, size = regexp_result.groups()
                    self.base.xdg.icon_install(temp_icon_path,
                                               theme,
                                               size,
                                               noupdate=True)
                else:
                    self.base.xdg.icon_install(temp_icon_path, noupdate=True)

            os.remove(temp_icon_path)

            return True
示例#6
0
 def execute_cmg_shell(self, cmg_path):
     cmg = KlikCmg(self, cmg_path)
     return cmg.execute_shell()
示例#7
0
 def is_valid_cmg(self, filename):
     return KlikCmg(self, filename).is_valid_cmg()
示例#8
0
    def sync(self, apps_dirs):
        # Perform some cleanup, registering and unregistering packages as needed,
        # trying to leave the system as consistent as possible.
        #
        # apps_dirs: List of Application directories. The goal of the function is to
        #            register every .cmg in that directory and unregister any previous
        #            registered .cmg that is currently not in that directory.

        # Make sure paths are absolute
        apps_dirs = map(os.path.abspath, apps_dirs)

        # List of valid CMGs in all Applications directories.
        registered_cmgs = map(lambda x: glob.glob(x + "/*"),
                              apps_dirs)  # list of lists
        registered_cmgs = reduce(list.__add__, registered_cmgs)  # flat list
        registered_cmgs = filter(lambda x: KlikCmg(self.base, x).is_valid_cmg,
                                 registered_cmgs)  # list of valid CMGs
        registered_cmgs = set(registered_cmgs)  # for faster lookups

        ### Register non-registered packages existent in any of the Application directories

        def cmg_is_not_registered(cmg_path):
            # Returns: True if there are NO .desktop files registered
            #          that correspond with `cmg_path`
            # TODO: overkill, speed up not creating objects
            cmg = KlikCmg(self.base, cmg_path)
            return not glob.glob(
                os.path.join(self.base.xdg.get_xdg_apps_path(),
                             cmg.get_unique_id()) + "*")

        cmgs_to_register = filter(cmg_is_not_registered, registered_cmgs)

        if cmgs_to_register:
            self.register(cmgs_to_register)

        ### Unregister packages that left litter in .desktop or icon directories

        def purge_dir(data_dir):
            # For each file in `data_dir`, look if the associated CMG is registered.
            # If not, unregister the associated CMG to remove all the litter it left
            #
            # data_dir: Path of directory with registered files (.desktop's, icons, etc)
            # Returns: Set of packages that need unregistration.

            if not os.path.isdir(data_dir):
                return set()

            packages_to_unregister = set()

            for filename in os.listdir(data_dir):
                if self.__is_valid_menu_entry(filename):
                    cmg_path = self.__get_cmg_path(filename)
                    if cmg_path not in registered_cmgs:
                        packages_to_unregister.add(cmg_path)

            return packages_to_unregister

        packages_to_unregister = set()

        # Orphan .desktop files
        packages_to_unregister.update(
            purge_dir(self.base.xdg.get_xdg_apps_path()))

        # Orphan icon files
        for icon_path in self.base.xdg.get_xdg_icon_paths():
            packages_to_unregister.update(purge_dir(icon_path))

        if packages_to_unregister:
            self.unregister(packages_to_unregister)
示例#9
0
 def __is_valid_cmg_name(self, path):
     # If the file exists, returns true if it's a valid CMG
     # Otherwise, returns true if the name is valid
     return KlikCmg(self.base,
                    path).is_valid_cmg() or path.lower().endswith(".cmg")
示例#10
0
    def register(self, cmg_list, command_options=set()):

        regexp_icon = re.compile("icons/([a-z]+)/([0-9]+)x")

        def register_icon(icon_path):
            # Tries to register the given icon, considering the different possible natures of icons:
            #   1.- Themed
            #   2.- Inside CMG
            #   3.- Already in the filesystem

            # If path is not in a filesystem, icon is themed: skip processing
            if icon_path[0] != "/":
                return True

            # icon_path[2:] to avoid `extension = .DirIcon`
            extension = os.path.splitext(icon_path[2:])[1]
            temp_icon_path = os.path.join(build_path, package_id + extension)

            # Try to extract icon from CMG
            cmg = KlikCmg(self.base, cmg_path)
            if cmg.extract_file(icon_path, temp_icon_path):
                if not extension:
                    # Guess image type
                    extension = "." + klik.utils.images.guess_type(
                        temp_icon_path)
                    shutil.move(temp_icon_path, temp_icon_path + extension)
                    temp_icon_path += extension

            # If image was not in CMG, try to get it from filesystem
            else:
                try:
                    shutil.copy(icon_path, temp_icon_path)
                except IOError:
                    return False

            # Try to guess icon size and theme
            regexp_result = regexp_icon.search(icon_path)
            if not temp_icon_path.endswith(
                    ".svg"):  # FIXME: xdg-utils do not support SVG icons
                if regexp_result:
                    theme, size = regexp_result.groups()
                    self.base.xdg.icon_install(temp_icon_path,
                                               theme,
                                               size,
                                               noupdate=True)
                else:
                    self.base.xdg.icon_install(temp_icon_path, noupdate=True)

            os.remove(temp_icon_path)

            return True

        def is_already_registered(cmg_path):
            if "f" in command_options: return False
            any_version = len(
                glob.glob(
                    self.__get_menu_entry_mask(cmg_path,
                                               check_version=False,
                                               check_path=False)))
            same_version = len(
                glob.glob(
                    self.__get_menu_entry_mask(cmg_path,
                                               check_version=True,
                                               check_path=False)))
            return any_version - same_version > 0

        # some distros do not have .local/share/applications by default
        #os.mkdir( self.base.xdg.get_xdg_apps_path() )

        apps_to_notify = set()
        notify_icon = None

        cmg_list = filter(lambda x: KlikCmg(self.base, x).is_valid_cmg(),
                          cmg_list)

        for cmg_path in cmg_list:

            # Make sure CMG path is absolute
            if cmg_path[0] != "/":
                cmg_path = os.path.abspath(cmg_path)

            print _("Registering %s") % cmg_path

            if is_already_registered(cmg_path):
                print "\t", _("Package already registered")
                continue

            cmg = KlikCmg(self.base, cmg_path)

            build_path = tempfile.mkdtemp(
                '.register.' + cmg.get_unique_id(),
                self.base.settings.temp_directory_path)
            self.base.temp_paths.append(build_path)

            # Registering one menu entry per desktop object found/created

            for do in cmg.get_desktop_objects():
                # Package ID is the CMG name escaped with the specific .desktop name...
                package_id = cmg.get_unique_id(do.get("Name"))

                # Convert execution command
                command = do.get("Exec") or ""
                do.set("Exec", "klik run %s '%s'" % (command, cmg.path))

                do.set("X-CMG", cmg.path)

                # Icons: each menu entry can have many icons, in different sizes and themes
                icon_list = cmg.scan_cmg_icons(do)
                icon_list = filter(register_icon, icon_list)
                if icon_list:
                    # At least one valid icon could be installed
                    if (icon_list[0][0] == "/"):  # Icon is not themed
                        do.set("Icon", package_id)
                else:
                    # No valid icon for this entry, fallback to klik themed icon
                    do.set("Icon", "application-x-application-cmg")

                # Write .desktop file
                temp_desktop_path = os.path.join(build_path,
                                                 package_id + ".desktop")
                temp_desktop_file = open(temp_desktop_path, "w")
                do.write(temp_desktop_file)
                temp_desktop_file.close()

                # Register .desktop file and remove temporal file
                self.base.xdg.desktop_install(temp_desktop_path, noupdate=True)
                os.remove(temp_desktop_path)

                # Checking if the CMG is already registered, with the
                # same version or with a different one.
                (paths, versions,
                 colliding_entries) = self.__check_already_registered(cmg_path)
                if paths:
                    map(self.__add_path, colliding_entries)
                if versions:
                    map(self.__add_version, colliding_entries)

                apps_to_notify.add(" - " + do.get("Name"))
                notify_icon = do.get("Icon")

            os.rmdir(build_path)

        self.base.xdg.icon_update()
        self.base.xdg.desktop_update()

        # Notification
        self.notify_event(
            _("The following menu items have been added") + ":\n\n%s\n\n" +
            ngettext(
                "To uninstall remove the file from your application folder",
                "To uninstall remove the files from your application folder",
                len(apps_to_notify)) + ".\n", apps_to_notify, notify_icon)
示例#11
0
				
				relative_path = os.path.join(root_directory, recipe.icon[1:].replace("file://", "")) 
				self.events.print_to_stdout( relative_path )
				if os.path.isfile( relative_path):
					shutil.copy(relative_path, icon_path)
			else:
				# maybe a url then ?
				try:
					urllib.urlretrieve(recipe.icon, icon_path)
				except ExecuteException, text:
					pass

		# postflight
		self.__execute_accepted_commands(root_directory, recipe.postflight)

		return KlikCmg(self.klik, self.pack(root_directory, app_path, build_path=build_path))

	
	def pack(self, root_directory, app_path, build_path=None):
		
		recipe_path = os.path.join(root_directory, "recipe.xml")
		recipe = None
		cmg_path = None
		
		# Load the recipe file	
		if  os.path.isfile( recipe_path ):
			recipe = KlikRecipe( recipe_path )
		else:
			raise ExecuteException( _("No recipe file found") )
			return