update
This commit is contained in:
1
AzA march 2026/_local_diagnostic_artifacts/README.txt
Normal file
1
AzA march 2026/_local_diagnostic_artifacts/README.txt
Normal file
@@ -0,0 +1 @@
|
||||
Lokale Diagnose-/Extraktions-Hilfsdateien. Nicht Teil des Release-Candidates.
|
||||
1
AzA march 2026/_local_diagnostic_artifacts/_bkp_name.txt
Normal file
1
AzA march 2026/_local_diagnostic_artifacts/_bkp_name.txt
Normal file
@@ -0,0 +1 @@
|
||||
backup_doku_prompt_publish_ui_fix_20260610_225613
|
||||
@@ -0,0 +1,94 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Erstellt AZA_PRE_RELEASE_BACKUP mit ZIP und SHA256."""
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import zipfile
|
||||
from datetime import datetime
|
||||
|
||||
ROOT = os.path.dirname(os.path.abspath(__file__))
|
||||
TS = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
BAK = os.path.join(ROOT, f"AZA_PRE_RELEASE_BACKUP_{TS}")
|
||||
ZIP_PATH = BAK + ".zip"
|
||||
|
||||
INCLUDE_DIRS = ("web", "installer", "deploy", "assets", "release")
|
||||
INCLUDE_GLOBS = ("*.py", "*.spec", "build_test*.ps1", "start_doku_prompt_test.ps1", "_test_*.py")
|
||||
SNAPSHOT_BUILDS = (
|
||||
"test_translator_presentation_placeholder_v1",
|
||||
"test_chat_only_host_update_v1",
|
||||
"test_final_release_candidate_v1",
|
||||
)
|
||||
|
||||
|
||||
def _git_out(args: list[str]) -> str:
|
||||
try:
|
||||
return subprocess.check_output(["git"] + args, cwd=ROOT, text=True, stderr=subprocess.DEVNULL)
|
||||
except Exception:
|
||||
return ""
|
||||
|
||||
|
||||
os.makedirs(BAK, exist_ok=True)
|
||||
for sub in ("git_meta", "dist_snapshots", "release_meta"):
|
||||
os.makedirs(os.path.join(BAK, sub), exist_ok=True)
|
||||
|
||||
(open(os.path.join(BAK, "README_RESTORE.txt"), "w", encoding="utf-8").write(
|
||||
"AZA Pre-Release Backup. Restore: Dateien zurueckkopieren oder git checkout.\n"
|
||||
))
|
||||
|
||||
for name, content in {
|
||||
"git_branch.txt": _git_out(["rev-parse", "--abbrev-ref", "HEAD"]),
|
||||
"git_commit.txt": _git_out(["rev-parse", "HEAD"]),
|
||||
"git_status_short.txt": _git_out(["status", "--short"]),
|
||||
"git_diff_stat.txt": _git_out(["diff", "--stat"]),
|
||||
"git_untracked.txt": _git_out(["ls-files", "--others", "--exclude-standard"]),
|
||||
}.items():
|
||||
with open(os.path.join(BAK, "git_meta", name), "w", encoding="utf-8") as fh:
|
||||
fh.write(content)
|
||||
|
||||
diff = _git_out(["diff"])
|
||||
if diff:
|
||||
with open(os.path.join(BAK, "git_meta", "git_diff.patch"), "w", encoding="utf-8") as fh:
|
||||
fh.write(diff)
|
||||
|
||||
for fn in os.listdir(ROOT):
|
||||
if fn.endswith(".py") or fn.endswith(".spec") or fn.startswith("build_test") or fn == "start_doku_prompt_test.ps1":
|
||||
if os.path.isfile(os.path.join(ROOT, fn)):
|
||||
shutil.copy2(os.path.join(ROOT, fn), os.path.join(BAK, fn))
|
||||
|
||||
for d in INCLUDE_DIRS:
|
||||
src = os.path.join(ROOT, d)
|
||||
if os.path.isdir(src):
|
||||
shutil.copytree(src, os.path.join(BAK, d), dirs_exist_ok=True)
|
||||
|
||||
for tb in SNAPSHOT_BUILDS:
|
||||
src = os.path.join(ROOT, "dist", tb)
|
||||
if os.path.isdir(src):
|
||||
shutil.copytree(src, os.path.join(BAK, "dist_snapshots", tb), dirs_exist_ok=True)
|
||||
|
||||
vj = os.path.join(ROOT, "release", "version.json")
|
||||
if os.path.isfile(vj):
|
||||
shutil.copy2(vj, os.path.join(BAK, "release_meta", "version.json"))
|
||||
|
||||
bi = os.path.join(ROOT, "_build_info.py")
|
||||
if os.path.isfile(bi):
|
||||
shutil.copy2(bi, os.path.join(BAK, "release_meta", "_build_info.py"))
|
||||
|
||||
with zipfile.ZipFile(ZIP_PATH, "w", zipfile.ZIP_DEFLATED) as zf:
|
||||
for dirpath, _, files in os.walk(BAK):
|
||||
for fn in files:
|
||||
full = os.path.join(dirpath, fn)
|
||||
arc = os.path.relpath(full, os.path.dirname(BAK))
|
||||
zf.write(full, arc)
|
||||
|
||||
h = hashlib.sha256()
|
||||
with open(ZIP_PATH, "rb") as fh:
|
||||
for chunk in iter(lambda: fh.read(1024 * 1024), b""):
|
||||
h.update(chunk)
|
||||
|
||||
print("BACKUP_DIR=", os.path.basename(BAK))
|
||||
print("ZIP=", os.path.basename(ZIP_PATH))
|
||||
print("SHA256=", h.hexdigest())
|
||||
print("SIZE=", os.path.getsize(ZIP_PATH))
|
||||
@@ -0,0 +1,52 @@
|
||||
# One-off extractor — not part of product
|
||||
from pathlib import Path
|
||||
|
||||
src = Path("basis14.py").read_text(encoding="utf-8").splitlines()
|
||||
ranges = [(2923, 3224), (14522, 15558)]
|
||||
chunks: list[str] = []
|
||||
for a, b in ranges:
|
||||
chunks.extend(src[a - 1 : b])
|
||||
|
||||
header = '''# -*- coding: utf-8 -*-
|
||||
"""Gemeinsame Empfang-/Chat-Desktop-Logik (Singleton Huelle + Kontaktpanel)."""
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
import ctypes
|
||||
from ctypes import wintypes
|
||||
from pathlib import Path
|
||||
from typing import Optional, Tuple
|
||||
from urllib.parse import quote
|
||||
|
||||
import requests
|
||||
import tkinter as tk
|
||||
from tkinter import messagebox
|
||||
|
||||
from aza_empfang_identity import _empfang_identity_key
|
||||
|
||||
|
||||
def init_empfang_desktop_core_state(host) -> None:
|
||||
host._empfang_webview_proc = None
|
||||
host._empfang_webview_last_child_pid = None
|
||||
host._kontakt_panel_proc = None
|
||||
host._kontakt_panel_last_child_pid = None
|
||||
host._kontakt_panel_inflight_until = 0.0
|
||||
host._kontakt_panel_launch_ts = 0.0
|
||||
host._kontakt_panel_launch_lock = threading.Lock()
|
||||
host._aza_tracked_external_pids = set()
|
||||
host._empfang_webview_launch_lock = threading.Lock()
|
||||
host._empfang_webview_launch_inflight_until = 0.0
|
||||
host._empfang_webview_launch_ts = 0.0
|
||||
|
||||
|
||||
class EmpfangDesktopCoreMixin:
|
||||
'''
|
||||
body = "\n".join(chunks)
|
||||
Path("aza_empfang_desktop_core.py").write_text(header + body + "\n", encoding="utf-8")
|
||||
print("written", len(body.splitlines()), "lines")
|
||||
@@ -0,0 +1,20 @@
|
||||
# One-off extractor
|
||||
from pathlib import Path
|
||||
|
||||
src = Path("basis14.py").read_text(encoding="utf-8").splitlines()
|
||||
a, b = 10302, 10490
|
||||
chunks = src[a - 1 : b]
|
||||
header = '''# -*- coding: utf-8 -*-
|
||||
"""Gemeinsame Nachrichten-Poll- und Popup-Helfer fuer Office- und Chat-Host."""
|
||||
from __future__ import annotations
|
||||
|
||||
import threading
|
||||
import time
|
||||
|
||||
import requests
|
||||
|
||||
|
||||
class EmpfangHostPollMixin:
|
||||
'''
|
||||
Path("aza_empfang_host_poll.py").write_text(header + "\n".join(chunks) + "\n", encoding="utf-8")
|
||||
print("poll mixin", len(chunks), "lines")
|
||||
@@ -0,0 +1,12 @@
|
||||
# One-off: remove lines moved to aza_empfang_desktop_core.py
|
||||
from pathlib import Path
|
||||
|
||||
path = Path("basis14.py")
|
||||
lines = path.read_text(encoding="utf-8").splitlines(keepends=True)
|
||||
remove = set()
|
||||
for a, b in ((2923, 3224), (14522, 15558)):
|
||||
for i in range(a - 1, b):
|
||||
remove.add(i)
|
||||
new_lines = [ln for i, ln in enumerate(lines) if i not in remove]
|
||||
path.write_text("".join(new_lines), encoding="utf-8")
|
||||
print("removed", len(remove), "lines; new total", len(new_lines))
|
||||
@@ -0,0 +1,9 @@
|
||||
# One-off: remove poll mixin lines from basis14
|
||||
from pathlib import Path
|
||||
|
||||
path = Path("basis14.py")
|
||||
lines = path.read_text(encoding="utf-8").splitlines(keepends=True)
|
||||
remove = set(range(10302 - 1, 10490))
|
||||
new_lines = [ln for i, ln in enumerate(lines) if i not in remove]
|
||||
path.write_text("".join(new_lines), encoding="utf-8")
|
||||
print("removed poll lines")
|
||||
@@ -0,0 +1,133 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Einmaliger Backend-Deploy-Smoke-Test — gibt keine Secrets aus."""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import urllib.error
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
|
||||
BASE = "https://api.aza-medwork.ch"
|
||||
ROOT = os.path.dirname(os.path.abspath(__file__))
|
||||
TOKEN_PATH = os.path.join(ROOT, "backend_token.txt")
|
||||
|
||||
|
||||
def _read_token() -> str:
|
||||
with open(TOKEN_PATH, encoding="utf-8") as fh:
|
||||
return fh.read().strip()
|
||||
|
||||
|
||||
def _req(method: str, path: str, *, headers: dict | None = None, body: dict | None = None) -> tuple[int, dict | str]:
|
||||
url = BASE + path
|
||||
hdrs = dict(headers or {})
|
||||
data = None
|
||||
if body is not None:
|
||||
data = json.dumps(body).encode("utf-8")
|
||||
hdrs.setdefault("Content-Type", "application/json")
|
||||
req = urllib.request.Request(url, data=data, headers=hdrs, method=method)
|
||||
try:
|
||||
with urllib.request.urlopen(req, timeout=20) as resp:
|
||||
raw = resp.read().decode("utf-8", errors="replace")
|
||||
try:
|
||||
return resp.status, json.loads(raw)
|
||||
except json.JSONDecodeError:
|
||||
return resp.status, raw
|
||||
except urllib.error.HTTPError as exc:
|
||||
raw = exc.read().decode("utf-8", errors="replace")
|
||||
try:
|
||||
return exc.code, json.loads(raw)
|
||||
except json.JSONDecodeError:
|
||||
return exc.code, raw
|
||||
|
||||
|
||||
def main() -> int:
|
||||
results: list[str] = []
|
||||
ok = True
|
||||
|
||||
code, _data = _req("GET", "/health")
|
||||
results.append(f"health: {code}")
|
||||
if code != 200:
|
||||
ok = False
|
||||
|
||||
tok = _read_token()
|
||||
auth = {"X-API-Token": tok}
|
||||
pid = (os.environ.get("SMOKE_PRACTICE_ID") or "").strip()
|
||||
email = (os.environ.get("SMOKE_LICENSE_EMAIL") or "").strip()
|
||||
|
||||
hdrs_base = {**auth, "X-User-Id": "smoke_test_user"}
|
||||
if pid:
|
||||
hdrs_base["X-Practice-Id"] = pid
|
||||
|
||||
code, data = _req("GET", "/v1/doku-prompts/public", headers=hdrs_base)
|
||||
results.append(f"doku_public_list: {code}")
|
||||
if code == 200 and isinstance(data, dict):
|
||||
results.append(f" count={data.get('count', '?')}")
|
||||
elif code not in (200, 403):
|
||||
ok = False
|
||||
|
||||
code, data = _req("GET", "/v1/library/public", headers=hdrs_base)
|
||||
results.append(f"library_public_list: {code}")
|
||||
if code == 200 and isinstance(data, dict):
|
||||
results.append(f" count={data.get('count', '?')}")
|
||||
elif code not in (200, 403):
|
||||
ok = False
|
||||
|
||||
pub_id = ""
|
||||
if pid:
|
||||
hdrs = {**auth, "X-Practice-Id": pid, "X-User-Id": "smoke_test_user"}
|
||||
payload = {
|
||||
"doc_type": "verlauf",
|
||||
"title": "AZA Smoke Test Vorlage",
|
||||
"description": "Smoke-Test, kann gelöscht werden.",
|
||||
"content": "Dies ist eine technische Testvorlage ohne Patientendaten.",
|
||||
"author_display": "AzA Smoke Test",
|
||||
"city": "Winterthur",
|
||||
"specialty": "Dermatologie",
|
||||
"language": "de",
|
||||
"visibility": "public",
|
||||
}
|
||||
code, data = _req("POST", "/v1/doku-prompts/publish", headers=hdrs, body=payload)
|
||||
results.append(f"doku_publish: {code}")
|
||||
if code == 200 and isinstance(data, dict) and data.get("ok"):
|
||||
pub_id = str(data.get("id") or "")
|
||||
results.append(f" published_id={pub_id[:24]}..." if len(pub_id) > 24 else f" published_id={pub_id}")
|
||||
else:
|
||||
detail = data.get("detail") if isinstance(data, dict) else str(data)[:120]
|
||||
results.append(f" detail={detail}")
|
||||
if code not in (200, 403):
|
||||
ok = False
|
||||
|
||||
if pub_id:
|
||||
code, data = _req("POST", f"/v1/doku-prompts/unpublish/{pub_id}", headers=hdrs, body={})
|
||||
results.append(f"doku_unpublish: {code}")
|
||||
if code != 200:
|
||||
ok = False
|
||||
else:
|
||||
results.append("doku_publish: SKIPPED (SMOKE_PRACTICE_ID not set)")
|
||||
results.append("doku_unpublish: SKIPPED")
|
||||
|
||||
lic_path = "/license/status"
|
||||
if email:
|
||||
lic_path += "?" + urllib.parse.urlencode({"email": email})
|
||||
lic_hdrs = {**auth}
|
||||
if pid:
|
||||
lic_hdrs["X-Practice-Id"] = pid
|
||||
lic_hdrs["X-Device-Id"] = "smoke-device-readonly"
|
||||
code, data = _req("GET", lic_path, headers=lic_hdrs)
|
||||
results.append(f"license_status: {code}")
|
||||
if isinstance(data, dict):
|
||||
for k in (
|
||||
"chat_device_limit", "chat_devices_used", "contributing_office_licenses",
|
||||
"chat_devices_per_license", "valid", "device_allowed", "reason",
|
||||
):
|
||||
if k in data:
|
||||
results.append(f" {k}={data[k]}")
|
||||
|
||||
print("\n".join(results))
|
||||
return 0 if ok else 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -0,0 +1,8 @@
|
||||
import sqlite3
|
||||
c = sqlite3.connect("/app/data/stripe_webhook.sqlite")
|
||||
r = c.execute(
|
||||
"SELECT customer_email FROM licenses WHERE customer_email IS NOT NULL "
|
||||
"AND TRIM(customer_email) != '' LIMIT 1"
|
||||
).fetchone()
|
||||
if r:
|
||||
print(r[0])
|
||||
@@ -0,0 +1,7 @@
|
||||
import sqlite3
|
||||
c = sqlite3.connect("/app/data/stripe_webhook.sqlite")
|
||||
r = c.execute(
|
||||
"SELECT customer_email FROM licenses WHERE lower(trim(coalesce(status,'')))='active' "
|
||||
"AND trim(coalesce(practice_id,''))!='' LIMIT 1"
|
||||
).fetchone()
|
||||
print(r[0] if r and r[0] else "")
|
||||
@@ -0,0 +1,7 @@
|
||||
import sqlite3
|
||||
c = sqlite3.connect("/app/data/stripe_webhook.sqlite")
|
||||
r = c.execute(
|
||||
"SELECT practice_id FROM licenses WHERE lower(trim(coalesce(status,'')))='active' "
|
||||
"AND trim(coalesce(practice_id,''))!='' LIMIT 1"
|
||||
).fetchone()
|
||||
print(r[0] if r else "NONE")
|
||||
@@ -0,0 +1,13 @@
|
||||
import sqlite3
|
||||
c = sqlite3.connect("/app/data/stripe_webhook.sqlite")
|
||||
r = c.execute(
|
||||
"SELECT practice_id, customer_email FROM licenses "
|
||||
"WHERE lower(trim(coalesce(status,'')))='active' "
|
||||
"AND trim(coalesce(practice_id,''))!='' LIMIT 1"
|
||||
).fetchone()
|
||||
if r:
|
||||
print(r[0])
|
||||
print("EMAIL_SET" if r[1] else "EMAIL_NONE")
|
||||
else:
|
||||
print("NONE")
|
||||
print("EMAIL_NONE")
|
||||
BIN
AzA march 2026/_local_diagnostic_artifacts/_tmp_probe_out.txt
Normal file
BIN
AzA march 2026/_local_diagnostic_artifacts/_tmp_probe_out.txt
Normal file
Binary file not shown.
@@ -0,0 +1 @@
|
||||
{"ts": 1781301076.2451897, "source": "test2"}
|
||||
@@ -0,0 +1 @@
|
||||
{"ts": 1, "mode": "direct", "peer_user_id": "old", "document_visible": true}
|
||||
Reference in New Issue
Block a user