Ejemplo n.º 1
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
Ejemplo n.º 2
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()) + "*" )
Ejemplo n.º 3
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
Ejemplo n.º 4
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()) + "*")
Ejemplo n.º 5
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)
Ejemplo n.º 6
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()
Ejemplo n.º 7
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
Ejemplo n.º 8
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 )
Ejemplo n.º 9
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
Ejemplo n.º 10
0
	def execute_cmg_shell(self, cmg_path):
		cmg = KlikCmg(self, cmg_path)
		return cmg.execute_shell()
Ejemplo n.º 11
0
 def execute_cmg_shell(self, cmg_path):
     cmg = KlikCmg(self, cmg_path)
     return cmg.execute_shell()
Ejemplo n.º 12
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 )
Ejemplo n.º 13
0
 def is_valid_cmg(self, filename):
     return KlikCmg(self, filename).is_valid_cmg()
Ejemplo n.º 14
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)
Ejemplo n.º 15
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")
Ejemplo n.º 16
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
Ejemplo n.º 17
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)