GNUmed Einrichtung

Fahrplan und Schritte

Nun, da eine »leere« GNUmed-Installation vorliegt, muss diese noch an ein realistisches Szenario angepasst werden.
Ganz zu Anfang muss der »GNUmed-Client« installiert werden: bisher läuft ja nur der GNUmed-Server, der allerdings einzig für den Administrator überhaupt »sichtbar« ist. Eine Anwenderin für die Alltags-Benutzung existiert (noch) nicht, es gibt keine Zugangsdaten und keine graphische Oberfläche.

1) Client-Pakete
2) Start GNUmed
3) Inspektion
4) Bereinigung

Client-Pakete

Der erste Schritt besteht im Installieren der Client-Pakete. Dies geschieht im ersten Schritt auf dem selben (virtuellen) Rechner, auf dem auch der PostgreSQL-Server mit der Datenbank läuft. Dies ist für das Procedere der Anwendungsentwicklung zum Start das einfachste Vorgehen. Später kann (genau genommen: muss) jeweils ein Client auf jedem Praxisrechner installiert werden, der mit SimpelMed arbeiten soll. Auch in der Entwicklungsumgebung wird später auf verschiedenen Rechnern der Client installiert, um dieses Szenario real zu testen.

Installation der Client-Pakete
apt install gnumed-client

Die Client-Pakete ziehen (leider) eine relativ umfangreiche Menge an verbindlicher anderer Software mit, z. B. Teile von LaTeX und LibreOffice. Dadurch ist die Datenmenge groß (auf einem Minimalsystem auch schon mal 1GB) und das Einspielen dauert seine Zeit.

Start GNUmed

Wenn alles geladen ist, läßt sich (endlich, hoffentlich) GNUmed starten.

Start des GNUmed-Clients in einer Konsole
xyz@xyz_pc:~$ gnumed
Log File: <...>/gnumed/logs/gnumed/gnumed/gnumed-<datum_zeit>.log
Temp dir: /tmp/gnumed-<laufwerk>/<zufaelliger_name>

Im sich öffnenden Fenster »Willkomen bei GNUmed - Arbeitsplatz GNUmed default (Version 1.x.y)« müssen folgende Eingaben getätigt werden:
- Anmeldung bei: GNUmed database on this machine/local (gnumed_v22@)
- Nutzer: »any-doc«
- Passwort: »any-doc«
und dann »ok«

Nur mit diessen Einstellungen ist jetzt ein Starten GNUmeds möglich; und das auch nur dann, wenn die PostgreSQL-eigene Firewall mittels der Datei »pg_hba.conf«, in der Regel im Verzeichnis »/etc/postgresql/15/main/«, korrekt modifiziert wurde (siehe unter »postgresql - pgadmin«).

Als nächstes erscheint (möglicherweise - hängt von den Datenbankeinstellungen ab) ein Fenster mit folgenden Angaben:

GmD: Verifiziere Datenbankeinstellungen

Die Datenbankeinstellungen sind riskant gewählt:
Option [log_connections]: off
...
Die Logdatei enthält genauere Angaben!

OK

Dies wird mit »ok« bestätigt und vorerst ignoriert. Es geht hier die Einhaltung bestimmter (Sicherheits-)Standards für medizinische Systeme, die insbesondere für den US-Raum verplichtend sind. Das erwähnte »HIPAA« steht für den »Health Insurance Portability and Accountability Act«. Dieser ist (ganz entfernt jedenfalls) mit den europäischen Datenschutzregeln verwandt, beide sind allerdings weder austauschbar noch gleichwertig.
Die Logdatei findet sich im oben angegebenen Ordner.

Nach dem »ok« erscheint der nächste Hinweis:

GmD: Verifiziere Datenbank

Datenbank gnumed_v22 auf localhost

Zweigstelle Generic Praxis Branch ...
...

Verbinden          Abmelden

Wie bestätigen natürlich »Verbinden«. Nun folgt (zumeist)

GmD: Updates suchen

Eine neue Version von GNUmed ist verfügbar
...

OK

Auch hier geht es weiter mit »OK«. Ab jetzt sind wir im GNUmed-Hauptprogramm und können darin »herumklicken« und uns einen Überblick verschaffen.
Die letzten drei Meldungen werden am Ende dieser Seite nochmals betrachtet.

