Initial commit

This commit is contained in:
Jonas Karneboge 2026-09-22 18:35:43 +02:00
commit 3cba772836
1341 changed files with 532924 additions and 0 deletions

BIN
#Surveys/WhiteleyIndex.xlsx Normal file

Binary file not shown.

BIN
#Surveys/acq_bsq_mi.xlsx Normal file

Binary file not shown.

Binary file not shown.

BIN
#Surveys/afka.xlsx Normal file

Binary file not shown.

BIN
#Surveys/aktivitaeten.xlsx Normal file

Binary file not shown.

BIN
#Surveys/asf.xlsx Normal file

Binary file not shown.

BIN
#Surveys/asrs.xlsx Normal file

Binary file not shown.

BIN
#Surveys/audit.xlsx Normal file

Binary file not shown.

BIN
#Surveys/bai.xlsx Normal file

Binary file not shown.

BIN
#Surveys/bdi2.xlsx Normal file

Binary file not shown.

BIN
#Surveys/bifl.xlsx Normal file

Binary file not shown.

BIN
#Surveys/bit_c.xlsx Normal file

Binary file not shown.

BIN
#Surveys/body_image.xlsx Normal file

Binary file not shown.

BIN
#Surveys/bsl.xlsx Normal file

Binary file not shown.

BIN
#Surveys/csas_e.xlsx Normal file

Binary file not shown.

BIN
#Surveys/csas_fp.xlsx Normal file

Binary file not shown.

BIN
#Surveys/ctq.xlsx Normal file

Binary file not shown.

BIN
#Surveys/cudit.xlsx Normal file

Binary file not shown.

BIN
#Surveys/desc_i.xlsx Normal file

Binary file not shown.

BIN
#Surveys/desc_ii.xlsx Normal file

Binary file not shown.

BIN
#Surveys/desii.xlsx Normal file

Binary file not shown.

BIN
#Surveys/dgbs_bipolar.xlsx Normal file

Binary file not shown.

BIN
#Surveys/dsf1.xlsx Normal file

Binary file not shown.

BIN
#Surveys/dsf2.xlsx Normal file

Binary file not shown.

BIN
#Surveys/edeq.xlsx Normal file

Binary file not shown.

BIN
#Surveys/edi2.xlsx Normal file

Binary file not shown.

BIN
#Surveys/esi.xlsx Normal file

Binary file not shown.

BIN
#Surveys/fas_pv.xlsx Normal file

Binary file not shown.

BIN
#Surveys/fas_sr.xlsx Normal file

Binary file not shown.

BIN
#Surveys/fea_fremd.xlsx Normal file

Binary file not shown.

BIN
#Surveys/fea_selbst.xlsx Normal file

Binary file not shown.

BIN
#Surveys/fkg.xlsx Normal file

Binary file not shown.

BIN
#Surveys/flz.xlsx Normal file

Binary file not shown.

BIN
#Surveys/gad7.xlsx Normal file

Binary file not shown.

BIN
#Surveys/gbb.xlsx Normal file

Binary file not shown.

BIN
#Surveys/hadsd.xlsx Normal file

Binary file not shown.

BIN
#Surveys/hase_adhssb.xlsx Normal file

Binary file not shown.

BIN
#Surveys/hase_wursk.xlsx Normal file

Binary file not shown.

BIN
#Surveys/hzi.xlsx Normal file

Binary file not shown.

BIN
#Surveys/iesr.xlsx Normal file

Binary file not shown.

BIN
#Surveys/iipc.xlsx Normal file

Binary file not shown.

BIN
#Surveys/iss20r.xlsx Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
#Surveys/itq.xlsx Normal file

Binary file not shown.

Binary file not shown.

BIN
#Surveys/lsas.xlsx Normal file

Binary file not shown.

BIN
#Surveys/mkf30.xlsx Normal file

Binary file not shown.

BIN
#Surveys/mlq.xlsx Normal file

Binary file not shown.

BIN
#Surveys/oci12.xlsx Normal file

Binary file not shown.

BIN
#Surveys/oci4.xlsx Normal file

Binary file not shown.

BIN
#Surveys/pas.xlsx Normal file

Binary file not shown.

BIN
#Surveys/pbq.xlsx Normal file

Binary file not shown.

