Пример #1
0
def load_desktop_entry_with_dropins(filename, dropins):
    desktop_entry = DesktopEntry(filename)
    for dropin in dropins:
        dropin_entry = DesktopEntry(dropin)
        for group_name, group in dropin_entry.content.items():
            desktop_entry.content.setdefault(group_name, {}).update(group)
    return desktop_entry
Пример #2
0
    def enabled_toggled(self, cell, path, model):
        iter = model.get_iter((int(path), ))
        active = model.get_value(iter, COLUMN_ACTIVE)
        path = model.get_value(iter, COLUMN_PATH)

        if self.is_defaultitem(path):
            shutil.copy(path, self.userdir)
            path = os.path.join(self.userdir, os.path.basename(path))
            desktopentry = DesktopEntry(path)
            desktopentry.set("X-GNOME-Autostart-enabled", "false")
            desktopentry.write()
            model.set(iter, COLUMN_PATH, path)
        else:
            if active:
                desktopentry = DesktopEntry(path)
                desktopentry.set("X-GNOME-Autostart-enabled", "false")
                desktopentry.write()
            else:
                if self.is_in_systemdir(path):
                    os.remove(path)
                    path = os.path.join(self.get_systemdir(path),
                                        os.path.basename(path))
                    model.set(iter, COLUMN_PATH, path)
                else:
                    desktopentry = DesktopEntry(path)
                    desktopentry.set("X-GNOME-Autostart-enabled", "true")
                    desktopentry.set("Hidden", "false")
                    desktopentry.write()

        active = not active

        model.set(iter, COLUMN_ACTIVE, active)
Пример #3
0
    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
Пример #4
0
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()))
Пример #5
0
    def on_edit_item(self, widget, treeview):
        model, iter = treeview.get_selection().get_selected()

        if iter:
            path = model.get_value(iter, COLUMN_PATH)
            if path[1:4] == "etc":
                shutil.copy(path, treeview.userdir)
                path = os.path.join(treeview.userdir, os.path.basename(path))
            dialog = AutoStartDialog(DesktopEntry(path), widget.get_toplevel())
            if dialog.run() == gtk.RESPONSE_OK:
                name = dialog.pm_name.get_text()
                cmd = dialog.pm_cmd.get_text()
                if not name:
                    ErrorDialog(
                        _("The name of the startup program cannot be empty")
                    ).launch()
                elif not cmd:
                    ErrorDialog(
                        _("Text field was empty (or contained only whitespace)"
                          )).launch()
                else:
                    desktopentry = DesktopEntry(path)
                    desktopentry.set("Name", name, locale=True)
                    desktopentry.set("Exec", cmd)
                    desktopentry.set("Comment",
                                     dialog.pm_comment.get_text(),
                                     locale=True)
                    desktopentry.write()
                    treeview.update_items(
                        all=self.show_all_button.get_active(),
                        comment=self.show_comment_button.get_active())
                    dialog.destroy()
                    return
            dialog.destroy()
Пример #6
0
 def get_autostart(self):
     if os.path.exists(self.autostart_desktop):
         desktop_entry = DesktopEntry(self.autostart_desktop)
         return not desktop_entry.getHidden()
     elif os.path.exists(self.sys_autostart_desktop):
         desktop_entry = DesktopEntry(self.sys_autostart_desktop)
         return not desktop_entry.getHidden()
     else:
         return False
Пример #7
0
def get_desktop_entry(desktop_file):
    if os.path.isabs(desktop_file):
        return DesktopEntry(desktop_file)
    else:
        filename = get_desktop_file(desktop_file)
        if filename is not None:
            return DesktopEntry(filename)
        else:
            return None
Пример #8
0
    def desktop(self, dest=None):
        '''
        Returns desktop file object which may be written to disk.
        '''
        if dest:
            self.desktop_file = DesktopEntry(dest)
        else:
            self.desktop_file = DesktopEntry()
            self.desktop_file.addGroup('Desktop Entry')
            self.desktop_file.set('Version', '1.0')
        self._update_desktop()

        return self.desktop_file
