Files
janssen/trilium_upload_file_v1.0.py
administrator 8c01fd6e1a Pridani novych skriptu, reportu a zpracovanych dat
- EmailsImport: jnj_mailbox_sync_v1.0 (sync JNJ schranky)
- Covance: create_lab_results_report_v1.0 + zpracovane CSV (samples/kits/equeries/test-results), browser profily
- Feasibility UCO2001: store_cda_*, store_sipiq_links, classify_krok, mark_sipiq_sent, report v1.1 (stary report do TRASH)
- IWRS/Drugs: pregenerovane onsite inventory / shipment reporty
- TrilliumMCP server + trilium upload/diacritics skripty
- .mcp.json

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 15:10:21 +02:00

81 lines
2.9 KiB
Python

# -*- coding: utf-8 -*-
"""
trilium_upload_file_v1.0.py
Verze: 1.0 | Datum: 2026-06-09
Popis: Nahraje libovolný soubor do Trilia (ETAPI) jako samostatnou poznámku
typu "file" pod zadaný rodič (default složka Claude). Ověří shodu
přes SHA-256 (lokál vs. uložený obsah).
Použití: python trilium_upload_file_v1.0.py "<cesta_k_souboru>" [parentNoteId]
"""
import sys, os, json, hashlib, mimetypes, urllib.request, io
# konzole na Windows (cp1250) neumi nektere znaky -> vynutime UTF-8 vystup
try:
sys.stdout.reconfigure(encoding="utf-8")
except Exception:
pass
BASE = "https://trilium.buzalka.cz/etapi"
TOKEN = "WoPH9O8hn2y6_r6pQSjpOVSmuL0os2hIQsLBHDOawebOx8l+MUc8v+GE="
DEFAULT_PARENT = "NeoXOIw0uBK2" # slozka Claude
def req(method, path, data=None, ctype="application/json; charset=utf-8", raw=False):
body = None
if data is not None:
body = data if isinstance(data, (bytes, bytearray)) else json.dumps(data, ensure_ascii=False).encode("utf-8")
r = urllib.request.Request(BASE + path, data=body, method=method)
r.add_header("Authorization", TOKEN)
if body is not None:
r.add_header("Content-Type", ctype)
try:
with urllib.request.urlopen(r) as resp:
out = resp.read()
if raw:
return out
txt = out.decode("utf-8")
return json.loads(txt) if txt.strip().startswith(("{", "[")) else txt
except urllib.error.HTTPError as e:
print(f" HTTP {e.code} {method} {path}: {e.read().decode('utf-8','replace')}")
raise
def main():
path = sys.argv[1]
parent = sys.argv[2] if len(sys.argv) > 2 else DEFAULT_PARENT
fname = os.path.basename(path)
blob = open(path, "rb").read()
mime = mimetypes.guess_type(fname)[0] or "application/octet-stream"
sha_local = hashlib.sha256(blob).hexdigest()
# 1) vytvor poznamku typu file (prazdny obsah)
note = req("POST", "/create-note", {
"parentNoteId": parent, "title": fname, "type": "file",
"mime": mime, "content": "",
})["note"]
nid = note["noteId"]
# 2) nahraj binarni obsah
req("PUT", f"/notes/{nid}/content", bytes(blob), ctype="application/octet-stream")
# 3) originalFileName label (spravne stahovani pod nazvem)
req("POST", "/attributes", {
"noteId": nid, "type": "label", "name": "originalFileName",
"value": fname, "isInheritable": False,
})
# 4) overeni
back = req("GET", f"/notes/{nid}/content", raw=True)
sha_remote = hashlib.sha256(back).hexdigest()
ok = (sha_local == sha_remote)
print(f"noteId: {nid}")
print(f"název: {fname}")
print(f"mime: {mime}")
print(f"lokál: {len(blob)} B sha256={sha_local[:16]}")
print(f"server: {len(back)} B sha256={sha_remote[:16]}")
print("OVĚŘENÍ: SHODA OK" if ok else "OVĚŘENÍ: NESHODA!")
if __name__ == "__main__":
main()