BIN
#Surveys/pds5.xlsx Normal file

Binary file not shown.

BIN
#Surveys/pg13r.xlsx Normal file

Binary file not shown.

BIN
#Surveys/plc5.xlsx Normal file

Binary file not shown.

BIN
#Surveys/plc5_lec5.xlsx Normal file

Binary file not shown.

BIN
#Surveys/psiq.xlsx Normal file

Binary file not shown.

BIN
#Surveys/psqi.xlsx Normal file

Binary file not shown.

BIN
#Surveys/pssi.xlsx Normal file

Binary file not shown.

BIN
#Surveys/pswq.xlsx Normal file

Binary file not shown.

Binary file not shown.

BIN
#Surveys/scid5spq.xlsx Normal file

Binary file not shown.

BIN
#Surveys/scl90r.xlsx Normal file

Binary file not shown.

BIN
#Surveys/sekes.xlsx Normal file

Binary file not shown.

BIN
#Surveys/smi.xlsx Normal file

Binary file not shown.

BIN
#Surveys/soms2.xlsx Normal file

Binary file not shown.

BIN
#Surveys/soms7t.xlsx Normal file

Binary file not shown.

BIN
#Surveys/spwb.xlsx Normal file

Binary file not shown.

BIN
#Surveys/stai_state.xlsx Normal file

Binary file not shown.

Binary file not shown.

BIN
#Surveys/staxi2.xlsx Normal file

Binary file not shown.

BIN
#Surveys/tas26.xlsx Normal file

Binary file not shown.

BIN
#Surveys/u_fragebogen.xlsx Normal file

Binary file not shown.

BIN
#Surveys/vds19.xlsx Normal file

Binary file not shown.

BIN
#Surveys/vds20bu.xlsx Normal file

Binary file not shown.

BIN
#Surveys/vds23.xlsx Normal file

Binary file not shown.

BIN
#Surveys/vds24.xlsx Normal file

Binary file not shown.

BIN
#Surveys/vds26.xlsx Normal file

Binary file not shown.

BIN
#Surveys/vds27.xlsx Normal file

Binary file not shown.

BIN
#Surveys/vds28.xlsx Normal file

Binary file not shown.

BIN
#Surveys/vds29.xlsx Normal file

Binary file not shown.

BIN
#Surveys/vds30_11.xlsx Normal file

Binary file not shown.

BIN
#Surveys/vds30_stil.xlsx Normal file

Binary file not shown.

BIN
#Surveys/vds31.xlsx Normal file

Binary file not shown.

BIN
#Surveys/vds31kade.xlsx Normal file

Binary file not shown.

BIN
#Surveys/vds32.xlsx Normal file

Binary file not shown.

BIN
#Surveys/vds33.xlsx Normal file

Binary file not shown.

BIN
#Surveys/vds34.xlsx Normal file

Binary file not shown.

BIN
#Surveys/vds36.xlsx Normal file

Binary file not shown.

BIN
#Surveys/vds48.xlsx Normal file

Binary file not shown.

BIN
#Surveys/vds51.xlsx Normal file

Binary file not shown.

BIN
#Surveys/vds90.xlsx Normal file

Binary file not shown.

BIN
#Surveys/vviq.xlsx Normal file

Binary file not shown.

BIN
#Surveys/ysq3.xlsx Normal file

Binary file not shown.

215
#alt_skripte/get_data.R Normal file
View file

