Zum Inhalt springen
Michael Blaess
IT-Consulting
Michael Blaess
EN

Warum es meinen Stundenzettel jetzt zweimal gibt: Terminal und Desktop

PythonQtPySide6JiraDesktop

Wer nach Aufwand abrechnet, braucht am Monatsende einen Stundenzettel. Die Zeiten stehen schon in Jira, gebucht auf Tickets, verteilt über Wochen. Sie von dort in eine unterschriftsreife Tabelle zu bekommen, ist jeden Monat dieselbe Fleißarbeit.

Genau dafür habe ich mir jira-timesheet gebaut, eine Anwendung fürs Terminal. Inzwischen gibt es das Ganze ein zweites Mal: Jira Timesheet Desktop, eine native Oberfläche mit Qt.

Terminal oder Desktop? Beide.

Warum baut man dasselbe Werkzeug zweimal? Weil die beiden Fassungen unterschiedliche Situationen bedienen, und keine ersetzt die andere.

Die Terminal-Fassung läuft in jedem Terminal, auch über eine SSH-Verbindung, und braucht keine grafische Oberfläche. Auf einem entfernten Rechner oder einem Linux-Server ohne Desktop ist sie die einzige der beiden, die dort überhaupt startet. Bedient wird sie über die Tastatur, und wer die Kürzel im Kopf hat, ist damit schnell.

Die Desktop-Fassung bringt echte Fenster, Menüs und Dialoge mit. Spalten zieht man mit der Maus breiter, Datei- und Druckdialoge kommen vom Betriebssystem. Wer eine Anwendung erwartet, die sich wie eine Anwendung anfühlt, bekommt genau das.

Beide laufen unter Windows, macOS und Linux. Sie legen ihre Daten an getrennten Orten ab und stören sich nicht gegenseitig, man kann sie also parallel benutzen 🙂

Was die Desktop-Fassung kann

Der Kern ist in beiden Fassungen derselbe. In der Desktop-Oberfläche verteilt er sich auf drei Ansichten:

  • Stundenzettel mit Kalenderwoche, Wochentag und Tagesgruppen. Tagessummen färben sich grün über und rot unter dem Soll.
  • Monat als Raster mit einer Zeile je Ticket und einem Soll-Ist-Balken je Tag und Woche. Vergangene Arbeitstage ohne Buchung sind markiert, die Ticketnummern öffnen den Detail-Dialog.
  • Jahr mit zwölf Monatskacheln, Fortschrittsbalken, Prognose und den wichtigsten Tickets je Monat.

Dazu die Dinge, die den Monatsabschluss ausmachen: Export als Excel mit Logo und Unterschriftszeile, als PDF, das sich in Adobe signieren lässt, sowie als JSON und Markdown. Eine Druckvorschau, deutsche Feiertage je Bundesland samt Lückenerkennung und ein Soll-Ist-Vergleich mit Jahresprognose.

Ein Punkt ist mir wichtiger als der Rest:

Nicht jede Stunde landet als Worklog in Jira.

Besprechungen, Telefonate, der Blick in ein Postfach. Solche Zeiten trägt man über einen Dialog nach, und zwar so, wie man sie sich ohnehin notiert: 3h 30m, 3:30, 3,5 oder 45m werden alle verstanden. Diese Einträge liegen in einer eigenen SQLite-Datei und niemals im Jira-Cache. Sie zählen überall mit, in Tagessumme, Monat, Jahr, Excel und PDF, und sind farblich markiert. So bleibt auf einen Blick klar, was aus Jira kommt und was nicht.

Taste Funktion
F5 Buchungen des Monats abrufen
Strg+F Suche
Strg+N Zeit manuell erfassen
Strg+E Export, das Format wählt man im Speichern-Dialog
Strg+P Druckvorschau
Strg +/- / 0 Zoom, auch mit dem Mausrad

Was seit dem ersten Release dazugekommen ist

Die Anwendung ist inzwischen über den Stundenzettel hinausgewachsen. Drei Beispiele:

  • Ticket-Analyse macht aus einem einzelnen Ticket einen Bericht mit Zeitachse, Liegezeit je Status und den Beteiligten. Das Ergebnis ist eine einzige HTML-Datei, die offline läuft und sich weitergeben lässt.
  • Meine Tickets gruppiert alle Tickets danach, wer gerade am Zug ist, und zeigt, wie lange sie schon liegen.
  • Mein Team zeigt denselben Blick für Kolleginnen und Kollegen, bewusst ohne Diagramme. Ein Durchsatz je Monat wäre über eine andere Person eine Leistungskennzahl, und darum geht es hier nicht.

Die kniffligste Entscheidung: kopierter Kern statt geteilter Bibliothek

