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()) + "*" )
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()) + "*")
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)
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 )
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)
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 )