Seite 2 von 2

Re: Anzeige eines Kontextmenus mit externen Programmen? Geht das?

Verfasst: Samstag 10. Mai 2025, 14:55
von ran
ist halt eine ziemliche Verrenkung, aus .desktop nur passende viewer raus zu filtern.

Code: Alles auswählen

import os

def finde_programme_mit_strengem_pdf_mimetype_und_namen():
    suchpfade = [
        "/usr/share/applications",
        os.path.expanduser("~/.local/share/applications"),
        "/var/lib/flatpak/exports/share/applications",
        os.path.expanduser("~/.local/share/flatpak/exports/share/applications")
    ]

    erlaubte_mimetypes = {"application/pdf", "application/x-pdf"}
    verbotene_namen = {"calibre", "image", "window"}

    ergebnisse = []

    for verzeichnis in suchpfade:
        if not os.path.exists(verzeichnis):
            continue

        for datei in os.listdir(verzeichnis):
            if not datei.endswith(".desktop"):
                continue

            pfad = os.path.join(verzeichnis, datei)
            try:
                with open(pfad, "r", encoding="utf-8", errors="ignore") as f:
                    lines = f.readlines()

                name = None
                mimetype = ""

                for zeile in lines:
                    if zeile.startswith("Name="):
                        name = zeile.strip().split("=", 1)[-1]
                    elif zeile.startswith("MimeType="):
                        full_mime = zeile.strip().split("=", 1)[-1]
                        pdf_types = [
                            m for m in full_mime.split(";")
                            if m.strip().lower() in erlaubte_mimetypes
                        ]
                        mimetype = ";".join(pdf_types)

                if not mimetype or not name:
                    continue

                # Namen filtern
                name_lower = name.lower()
                if any(verboten in name_lower for verboten in verbotene_namen):
                    continue

                ergebnisse.append((name, mimetype))

            except Exception:
                continue

    return ergebnisse

# Ausgabe
if __name__ == "__main__":
    ergebnisse = finde_programme_mit_strengem_pdf_mimetype_und_namen()
    print("📄 Final gefilterte PDF-Programme:\n")
    for name, mimetype in ergebnisse:
        print(f"{name:<30} → {mimetype}")
ergibt (ich habe extra ein paar mehr installiert)
📄 Final gefilterte PDF-Programme:

E-book viewer → application/pdf
Slim PDF Reader 2.0 → application/pdf
Okular → application/pdf
Document Viewer → application/pdf
MuPDF → application/pdf
Atril Document Viewer → application/pdf
New Drawing → application/pdf
Zathura → application/pdf
Paperwork → application/pdf
[Finished in 44ms]

Re: Anzeige eines Kontextmenus mit externen Programmen? Geht das?

Verfasst: Samstag 10. Mai 2025, 15:09
von __blackjack__
@ran: Da sind ja auch wieder hart kodierte Pfade. Du fragtest nach einem Standard, programmierst dann aber selbst etwas das schlechter ist als sich tatsächlich an dem Standard zu orientieren, und was man nicht selbst machen muss, weil es ja das `xdg`-Modul gibt. XDG/Freedesktop ist halt der Standard, und da bekommen Gnome und KDE auch ihre „Öffnen mit…“-Listen her. Danach fragtest Du ja.

Re: Anzeige eines Kontextmenus mit externen Programmen? Geht das?

Verfasst: Samstag 10. Mai 2025, 15:15
von ran
Danke für die schnelle Antwort, ich muss jetzt mal ein wenig darüber meditieren

Re: Anzeige eines Kontextmenus mit externen Programmen? Geht das?

Verfasst: Samstag 10. Mai 2025, 15:52
von ran
@blackjack Ja, stimmt, du hattest es ja schon ganz am Anfang des Threads angesprochen, aber ich habe rumgedooft statt das direkt umzusetzen. Jetzt wird alles sauber gefunden, hätte ich damit auch gleich haben können. Entschuldige bitte.

Code: Alles auswählen


def finde_verfügbare_pdf_viewer():
    erlaubte_mimetypes = {"application/pdf", "application/x-pdf"}
    verbotene_namen = {"calibre", "image", "window"}

    viewer_dict = {}

    # Durchlaufe alle .desktop-Dateien in XDG-konformen Pfaden
    for verzeichnis in BaseDirectory.load_data_paths("applications"):
        if not os.path.exists(verzeichnis):
            continue
        for root, _, files in os.walk(verzeichnis):
            for datei in files:
                if not datei.endswith(".desktop"):
                    continue
                pfad = os.path.join(root, datei)
                try:
                    eintrag = DesktopEntry.DesktopEntry(pfad)

                    name = eintrag.getName()
                    exec_line = eintrag.getExec()
                    mimetypes = eintrag.getMimeTypes()

                    if not name or not exec_line or not mimetypes:
                        continue

                    if any(wort in name.lower() for wort in verbotene_namen):
                        continue

                    if not any(mt in erlaubte_mimetypes for mt in mimetypes):
                        continue

                    befehl = shlex.split(exec_line)
                    befehl = [arg for arg in befehl if not arg.startswith("%")]

                    if befehl and name not in viewer_dict:
                        viewer_dict[name] = befehl

                except Exception:
                    continue

    viewer_dict["System-Standard (xdg-open)"] = ["xdg-open"]
    return dict(sorted(viewer_dict.items()))