Lizenzmanagement-Software von SaaS-Anbietern kann schnell mehrere hundert Euro pro Monat kosten. Doch für viele Anwendungsfälle reicht eine einfache, selbst entwickelte Lösung aus. Das zeigt das Projekt LiMa, eine in Python mit PyQt5 erstellte Desktop-Anwendung zur Verwaltung von Softwarelizenzen. Statt auf teure Cloud-Dienste zu setzen, setzt der Entwickler auf lokale Verarbeitung mit einer SQLite-Datenbank und automatisierten Benachrichtigungen. Die App demonstriert, wie grundlegende Funktionen eines Lizenzmanagementsystems mit minimalem Aufwand umgesetzt werden können – und warum selbstgebaute Tools in vielen Fällen die bessere Wahl sind.
Warum selbst machen? Die SaaS-Alternative
Die Idee zu LiMa entstand, als ein IT-Verantwortlicher einen jährlichen Lizenzkostenbericht eines SaaS-Anbieters für Software-Asset-Management erhielt. Der Preis belief sich auf mehrere hundert Euro pro Monat. Doch die Kernfunktionen des Tools beschränkten sich auf:
- Eine Tabelle mit Lizenzdaten und Ablaufdaten
- Automatisierte Benachrichtigungen per E-Mail
- Monatliche Zusammenfassungen
Diese Aufgaben lassen sich mit wenigen Zeilen Code und einer lokalen Anwendung lösen. Statt teure Abos zu bezahlen, entschied sich der Entwickler für eine DIY-Lösung – und schuf damit ein Tool, das nicht nur kostengünstig ist, sondern auch volle Kontrolle über Daten und Funktionalität bietet.
Datenbankdesign: Minimalismus mit SQLite
Das Herzstück von LiMa ist eine einfache SQLite-Datenbank mit nur zwei Spalten: nom_logiciel für den Namen der Software und date_expiration für das Ablaufdatum. Die Berechnung der verbleibenden Tage erfolgt in Echtzeit, statt sie dauerhaft zu speichern. Das vermeidet Inkonsistenzen und reduziert den Wartungsaufwand.
self.c.execute('''CREATE TABLE licences (nom_logiciel TEXT, date_expiration TEXT)''')Für die Aktualisierung der Tabelle wird ein QTimer verwendet, der alle 60 Sekunden die Daten neu berechnet:
self.timer = QTimer(self)
self.timer.timeout.connect(self.actualiser_tableau)
self.timer.start(60_000) # 1 Minute IntervallDie verbleibenden Tage werden pro Lizenz berechnet und direkt in die Tabelle eingetragen. Überschreitet eine Lizenz ihr Ablaufdatum, wird die Zeile rot markiert – ohne zusätzliche Logik oder Datenbankanpassungen.
Benachrichtigungen mit plyer: Plattformübergreifend und natürlich
LiMa nutzt die Bibliothek plyer, um Benachrichtigungen plattformübergreifend darzustellen – etwa über das Windows-Benachrichtigungscenter, macOS Notification Center oder Linux libnotify. Die App unterstützt sechs Stufen von Warnungen:
- Mehr als 30 Tage verbleibend: Keine Benachrichtigung
- 15 bis 30 Tage: Warnung „Lizenz läuft in weniger als einem Monat ab“
- 8 bis 14 Tage: Warnung „Lizenz läuft in weniger als zwei Wochen ab“
- 4 bis 7 Tage: Warnung „Lizenz läuft in weniger als einer Woche ab“
- 2 bis 3 Tage: Warnung „Lizenz läuft in weniger als drei Tagen ab“
- 1 Tag: Warnung „Lizenz läuft morgen ab“
- Ablaufdatum erreicht: Warnung „Lizenz ist bereits abgelaufen“
Die Implementierung ist kompakt und nutzt die nativen Benachrichtigungsdienste des Betriebssystems – ohne aufdringliche Popup-Fenster oder hässliche Eigenimplementierungen.
Automatisierte E-Mail-Reports mit Matplotlib-Grafiken
Ein zentraler Bestandteil von LiMa ist die monatliche Zusammenfassung per E-Mail. Die App generiert einen Kreissektor-Diagramm (Pie Chart) mit den Anteilen an abgelaufenen und aktiven Lizenzen und fügt diesen als Bilddatei bei. Die E-Mail wird als HTML-Nachricht mit smtplib verschickt.
def generer_graphique_pie(self):
expirations = sum(1 for row in range(self.tableau_licences.rowCount())
if int(self.tableau_licences.item(row, 2).text()) < 0)
non_expirations = row_count - expirations
plt.pie([expirations, non_expirations],
labels=["Abgelaufene Lizenzen", "Aktive Lizenzen"],
colors=["red", "green"],
autopct='%1.1f%%')
plt.savefig("graphique_pie.png")Die E-Mail wird mit MIMEMultipart aufgebaut, inklusive HTML-Inhalt und angehängtem Diagramm. Als Versandmethode dient ein interner SMTP-Server – etwa ein unternehmensinterner Dienst oder ein privates Gmail-Konto. Keine Abhängigkeit von externen APIs oder Tokens nötig.
Vollständige Anwendung: Menü, Dark Mode und Exportfunktionen
LiMa ist keine bloße Demo, sondern eine vollwertige Desktop-Anwendung mit allen wichtigen Funktionen:
- Import/Export von CSV-Dateien für einfache Datenübernahme und -sicherung
- Druckfunktion über
QPrinterfür physische Berichte - Sortierfunktionen (alphabetisch auf- und absteigend)
- Aktivierung/Deaktivierung von Benachrichtigungen
- Statistiken und Visualisierungen mit Matplotlib
- SMTP-Konfiguration für E-Mail-Versand
- Dark/Light Mode durch CSS-Stylesheets in PyQt5
- „Über“-Dialog mit Versionsinformationen
All dies ist in einer einzigen Datei (lima.py) zusammengefasst. Der Code ist bewusst schlank gehalten und verzichtet auf unnötige Abhängigkeiten. Selbst der Dark Mode wird ohne externe Bibliotheken umgesetzt:
def toggle_dark_mode(self):
self.setStyleSheet("""
QMainWindow {
background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
stop:0 #2a2a2a, stop:1 #1a1a1a);
}
QTableWidget {
background-color: #333333;
color: #ffffff;
}
""")Fazit: DIY statt SaaS – eine Frage der Prioritäten
LiMa beweist, dass viele Standardaufgaben im IT-Bereich mit minimalem Aufwand selbst umgesetzt werden können – und das oft effizienter als mit teuren SaaS-Lösungen. Die App ist ein Beispiel dafür, wie Python, PyQt5 und einige Standardbibliotheken ausreichen, um ein voll funktionsfähiges Lizenzmanagement-Tool zu erstellen.
Natürlich ist nicht jedes Szenario für eine Eigenentwicklung geeignet. Komplexe Anforderungen oder unternehmensweite Skalierung erfordern möglicherweise professionelle Tools. Doch für viele Teams lohnt es sich, vor dem Kauf eines SaaS-Abos zu prüfen, ob eine DIY-Lösung nicht die bessere Wahl ist. Mit LiMa steht ein praxisnahes Beispiel zur Verfügung – inklusive vollständigen Quellcodes und der Freiheit, es nach eigenen Bedürfnissen anzupassen.
KI-Zusammenfassung
Yıllık yüzlerce euro ödemek yerine kendi lisans takip uygulamanızı PyQt5 ve Python ile sadece 100 satır kodla geliştirin. Veriler yerelde, abonelik yok.