Alles unter ravokk - und ein Deinstallieren laesst nichts liegen

Gleiche Umstellung wie im Rechnungstool, gleiche gemeinsame Dateien
(gemeinsam.py, ordnerwahl.py, wasserzeichen.py, bauen.py).

  %LOCALAPPDATA%/ravokk/
      journal.sqlite3, berichte/, Nummernbuch, config.json   <- Daten
      Rechnungstool/                                          <- Programm
      Steuerrechnungstool/                                    <- Programm

⚠ Hier gefunden und behoben: das Journal der INSTALLIERTEN Fassung lag im
  Temp-Ordner. Der Merkzettel (ablage.py) zeigte auf
  %TEMP%/abnahme_bst/Daten - haengengeblieben aus einem Abnahmelauf vom
  03.09.2026. Windows raeumt den Temp-Ordner von selbst auf; das Journal
  waere ohne Vorwarnung verschwunden. Ein Merkzettel, der dorthin zeigt,
  wird jetzt verworfen statt befolgt.

  Sein Echtbestand (238 Buchungen) lag davon unberuehrt in der Quelle und
  ist gesichert.

Kein Ordner-Dialog mehr beim ersten Start - der gemeinsame Ordner steht
fest. Der Knopf hiess dort "Install-Ordner auswaehlen...", was schon immer
falsch war: es geht um das gemeinsame Nummernbuch, nicht um den
Installationsort.

Uninstaller raeumt jetzt auch die vom Updater geladenen Fassungen weg.
pruef_installation.py prueft beides zusammen: Programmordner leer, Daten
unangetastet.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax
This commit is contained in:
TheMockTv 2026-09-07 10:43:24 +02:00
parent 319c680a62
commit 1562388e78
12 changed files with 660 additions and 153 deletions

View file

@ -44,6 +44,43 @@ def _beschreibbar(ordner):
return False
def _ist_temp(pfad):
"""Liegt dieser Pfad im Temp-Ordner von Windows?
⚠ Am 07.09.2026 gefunden: der Merkzettel zeigte auf
%TEMP%/abnahme_bst/Daten - haengengeblieben aus einem Abnahmelauf vom
03.09. Die INSTALLIERTE Fassung fuehrte ihr Journal seitdem im
Temp-Ordner. Windows raeumt den automatisch auf (Datentraegerbereinigung,
Speicheroptimierung); das Journal waere ohne Vorwarnung verschwunden.
Ein Merkzettel, der dorthin zeigt, wird deshalb verworfen - lieber ein
frischer, richtiger Ordner als ein Journal auf Abruf.
"""
import tempfile
try:
temp = os.path.realpath(tempfile.gettempdir()).lower()
ziel = os.path.realpath(pfad).lower()
return ziel == temp or ziel.startswith(temp + os.sep)
except (OSError, ValueError):
return False
def firmen_ordner():
"""Das gemeinsame Dach: %LOCALAPPDATA%/ravokk.
Seine Ansage am 07.09.2026: *"es gibt ravokk als main verzeichnis, da
liegt config und sqlite drin, und dann gibt es den ordner rechnungstool
und steuertool"* - und dazu, warum es so heisst: *"ravokk ist meine firma
und die programme gehoeren zu der firma"*.
Darunter liegt je Programm ein eigener Ordner, und das gemeinsame
Nummernbuch eine Ebene darueber - so nimmt ein Deinstallieren es nicht mit
(siehe gemeinsam.standard_ordner).
"""
heim = os.environ.get("LOCALAPPDATA") or os.path.expanduser("~")
return os.path.join(heim, "ravokk")
def _zeiger_datei():
"""Merkzettel, WO der Datenordner liegt - liegt bewusst ausserhalb davon."""
heim = os.environ.get("LOCALAPPDATA") or os.path.expanduser("~")
@ -106,11 +143,22 @@ def daten_ordner():
log.warning("Datenordner %s ist nicht erreichbar - es wird nichts geändert", gemerkt)
return gemerkt if _beschreibbar(gemerkt) else EXE_DIR
kandidat = os.path.join(EXE_DIR, "Daten")
# Erste Wahl: der Ordner der Firma. Dort liegen beide Programme und das
# gemeinsame Nummernbuch - alles an einer Stelle, und ein Deinstallieren
# raeumt nur den Programmordner.
# NEBEN dem Programm, nicht darin - siehe firmen_ordner(). Journal,
# Berichte und Log liegen damit in ravokk, das Programm in
# ravokk/Steuerrechnungstool. Ein Deinstallieren leert nur den
# Programmordner.
kandidat = firmen_ordner()
if not _beschreibbar(kandidat):
kandidat = os.path.join(os.environ.get("LOCALAPPDATA", EXE_DIR), "Beherbergungssteuer")
# Rueckfall wie frueher: neben der EXE, dann der alte eigene Ordner.
kandidat = os.path.join(EXE_DIR, "Daten")
if not _beschreibbar(kandidat):
return EXE_DIR
kandidat = os.path.join(os.environ.get("LOCALAPPDATA", EXE_DIR),
"Beherbergungssteuer")
if not _beschreibbar(kandidat):
return EXE_DIR
_ordner_merken(kandidat)
for name in EIGENE_DATEN:
alt, neu = os.path.join(EXE_DIR, name), os.path.join(kandidat, name)