def main(argv): args = parse_args(argv[1:]) if args.list_dirs: for directory in xdg_data_dirs: print(os.path.join(directory, "applications")) elif args.list_files: for directory in xdg_data_dirs: path = os.path.join(directory, "applications") try: for entry in os.listdir(path): if entry.endswith(".desktop"): if args.verbose: filename = os.path.join(path, entry) desktop = DesktopEntry(filename) print("{:70} {:40} {:40}".format( filename, desktop.getName(), desktop.getExec())) else: print(os.path.join(path, entry)) except FileNotFoundError: pass else: filename = get_desktop_file(args.DESKTOP) print(filename) desktop = DesktopEntry(filename) print("Name: {}".format(desktop.getName())) print("Exec: {}".format(desktop.getExec())) print("TryExec: {}".format(desktop.getTryExec())) print("Mime-Types: {}".format(desktop.getMimeTypes()))
def _find_pdf_viewers(self): pdf_viewers = {} if platform.system() == "Linux": # Find all .desktop files for search_path in [ "/usr/share/applications", "/usr/local/share/applications", os.path.expanduser("~/.local/share/applications"), ]: try: for filename in os.listdir(search_path): full_filename = os.path.join(search_path, filename) if os.path.splitext(filename)[1] == ".desktop": # See which ones can open PDFs desktop_entry = DesktopEntry(full_filename) if ("application/pdf" in desktop_entry.getMimeTypes() and desktop_entry.getName() != "dangerzone"): pdf_viewers[desktop_entry.getName( )] = desktop_entry.getExec() except FileNotFoundError: pass return pdf_viewers
def from_dotdesktop(cls, app_def: Path, distro: WSLDistro) -> Optional[WSLApp]: """ Return a WSLApp from a .desktop file. Args: app_def: .desktop file path """ de = DesktopEntry(app_def) name = de.getName() generic_name = de.getGenericName() cmd = de.getExec() gui = not de.getTerminal() icon = de.getIcon() if name: return cls(name, generic_name, cmd, gui, icon) else: # This is a symlink linux_path = str(app_def)[str(app_def).index(r"\\wsl$") + 7:] linux_path = linux_path[linux_path.index("\\"):].replace("\\", "/") # Turn symlink target into Windows Path symlink = distro.get_cmd_output(f"readlink -f -e '{linux_path}'") app_def = distro._unc_path_from_cmd(symlink) de = DesktopEntry(app_def) name = de.getName() generic_name = de.getGenericName() cmd = de.getExec() gui = not de.getTerminal() icon = de.getIcon() if name: return cls(name, generic_name, cmd, gui, icon) return None
def provide(self): from fnmatch import fnmatch from xdg.DesktopEntry import DesktopEntry items = [] for app_directory in map(os.path.expanduser, self.app_directories): for root, dirs, files in os.walk(app_directory): for filename in files: if fnmatch(filename, "*.desktop"): app_entry = DesktopEntry(os.path.join(root, filename)) icon_theme = Gtk.IconTheme.get_default() if app_entry.getNoDisplay(): continue if app_entry.getIcon() == "": icon = Gtk.IconTheme.load_icon(icon_theme, "image-missing", self.icon_size, 0) elif "/" in app_entry.getIcon(): try: unscaled_icon = GdkPixbuf.Pixbuf.new_from_file(app_entry.getIcon()) icon = unscaled_icon.scale_simple(self.icon_size, self.icon_size, GdkPixbuf.InterpType.BILINEAR) except: icon = Gtk.IconTheme.load_icon(icon_theme, "image-missing", self.icon_size, 0) else: try: unscaled_icon = Gtk.IconTheme.load_icon(icon_theme, app_entry.getIcon(), self.icon_size, 0) icon = unscaled_icon.scale_simple(self.icon_size, self.icon_size, GdkPixbuf.InterpType.BILINEAR) except: icon = Gtk.IconTheme.load_icon(icon_theme, "image-missing", self.icon_size, 0) words = app_entry.getName().split() # words.append(app_entry.getExec()) command = self.escape_command(app_entry.getExec()) if app_entry.getTerminal(): command = "%s '%s'" % (self.terminal_emulator_command, command) item = { "indexer": self, "name": app_entry.getName(), "description": app_entry.getComment(), "icon": icon, "command": command, "words": words, } items.append(item) items.sort(key=lambda i: i["name"]) return items
def _find_pdf_viewers(self): pdf_viewers = {} if platform.system() == "Darwin": # Get all installed apps that can open PDFs bundle_identifiers = LaunchServices.LSCopyAllRoleHandlersForContentType( "com.adobe.pdf", CoreServices.kLSRolesAll ) for bundle_identifier in bundle_identifiers: # Get the filesystem path of the app res = LaunchServices.LSCopyApplicationURLsForBundleIdentifier( bundle_identifier, None ) if res[0] is None: continue app_url = res[0][0] app_path = str(app_url.path()) # Load its plist file plist_path = os.path.join(app_path, "Contents/Info.plist") # Skip if there's not an Info.plist if not os.path.exists(plist_path): continue with open(plist_path, "rb") as f: plist_data = f.read() plist_dict = plistlib.loads(plist_data) if plist_dict.get("CFBundleName") and plist_dict["CFBundleName"] != "Dangerzone": pdf_viewers[plist_dict["CFBundleName"]] = bundle_identifier elif platform.system() == "Linux": # Find all .desktop files for search_path in [ "/usr/share/applications", "/usr/local/share/applications", os.path.expanduser("~/.local/share/applications"), ]: try: for filename in os.listdir(search_path): full_filename = os.path.join(search_path, filename) if os.path.splitext(filename)[1] == ".desktop": # See which ones can open PDFs desktop_entry = DesktopEntry(full_filename) if ( "application/pdf" in desktop_entry.getMimeTypes() and desktop_entry.getName() != "dangerzone" ): pdf_viewers[ desktop_entry.getName() ] = desktop_entry.getExec() except FileNotFoundError: pass return pdf_viewers
def load_dir(self, dir_path): for subdir, dirs, files in os.walk(dir_path): for desktop_file in files: desktop_file = subdir + "/" + desktop_file if desktop_file[-8:] == ".desktop": entry = DesktopEntry(desktop_file) if not (entry.getName() == None or entry.getName() == ""): if not (entry.getExec() == None or entry.getExec() == ""): self.DESKTOP_ENTRIES[entry.getName()] = entry
def __create_model(self, all = False, comment = False): model = self.get_model() model.clear() allitems = [] allitems.extend(self.useritems) allitems.extend(self.systemitems) for item in allitems: try: desktopentry = DesktopEntry(item) except: continue if desktopentry.get("Hidden"): if not all: continue iter = model.append() enable = desktopentry.get("X-GNOME-Autostart-enabled") if enable == "false": enable = False else: enable = True iconname = desktopentry.get('Icon', locale = False) if not iconname: iconname = desktopentry.get('Name', locale = False) if not iconname: iconname = desktopentry.getName() icon = get_icon_with_name(iconname, 32) try: name = desktopentry.getName() except: name = desktopentry.get('Name', locale=False) if comment: comment = desktopentry.getComment() if not comment: comment = _("No description") description = "<b>%s</b>\n%s" % (name, comment) else: description = "<b>%s</b>" % name model.set(iter, COLUMN_ACTIVE, enable, COLUMN_ICON, icon, COLUMN_PROGRAM, description, COLUMN_PATH, item)
def load_desktop_sessions(): xsessions_dir = "%s/share/xsessions" % sys.prefix if not os.path.exists(xsessions_dir) or not os.path.isdir(xsessions_dir): return {} xsessions = {} with IconLoadingContext(): from xdg.DesktopEntry import DesktopEntry for f in os.listdir(xsessions_dir): filename = os.path.join(xsessions_dir, f) de = DesktopEntry(filename) try: entry = load_xdg_entry(de) if not entry: continue name = de.getName() if not entry.get("IconData"): names = get_icon_names_for_session(name.lower()) v = find_icon(*names) if v: entry["IconData"] = v[0] entry["IconType"] = v[1] xsessions[name] = entry except Exception as e: log("load_desktop_sessions(%s)", remove_icons, exc_info=True) log.error("Error loading desktop entry '%s':", filename) log.error(" %s", e) return xsessions
def ShowAll(self):#elenca tutti i file nelle 4 cartelle di autostart autolist = [] path = self.user_autostart for file_name in os.listdir(path): myitem = DesktopEntry(path + '/' + file_name) #print(path + '/' + file_name) a = DeskStruct() a.Name = myitem.getName() a.Exec = myitem.getExec() a.Icon = myitem.getIcon() a.Comment = myitem.getComment() autolist.append(a) #lista di oggetti Deskstruct #path=self.xdg_autostart #autolist.append(' XDG files') #for file_name in os.listdir(path): # autolist.append(path+'/'+file_name) # #path=self.sys_autostart #autolist.append(' Sys Files') #for file_name in os.listdir(path): # autolist.append(path+'/'+file_name) #path=self.gdm_autostart #autolist.append(' GDM files') #for file_name in os.listdir(path): # autolist.append(path+'/'+file_name) return autolist
def __new__(cls, desk): desk = DesktopEntry(str(a)) name = desk.getName() icon = getIconPath(desk.getIcon()) exe = shlex.split(re.sub('%[fFuUdDnNickvm]', '', desk.getExec())) launch = partial(QProcess.startDetached, exe[0], exe[1:]) return super().__new__(cls, name, icon, launch)
class PackageInfo: DESKTOP_DIR = '/usr/share/app-install/desktop/' def __init__(self, name): self.name = name self.pkg = PACKAGE_WORKER.get_cache()[name] self.desktopentry = DesktopEntry(self.DESKTOP_DIR + name + '.desktop') def check_installed(self): return self.pkg.isInstalled def get_comment(self): return self.desktopentry.getComment() def get_name(self): appname = self.desktopentry.getName() if appname == '': return self.name.title() return appname def get_version(self): try: return self.pkg.versions[0].version except: return ''
def parse(desktop_file, debug_enabled): """ Returns a dict if the .desktop entry should be included in the dmenu, or none if not applicable """ application = DesktopEntry(desktop_file) if debug_enabled: eprint('PARSED: ' + desktop_file) if application.getHidden(): if debug_enabled: eprint('HIDDEN: ' + desktop_file) return None if application.getNoDisplay(): if debug_enabled: eprint('NODISPLAY: ' + desktop_file) return None executable = application.getTryExec() if not executable: executable = application.getExec() if not executable: if debug_enabled: eprint('NO EXECUTABLE: ' + desktop_file) return None return { application.getName(): [part for part in executable.split(' ') if not part.startswith('%')] }
def _get_app_list(self, directory, user): for root, dirs, files in os.walk(directory): for name in files: if name.endswith(".desktop"): app_path = root + "/" + name # setup desktop entry to access its elements xgd_de = DesktopEntry(app_path) # self.app_entry = Desktop_Entry( name, xgd_de.getName( ), xgd_de.getGenericName( ), xgd_de.getNoDisplay( ), xgd_de.getHidden( ), xgd_de.getOnlyShowIn( ), xgd_de.getNotShowIn( ), xgd_de.getCategories( ), app_path, user, False ) # Just as a note, skip no display or hidden .desktop if not (self.app_entry.de_nodisp or self.app_entry.de_hidden): self._add_entry(self.app_entry)
class PackageInfo: DESKTOP_DIR = '/usr/share/app-install/desktop/' def __init__(self, name): self.name = name self.pkg = AptWorker.get_cache()[name] self.desktopentry = DesktopEntry(self.DESKTOP_DIR + name + '.desktop') def check_installed(self): return self.pkg.isInstalled def get_comment(self): return self.desktopentry.getComment() def get_name(self): appname = self.desktopentry.getName() if appname == '': return self.name.title() return appname def get_version(self): try: return self.pkg.versions[0].version except: return ''
def parse_xdg(self, path): de = DesktopEntry(path) # type: popup, notify msg_type = de.get('X-CLIP-Msg-Type') # mode: info, warning, error msg_mode = de.get('X-CLIP-Msg-Mode') # content: user message msg_cont = de.get('X-CLIP-Msg-Content') cache = {'type': msg_type, 'mode': msg_mode, 'cont': msg_cont} if self.cache != cache: self.cache = cache if len(msg_mode) > 0 and len(msg_type) > 0 and len(msg_cont) > 0: if msg_type == 'popup': self.popup(de.getName(), msg_cont, msg_mode) elif msg_type == 'notify': self.notify(de.getName(), msg_cont, msg_mode)
def __create_model(self, all=False, comment=False): model = self.get_model() model.clear() allitems = [] allitems.extend(self.useritems) allitems.extend(self.systemitems) for item in allitems: try: desktopentry = DesktopEntry(item) except: continue if desktopentry.get("Hidden"): if not all: continue iter = model.append() enable = desktopentry.get("X-GNOME-Autostart-enabled") if enable == "false": enable = False else: enable = True iconname = desktopentry.get('Icon', locale=False) if not iconname: iconname = desktopentry.get('Name', locale=False) if not iconname: iconname = desktopentry.getName() pixbuf = icon.get_from_name(iconname, size=32) try: name = desktopentry.getName() except: name = desktopentry.get('Name', locale=False) if comment: comment = desktopentry.getComment() if not comment: comment = _("No description") description = "<b>%s</b>\n%s" % (name, comment) else: description = "<b>%s</b>" % name model.set(iter, COLUMN_ACTIVE, enable, COLUMN_ICON, pixbuf, COLUMN_PROGRAM, description, COLUMN_PATH, item)
def xdg_name_and_icon(app): entry = DesktopEntry() for directory in xdg.BaseDirectory.xdg_data_dirs: path = os.path.join(directory, "applications", f"{app}.desktop") if os.path.exists(path): entry.parse(path) return entry.getName(), entry.getIcon() return None, None
def run(self, term): data = [] for file in os.listdir("/usr/share/applications"): if file.endswith(".desktop"): entry = DesktopEntry( os.path.join("/usr/share/applications", file)) data.append(Datum(entry.getName(), entry.getComment())) return [datum for datum in data if term in datum.title]
def __init__(self, parent=None, **kwargs): super(LaunchButton, self).__init__(parent) self.setObjectName("LaunchButton") self.launcher_size = kwargs.get("launcher_size") self.icon_size = kwargs.get("icon_size") self.name, self.comment, self.icon, self.command = None, None, None, None # Load in details from a .desktop file, if there is one. if kwargs.get("desktop_file"): de = DesktopEntry(kwargs.get("desktop_file")) self.name = de.getName() self.comment = de.getComment() self.icon = de.getIcon() self.command = de.getExec() # This allows for overriding the settings in DesktopEntry self.name = kwargs.get("name", self.name) self.comment = kwargs.get("comment", self.comment) self.icon = kwargs.get("icon", self.icon) self.command = kwargs.get("command", self.command) # Create the layouts and widgets to hold the information toplayout = QHBoxLayout() leftlayout = QVBoxLayout() # The button's title title = QLabel(self.name) title.setObjectName("LaunchButtonTitle") leftlayout.addWidget(title) # The button's descriptive comment comment = QLabel(self.comment) comment.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) comment.setWordWrap(True) comment.setObjectName("LaunchButtonDescription") leftlayout.addWidget(comment) # The button's icon, if there is one iconpane = QLabel() icon = (self.icon and icon_anyway_you_can(self.icon, kwargs.get("aggressive_icon_search", False))) or QIcon() pixmap = icon.pixmap(*self.icon_size) if not pixmap.isNull(): pixmap = pixmap.scaled(*self.icon_size) iconpane.setPixmap(pixmap) # Add everything to layouts and layouts to the button toplayout.addWidget(iconpane) toplayout.addLayout(leftlayout) self.setLayout(toplayout) # Set the button's size from config. self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.setMinimumSize(QSize(*self.launcher_size)) # Connect the callback self.connect(self, SIGNAL("clicked()"), self.callback)
def test_values(self): entry = DesktopEntry(self.test_file) self.assertEqual(entry.getName(), 'gedit') self.assertEqual(entry.getGenericName(), 'Text Editor') self.assertEqual(entry.getNoDisplay(), False) self.assertEqual(entry.getComment(), 'Edit text files') self.assertEqual(entry.getIcon(), 'accessories-text-editor') self.assertEqual(entry.getHidden(), False) self.assertEqual(entry.getOnlyShowIn(), []) self.assertEqual(entry.getExec(), 'gedit %U') self.assertEqual(entry.getTerminal(), False) self.assertEqual(entry.getMimeTypes(), ['text/plain']) self.assertEqual(entry.getCategories(), ['GNOME', 'GTK', 'Utility', 'TextEditor']) self.assertEqual(entry.getTerminal(), False)
def load_desktop_sessions(): xsessions_dir = "%s/share/xsessions" % sys.prefix xsessions = {} if os.path.exists(xsessions_dir): from xdg.DesktopEntry import DesktopEntry for f in os.listdir(xsessions_dir): filename = os.path.join(xsessions_dir, f) de = DesktopEntry(filename) try: entry = load_xdg_entry(de) if not entry: continue if getattr(entry, "IconData", None) is None: names = get_icon_names_for_session(de.getName().lower()) v = find_session_icon(*names) if v: entry["IconData"] = v[0] entry["IconType"] = v[1] xsessions[de.getName()] = entry except Exception as e: log("load_desktop_sessions(%s)", remove_icons, exc_info=True) log.error("Error loading desktop entry '%s':", filename) log.error(" %s", e) return xsessions
def addDesktopEntry(file): entry=DesktopEntry() try: entry.parse(file) except: return if entry.getNoDisplay(): return tryexec=entry.getTryExec() if tryexec and not os.path.exists(tryexec): return entry.setLocale("C") display_name=entry.getName() catalog.insertEntry(file, display_name, run)
def populate_command(self): log("populate_command()") self.command_combo.get_model().clear() if self.xsessions is None: assert xdg from xdg.DesktopEntry import DesktopEntry xsessions_dir = "%s/share/xsessions" % sys.prefix self.xsessions = {} if os.path.exists(xsessions_dir): for f in os.listdir(xsessions_dir): filename = os.path.join(xsessions_dir, f) de = DesktopEntry(filename) self.xsessions[de.getName()] = de log("populate_command() xsessions=%s", self.xsessions) for name in sorted(self.xsessions.keys()): self.command_combo.append_text(name) self.command_combo.set_active(0)
def add_desktop(self, filename): try: d = DesktopEntry(filename) if d.getHidden() or d.getNoDisplay() or d.getTerminal( ) or d.getType() != 'Application': return app = Application(name=d.getName(), command_line=get_command(d), mtime=datetime.fromtimestamp( os.path.getmtime(filename)), is_desktop=True) if d.getPath(): app.path = d.getPath() self.add_app(app) except (xdg.Exceptions.ParsingError, xdg.Exceptions.DuplicateGroupError, xdg.Exceptions.DuplicateKeyError): pass
class VeraCCModule: """ An object representing a Vera Control Center module. """ def __init__(self, module_name, module_path): """ Initialize the object """ self.module_is_external = False self.module_name = module_name self.module_path = module_path self.launcher_icon = None self.launcher_name = None self.launcher_comment = None self.launcher_section = None self.module_launcher = DesktopEntry( os.path.join(self.module_path, "%s.desktop" % self.module_name)) # Icon self.launcher_icon = self.module_launcher.getIcon() if not self.launcher_icon: self.launcher_icon = "preferences-system" #ICON_THEME.connect("changed", lambda x: self.replace_icon(icon)) # Name self.launcher_name = self.module_launcher.getName() # Comment self.launcher_comment = self.module_launcher.getComment() # Section self.launcher_section = self.module_launcher.get("X-VeraCC-Section") # Keywords self.launcher_keywords = [ x.lower() for x in self.module_launcher.getKeywords() ] # External? _exec = self.module_launcher.getExec() if _exec: # Yeah! self.module_is_external = True self.module_path = _exec
def _populate(self): for item in self.EDITORS: if os.path.isfile(item): args = self.EDITORS[item] desktop_entry = DesktopEntry(item) command = desktop_entry.getExec() # For .desktop files with ' %U' or ' # %F' command = command.split(" ")[0] name = desktop_entry.getName() icon_name = desktop_entry.getIcon() self._add_item(icon_name, name, command, args) if len(self.get_model()): self.empty = False else: self.empty = True
class VeraCCModule: """ An object representing a Vera Control Center module. """ def __init__(self, module_name, module_path): """ Initialize the object """ self.module_is_external = False self.module_name = module_name self.module_path = module_path self.launcher_icon = None self.launcher_name = None self.launcher_comment = None self.launcher_section = None self.module_launcher = DesktopEntry(os.path.join(self.module_path, "%s.desktop" % self.module_name)) # Icon self.launcher_icon = self.module_launcher.getIcon() if not self.launcher_icon: self.launcher_icon = "preferences-system" #ICON_THEME.connect("changed", lambda x: self.replace_icon(icon)) # Name self.launcher_name = self.module_launcher.getName() # Comment self.launcher_comment = self.module_launcher.getComment() # Section self.launcher_section = self.module_launcher.get("X-VeraCC-Section") # Keywords self.launcher_keywords = [x.lower() for x in self.module_launcher.getKeywords()] # External? _exec = self.module_launcher.getExec() if _exec: # Yeah! self.module_is_external = True self.module_path = _exec
class PackageInfo: DESKTOP_DIR = "/usr/share/app-install/desktop/" def __init__(self, name): self.name = name self.pkg = cache[name] self.desktopentry = DesktopEntry(self.DESKTOP_DIR + name + ".desktop") def check_installed(self): return self.pkg.isInstalled def get_comment(self): return self.desktopentry.getComment() def get_name(self): appname = self.desktopentry.getName() if appname == "": return self.name.title() return appname
class PackageInfo: DESKTOP_DIR = '/usr/share/app-install/desktop/' def __init__(self, name): self.name = name self.pkg = package_worker.get_cache()[name] self.desktopentry = DesktopEntry(self.DESKTOP_DIR + name + '.desktop') def check_installed(self): return self.pkg.isInstalled def get_comment(self): return self.desktopentry.getComment() def get_name(self): appname = self.desktopentry.getName() if appname == '': return self.name.title() return appname
def listAndUpdateDesktopFiles(self, path, menuObjs): for f in listdir(path): fPath = path + f if isfile(fPath) and f.endswith(".desktop"): xdgObj = DesktopEntry(fPath) title = xdgObj.getName() groups = xdgObj.getCategories() comment = xdgObj.getComment() icon = xdgObj.getIcon() mainExec = xdgObj.getExec() tryExec = xdgObj.getTryExec() group = "" if "Accessories" in groups or "Utility" in groups: group = "Accessories" elif "Multimedia" in groups or "Video" in groups or "Audio" in groups: group = "Multimedia" elif "Development" in groups: group = "Development" elif "Game" in groups: group = "Game" elif "Internet" in groups or "Network" in groups: group = "Internet" elif "Graphics" in groups: group = "Graphics" elif "Office" in groups: group = "Office" elif "System" in groups: group = "System" elif "Settings" in groups: group = "Settings" elif "Wine" in groups: group = "Wine" else: group = "Other" menuObjs[group].append( {"title": title, "groups": groups, "comment": comment, "exec": mainExec, "tryExec": tryExec, "fileName": f, "filePath": fPath, "icon": icon})
def from_dotdesktop(app_def): """ Return a WSLApp from a .desktop file. Args: app_def: .desktop file path """ de = DesktopEntry(app_def) name = de.getName() generic_name = de.getGenericName() cmd = de.getExec() gui = not de.getTerminal() icon = de.getIcon() return { "name": name, "generic_name": generic_name, "cmd": cmd, "gui": gui, "icon": icon }
def _generate_app_actions(self, path): app_actions = [] filename_pattern = os.path.expanduser(os.path.join( path, AppsOperator.FILE_TYPE )) for filename in glob.glob(filename_pattern): app = DesktopEntry(filename) # TODO: Comply with full DesktopEntries spec - OnlyShowIn, TryExec if app.getType() == "Application" and not app.getNoDisplay() and \ not app.getHidden() and not app.getTerminal(): action = AppAction( name=app.getName(), description="application", run=self._launch_application, data={"desktop_entry": app, "cmd": self.get_cmd(app)}, icon=get_icon(app.getIcon()), ) app_actions.append(action) return app_actions
def __post_init__(self): if isinstance(self.icon_size, str): self.icon_size = utils.parse_size(self.icon_size) if isinstance(self.launcher_size, str): self.launcher_size = utils.parse_size(self.launcher_size) # Load in details from a .desktop file, if there is one. if self.desktop_file: try: de = DesktopEntry(self.desktop_file) except PermissionError as e: utils.debug( "Access denied on desktop file: {}, {}" .format(self.desktop_file, e) ) else: self.name = de.getName() self.comment = de.getComment() self.icon = de.getIcon() self.command = de.getExec() self.categories = [c.lower() for c in de.getCategories()]
def parse_linux_desktop_entry(fpath): """Load data from desktop entry with xdg specification.""" from xdg.DesktopEntry import DesktopEntry try: entry = DesktopEntry(fpath) entry_data = {} entry_data['name'] = entry.getName() entry_data['icon_path'] = entry.getIcon() entry_data['exec'] = entry.getExec() entry_data['type'] = entry.getType() entry_data['hidden'] = entry.getHidden() entry_data['fpath'] = fpath except Exception: entry_data = { 'name': '', 'icon_path': '', 'hidden': '', 'exec': '', 'type': '', 'fpath': fpath } return entry_data
def main(args): args =args[1:] if len(args )!=1: print("takes one argument") return try: desktop =DesktopEntry() desktop.parse(args[0]) except: print("parse error" ,args[0]) name =desktop.getName() name =''.join(lazy_pinyin(name)) AppName=desktop.getName() NoDisplay=False; if len(AppName)==0: AppName=desktop.getGenericName AppComment=desktop.getComment() AppIcon=desktop.getIcon() if not os.path.exists(AppIcon): ip=getIconPath(AppIcon,theme="deepin") # if ip is None: # ip=getIconPath(AppIcon,theme="hicolor") else: ip=AppIcon if ip is None: #TODO add defauult icon ip="test" pass AppIcon=ip NoDisplay=desktop.getNoDisplay() onlydi=desktop.getOnlyShowIn() if NoDisplay is True or len(onlydi)>0: AppIcon="" AppName="" AppComment="" NoDisplay="true" else: NoDisplay="false" print(''' <html><head> <title>''' +name+ '''</title> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" > <meta name="AppName" content="'''+AppName+'''" /> <meta name="AppComment" content="'''+AppComment+'''" /> <meta name="AppIcon" content="'''+AppIcon+'''" /> <meta name="AppNoDisplay" content="'''+NoDisplay+'''" /> </head> <body> '''+AppName+''' </body> </html> ''')
glob(os.path.join(path, '*.desktop')) for path in BaseDirectory.load_data_paths('applications') ): desktop = DesktopEntry(dfile) fname = os.path.splitext(os.path.basename(dfile))[0] try: cmd = FILTER.sub('', desktop.getExec()).split(' ', 1) cmd[0] = which(cmd[0]) except ProgramNotFound: continue if desktop.getTerminal(): cmd.insert(0, withpty) #service_path = os.path.join(generator_dir, fname) service_path = os.path.join(generator_dir, fname + "@.service") service = IniFile() service.addGroup('Unit') service.set('SourcePath', dfile, 'Unit') if not desktop.getHidden(): service.set('X-ShowInMenu', "True", 'Unit') service.set('Description', desktop.getName(), 'Unit') service.addGroup('Service') service.set('EnvironmentFile', "%t/sessions/%i/environ", 'Service') service.set('ExecStart', " ".join(cmd), 'Service') service.defaultGroup = 'Unit' service.write(service_path)
def test_unicode_name(self): with io.open(self.test_file, "w", encoding='utf-8') as f: f.write(resources.unicode_desktop) entry = DesktopEntry(self.test_file) self.assertEqual(entry.getName(), u('Abc€þ'))
def __init__(self, parent=None, **kwargs): """Construct a LaunchButton""" super(LaunchButton, self).__init__(parent) self.setObjectName("LaunchButton") self.launcher_size = kwargs.get("launcher_size") self.icon_size = kwargs.get("icon_size") self.name = None self.comment = None self.icon = None self.command = None self.categories = None # Load in details from a .desktop file, if there is one. desktop_file = kwargs.get("desktop_file") if desktop_file: if os.access(desktop_file, os.R_OK): de = DesktopEntry(desktop_file) self.name = de.getName() self.comment = de.getComment() self.icon = de.getIcon() self.command = de.getExec() self.categories = [c.lower() for c in de.getCategories()] else: sys.stderr.write( "Read access denied on manually-specified " "desktop file {}. Button may be missing data.\n".format( desktop_file)) # This allows for overriding the settings in DesktopEntry self.name = kwargs.get("name", self.name) self.comment = kwargs.get("comment", self.comment) self.icon = kwargs.get("icon", self.icon) self.command = kwargs.get("command", self.command) # Create the layouts and widgets to hold the information toplayout = QHBoxLayout() leftlayout = QVBoxLayout() # The button's title title = QLabel(self.name) title.setObjectName("LaunchButtonTitle") leftlayout.addWidget(title) # The button's descriptive comment comment = QLabel(self.comment) comment.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) comment.setWordWrap(True) comment.setObjectName("LaunchButtonDescription") leftlayout.addWidget(comment) # The button's icon, if there is one iconpane = QLabel() icon = (self.icon and icon_anyway_you_can( self.icon, kwargs.get("aggressive_icon_search", False))) or QIcon() pixmap = icon.pixmap(*self.icon_size) if not pixmap.isNull(): pixmap = pixmap.scaled(*self.icon_size) iconpane.setPixmap(pixmap) # Add everything to layouts and layouts to the button toplayout.addWidget(iconpane) toplayout.addLayout(leftlayout) self.setLayout(toplayout) # Set the button's size from config. self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.setMinimumSize(QSize(*self.launcher_size)) # Connect the callback self.clicked.connect(self.callback)
class MenuEntry: "Wrapper for 'Menu Style' Desktop Entries" def __init__(self, filename, dir="", prefix=""): # Create entry self.DesktopEntry = DesktopEntry(os.path.join(dir,filename)) self.setAttributes(filename, dir, prefix) # Can be one of Deleted/Hidden/Empty/NotShowIn/NoExec or True self.Show = True # Semi-Private self.Original = None self.Parents = [] # Private Stuff self.Allocated = False self.Add = False self.MatchedInclude = False # Caching self.Categories = self.DesktopEntry.getCategories() def save(self): """Save any changes to the desktop entry.""" if self.DesktopEntry.tainted == True: self.DesktopEntry.write() def getDir(self): """Return the directory containing the desktop entry file.""" return self.DesktopEntry.filename.replace(self.Filename, '') def getType(self): """Return the type of MenuEntry, System/User/Both""" if xdg.Config.root_mode == False: if self.Original: return "Both" elif xdg_data_dirs[0] in self.DesktopEntry.filename: return "User" else: return "System" else: return "User" def setAttributes(self, filename, dir="", prefix=""): self.Filename = filename self.Prefix = prefix self.DesktopFileID = os.path.join(prefix,filename).replace("/", "-") if not os.path.isabs(self.DesktopEntry.filename): self.__setFilename() def updateAttributes(self): if self.getType() == "System": self.Original = MenuEntry(self.Filename, self.getDir(), self.Prefix) self.__setFilename() def __setFilename(self): if xdg.Config.root_mode == False: path = xdg_data_dirs[0] else: path= xdg_data_dirs[1] if self.DesktopEntry.getType() == "Application": dir = os.path.join(path, "applications") else: dir = os.path.join(path, "desktop-directories") self.DesktopEntry.filename = os.path.join(dir, self.Filename) def __cmp__(self, other): return locale.strcoll(self.DesktopEntry.getName(), other.DesktopEntry.getName()) def _key(self): """Key function for locale-aware sorting.""" return _strxfrm(self.DesktopEntry.getName()) def __lt__(self, other): try: other = other._key() except AttributeError: pass return self._key() < other def __eq__(self, other): if self.DesktopFileID == str(other): return True else: return False def __repr__(self): return self.DesktopFileID
class Mapping(object): """ An object representation of a wiican mapping. A wiican mapping must be located in a single directory containing a file with the wminput code, a file containing the metadata (name, description, author, version) and an optional icon file. """ # Mandatory filename for the metadata file info_filename = "info.desktop" # Mandatory filename for the wminput config file mapping_filename = "mapping.wminput" def __init__(self, path=None): """ Builds a mapping object. Parameters: path - scans the path for building a mapping object if the needed files where found. If None it builds an empty mapping. If some of the needed files wasn't found it tries to build a mapping with the found info. The Mapping.info_filename and Mapping.mapping_filename class attributes marks the requiered filenames for the metadata file and wminput config file respectively. The Mapping.mapping_filename file must contain wminput config file code The Mapping.info_filename follows XDG DesktopEntry syntax. The Mapping.info_filename contains the source of the optional associated icon. If no icon found or no icon directive it falls back to default icon. There are three posibilities for icon setting: - An absolute path where the icon it's stored - Icon filename if it's stored in the same dir as Mapping.info_filename - Theme-icon-name for auto-getting the icon from the icon theme """ self.__path = path # Getting freedesktop definition file self.__info = DesktopEntry() if path and os.path.exists(os.path.join(path, Mapping.info_filename)): self.__info.parse(os.path.join(path, Mapping.info_filename)) else: self.__info.new(self.info_filename) self.__info.set("Type", "Wiican Mapping") # Getting wminput mapping file if path and os.path.exists(os.path.join(path, Mapping.mapping_filename)): mapping_fp = open(os.path.join(path, Mapping.mapping_filename), "r") self.__mapping = mapping_fp.read() mapping_fp.close() else: self.__mapping = "" # Getting icon file path icon_name = self.__info.getIcon() if path and icon_name in os.listdir(path): # Icon included self.set_icon(os.path.join(path, icon_name)) elif getIconPath(icon_name): # Theme icon self.set_icon(getIconPath(icon_name)) else: # Default icon self.set_icon(ICON_DEFAULT) def get_path(self): """Returns the absolute path where the wiican mapping it's saved. It returns None if the mapping it's not saved yet""" return self.__path def get_name(self): """Gets the name of the mapping""" return self.__info.getName() def set_name(self, name): """Sets the name for the mapping""" self.__info.set("Name", name) self.__info.set("Name", name, locale=True) def get_comment(self): """Gets the descriptional comment""" return self.__info.getComment() def set_comment(self, comment): """Sets the descriptional comment for the mapping""" self.__info.set("Comment", comment) self.__info.set("Comment", comment, locale=True) def get_icon(self): """ Gets the associated icon. If no icon found or no icon directive it falls back to default icon. """ icon_name = self.__info.getIcon() # Icon included if self.__path and icon_name in os.listdir(self.__path): return os.path.join(self.__path, icon_name) # Theme icon elif getIconPath(icon_name): return getIconPath(icon_name) # Default icon else: return ICON_DEFAULT def set_icon(self, icon_path): """ Sets the icon for the mapping. There are three posibilities for icon setting: - An absolute path where the icon it's stored - Icon filename if it's stored in the same dir as Mapping.info_filename - Theme-icon-name for auto-getting the icon from the icon theme """ self.__info.set("Icon", icon_path) def get_authors(self): """Gets the mapping author/s""" return self.__info.get("X-Authors") def set_authors(self, authors): """Sets the author/s for the mapping""" self.__info.set("X-Authors", authors) def get_version(self): """Gets the version of the mapping""" return self.__info.get("X-Version") def set_version(self, version): """Sets the version of the mapping""" self.__info.set("X-Version", version) def get_mapping(self): """Gets the wminput config code""" return self.__mapping def set_mapping(self, mapping): """Sets the wminput config code""" self.__mapping = mapping def write(self, dest_path=None): """ Saves the mapping object by writing the files in the mapping directory. The metadata it's saved in Mapping.info_filename file. The wminput config code it's saved in Mapping.mapping_filename file. The associated icon it's copied to the mapping directory. """ if not dest_path: if not self.__path: raise MappingError, _("No path provided for writing mapping") dest_path = self.__path elif not os.path.exists(dest_path): os.mkdir(dest_path) icon_path = self.get_icon() icon_filename = os.path.basename(icon_path) if not icon_path == os.path.join(dest_path, icon_filename): shutil.copy(icon_path, dest_path) self.set_icon(icon_filename) self.__info.write(os.path.join(dest_path, Mapping.info_filename)) mapping_fp = open(os.path.join(dest_path, Mapping.mapping_filename), "w") mapping_fp.write(self.__mapping) mapping_fp.close() # Clean not useful files for item in [ x for x in os.listdir(dest_path) if not x in [Mapping.info_filename, Mapping.mapping_filename, icon_filename] ]: os.unlink(os.path.join(dest_path, item)) self.__path = dest_path def __repr__(self): return "Mapping <" + self.__info.get("Name", locale=False) + " " + str(self.__info.getVersion()) + ">"
class AutostartFile: def __init__(self, path): self.path = path self.filename = os.path.basename(path) self.dirname = os.path.dirname(path) self.de = DesktopEntry(path) def __eq__(self, other): return self.filename == other.filename def __str__(self): return self.path + " : " + self.de.getName() def _isexecfile(self, path): return os.access(path, os.X_OK) def _findFile(self, path, search, match_func): # check empty path if not path: return None # check absolute path if path[0] == "/": if match_func(path): return path else: return None else: # check relative path for dirname in search.split(os.pathsep): if dirname != "": candidate = os.path.join(dirname, path) if match_func(candidate): return candidate def _alert(self, mstr, info=False): if info: print("\t " + mstr) else: print("\t*" + mstr) def _showInEnvironment(self, envs, verbose=False): default = not self.de.getOnlyShowIn() noshow = False force = False for i in self.de.getOnlyShowIn(): if i in envs: force = True for i in self.de.getNotShowIn(): if i in envs: noshow = True if verbose: if not default and not force: s = "" for i in self.de.getOnlyShowIn(): if s: s += ", " s += i self._alert("Excluded by: OnlyShowIn (" + s + ")") if default and noshow and not force: s = "" for i in self.de.getNotShowIn(): if s: s += ", " s += i self._alert("Excluded by: NotShowIn (" + s + ")") return (default and not noshow) or force def _shouldRun(self, envs, verbose=False): if not self.de.getExec(): if verbose: self._alert("Excluded by: Missing Exec field") return False if self.de.getHidden(): if verbose: self._alert("Excluded by: Hidden") return False if self.de.getTryExec(): if not self._findFile(self.de.getTryExec(), os.getenv("PATH"), self._isexecfile): if verbose: self._alert("Excluded by: TryExec (" + self.de.getTryExec() + ")") return False if not self._showInEnvironment(envs, verbose): return False return True def display(self, envs): if self._shouldRun(envs): print("[*] " + self.de.getName()) else: print("[ ] " + self.de.getName()) self._alert("File: " + self.path, info=True) if self.de.getExec(): self._alert("Executes: " + self.de.getExec(), info=True) self._shouldRun(envs, True) print def run(self, envs): here = os.getcwd() if self.de.getPath(): os.chdir(self.de.getPath()) if self._shouldRun(envs): args = ["/bin/sh", "-c", "exec " + self.de.getExec()] os.spawnv(os.P_NOWAIT, args[0], args) os.chdir(here)
#!/usr/bin/env python3 # Author: Juho Teperi from xdg.BaseDirectory import load_data_paths from xdg.DesktopEntry import DesktopEntry from glob import glob from re import sub from os.path import basename # To remove duplicates data = {} for d in load_data_paths("applications"): for app in glob(d + "/*.desktop"): desktop = DesktopEntry(app) name = desktop.getName() if (not desktop.getHidden() and not desktop.getNoDisplay()) and name not in data: data[name] = basename(app) for name, cmd in data.items(): print('{}\t{}'.format(name, cmd))
def parseMenu(menu, menuJSON): for submenu in menu.Entries: if isinstance(submenu, Menu): newmenu=parseMenu(submenu, []); #print ("Submenu icon: "+submenu.getIcon() + " is "+theme.getIconPath(submenu.getIcon())) iconpath=theme.getIconPath(submenu.getIcon(), None, 'Numix-Circle') #iconpath=theme.getIconPath(submenu.getIcon(), 128, 'future-green') #iconpath=theme.getIconPath(submenu.getIcon(), 128, 'Numix-Circle') iconpath=give_me_png(iconpath) if iconpath==None: iconpath='' print "cat icon: "+submenu.getIcon()+" is "+iconpath menuJSON.append({"id": unicode(submenu).replace(" ", "_"), "name":submenu.getName(), "icon":iconpath, "children":newmenu}); elif isinstance(submenu, MenuEntry): # Description at # http://pyxdg.readthedocs.org/en/latest/_modules/xdg/DesktopEntry.html newitem={} filename="/usr/share/applications/"+unicode(submenu); item=False if (os.path.isfile(filename)): item=DesktopEntry(filename) else: # is kde4- prexifed? if (unicode(submenu)[0:5]=="kde4-"): filename="/usr/share/applications/kde4/"+unicode(submenu)[5:]; item=DesktopEntry(filename) #print "!!"+item; if item is not False: newitem["id"]=unicode(submenu).replace(" ", "_") newitem["name"]=item.getName() #newitem["icon"]=item.getIcon() newitem["comment"]=item.getComment() newitem["tryexec"]=item.getTryExec() newitem["exec"]=item.getExec() newitem["path"]=item.getPath() iconpath=theme.getIconPath(item.getIcon(), 128, 'Numix-Circle') #iconpath=theme.getIconPath(item.getIcon(), 128, 'future-green') #iconname=item.getIcon(); # Convert png if not exists... #iconpath=give_me_png(iconname); iconpath=give_me_png(iconpath); if iconpath==None: iconpath='' #print "icon: "+item.getIcon()+" is "+iconpath #print ("Icon: "+item.getIcon() + " is "+iconpath) newitem["icon"]=iconpath #newitem["name"]=a.getName(); #newitem["id"]=unicode(submenu) # Only Append if it's executable #if (item.findTryExec()): # menuJSON.append(newitem); #if newitem["name"]!="": menuJSON.append(newitem); return menuJSON
def __init__(self, parent=None, **kwargs): """Construct a LaunchButton""" super(LaunchButton, self).__init__(parent) self.setObjectName("LaunchButton") self.launcher_size = kwargs.get("launcher_size") self.icon_size = kwargs.get("icon_size") self.name = None self.comment = None self.icon = None self.command = None self.categories = None # Load in details from a .desktop file, if there is one. desktop_file = kwargs.get("desktop_file") if desktop_file: if os.access(desktop_file, os.R_OK): de = DesktopEntry(desktop_file) self.name = de.getName() self.comment = de.getComment() self.icon = de.getIcon() self.command = de.getExec() self.categories = [c.lower() for c in de.getCategories()] else: sys.stderr.write( "Read access denied on manually-specified " "desktop file {}. Button may be missing data.\n" .format(desktop_file)) # This allows for overriding the settings in DesktopEntry self.name = kwargs.get("name", self.name) self.comment = kwargs.get("comment", self.comment) self.icon = kwargs.get("icon", self.icon) self.command = kwargs.get("command", self.command) # Create the layouts and widgets to hold the information toplayout = QHBoxLayout() leftlayout = QVBoxLayout() # The button's title title = QLabel(self.name) title.setObjectName("LaunchButtonTitle") leftlayout.addWidget(title) # The button's descriptive comment comment = QLabel(self.comment) comment.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) comment.setWordWrap(True) comment.setObjectName("LaunchButtonDescription") leftlayout.addWidget(comment) # The button's icon, if there is one iconpane = QLabel() icon = ( self.icon and icon_anyway_you_can( self.icon, kwargs.get("aggressive_icon_search", False) ) ) or QIcon() pixmap = icon.pixmap(*self.icon_size) if not pixmap.isNull(): pixmap = pixmap.scaled(*self.icon_size) iconpane.setPixmap(pixmap) # Add everything to layouts and layouts to the button toplayout.addWidget(iconpane) toplayout.addLayout(leftlayout) self.setLayout(toplayout) # Set the button's size from config. self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.setMinimumSize(QSize(*self.launcher_size)) # Connect the callback self.clicked.connect(self.callback)