@ -0,0 +1,215 @@
library(formr)
formr_store_keys(host = "https://diagnostik.karneboge.de/api", client_id = "a007099d1ce340b2c701910b01d821ae", client_secret = "ff3f43bdca93c92fa5a854c97fbefc0d67f1900545fc79745a6e6565c1cbc07b", verbose = F)
formr_api_authenticate(host = "https://diagnostik.karneboge.de/api", verbose = F)
#formr_api_surveys(name_pattern = NULL, verbose = TRUE)
daten_scid5spq=formr_api_results(
run_name = "SKID5-SPQ",
"scid5spq",
compute_scales = FALSE,
join = TRUE,
remove_test_sessions = FALSE,
verbose = FALSE
)
daten_bdi2=formr_api_results(
run_name = "BDI2",
"bdi2",
compute_scales = FALSE,
join = TRUE,
remove_test_sessions = FALSE,
verbose = FALSE
)
daten_itq=formr_api_results(
run_name = "ITQ",
"itq",
compute_scales = FALSE,
join = TRUE,
remove_test_sessions = FALSE,
verbose = FALSE
)
daten_vds90=formr_api_results(
run_name = "VDS90",
"vds90",
compute_scales = FALSE,
join = TRUE,
remove_test_sessions = FALSE,
verbose = FALSE
)
daten_scl90r=formr_api_results(
run_name = "SCL90R",
"scl90r",
compute_scales = FALSE,
join = TRUE,
remove_test_sessions = FALSE,
verbose = FALSE
)
daten_pcl5lec5=formr_api_results(
run_name = "PCL5-LEC5",
"plc5_lec5",
compute_scales = FALSE,
join = TRUE,
remove_test_sessions = FALSE,
verbose = FALSE
)
daten_pcl5=formr_api_results(
run_name = "PCL5",
"plc5",
compute_scales = FALSE,
join = TRUE,
remove_test_sessions = FALSE,
verbose = FALSE
)
daten_pg13r=formr_api_results(
run_name = "PG13r",
"pg13r",
compute_scales = FALSE,
join = TRUE,
remove_test_sessions = FALSE,
verbose = FALSE
)
daten_ctq=formr_api_results(
run_name = "CTQ",
"ctq",
compute_scales = FALSE,
join = TRUE,
remove_test_sessions = FALSE,
verbose = FALSE
)
daten_bitc=formr_api_results(
run_name = "BIT-C",
"bit_c",
compute_scales = FALSE,
join = TRUE,
remove_test_sessions = FALSE,
verbose = FALSE
)
daten_acqbsqmi=formr_api_results(
run_name = "ACQ-BSQ-MI",
"acq_bsq_mi",
compute_scales = FALSE,
join = TRUE,
remove_test_sessions = FALSE,
verbose = FALSE
)
daten_lsas=formr_api_results(
run_name = "LSAS",
"lsas",
compute_scales = FALSE,
join = TRUE,
remove_test_sessions = FALSE,
verbose = FALSE
)
daten_desci=formr_api_results(
run_name = "DESC-I",
"desc_i",
compute_scales = FALSE,
join = TRUE,
remove_test_sessions = FALSE,
verbose = FALSE
)
daten_descii=formr_api_results(
run_name = "DESC-II",
"desc_ii",
compute_scales = FALSE,
join = TRUE,
remove_test_sessions = FALSE,
verbose = FALSE
)
daten_cuditr=formr_api_results(
run_name = "CUDIT",
"cudit",
compute_scales = FALSE,
join = TRUE,
remove_test_sessions = FALSE,
verbose = FALSE
)
daten_audit=formr_api_results(
run_name = "AUDIT",
"audit",
compute_scales = FALSE,
join = TRUE,
remove_test_sessions = FALSE,
verbose = FALSE
)
daten_pssi=formr_api_results(
run_name = "PSSI",
"pssi",
compute_scales = FALSE,
join = TRUE,
remove_test_sessions = FALSE,
verbose = FALSE
)
daten_iss20r=formr_api_results(
run_name = "ISS20R",
"iss20r",
compute_scales = FALSE,
join = TRUE,
remove_test_sessions = FALSE,
verbose = FALSE
)
daten_bsl=formr_api_results(
run_name = "BSL",
"bsl",
compute_scales = FALSE,
join = TRUE,
remove_test_sessions = FALSE,
verbose = FALSE
)
daten_desii=formr_api_results(
run_name = "DES-II",
"desii",
compute_scales = FALSE,
join = TRUE,
remove_test_sessions = FALSE,
verbose = FALSE
)
daten_bai=formr_api_results(
run_name = "BAI",
"bai",
compute_scales = FALSE,
join = TRUE,
remove_test_sessions = FALSE,
verbose = FALSE
)
daten_pds5=formr_api_results(
run_name = "PDS-5",
"pds5",
compute_scales = FALSE,
join = TRUE,
remove_test_sessions = FALSE,
verbose = FALSE
)
daten_mkf30=formr_api_results(
run_name = "MKF-30",
"mkf30",
compute_scales = FALSE,
join = TRUE,
remove_test_sessions = FALSE,
verbose = FALSE
)
formr_api_logout(verbose = FALSE)