Beide Anwendungen benutzen denselben fachlichen Kern - Jira-Anbindung, Stundenlogik, manuelle Zeiten, Feiertagskalender, Export. Der naheliegende Weg wäre, diesen Kern als Bibliothek zu veröffentlichen und in beiden Anwendungen zu importieren. Genau das macht die Desktop-Fassung nicht. Der Kern ist kopiert.

Der Grund ist simpel. Ein Import hätte das komplette Terminal-Framework mit in die Desktop-Anwendung gezogen. Eine Qt-Anwendung, die Textual mitschleppt, nur um an ein paar Modelle und Dienste zu kommen, wäre der schlechtere Tausch.

Kopierter Code hat einen bekannten Preis: Er läuft auseinander. Damit das nicht unbemerkt passiert, gibt es einen Befehl, der beide Kerne vergleicht und Unterschiede meldet:

uv run poe core-sync

Elegant ist das nicht.

Die Alternative wäre eine dritte veröffentlichte Bibliothek gewesen, mit eigenem Versionsstand und eigenem Release-Rhythmus, für zwei Anwendungen aus derselben Hand. Das schien mir der größere Aufwand für den kleineren Gewinn.

Anonymisieren auf Knopfdruck

Wer ein Werkzeug zeigen will, das mit echten Vorgängen arbeitet, hat ein Problem: Auf jedem Screenshot stehen echte Ticketnummern, Beschreibungen, Namen und der Hostname der Jira-Instanz.

Genau deshalb gibt es im Menü Ansicht den Punkt Daten anonymisieren. Ein Klick ersetzt Tickets, Beschreibungen, Autoren, Statusnamen und den Jira-Host in allen Ansichten und im Protokoll durch neutrale Platzhalter. Die echten Daten bleiben im Cache und sind sofort wieder da, wenn man den Schalter zurückstellt.

Sämtliche Screenshots auf der Projektseite sind so entstanden. Wer selbst etwas vorführen muss, kann die Anwendung auch ganz ohne Jira-Zugang starten:

jira-timesheet-qt --demo

Installation und Lizenz

Ein Einzeiler holt den Quelltext des neuesten Release und richtet ihn mit allen Abhängigkeiten ein. Voraussetzung ist Python ab Version 3.12:

irm https://raw.githubusercontent.com/michaelblaess/jira-timesheet-qt/main/install.ps1 | iex

Unter Linux und macOS entsprechend mit curl ... | bash.

Aber Achtung: Anders als die Terminal-Fassung steht die Desktop-Anwendung nicht unter der Apache-Lizenz, sondern unter der Business Source License 1.1. Das bedeutet:

  • Lesen, selbst bauen und benutzen ist kostenlos, als Privatperson auch für die berufliche Arbeit.
  • Fertige Programmpakete, die ohne Python laufen, gibt es gegen einen kleinen Betrag. Sie dürfen nicht weitergegeben werden.
  • Organisationen und wer die Anwendung entgeltlich als Dienst anbietet, brauchen eine kommerzielle Lizenz.
  • Jede Version wird vier Jahre nach ihrer Veröffentlichung automatisch zur Mozilla Public License 2.0.

Der Grund dafür ist schlicht der Aufwand. Eine Desktop-Anwendung für drei Betriebssysteme zu bauen und zu pflegen kostet echte Zeit, und dafür darf ein kleiner Betrag fließen. Streng genommen ist die Desktop-Fassung damit nicht mehr “Open Source”, sondern “Source Available”: Der Quelltext bleibt offen, die kommerzielle Nutzung ist aber eingeschränkt.

Was beim ersten Start passiert

Beim ersten Start zeigt das Programm einen Hinweis, der bestätigt werden muss, sonst beendet es sich.

Der Grund: Das Werkzeug liest über die Jira-Schnittstelle Arbeitszeiten aus einem fremden System. Welche Vorgänge und Buchungen dabei sichtbar werden, entscheidet allein die Berechtigung des verwendeten Kontos. Je nach Rechtevergabe können darunter auch Einträge anderer Personen sein. Mit der Bestätigung erklärt man, das Programm nur gegen Jira-Instanzen einzusetzen, für die man eine Zugriffsberechtigung hat.

Der Hinweis gehört für mich zum Werkzeug dazu. Wer ein Programm baut, das Daten aus einem fremden System liest, sollte die Frage, wer da eigentlich hineinschauen darf, nicht dem Anwender allein überlassen.

Links: Projektseite mit allen Screenshots · Quellcode auf GitHub · die Terminal-Fassung

“Jira” und “Atlassian” sind eingetragene Marken der Atlassian Corporation. Dieses Projekt wird von Atlassian weder entwickelt noch unterstützt oder genehmigt und nutzt ausschließlich die öffentliche Jira-Schnittstelle.

“Wir sehen nur ein kurzes Stück voraus, aber dort sehen wir reichlich, was getan werden muss.”

- Alan Turing