Пример #9
0
    def on_drag_data_received(self, widget, context, x, y, selection, target,
                              timestamp, box):
        droppeduris = selection.get_uris()

        # url-unquote the list, strip file:// schemes, handle .desktop-s
        pathlist = []
        app = None
        for uri in droppeduris:
            scheme, _, path, _, _ = urlsplit(uri)

            if scheme != "file":
                pathlist.append(uri)
            else:
                filename = url2pathname(path)

                desktopentry = DesktopEntry()
                try:
                    desktopentry.parse(filename)
                except xdg.Exceptions.ParsingError:
                    pathlist.append(filename)
                    continue

                if desktopentry.getType() == 'Link':
                    pathlist.append(desktopentry.getURL())

                if desktopentry.getType() == 'Application':
                    app = desktopentry.getExec()

        if app and len(droppeduris) == 1:
            text = app
        else:
            text = str.join("", (shell_quote(path) + " " for path in pathlist))

        box.terminal.feed_child(text)
        return True
Пример #10
0
    def test_invalid_unicode(self):
        test_file = os.path.join(self.tmpdir, "gnome-alsamixer.desktop")
        with io.open(test_file, "w", encoding='latin-1') as f:
            f.write(resources.gnome_alsamixer_desktop)

        # Just check this doesn't throw a UnicodeError.
        DesktopEntry(test_file)
Пример #11
0
    def test_basic(self):
        entry = DesktopEntry(self.test_file)
        assert entry.hasKey("Categories")
        assert not entry.hasKey("TryExec")

        assert entry.hasGroup("Desktop Action Window")
        assert not entry.hasGroup("Desktop Action Door")
Пример #12
0
 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)
Пример #13
0
    def _extract_desktop_entry(self, app):
        '''Get DesktopEntry for desktop file and verify it'''
        d = self.manifest['hooks'][app]['desktop']
        fn = os.path.join(self.unpack_dir, d)

        bn = os.path.basename(fn)
        if not os.path.exists(fn):
            error("Could not find '%s'" % bn)

        fh = open_file_read(fn)
        contents = ""
        for line in fh.readlines():
            contents += line
        fh.close()

        try:
            de = DesktopEntry(fn)
        except xdgParsingError as e:
            error("desktop file unparseable: %s (%s):\n%s" %
                  (bn, str(e), contents))
        try:
            de.parse(fn)
        except Exception as e:
            error("desktop file unparseable: %s (%s):\n%s" %
                  (bn, str(e), contents))
        return de, fn
Пример #14
0
    def _create_autostarter(self):
        autostart_file = self._get_autostart_file_path()
        autostart_dir = os.path.dirname(autostart_file)

        if not os.path.isdir(autostart_dir):
            # create autostart dir
            try:
                os.mkdir(autostart_dir)
            except DirectoryCreationError as e:
                print("Creation of autostart dir failed, please make it yourself: {}".format(autostart_dir))
                raise e

        if not os.path.isfile(autostart_file):
            # create autostart entry
            starter_item = DesktopEntry(autostart_file)
            starter_item.set('Name', 'f.lux indicator applet')
            # Use the user's shell to start 'fluxgui', in case
            # 'fluxgui' is not installed on a standard system path. We
            # use 'sh' to start the users '/etc/passwd' shell via
            # '$SHELL', so that this will still work if the user
            # changes their shell after the
            # 'autostart/fluxgui.desktop' file is created.
            #
            # See PR #89 for an alternative approach:
            #
            #   https://github.com/xflux-gui/fluxgui/pull/89
            #
            # The escaping of the 'Exec' field is described in
            #
            #   https://developer.gnome.org/desktop-entry-spec/#exec-variables.
            starter_item.set('Exec', r'sh -c "\\"\\$SHELL\\" -c fluxgui"')
            starter_item.set('Icon', 'fluxgui')
            starter_item.set('X-GNOME-Autostart-enabled', 'true')
            starter_item.write()
            self.autostart = True