View file

@ -0,0 +1,35 @@
#!/usr/bin/env bash
# Injiziert den URL-Parameter-Block (Chiffre aus ?chiffre=... vorausfuellen)
# in alle app.R-Dateien neben diesem Skript (bzw. im Root, ausgefuehrt dort).
# Idempotent: bereits gepatchte Dateien werden uebersprungen. Legt vor jeder
# Aenderung ein .bak an.
set -euo pipefail
SNIPPET=' observe({
query = parseQueryString(session$clientData$url_search)
if (!is.null(query$chiffre) && nchar(trimws(query$chiffre)) > 0) {
updateTextInput(session, "chiffre", value = toupper(trimws(query$chiffre)))
}
})'
MARKER='parseQueryString(session$clientData$url_search)'
find . -maxdepth 2 -iname 'app.R' -print0 | while IFS= read -r -d '' f; do
if grep -qF "$MARKER" "$f"; then
echo "SKIP (bereits vorhanden): $f"
continue
fi
if ! grep -qE 'server[[:space:]]*=[[:space:]]*function\(input, output, session\)[[:space:]]*\{' "$f"; then
echo "WARNUNG: Server-Signatur nicht gefunden, uebersprungen: $f"
continue
fi
cp "$f" "$f.bak"
awk -v snippet="$SNIPPET" '
{ print }
/server[ \t]*=[ \t]*function\(input, output, session\)[ \t]*\{/ && !done {
print snippet
done = 1
}
' "$f.bak" > "$f"
echo "OK: $f (Backup: $f.bak)"
done

View file

@ -0,0 +1,267 @@
#!/usr/bin/env python3
"""Injects pseudonym-based matching into every Diagnostik-App Shiny app.R.
Usage (run from the "formr" folder that directly contains all the app
subfolders, next to server.py / get_pseudo.R / pseudonyme.db):
python inject_pseudonym.py # dry run: reports what WOULD happen
python inject_pseudonym.py --apply # actually writes the changes
Finds every "<app-folder>/app.R" itself (no shell globbing needed, so this
works the same from Windows cmd.exe as from bash). Idempotent (marker-based -
safe to rerun), makes a .bak next to each file it actually changes, and
leaves a file completely untouched if any of the required anchors can't be
found unambiguously - such files are reported with a reason instead of being
guessed at.
"""
import re
import shutil
import sys
from pathlib import Path
MARKER = "# --- pseudonym-support-injection v1 ---"
def inject(path, write=True):
path = str(path)
raw = open(path, encoding="utf-8", newline="").read()
uses_crlf = raw.count("\r\n") > raw.count("\n") - raw.count("\r\n")
text = raw.replace("\r\n", "\n")
if MARKER in text:
return "skip: already patched", text
orig = text
warnings = []
notes = []
# 1. UI field: a pseudonym textInput with a small italic hint instead of
# a bulky bold label. If textInput("chiffre", ...) is directly preceded
# by a simple single-purpose `div(style = "...",` wrapper (the common
# shape), clone a sibling div so both fields sit side by side in the
# same flex row instead of stacking. Otherwise fall back to a plain
# inline sibling insert (functional, just possibly stacked) and note it.
label_block = (
'tagList(\n'
'{i} "Pseudonym",\n'
'{i} tags$span(style = "font-weight: normal; font-style: italic; '
'font-size: 0.78em; color: #888; margin-left: 4px; white-space: nowrap;",\n'
'{i} "optional, hat Vorrang vor Chiffre")\n'
'{i} )'
)
m_wrapped = re.search(
r'^([ \t]*)div\(style\s*=\s*"[^"]*"\s*,\s*\n([ \t]*)textInput\("chiffre"',
text, re.MULTILINE,
)
if m_wrapped:
outer_indent, inner_indent = m_wrapped.group(1), m_wrapped.group(2)
label = label_block.format(i=inner_indent)
insertion = (
f'{outer_indent}div(style = "min-width: 360px; white-space: nowrap;",\n'
f'{inner_indent}textInput("pseudonym",\n'
f'{inner_indent} label = {label},\n'
f'{inner_indent} placeholder = "optional", width = "340px")\n'
f'{outer_indent}),\n'
)
text = text[: m_wrapped.start()] + insertion + text[m_wrapped.start() :]
else:
m = re.search(r'^([ \t]*)textInput\("chiffre"', text, re.MULTILINE)
if not m:
warnings.append('UI: textInput("chiffre" not found')
else:
indent = m.group(1)
label = label_block.format(i=indent)
insertion = (
f'{indent}textInput("pseudonym",\n'
f'{indent} label = {label},\n'
f'{indent} placeholder = "optional", width = "340px"),\n'
)
text = text[: m.start()] + insertion + text[m.start() :]
notes.append(
"UI: no simple preceding div(style=...) wrapper found around "
"textInput(\"chiffre\" - pseudonym field inserted inline; layout "
"may need a manual look (may stack instead of sitting side by side)"
)
# 2. URL prefill: new observe() block right after the server function
# signature, independent of/in addition to the existing chiffre one.
m = re.search(r"server\s*=\s*function\(input,\s*output,\s*session\)\s*\{\n", text)
if not m:
warnings.append("server = function(input, output, session) { not found")
else:
block = (
f" {MARKER}\n"
" observe({\n"
" query = parseQueryString(session$clientData$url_search)\n"
" if (!is.null(query$pseudonym) && nchar(trimws(query$pseudonym)) > 0) {\n"
' updateTextInput(session, "pseudonym", value = trimws(query$pseudonym))\n'
" }\n"
" })\n\n"
)
idx = m.end()
text = text[:idx] + block + text[idx:]
# Some apps run their chiffre-empty/format checks inside a dedicated
# top-level helper function (e.g. desii_validiere_chiffre(),
# validiere_chiffre()) defined OUTSIDE server() - such a function has no
# `input` in scope. Blindly rewriting a check there would compile fine
# but throw "object 'input' not found" at runtime on every single click,
# for every patient, whether pseudonym is used or not. So items 3 and 4
# only ever touch occurrences that are reachable from inside server()
# (i.e. at/after the server function's opening brace); anything found
# only earlier in the file is left completely untouched and reported as
# a note instead - pseudonym-only entry (no chiffre at all) just won't
# work for that one app, but the chiffre+pseudonym disambiguation (the
# actual bug this whole thing fixes) is unaffected either way.
m_anchor = re.search(r"server\s*=\s*function\(input,\s*output,\s*session\)\s*\{", text)
reactive_start = m_anchor.start() if m_anchor else None
def patch_reachable(text, target, replacement):
matches = list(re.finditer(re.escape(target), text))
reachable = [
mm for mm in matches
if reactive_start is not None and mm.start() >= reactive_start
]
for mm in reversed(reachable):
text = text[: mm.start()] + replacement + text[mm.end() :]
return text, len(matches), len(reachable)
# 3. Relax the "chiffre leer" gate - phrasing varies (some apps check
# `chiffre`, others read into `chiffre_roh` first).
empty_gate_variants = [
("nchar(chiffre) == 0",
"(nchar(trimws(input$pseudonym)) == 0 && nchar(chiffre) == 0)"),
("nchar(trimws(chiffre_roh)) == 0",
"(nchar(trimws(input$pseudonym)) == 0 && nchar(trimws(chiffre_roh)) == 0)"),
('trimws(chiffre_roh) == ""',
'(nchar(trimws(input$pseudonym)) == 0 && trimws(chiffre_roh) == "")'),
]
any_empty_gate_patched = False
for target, replacement in empty_gate_variants:
text, total, reachable = patch_reachable(text, target, replacement)
if reachable:
any_empty_gate_patched = True
if not any_empty_gate_patched:
notes.append(
"no reachable chiffre-empty gate found (the format-check gate below "
"usually already covers an empty chiffre too, so this is often fine)"
)
# 4. Relax the chiffre-format gate.
target = 'grepl("^[A-Z][0-9]{6}$", chiffre)'
replacement = '(nchar(trimws(input$pseudonym)) > 0 || grepl("^[A-Z][0-9]{6}$", chiffre))'
text, total, reachable = patch_reachable(text, target, replacement)
if reachable == 0:
if total > 0:
notes.append(
"chiffre-format check only exists inside a top-level helper function "
"with no access to the pseudonym input - pseudonym-only entry (no "
"chiffre at all) won't work for this app, but chiffre+pseudonym "
"disambiguation (the main fix) is unaffected"
)
else:
warnings.append(f'gate not found: "{target}"')
# 5. Backfill `chiffre` from the pseudonym right after the pseudonym
# script is sourced (pseudo now exists in .GlobalEnv - guaranteed
# name, set by the one shared get_pseudo.R).
target = "source(PFAD_PSEUDONYM_SKRIPT, local = FALSE)"
occurrences = [mm.start() for mm in re.finditer(re.escape(target), text)]
if len(occurrences) != 1:
warnings.append(
f'expected exactly 1 occurrence of source(PFAD_PSEUDONYM_SKRIPT...), found {len(occurrences)}'
)
else:
pos = occurrences[0]
line_start = text.rfind("\n", 0, pos) + 1
indent = re.match(r"[ \t]*", text[line_start:pos]).group(0)
end = pos + len(target)
backfill = (
f"\n{indent}if (nchar(trimws(input$pseudonym)) > 0) {{\n"
f'{indent} .pw_wert = trimws(input$pseudonym)\n'
f'{indent} .pw_tab = get("pseudo", envir = .GlobalEnv)\n'
f"{indent} .pw_treffer = .pw_tab[.pw_tab$pseudonym == .pw_wert, ]\n"
f"{indent} if (nrow(.pw_treffer) > 0) chiffre = toupper(trimws(.pw_treffer$chiffre[1]))\n"
f"{indent}}}"
)
text = text[:end] + backfill + text[end:]
# 6. Override the final session-id(s) with the exact pseudonym, so an
# ambiguous chiffre (multiple pseudonyms) doesn't silently pick the
# wrong / most-recent entry.
sid_pattern = re.compile(
r"^([ \t]*)([A-Za-z_][A-Za-z0-9_.]*)\s*=\s*"
r"(unique\(as\.character\(\w+\$pseudonym\)\)|unique\(\w+\$pseudonym\)|\w+\$pseudonym\[1\])[ \t]*$",
re.MULTILINE,
)
matches = list(sid_pattern.finditer(text))
if len(matches) == 0:
warnings.append("session-id assignment (X = unique(Y$pseudonym) / Y$pseudonym[1]) not found")
else:
for mm in reversed(matches):
indent, varname = mm.group(1), mm.group(2)
override = f"\n{indent}if (nchar(trimws(input$pseudonym)) > 0) {varname} = trimws(input$pseudonym)"
text = text[: mm.end()] + override + text[mm.end() :]
if warnings:
return "skip: " + "; ".join(warnings), orig
out = text.replace("\n", "\r\n") if uses_crlf else text
if write:
shutil.copy(path, path + ".bak")
with open(path, "w", encoding="utf-8", newline="") as f:
f.write(out)
status = "patched"
if notes:
status += " (note: " + "; ".join(notes) + ")"
return status, out
def main():
args = sys.argv[1:]
apply_changes = "--apply" in args
args = [a for a in args if a != "--apply"]
if args:
paths = [Path(a) for a in args]
else:
paths = sorted(Path(".").glob("*/app.R"))
if not paths:
print('No "*/app.R" files found in the current directory. '
"Run this from the folder that directly contains all the app "
"subfolders (next to server.py / get_pseudo.R / pseudonyme.db), "
"or pass explicit paths.")
sys.exit(1)
print(f"{'DRY RUN (no files will be changed - pass --apply to write)' if not apply_changes else 'APPLYING CHANGES'}")
print(f"{len(paths)} app(s) found.\n")
counts = {"patched": 0, "patched-with-note": 0, "skip-already-patched": 0, "skip": 0}
for p in paths:
try:
status, _ = inject(p, write=apply_changes)
except Exception as e:
status = f"skip: UNEXPECTED ERROR ({type(e).__name__}: {e}) - file left untouched, please report this"
if status.startswith("skip: already patched"):
counts["skip-already-patched"] += 1
elif status.startswith("skip:"):
counts["skip"] += 1
elif "(note:" in status:
counts["patched-with-note"] += 1
else:
counts["patched"] += 1
print(f"{p}: {status}")
print(
f"\n{counts['patched']} clean, {counts['patched-with-note']} patched-with-note, "
f"{counts['skip']} skipped, {counts['skip-already-patched']} already patched."
)
if not apply_changes:
print("This was a dry run - nothing was written. Rerun with --apply once you're happy.")
if __name__ == "__main__":
main()

View file

@ -0,0 +1,40 @@
library(formr)
formr_store_keys(host = "https://diagnostik.karneboge.de/api", client_id = "6be1cb43d9964516089238a292b30098", client_secret = "e10c32d15c5ad9ecf44dc17d3d997fd3e7fc4c4153478fec5006904a7056f02e")
formr_api_authenticate(host = "https://diagnostik.karneboge.de/api")
pseudoID="4V8QodhlrGKifPKRdSpSFj-OFC4etlCvaa4GCQ1FAXE_PjDE7UdBCynDVa29guRu"
#SKID 5 SPQ ####
formr_api_create_session(
"SKID5-SPQ",
codes = pseudoID,
testing = FALSE,
verbose = TRUE
)
formr_api_logout(verbose = FALSE)
as.data.frame(
formr_api_sessions(
"SKID5-SPQ",
session_codes = pseudoID,
active = NULL,
testing = NULL,
limit = 1000,
offset = 0,
verbose = TRUE
)
)
#BDI2 ####
formr_api_create_session(
"BDI2",
codes = pseudoID,
testing = FALSE,
verbose = TRUE
)
formr_api_logout(verbose = FALSE)

View file

@ -0,0 +1,66 @@
# Basisordner, in dem alle Shiny App Unterordner liegen
$baseDir = "C:\Users\johnn\Desktop\formr"
# Voller Pfad zu Rscript.exe
$rscriptExe = "C:\Program Files\R\R-4.6.0\bin\x64\Rscript.exe"
# Logdatei für die Ergebnisse
$logFile = Join-Path $baseDir "renv_restore_log.txt"
"Start: $(Get-Date)" | Out-File -FilePath $logFile
# Alle Unterordner finden, die eine renv.lock enthalten
$appFolders = Get-ChildItem -Path $baseDir -Recurse -Filter "renv.lock" |
ForEach-Object { $_.Directory.FullName } |
Sort-Object -Unique
Write-Host "Gefundene Apps mit renv.lock: $($appFolders.Count)"
$erfolgreich = @()
$fehlgeschlagen = @()
foreach ($folder in $appFolders) {
Write-Host "Bearbeite: $folder"
"----" | Out-File -FilePath $logFile -Append
"App: $folder" | Out-File -FilePath $logFile -Append
# R Befehl als Einzeiler, escaped für Rscript -e
$rCommand = "renv::restore(project = '$($folder -replace '\\','/')', prompt = FALSE)"
$output = & $rscriptExe -e $rCommand 2>&1
$output | Out-File -FilePath $logFile -Append
# Grobe Erfolgsprüfung: enthält die Ausgabe Fehlerhinweise?
$hatFehler = $output -match "Error|error in|konnte nicht|es gibt kein Paket"
if ($hatFehler) {
"Status: FEHLER" | Out-File -FilePath $logFile -Append
$fehlgeschlagen += $folder
} else {
"Status: OK" | Out-File -FilePath $logFile -Append
$erfolgreich += $folder
}
}
"Ende: $(Get-Date)" | Out-File -FilePath $logFile -Append
# Zusammenfassung
Write-Host ""
Write-Host "===== Zusammenfassung ====="
Write-Host "Gesamt: $($appFolders.Count)"
Write-Host "Erfolgreich: $($erfolgreich.Count)"
Write-Host "Fehlgeschlagen: $($fehlgeschlagen.Count)"
if ($fehlgeschlagen.Count -gt 0) {
Write-Host ""
Write-Host "Fehlgeschlagene Ordner:"
$fehlgeschlagen | ForEach-Object { Write-Host " - $_" }
}
"===== Zusammenfassung =====" | Out-File -FilePath $logFile -Append
"Gesamt: $($appFolders.Count)" | Out-File -FilePath $logFile -Append
"Erfolgreich: $($erfolgreich.Count)" | Out-File -FilePath $logFile -Append
"Fehlgeschlagen: $($fehlgeschlagen.Count)" | Out-File -FilePath $logFile -Append
$fehlgeschlagen | Out-File -FilePath $logFile -Append
Write-Host ""
Write-Host "Fertig. Log unter: $logFile"

Some files were not shown because too many files have changed in this diff Show more