Alternative zu python-apt

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
pExplorer
User
Beiträge: 4
Registriert: Dienstag 21. Mai 2019, 19:54

Hallo,

das Vorhandensein von nötigen linux-packages prüfe ich in einem kleinen Programm mittels python-apt.
Dieses Modul wird aber nicht mehr gepflegt:
https://pypi.org/project/python-apt/

Code: Alles auswählen

import apt
	
self.worker.packages_to_check.append("lame")
self.worker.packages_to_check.append(self.lineEditConfigDP.text())
        
def run_packages_to_check(self):        
	self.progress.emit("<b>Installationspruefung:</b>")
        cache = apt.Cache()
        cache.open()
        for item in self.packages_to_check:
            try:
                cache[item].is_installed
                self.progress.emit(item)
            except KeyError:
                error_message = (
                    "Es fehlt das Paket:<br> " + item
                    + "<br>Zur Nutzung des vollen Funktionsumfanges "
                    + "muss es installiert werden!")
                self.progress.emit(error_message)
Gibt es dafür ein Äquivalent oder eine Alternative?
Benutzeravatar
__blackjack__
User
Beiträge: 14035
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@pExplorer: Anmerkungen zum gezeigten Quelltext:

Das `Cache`-Objekt ist ein Kontextmanager, das sollte man mit ``with`` verwenden.

Der Code prüft eigentlich nur ob das Paket im Cache vorhanden ist, meldet aber keine Probleme mit Paketen die zwar im Cache sind, aber gar nicht vollständig installiert sind, entweder weil die Installation mitten drin abgebrochen wurde, oder das Paket entfernt wurde und noch Konfigurationsdateien vorhanden sind. Mit dem `is_installed`-Wert muss man halt auch irgend etwas *machen*.

Zeichenketten mit ``+`` zusammenstückeln ist eher BASIC denn Python. Um Werte in Zeichenketten zu formatieren gibt es f-Zeichenketten, und der Compiler verbindet Zeichenketten die nur durch Whitespace-Zeichen voneinander getrennt sind.

Ungetestet:

Code: Alles auswählen

    def run_packages_to_check(self):
        self.progress.emit("<b>Installationspruefung:</b>")
        with apt.Cache() as cache:
            cache.open()
            for package_name in self.packages_to_check:
                package = cache.get(package_name)
                self.progress.emit(
                    package_name
                    if package and package.is_installed
                    else (
                        f"Es fehlt das Paket:<br>"
                        f"{package_name}<br>"
                        f"Zur Nutzung des vollen Funktionsumfanges muss es"
                        f" installiert werden!"
                    )
                )
Wenn es nur um den Test auf „installiert“ geht, würde ich mir einfach eine Funktion basteln die ``dpkg-query`` aufruft:

Code: Alles auswählen

import subprocess


def is_installed(package_name):
    result = subprocess.run(
        ["dpkg-query", "--show", "--showformat", "${Status}\n", package_name],
        capture_output=True,
        check=False,
    )
    return b"install ok installed" in result.stdout.splitlines()

...

    def run_packages_to_check(self):
        self.progress.emit("<b>Installationspruefung:</b>")
        for package_name in self.packages_to_check:
            self.progress.emit(
                package_name
                if is_installed(package_name)
                else (
                    f"Es fehlt das Paket:<br>"
                    f"{package_name}<br>"
                    f"Zur Nutzung des vollen Funktionsumfanges muss es"
                    f" installiert werden!"
                )
            )
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Antworten