Пример #15
0
    def init(self, info, progress):
        """
        If needed, perform long initialisation tasks here.

        info is a dictionary with useful information.  Currently it contains
        the following values:

          "values": a dict mapping index mnemonics to index numbers

        The progress indicator can be used to report progress.
        """

        # Read the value indexes we will use
        values = info['values']
        self.val_popcon = values.get("app-popcon", -1)

        self.indexers = [Indexer(lang, self.val_popcon, progress) for lang in [None] + list(self.langs)]
        self.entries = {}

        progress.begin("Reading .desktop files from %s" % APPINSTALLDIR)
        for f in os.listdir(APPINSTALLDIR):
            if f[0] == '.' or not f.endswith(".desktop"): continue
            entry = DesktopEntry(os.path.join(APPINSTALLDIR, f))
            pkg = entry.get("X-AppInstall-Package")
            self.entries.setdefault(pkg, []).append((f, entry))
        progress.end()
Пример #16
0
    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
Пример #17
0
def parse_to_entries(file_name):
    if file_name.endswith('.menu'):
        return xdg.Menu.parse(file_name)
    else:
        result = DesktopEntry()
        result.parse(file_name)
        return result
Пример #18
0
    def fetchMore(self, parent):
        # print("RecollQuery.fetchMore:")
        num_to_fetch = min(self.pagelen, self.totres - len(self.searchResults))
        titem = []
        for count in range(num_to_fetch):
            try:
                item = self.query.fetchone()
                url = str(item['url'][7:])
                if url.endswith("desktop"):
                    desktop = DesktopEntry()
                    try:
                        desktop.parse(url)
                    except (ParsingError, DuplicateGroupError,
                            DuplicateKeyError) as e:
                        print(e)
                    if desktop.getNoDisplay():
                        continue
                    if len(desktop.getOnlyShowIn()) != 0:
                        continue

                titem.append(item)
            except:
                break
        self.beginInsertRows(QtCore.QModelIndex(), len(self.searchResults),
                             len(self.searchResults) + len(titem) - 1)
        self.searchResults.extend(titem)
        self.endInsertRows()
Пример #19
0
def get_or_create_desktop_file():
    desktop = lookup_desktop_file('uroute.desktop')

    if desktop is None:
        path = os.path.join(
            xdg.BaseDirectory.xdg_data_home,
            'applications',
            'uroute.desktop',
        )
        desktop = DesktopEntry(path)
        desktop.set('Version', '1.0')
        desktop.set('Name', 'Uroute')
        desktop.set('Comment', 'URL router.')
        desktop.set('Exec', 'uroute %U')
        desktop.set('StartupNotify', 'true')
        desktop.set('Terminal', 'false')
        desktop.set('Categories', 'Network;WebBrowser;')
        desktop.set(
            'MimeType',
            ';'.join((
                'text/html',
                'text/xml',
                'application/xhtml_xml',
                'application/xhtml+xml',
                'image/webp',
                'video/webp',
                'x-scheme-handler/http',
                'x-scheme-handler/https',
                'x-scheme-handler/ftp',
                ''  # End with a ;
            )))
        desktop.write(trusted=True)
        log.debug('Created Uroute desktop entry at %s', path)

    return desktop
Пример #20
0
    def desktop(self):
        '''
        Returns desktop file object which may be written to disk.
        '''
        self.desktop_file = DesktopEntry()
        self.desktop_file.addGroup('Desktop Entry')

        if self.type == TargetType.URL:
            self.desktop_file.set('Type', 'Link')
        else:
            self.desktop_file.set('Type', 'Application')

        self.desktop_file.set('Version', '1.0')
        self.desktop_file.set('Name', self.name)

        if self.type == TargetType.URL:
            self.desktop_file.set('URL', self.path)
        else:
            self.desktop_file.set('Terminal', 'false')
            self.desktop_file.set('Exec',
                                  '{} {}'.format(self.path, self.arguments))

        if self.icon:
            self.desktop_file.set('Icon', self.icon)

        return self.desktop_file