Inspektion

Bemerkenswert ist
- das frisch installierte GNUmed ist keineswegs »leer«. Es sind einige Patienten (augenscheinlich aus dem Universum der US-Serie Star Trek »Raumschiff Enterprise«), Befunde und weitere Daten vorhanden.
- Ein Blick in den Server als Administrator zeigt auch, dass eine Datenbank »gnumed_v21«, also die vorherige Version, sowie einge Rollen/Nutzerkonti außer dem bekannten »any-doc« angelegt sind.

Datenbanken und Rollen einer »frischen« GNUmed-Installation (gekürzt)
h@hpc:~$ sudo -u postgres psql
[sudo] Passwort für h:
...
psql (15.3 (Debian 15.3-0+deb12u1))
Type "help" for help.

postgres=# \l
                                                  List of databases
    Name    |  Owner   | Encoding |   Collate   |    Ctype    | ICU Locale | Locale Provider |   Access privileges
------------+----------+----------+-------------+-------------+------------+-----------------+
 gnumed_v21 | gm-dbo   | UTF8     | de_DE.UTF-8 | de_DE.UTF-8 |            | libc            |
 gnumed_v22 | gm-dbo   | UTF8     | de_DE.UTF-8 | de_DE.UTF-8 |            | libc            |
 postgres   | postgres | UTF8     | de_DE.UTF-8 | de_DE.UTF-8 |            | libc            |
 template0  | postgres | UTF8     | de_DE.UTF-8 | de_DE.UTF-8 |            | libc            | =c/postgres          +
            |          |          |             |             |            |                 | postgres=CTc/postgres
 template1  | postgres | UTF8     | de_DE.UTF-8 | de_DE.UTF-8 |            | libc            | =c/postgres          +
            |          |          |             |             |            |                 | postgres=CTc/postgres
(6 rows)

postgres=# \du
                                                List of roles
   Role name    |     Attributes                                             | Member of
 any-doc        |                                                            | {gnumed_v6,gnumed_v7,...}
 any-staff      |                                                            | {gnumed_v20,gnumed_v17,...}
 gm-dbo         | Create role, Create DB                                     | {gnumed_v6,gnumed_v7,...}
 gm-doctors     | Cannot login                                               | {gm-staff,gm-public}
 gm-logins      | Cannot login                                               | {}
 gm-public      | Cannot login                                               | {}
 gm-staff       | Cannot login                                               | {gm-public}
 gnumed_v10     | Cannot login                                               | {}
 gnumed_v11     | Cannot login                                               | {}
 gnumed_v12     | Cannot login                                               | {}
 gnumed_v13     | Cannot login                                               | {}
 gnumed_v14     | Cannot login                                               | {}
 gnumed_v15     | Cannot login                                               | {}
 gnumed_v16     | Cannot login                                               | {}
 gnumed_v17     | Cannot login                                               | {}
 gnumed_v18     | Cannot login                                               | {}
 gnumed_v19     | Cannot login                                               | {}
 gnumed_v2      | Cannot login                                               | {}
 gnumed_v20     | Cannot login                                               | {}
 gnumed_v21     | Cannot login                                               | {}
 gnumed_v22     | Cannot login                                               | {}
 gnumed_v3      | Cannot login                                               | {}
 gnumed_v4      | Cannot login                                               | {}
 gnumed_v5      | Cannot login                                               | {}
 gnumed_v6      | Cannot login                                               | {}
 gnumed_v7      | Cannot login                                               | {}
 gnumed_v8      | Cannot login                                               | {}
 gnumed_v9      | Cannot login                                               | {}
 postgres       | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
 test-doc       | Password valid until 2004-12-31 00:00:00+01                | {gm-doctors,gm-public}
 test-nurse     | Password valid until 2004-12-31 00:00:00+01                | {gm-public}
 test-secretary | Password valid until 2004-12-31 00:00:00+01                | {gm-public}

\q

Bereinigung

Nun stehen die Aufgaben an, die »frische« Datenbank für die Entwicklungsarbeiten vorzubereiten. Die Analyse der Programmaufrufe im Sourcecode bringt dabei einige wertvolle Erkenntnisse zu Tage, die unmittelbar zur Optimierung dienen können.
Im Folgenden daher die Schritte auf Sourcecode-Ebene im Einzelnen.

