In einem früheren Post hatte ich schon einmal angedeutet, dass ich im Alter von 10 Jahren zum IT-Beauftragten eines Familienunternehmens wurde. Der allererste Windows 98 PC dieser Firma stand eine Woche lang zum Üben für mich und meine Mutter in unserem Wohnzimmer. Als pflichtbewusster ITler war mein erster Arbeitsschritt, zwei Kilometer ins EDEKA zu laufen, damit ich die Demo von Tibrium Sun von der PC GAMES kaufen und installieren konnte... Der zweite Arbeitsschritt war, den PC zu erkunden. Ich habe wirklich und allen Ernstes alle frei lesbaren Dateien im System32-Ordner gelesen.
Ich wollte halt wissen, wie das Windows funktioniert. Das begleitet mich bis heute, und da MintInstall in Python geschrieben ist, verstehe ich das ganze Gedöns auch. Daher stelle ich heute die Frage:
Wie kommen eigentlich die Screenshots in die Mint-Anwendungsverwaltung?
Kurze Anmerkung: Das Ganze ist nichts für Anfänger, euch werden danach die Köpfe rauchen.
Zu wissen, wo man suchen muss, ist alles. Kleine Programme und Bash-Dateien liegen für gewöhnlich in /bin. Scrollen wir durch den Ordner, so finden wir irgendwann eine Datei mit dem Namen "mintinstall". Öffnet man diese, bekommt man einen Pfad zur ausführbaren Datei [/usr/lib/linuxmint/mintinstall]. Im Hauptverzeichnis befinden sich noch andere Skripte, denn für die Übersichtlichkeit ist das Ganze auf viele Skripte aufgeteilt, die zusammenarbeiten.
Ich persönlich habe alle Dateien komplett gelesen und bin zu dem Schluss gekommen, dass eine Stichwortsuche nach "Screenshot" alles viel einfacher gemacht hätte.
Unsere erste Station ist gi.require_version('AppStreamGlib', '1.0'). Wenn ihr euch auf Flathub rumtreibt, wird euch bestimmt schon aufgefallen sein, dass die Indexnamen von Programmen in Flatpak eine gewisse Struktur haben: org.gimp.GIMP > also z.B. git,org,de,com + Projekt/Entwickler + Programmname. Das ist wichtig für AppStream zur Identifizierung des Programms. Das Ganze folgt FreeDesktop-Richtlinien, die ihr hier einfach mal nachlesen könnt: https://www.freedesktop.org/software/appstream/docs/
AppStreamGlib ist eine Bibliothek in Linux, die Entwicklern dabei hilft, mit Metadaten von Anwendungen und Softwarepaketen umzugehen. Sie wird oft in Anwendungen und Tools verwendet, die mit Software- oder Anwendungsinformationen arbeiten, wie z.B. Software-Centern oder Paketmanagern. AppStreamGlib ermöglicht es, Metadaten zu lesen, zu analysieren und zu manipulieren, was es Entwicklern erleichtert, Anwendungsdaten zu verarbeiten und anzuzeigen. Sie ist Teil des AppStream-Projekts, das sich auf die Standardisierung und Verbesserung der Softwareverteilung und -installation auf Linux-Systemen konzentriert. |
Für uns ist wichtig, dass wir appstream auch über das Terminal ansteuern können. Mit appstreamcli --help bekommen wir heraus, wie man das Tool nutzt. Der Befehl appstreamcli dump org.gimp.GIMP druckt das komplette Index-File ins Terminal. Wir können den Output mit > gimp_test.txt hinten dran in eine Datei umleiten.
Relevant sind aber in unserem Fall die folgenden Zeilen, die ganz klar die Größe und den abrufbaren Ort der Bilddatei definieren:
<screenshots>
<screenshot type="default">
<caption>Zeichnen in GIMP</caption>
<image type="source" width="1504" height="846">https://dl.flathub.org/media/org/gimp/GIMP/2acd7abfc48a8f2932f425ddb03aca56/screenshots/image-1_orig.png</image>
<image type="thumbnail" width="1248" height="702">https://dl.flathub.org/media/org/gimp/GIMP/2acd7abfc48a8f2932f425ddb03aca56/screenshots/image-1_1248x702@1.png</image>
<image type="thumbnail" width="752" height="423">https://dl.flathub.org/media/org/gimp/GIMP/2acd7abfc48a8f2932f425ddb03aca56/screenshots/image-1_752x423@1.png</image>
<image type="thumbnail" width="624" height="351">https://dl.flathub.org/media/org/gimp/GIMP/2acd7abfc48a8f2932f425ddb03aca56/screenshots/image-1_624x351@1.png</image>
<image type="thumbnail" width="224" height="126">https://dl.flathub.org/media/org/gimp/GIMP/2acd7abfc48a8f2932f425ddb03aca56/screenshots/image-1_224x126@1.png</image>
</screenshot>
<screenshot type="default">
<caption>Fotobearbeitung in GIMP</caption>
<image type="source" width="1504" height="846">https://dl.flathub.org/media/org/gimp/GIMP/2acd7abfc48a8f2932f425ddb03aca56/screenshots/image-2_orig.png</image>
<image type="thumbnail" width="1248" height="702">https://dl.flathub.org/media/org/gimp/GIMP/2acd7abfc48a8f2932f425ddb03aca56/screenshots/image-2_1248x702@1.png</image>
<image type="thumbnail" width="752" height="423">https://dl.flathub.org/media/org/gimp/GIMP/2acd7abfc48a8f2932f425ddb03aca56/screenshots/image-2_752x423@1.png</image>
<image type="thumbnail" width="624" height="351">https://dl.flathub.org/media/org/gimp/GIMP/2acd7abfc48a8f2932f425ddb03aca56/screenshots/image-2_624x351@1.png</image>
<image type="thumbnail" width="224" height="126">https://dl.flathub.org/media/org/gimp/GIMP/2acd7abfc48a8f2932f425ddb03aca56/screenshots/image-2_224x126@1.png</image>
</screenshot>
</screenshots>
Alles anzeigen
Wenn ihr also nach einem Programm sucht, wird diese XML-Datei temporär geladen, und der Screenshot für eine gewisse Zeit gespeichert.
Hier gut zu sehen ab Zeile 316 (https://github.com/linuxmint/mint…install.py#L316)
Von da aus geht die Information nach screenshot_window.py(https://github.com/linuxmint/mint…nshot_window.py) zum Anzeigen. Das ist aber alles ganz langweilig, da wir ja alle Infos in einem Register haben. Richtig freaky wird es erst bei den .DEB-Dateien, da haben wir ....
Variablen mit mehreren Unbekannten
Die Debian-Dateien kommen zwar auch mit einer Fülle an Informationen (apt show gimp), aber nichts mit Screenshots. Wenn wir weiter mintinstall durchgucken, sehen wir ab Zeile 360 (https://github.com/linuxmint/mint…install.py#L360), wie die Magie passiert.
Über from bs4 import BeautifulSoup werden HTML-Parameter ausgelesen. Man könnte sagen, bs4 ist ein Suchhund für Zeug im Web. In den folgenden Zeilen lernen wir, dass Debian ein Screenshotarchiv hat: "http://screenshots.debian.net".
Gimp hat hier auch eine Galerie (https://screenshots.debian.net/package/gimp), und die Adresse für einen Screenshot kann man über den Browser gleich herausfinden: "https://screenshots.debian.net/shrine/screens…7567a261cf7.png".
Blöd nur, wenn man mal etwas anderes als gimp sucht. Die Adresse für das PNG kennen wir ja, aber was ist mit den 64.000 anderen Programmen? Nun, der erste Teil der Information ist statisch: "https://screenshots.debian.net/shrine/screenshot/simage/large-". Was wir nicht wissen, ist, was zwischen "large-" und ".png" los ist. Da kommt BeautifulSoup ins Spiel.
Die Variable images = page.findAll('img') weist an, alle Bilder zu finden, die sich unter der genannten Adresse befinden. Crazy!!!! mintinstall sucht dann bis zu 4 Bilder und gibt die HTTP-Adresse dazu aus.
Laber Rababer .... Selber mach'n Junge!
Das Problem ist das bei mintinstall sehr viele Räder in einander greifen. Man kann diese eine Funktion nicht einfach rauskopieren und erwarten, das es Funktioniert. Vor zwei Jahren habe ich mir die Nächte um die Ohren geschlagen um meine Eigene Variante zu schreiben. Das ist eine sehr stark vereinfachte Version (Warnung GPL3 ):
In der Variable apt_app = "gimp" kann man nun "gimp" mit so ziemlich jedem Programm-Namen austauschen.
from bs4 import BeautifulSoup
from urllib.request import urlopen
import requests
from PIL import ImageTk, Image
import tkinter as tk
def get_img():
apt_app = "gimp"
url = f"https://screenshots.debian.net/package/{apt_app}#gallery-1"
response = requests.get(url)
soup = BeautifulSoup(response.text, "html.parser")
links = [
link.get("href")
for link in soup.find_all("a")
if link.get("href").endswith(".png")
]
url_output = f"https://screenshots.debian.net{str(links[1])}"
with urlopen(url_output) as url_output:
app_img = Image.open(url_output)
app_img = resize(app_img)
app_img = ImageTk.PhotoImage(app_img)
apt_panel.config(image=app_img)
# Keeping a reference to the image to avoid garbage collection
apt_panel.image = app_img
def resize(image, width=200, height=200):
return image.resize((width, height))
root = tk.Tk()
root.title("Screenshot")
apt_panel = tk.Label(root)
apt_panel.pack(pady=20)
get_img()
root.mainloop()
Alles anzeigen
Und jetzt entschuldigt mich... Seit kurzem gibt es Tibirian Sun auf Steam und das muss gezockt werden!