Пример #21
0
    def test_present(self):
        with io.open(self.test_file, "w", encoding='utf-8') as f:
            f.write(resources.python_desktop)

        entry = DesktopEntry(self.test_file)
        res = entry.findTryExec()
        assert res, repr(res)
Пример #22
0
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('%')]
    }
Пример #23
0
    def test_absent(self):
        with io.open(self.test_file, "w", encoding='utf-8') as f:
            f.write(resources.unicode_desktop)

        entry = DesktopEntry(self.test_file)
        res = entry.findTryExec()
        assert res is None, repr(res)
Пример #24
0
 def launch_desktop(self, request, handler, desktop):
     entry = DesktopEntry()
     entry.parse(desktop)
     exec_ = entry.getExec()
     self.launch(
         request, handler, '/bin/bash -c "%s"' %
         exec_.replace('"', '\\"'))  # Is it really necessary to call bash ?
Пример #25
0
    def add_applications(self):
        """
		Populates the self.objects.list ListBox with the applications
		in SEARCH_PATH.
		"""

        for path in SEARCH_PATH:

            if not os.path.exists(path): continue

            for application in os.listdir(path):

                # Add the application, if we can
                try:
                    entry = DesktopEntry(os.path.join(path, application))
                    if not "KDE" in entry.getOnlyShowIn(
                    ) and not application in self.desktop_list:

                        # While excluding only KDE is not ideal, we do so
                        # to have consistency with vera's AutostartManager.
                        # This check is obviously a FIXME.

                        row = ApplicationRow(application, entry)

                        # Connect the changed signal
                        row.connect("changed", self.on_row_changed)

                        # Connect the requests_edit signal
                        row.connect("requests_edit", self.on_row_requests_edit)

                        GObject.idle_add(self.objects.list.insert, row, -1)

                        self.desktop_list.append(application)
                except:
                    print("Unable to show informations for %s." % application)
Пример #26
0
 def on_add_item(self, widget, treeview):
     dialog = AutoStartDialog(parent=widget.get_toplevel())
     if dialog.run() == gtk.RESPONSE_OK:
         name = dialog.pm_name.get_text()
         cmd = dialog.pm_cmd.get_text()
         if not name:
             ErrorDialog(
                 _("The name of the startup program cannot be empty")
             ).launch()
         elif not cmd:
             ErrorDialog(
                 _("Text field was empty (or contained only whitespace)")
             ).launch()
         else:
             path = os.path.join(treeview.userdir,
                                 os.path.basename(cmd) + ".desktop")
             desktopentry = DesktopEntry(path)
             desktopentry.set("Name", dialog.pm_name.get_text())
             desktopentry.set("Exec", dialog.pm_cmd.get_text())
             desktopentry.set("Comment", dialog.pm_comment.get_text())
             desktopentry.set("Type", "Application")
             desktopentry.set("Version", "1.0")
             desktopentry.set("X-GNOME-Autostart-enabled", "true")
             desktopentry.write()
             treeview.update_items(
                 all=self.show_all_button.get_active(),
                 comment=self.show_comment_button.get_active())
             dialog.destroy()
             return
     dialog.destroy()
Пример #27
0
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
Пример #28
0
    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
Пример #29
0
def getPrograms():
    return {
        desktop.getName(): desktop
        for desktop in (DesktopEntry(dfile) for dfile in itertools.chain(
            *(glob(os.path.join(path, '*.desktop'))
              for path in BaseDirectory.load_data_paths('applications'))))
        if not desktop.getHidden()
    }
Пример #30
0
 def add_startup(self) -> None:
     """Creates the auto-start entry if the user wants one."""
     entry = DesktopEntry()
     entry.addGroup(DesktopEntry.defaultGroup)
     entry.set("Type", "Application")
     entry.set("Name", State.current.my_name)
     entry.set("Exec", "{0} \"{1}\"".format(State.current.python, State.current.my_path))
     entry.write(self.__auto_start_entry)