gnumed

Durch den Start des Programms durch den Anwender mittels des Konsolen-Kommandos h@pc: gnumed startet das Skript
/usr/bin/gnumed
Dieses Skript startet, führt aus und schließt zum hoffentlich guten Ende eine SimpelMed/GNUmed-Sitzung.

gnumed-client.conf
Für das Skript zwingend vorhanden sein muss die Datei SYSCONF="/etc/gnumed/gnumed-client.conf", da sonst die Ausführung sofort abgebrochen wird. Diese Datei steuert das zum Start sichtbare Auswahlmenü, sonstige Präferenzen, die zu ladendenden Plugins und den »Workplace« (die Module, welche die Nutzerin »zu sehen« bekommt). Dazu später mehr.

Als erstes kann /usr/bin/gnumed Nutzer- oder Datenbank-spezifische Skripte (systemweit und/oder lokal angelegt) ausführen - in einer Standardinstallation gibt es solche nicht.
Vor dem »eigentlichen« Programm erfolgt noch eine Paranoia-Einstellung (Paranoia, da heutzutage normalerweise nicht (mehr) notwendig):
export PYTHONIOENCODING=utf-8:surrogateescape

Nun startet endlich das »eigentliche« Programm gnumed.py:
Schließlich zum Shutdown sind wiederum user-spezifische Skripte systemweit und/oder lokal möglich (Standard: Fehlanzeige). Alle genannten Skripte werden an bestimmten Stellen im Verzeichnisbaum eingehängt.

gnumed.py

Das zentrale Programm gnumed.py, das durch /usr/bin/gnumed aufgerufen wird, findet sich hier:
/usr/share/gnumed/Gnumed/gnumed.py

Im Quelltext ist die Aufgabe benannt: »main - launch the GNUmed wxPython GUI client«.

Der Quellcode lässt sich wie üblich gliedern in die logischen Teile
1) setup,
2) main/run
3) shutdown.

1) setup:
Hier folgen Initialisierungen für das Logging und Pfade sowie die Prüfung auf bestimmte Hilfsprogramme etc.
Bei einer Standardanmeldung, z.B. als any-doc, wird ausgeführt:
… exit_code = run_gui()
Der Terminus exit_code scheint etwas missverständlich. Damit ist gemeint, die grafische Oberfläche wird gestartet/ausgeführt. Zur Zeit besteht hier nur eine einzige Option, nämlich wxPython (= wxp).
Wie schon beim vorherigen Skript können vor und nach der Ausführung der grafischen Oberfläche individuelle Skripts/Hooks eingebunden werden.

Ein Blick in den Quellcode verdeutlicht das Gesagte.

Funktion run_gui innerhalb gnumed.py (/usr/share/gnumed/Gnumed/gnumed.py)
def run_gui():
        gmHooks.run_hook_script(hook = 'startup-before-GUI')

        if ui_type == 'wxp':
                from Gnumed.wxpython import gmGuiMain
                profile_file = _cfg.get(option = '--profile', source_order = [('cli', 'return')])
                if profile_file is not None:
                        _log.info('writing profiling data into %s', profile_file)
                        import profile
                        profile.run('gmGuiMain.main()', profile_file)
                else:
                        gmGuiMain.main()
        #elif ui_type == u'web':
        #       from Gnumed.proxiedpyjamas import gmWebGuiServer
        #       gmWebGuiServer.main()
        #elif ui_type == u'chweb':
        #       from Gnumed.CherryPy import gmGuiWeb
        #       gmGuiWeb.main()

        gmHooks.run_hook_script(hook = 'shutdown-post-GUI')

        return 0

Zur Zeit sind wie gesagt keine Hooks gesetzt, weder startup-before-GUI noch shutdown-post-GUI.
Zum Zweiten sieht man, dass ui_type immer gleich wxp ist → als Nächstes wird gmGuiMain importiert und entweder mit oder ohne profile_file gestartet.

Warnungen und Fehler im Log

An dieser Stelle unterbrechen wir für einen Moment die weitere Ausführung und betrachten das informative Log, welches GNUmed standardmäßig schreibt. Dieses finden wir (siehe die Meldung Log File beim Start oben) unter
/home/<user/.gnumed/gnumed/logs/gnumed/gnumed/gnumed-<datum_zeit>
Es handelt sich also um einen (unter Linux) versteckten Ordner, der explizit geöffnet werden muss.

In unserer Umgebung zeigten sich mehrere Warnungen/Fehler, die allesamt aber nicht zu einem Abbruch des Programms führten, sondern ignoriert werden. Die nicht ladbaren Komponenten werden schlicht und einfach übersprungen und sind in der Folge eben nicht nutzbar. Der folgenden Auszug aus dem Log zeigt die interessanten Punkte.

getrefcount / getsizeof: <cannot log>

Als erstes begegnen uns zwei Warnungen bei der Abfrage bestimmter Infos aus Pythons built-in Modul sys

2023-11-14 15:35:29  INFO      gm.launcher   [139817169768512 MainThread]  (/usr/share/gnumed/Gnumed/gnumed.py::log_startup_info() #380):              getrecursionlimit: 1000
2023-11-14 15:35:29  ERROR     gm.launcher   [139817169768512 MainThread]  (/usr/share/gnumed/Gnumed/gnumed.py::log_startup_info() #382):                    getrefcount: <cannot log>
Traceback (most recent call last):
  File "/usr/share/gnumed/Gnumed/gnumed.py", line 380, in log_startup_info
    _log.info('%s: %s', attr_name.rjust(30), attr())
                                             ^^^^^^
TypeError: sys.getrefcount() takes exactly one argument (0 given)
2023-11-14 15:35:29  ERROR     gm.launcher   [139817169768512 MainThread]  (/usr/share/gnumed/Gnumed/gnumed.py::log_startup_info() #382):                      getsizeof: <cannot log>
Traceback (most recent call last):
  File "/usr/share/gnumed/Gnumed/gnumed.py", line 380, in log_startup_info
    _log.info('%s: %s', attr_name.rjust(30), attr())
                                             ^^^^^^
TypeError: getsizeof() missing required argument 'object' (pos 1)
2023-11-14 15:35:29  INFO      gm.launcher   [139817169768512 MainThread]  (/usr/share/gnumed/Gnumed/gnumed.py::log_startup_info() #380):              getswitchinterval: 0.005

Diese Meldungen tauchen bei bestimmten Python-Version auf - ab Python3.11. Frühere Versionen laufen durch.
FIX: Um die Kompatibiltät zu erhalten, wird an den kritischen Stellen im Code eine Ausnahme geprüft und abgefangen. Das ist möglich, da die inkriminierten Infos aus sys (im Regelfall) nicht von Belang sind.


   Hier gilt, wie überhaupt bei jeder Edierung der
   Python-Quellcode-Dateien:
   Als erster Schritt sollen/müssen alle Tabs in vier Leerschritte umgewandelt werden.


Python-Quellcode: Tabs zu Leerschritten
expand -t4 -i ./gnumed.alt > gnumed.py

Ein Schnipsel aus der angepassten Datei zeigt das Ergebnis.

Korrigierte gnumed.py (Ausschnitt)
...
#### Begin FIX
##        if callable(attr):
##            try:
##                _log.info('%s: %s', attr_name.rjust(30), attr())
##            except Exception:
##                _log.exception('%s: <cannot log>', attr_name.rjust(30))
##            continue
#### End FIX
         if callable(attr):
            try:
                _log.info('%s: %s', attr_name.rjust(30), attr())
            except TypeError:
                try:
                    _log.info('%s: %s', attr_name.rjust(30), attr(object))
                except Exception:
                    _log.exception('%s: <cannot log>', attr_name.rjust(30))
                continue
            except Exception:
                _log.exception('%s: <cannot log>', attr_name.rjust(30))
            continue
...


system_alias / uname_result <cannot log> / SC_EQUIV_CLASS_MAX

Ganz analog lassen sich die drei nächsten Warnungen/Fehler beschreiben und berichtigen:

<....>
2023-11-14 16:53:29  ERROR     gm.launcher   [140027945967680 MainThread]  (/usr/share/gnumed/Gnumed/gnumed.py::log_startup_info() #412):                   system_alias: <cannot log>
Traceback (most recent call last):
  File "/usr/share/gnumed/Gnumed/gnumed.py", line 410, in log_startup_info
    _log.info('%s: %s', attr_name.rjust(30), attr())
                                             ^^^^^^
TypeError: system_alias() missing 3 required positional arguments: 'system', 'release', and 'version'
2023-11-14 16:53:29  INFO      gm.launcher   [140027945967680 MainThread]  (/usr/share/gnumed/Gnumed/gnumed.py::log_startup_info() #410):                          uname: uname_result(system='Linux', node='hpc', release='6.1.0-13-amd64', version='#1 SMP PREEMPT_DYNAMIC Debian 6.1.55-1 (2023-09-29)', machine='x86_64')
2023-11-14 16:53:29  ERROR     gm.launcher   [140027945967680 MainThread]  (/usr/share/gnumed/Gnumed/gnumed.py::log_startup_info() #412):                   uname_result: <cannot log>
Traceback (most recent call last):
  File "/usr/share/gnumed/Gnumed/gnumed.py", line 410, in log_startup_info
    _log.info('%s: %s', attr_name.rjust(30), attr())
                                             ^^^^^^
TypeError: uname_result_base.__new__() missing 5 required positional arguments: 'system', 'node', 'release', 'version', and 'machine'
2023-11-14 16:53:29  INFO      gm.launcher   [140027945967680 MainThread]  (/usr/share/gnumed/Gnumed/gnumed.py::log_startup_info() #410):                        version: #1 SMP PREEMPT_DYNAMIC Debian 6.1.55-1 (2023-09-29)

<....>
2023-11-14 16:53:29  INFO      gm.launcher   [140027945967680 MainThread]  (/usr/share/gnumed/Gnumed/gnumed.py::log_startup_info() #421):               sysconf[SC_DELAYTIMER_MAX]: 2147483647
2023-11-14 16:53:29  ERROR     gm.launcher   [140027945967680 MainThread]  (/usr/share/gnumed/Gnumed/gnumed.py::log_startup_info() #423):    sysconf[SC_EQUIV_CLASS_MAX]: <invalid> ??
Traceback (most recent call last):
  File "/usr/share/gnumed/Gnumed/gnumed.py", line 421, in log_startup_info
    _log.info('%s: %s', ('sysconf[%s]' % n).rjust(40), os.sysconf(n))
                                                       ^^^^^^^^^^^^^
OSError: [Errno 22] Invalid argument
2023-11-14 16:53:29  INFO      gm.launcher   [140027945967680 MainThread]  (/usr/share/gnumed/Gnumed/gnumed.py::log_startup_info() #421):                sysconf[SC_EXPR_NEST_MAX]: 32
<....>

Diese Meldungen werden ebenso durch entsprechende Ausnahmeklauseln abgfangen, die in den Code zu gnumed.py eingefügt werden.
Die vollständige, gefixte, Datei gnumed.py findet sich im Simpelmed-Repo
https://gitlab.com/bgehrke/simpelmed/-/tree/main/gnumed/gnumed/client?ref_type=heads

wxGridSelectRows

Der nächste Error betrifft die wxpython-Datei gmMedicationWidgets.py, zu finden im Verzeichnis /usr/share/gnumed/Gnumed/wxpython/

Fehlermeldung »attribute wxGridSelectRows«
<....>

2023-11-14 19:18:16  ERROR     gm.ui         [140644204879936 MainThread]  (/usr/share/gnumed/Gnumed/wxpython/gmHorstSpace.py::__load_plugins() #293): failed to load plugin gmCurrentSubstancesPlugin
Traceback (most recent call last):
  File "/usr/share/gnumed/Gnumed/wxpython/gmHorstSpace.py", line 286, in __load_plugins
    plugin.register()
  File "/usr/share/gnumed/Gnumed/wxpython/gmAccessPermissionWidgets.py", line 60, in _func_decorated_with_required_role_checking
    return original_function(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/share/gnumed/Gnumed/wxpython/gui/gmCurrentSubstancesPlugin.py", line 34, in register
    gmPlugin.cNotebookPlugin.register(self)
  File "/usr/share/gnumed/Gnumed/wxpython/gmPlugin.py", line 92, in register
    widget = self.GetWidget(nb)
             ^^^^^^^^^^^^^^^^^^
  File "/usr/share/gnumed/Gnumed/wxpython/gui/gmCurrentSubstancesPlugin.py", line 40, in GetWidget
    self._widget = gmMedicationWidgets.cCurrentSubstancesPnl(parent, -1)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/share/gnumed/Gnumed/wxpython/gmMedicationWidgets.py", line 1977, in __init__
    wxgCurrentSubstancesPnl.wxgCurrentSubstancesPnl.__init__(self, *args, **kwargs)
  File "/usr/share/gnumed/Gnumed/wxGladeWidgets/wxgCurrentSubstancesPnl.py", line 27, in __init__
    self._grid_substances = cCurrentSubstancesGrid(self, wx.ID_ANY, size=(1, 1))
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/share/gnumed/Gnumed/wxpython/gmMedicationWidgets.py", line 1346, in __init__
    self.__init_ui()
  File "/usr/share/gnumed/Gnumed/wxpython/gmMedicationWidgets.py", line 1828, in __init_ui
    self.SetSelectionMode(wx.grid.Grid.wxGridSelectRows)
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: type object 'Grid' has no attribute 'wxGridSelectRows'

<....>

Hier scheint es einen Wechsel in der wxPython-API zu geben. In einer Version heißt es wxGridSelectRows, in einer anderen GridSelectRows ohne wx zu Beginn.
Die gefixte Version der Datei steht ebenso im Repo
https://gitlab.com/bgehrke/simpelmed/-/tree/main/gnumed/gnumed/client/wxpython?ref_type=heads

Modul humblewx fehlt

Den nächsten Error verursacht das Modul humblewx, das in bestimmte Python/wxPython-Umgebungen nicht gefunden wird. Die Log-Meldung dazu:

ModuleNotFoundError: No module named humblewx
2023-11-14 19:18:16  ERROR     gm.ui         [140644204879936 MainThread]  (/usr/share/gnumed/Gnumed/wxpython/gmPlugin.py::__gm_import() #265): Cannot __import__() module [Gnumed.wxpython.gui.gmEMRTimelinePlugin].
Traceback (most recent call last):
  File "/usr/share/gnumed/Gnumed/wxpython/gmPlugin.py", line 263, in __gm_import
    mod = __import__(module_name)
          ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/share/gnumed/Gnumed/wxpython/gui/gmEMRTimelinePlugin.py", line 14, in <module>
    from Gnumed.wxpython import gmPlugin, gmEMRTimelineWidgets
  File "/usr/share/gnumed/Gnumed/wxpython/gmEMRTimelineWidgets.py", line 38, in <module>
    from Gnumed.timelinelib.canvas.data import TimePeriod
  File "/usr/share/gnumed/Gnumed/timelinelib/canvas/__init__.py", line 23, in <module>
    from timelinelib.canvas.events import EVT_DIVIDER_POSITION_CHANGED
  File "/usr/share/gnumed/Gnumed/timelinelib/canvas/__init__.py", line 25, in <module>
    from timelinelib.canvas.timelinecanvas import TimelineCanvas
  File "/usr/share/gnumed/Gnumed/timelinelib/canvas/timelinecanvas.py", line 22, in <module>
    from timelinelib.canvas.timelinecanvascontroller import TimelineCanvasController
  File "/usr/share/gnumed/Gnumed/timelinelib/canvas/timelinecanvascontroller.py", line 21, in <module>
    from timelinelib.canvas.appearance import Appearance
  File "/usr/share/gnumed/Gnumed/timelinelib/canvas/appearance.py", line 22, in <module>
    from timelinelib.wxgui.components.font import Font
  File "/usr/share/gnumed/Gnumed/timelinelib/wxgui/components/__init__.py", line 19, in <module>
    from .categorychoice import CategoryChoice
  File "/usr/share/gnumed/Gnumed/timelinelib/wxgui/components/categorychoice.py", line 23, in <module>
    from timelinelib.wxgui.dialogs.editcategory.view import EditCategoryDialog
  File "/usr/share/gnumed/Gnumed/timelinelib/wxgui/dialogs/editcategory/view.py", line 19, in <module>
    from timelinelib.wxgui.dialogs.editcategory.controller import EditCategoryDialogController
  File "/usr/share/gnumed/Gnumed/timelinelib/wxgui/dialogs/editcategory/controller.py", line 19, in <module>
    from timelinelib.wxgui.framework import Controller
  File "/usr/share/gnumed/Gnumed/timelinelib/wxgui/framework.py", line 19, in <module>
    from humblewx import Controller
ModuleNotFoundError: No module named 'humblewx'

Wie gesagt, trifft dieser Fehler nur in den neueren Python-Version ab 11 und höher auf. Zugrunde liegt möglicherweise ein modifiziertes Import- bzw. Modulkonzept (Suchphrase für weitere Recherchen: error: externally-managed-environment This environment is externally managed …; hierauf gehen wir nicht weiter ein, da erhebliche Eingriffe ins System notwendig wären, dieses Verhalten zu ändern). Der Fix besteht darin, das Modul humblewx.py händisch in das »Wurzelverzeichnis« zu kopieren.
Kopieren Sie dazu die Datei humblewx.py (im Repo: https://gitlab.com/bgehrke/simpelmed/-/tree/main/gnumed/gnumed/client?ref_type=heads) auf Ihren Rechner und kopieren diese dann in das Heimatverzeichnis des Clients zu kopieren, da dieser hier zuerst nach Modulen zum Import sucht. An dieser Stelle im Verzeichnisbaum liegt im Übrigen auch die Datei gnumed.py.

Kopieren der Datei humblewx.py (root/sudo!)
sudo cp ./humblewx.py /usr/share/gnumed/Gnumed/humblewx.py

konsolekalendar

Relativ einfach ist die nächste Meldung zu unterdrücken bzw. abzuhaken. Das Programm meldet, konsolekalendar nicht finden zu können.

cannot detect "konsolekalendar"
<...>
2023-11-14 19:18:16  ERROR     gm.ui         [140644204879936 MainThread]  (/usr/share/gnumed/Gnumed/wxpython/gmHorstSpace.py::__load_plugins() #293): failed to load plugin gmEMRTimelinePlugin
Traceback (most recent call last):
  File "/usr/share/gnumed/Gnumed/wxpython/gmHorstSpace.py", line 284, in __load_plugins
    plugin = gmPlugin.instantiate_plugin('gui', curr_plugin)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/share/gnumed/Gnumed/wxpython/gmPlugin.py", line 300, in instantiate_plugin
    plugin_class = module_from_package.__dict__[plugin_name]
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute '__dict__'
2023-11-14 19:18:16  ERROR     gm.ui         [140644204879936 MainThread]  (/usr/share/gnumed/Gnumed/wxpython/gmPlugin.py::instantiate_plugin() #310): Cannot open module "gui.gmKOrganizerPlugin".
Traceback (most recent call last):
  File "/usr/share/gnumed/Gnumed/wxpython/gmPlugin.py", line 308, in instantiate_plugin
    plugin = plugin_class()
             ^^^^^^^^^^^^^^
  File "/usr/share/gnumed/Gnumed/wxpython/gui/gmKOrganizerPlugin.py", line 35, in __init__
    raise gmExceptions.ConstructorError('cannot detect "konsolekalendar" via [%s]' % cmd)
Gnumed.pycommon.gmExceptions.ConstructorError: cannot detect "konsolekalendar" via [None]
2023-11-14 19:18:16  ERROR     gm.ui         [140644204879936 MainThread]  (/usr/share/gnumed/Gnumed/wxpython/gmHorstSpace.py::__load_plugins() #289): plugin [gmKOrganizerPlugin] not loaded, see errors above
<...>

Das liegt ganz banal daran, dass dieses Programm nicht installiert ist. Abhilfe schafft ein einfaches sudo apt install konsolekalendar.


   Da das Modul nicht zwingend erforderlich ist, kann auf die
   Installation auch verzichtet werden.
   Der Grund für diesen Ratschlag: Damit vermeidet man die notwendige Installation des Paketes »Akonadi«, einer notorischen »Datenkrake«. Insbesondere im Gesundheitsumfeld kann der Einsatz dieser Software als bedenklich bewertet werden. Diese beiden Quellen enthalten weitere Infos: hier oder auch da.


Datenbankeinstellungen

Bei den meisten Neuinstallationen begrüßt Sie das Programm mit folgender oder einer ähnlichen Meldung:

Die Datenbankeinstellungen sind riskant gewählt:

 Option [log_connections]: off
  Risiko: non-compliance with HIPAA
 Option [log_disconnections]: off
  Risiko: non-compliance with HIPAA
 Option [track_commit_timestamp]: off
  Risiko: suboptimal auditing

Eventuell müssen Sie Ihren Systembetreuer zu Rate ziehen.

Die Logdatei enthält genauere Angaben !

Die entsprechenden Log-Einträge sehen so aus:

»database settings warning«
2023-11-15 17:45:35  WARNING   gm.db         [140030872350720 MainThread]  (/usr/share/gnumed/Gnumed/pycommon/gmPG2.py::sanity_check_database_settings() #2087): PG option [log_connections] set to [off], expected ['on'], risk: <non-compliance with HIPAA>
2023-11-15 17:45:35  WARNING   gm.db         [140030872350720 MainThread]  (/usr/share/gnumed/Gnumed/pycommon/gmPG2.py::sanity_check_database_settings() #2087): PG option [log_disconnections] set to [off], expected ['on'], risk: <non-compliance with HIPAA>
2023-11-15 17:45:35  WARNING   gm.db         [140030872350720 MainThread]  (/usr/share/gnumed/Gnumed/pycommon/gmPG2.py::sanity_check_database_settings() #2087): PG option [track_commit_timestamp] set to [off], expected ['on'], risk: <suboptimal auditing>

Das stellt keinen Grund zur Aufregung dar und beeinflusst die Ausführung in keinster Weise. Es geht hier um bestimmte Aufzeichnungen innerhalb der Datenbank, die für eine forensische Analyse der Nutzereingaben und Sitzungszeiten notwendig sind. Insbesondere US-Behörden interessieren sich (im Falle des Falles, wenn etwas wirklich schiefgeht mit Personenschaden) für diese Informationen. Dennoch ist es sicherlich eine gute Idee, diese Meldungen zu umgehen, zumal damit keine Einbuße an Komfort oder Geschwindigkeit einhergeht.
Der Datenbankadministrator muss dazu die PostgreSQL-Konfiguration anpassen - danach ist PostgreSQL neu zu starten.

Riskante Datenbankeinstellungen /etc/postgresql/15/main/postgresql.conf
<...>
#------------------------------------------------------------------------------
# REPLICATION
#------------------------------------------------------------------------------

track_commit_timestamp = on     # collect timestamp of transaction commit
                                            # (change requires restart)
<...>
#------------------------------------------------------------------------------
# REPORTING AND LOGGING
#------------------------------------------------------------------------------
<...>

# - What to Log -
<...>

log_connections = on
log_disconnections = on

Dargestellt sind hier nur die notwendigen Änderungen, gezeigt ist jeweils die Zeile nach Edierung. Damit erscheinen die genannte Risikowarnung nicht mehr.

Weitere Meldungen zum Start

Zu guter Letzt sollen die folgenden Meldungen - sie sind natürlich kein eigentlicher Fehler - erwähnt werden.

Versionsinfo
Eine neue Version von GNUmed ist verfügbar.
 Ihre jetzige Version: "1.8.9"

 Neue Version: "1.8.15"
 - ausschließlich Fehlerkorrekturen
 - Datenbank-Fixes können nötig sein

Achtung: Es kann natürlich sein, daß für Ihr System diese Version noch nicht bereitgestellt wurde.
Details are found on <http://www.gnumed.de>.

Versionsinformationen geladen von:
 [https://www.gnumed.de/downloads/gnumed-versions.txt]

Hier besteht kein Handlungsbedarf.



In statu nascendi begrüßt uns eine geradzu kosmische Praxis:

Raumflottenpraxis
Zweigstelle "generic praxis branch" der "generic praxis"
...
Uncle Pawel Wants You! --- Sign up for Starfleet Now!
...

Auch hier muss vorerst nichts geändert werden. Die »richtigen« Daten werden später ins System eingepflegt.



-> Zurück zu arbeitsumgebung.

-> Zurück zu postgresql-pgadmin.

-> Zurück zu gnumed-installation.

-> Weiter zu simpelmed-start.