Files
metavox-loadtest/templates/setup_metadata_fields.py.j2
Sam428-png a1eda430c8 Initial commit: MetaVox loadtest playbook
Ansible playbook voor het opzetten van een MetaVox loadtest omgeving:
- 50 teamfolders met 10.000 bestanden elk (500K totaal)
- 100 metadata velddefinities (10 teamfolder + 90 file-level)
- 3-niveau mappenstructuur (10 hoofdmappen x 3 submappen)
- ~43M metadata records via directe MySQL inserts
- Geoptimaliseerde database indexes (7 redundante indexes gedropt)

Gebruikt directe filesystem writes en MySQL inserts i.p.v. WebDAV/API
voor maximale performance.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 16:55:30 +01:00

192 lines
6.3 KiB
Django/Jinja

#!/usr/bin/env python3
"""
MetaVox Metadata Velden Setup Script
=====================================
Maakt teamfolder-velden en file-metadata-velden aan via de MetaVox OCS API.
POST /ocs/v2.php/apps/metavox/api/v1/groupfolder-fields
Payload: field_name, field_label, field_type, field_description,
field_options (array), is_required, sort_order,
applies_to_groupfolder (1=teamfolder metadata, 0=file metadata)
POST /ocs/v2.php/apps/metavox/api/v1/groupfolders/{id}/fields
Payload: field_ids (array) - wijst velden toe aan een specifieke groupfolder
"""
import json
import sys
import time
import requests
from requests.auth import HTTPBasicAuth
NC_URL = "{{ nextcloud_url }}"
NC_USER = "{{ nextcloud_admin_user }}"
NC_PASS = "{{ nextcloud_admin_password }}"
TIMEOUT = {{ http_timeout }}
MAX_RETRIES = {{ max_retries }}
OCS_BASE = f"{NC_URL}/ocs/v2.php/apps/metavox/api/v1"
AUTH = HTTPBasicAuth(NC_USER, NC_PASS)
HEADERS = {
"OCS-APIRequest": "true",
"Accept": "application/json",
"Content-Type": "application/json",
}
def api_request(method, url, data=None, retries=MAX_RETRIES):
for attempt in range(retries):
try:
resp = requests.request(
method, url, auth=AUTH, headers=HEADERS,
json=data, timeout=TIMEOUT,
)
if resp.status_code in [200, 201]:
return resp
elif resp.status_code == 500 and "already exists" in resp.text:
print(f" [SKIP] Veld bestaat al")
return resp
else:
print(f" [WARN] HTTP {resp.status_code}: {resp.text[:200]}")
if attempt < retries - 1:
time.sleep(2 ** attempt)
return resp
except requests.exceptions.RequestException as e:
print(f" [ERROR] Poging {attempt+1}/{retries}: {e}")
if attempt < retries - 1:
time.sleep(2 ** attempt)
else:
raise
return None
def create_field(field, applies_to_groupfolder):
options = field.get("options", "")
if isinstance(options, str) and options:
options = [o.strip() for o in options.split(",")]
elif not isinstance(options, list):
options = []
payload = {
"field_name": field["name"],
"field_label": field.get("description", field["name"]),
"field_type": field["type"],
"field_description": field.get("description", ""),
"field_options": options,
"is_required": False,
"sort_order": 0,
"applies_to_groupfolder": applies_to_groupfolder,
}
url = f"{OCS_BASE}/groupfolder-fields"
return api_request("POST", url, payload)
def assign_fields_to_groupfolder(groupfolder_id, field_ids):
url = f"{OCS_BASE}/groupfolders/{groupfolder_id}/fields"
return api_request("POST", url, {"field_ids": field_ids})
def get_existing_fields():
url = f"{OCS_BASE}/groupfolder-fields"
resp = api_request("GET", url)
if resp and resp.status_code == 200:
try:
data = resp.json()
if "ocs" in data and "data" in data["ocs"]:
return data["ocs"]["data"]
except Exception:
pass
return []
def get_groupfolders():
url = f"{OCS_BASE}/groupfolders"
resp = api_request("GET", url)
if resp and resp.status_code == 200:
try:
data = resp.json()
if "ocs" in data and "data" in data["ocs"]:
return data["ocs"]["data"]
except Exception:
pass
return []
def main():
print("=" * 60)
print("MetaVox Metadata Velden Setup (OCS API)")
print(f"Endpoint: {OCS_BASE}/groupfolder-fields")
print("=" * 60)
created_field_ids = []
# ---- Teamfolder metadata-velden (applies_to_groupfolder=1) ----
tf_fields = json.loads("""{{ teamfolder_metadata_fields | to_json }}""")
print(f"\n[1/3] {len(tf_fields)} teamfolder-velden (applies_to_groupfolder=1)...")
tf_created = 0
for field in tf_fields:
print(f" Aanmaken: {field['name']} ({field['type']})")
resp = create_field(field, applies_to_groupfolder=1)
if resp and resp.status_code in [200, 201]:
tf_created += 1
try:
fid = resp.json().get("ocs", {}).get("data", {}).get("id")
if fid:
created_field_ids.append(fid)
except Exception:
pass
print(f" -> {tf_created} teamfolder-velden created")
# ---- File metadata-velden (applies_to_groupfolder=0) ----
file_fields = json.loads("""{{ file_metadata_fields | to_json }}""")
print(f"\n[2/3] {len(file_fields)} file-velden (applies_to_groupfolder=0)...")
f_created = 0
for field in file_fields:
print(f" Aanmaken: {field['name']} ({field['type']})")
resp = create_field(field, applies_to_groupfolder=0)
if resp and resp.status_code in [200, 201]:
f_created += 1
try:
fid = resp.json().get("ocs", {}).get("data", {}).get("id")
if fid:
created_field_ids.append(fid)
except Exception:
pass
print(f" -> {f_created} file-velden created")
# ---- Wijs alle velden toe aan alle groupfolders ----
print(f"\n[3/3] Velden toewijzen aan groupfolders...")
all_fields = get_existing_fields()
all_field_ids = [f["id"] for f in all_fields if "id" in f]
if not all_field_ids:
all_field_ids = created_field_ids
if all_field_ids:
groupfolders = get_groupfolders()
gf_count = 0
for gf in groupfolders:
gf_id = gf.get("id") or gf.get("group_folder_id")
if gf_id:
resp = assign_fields_to_groupfolder(gf_id, all_field_ids)
if resp and resp.status_code == 200:
gf_count += 1
if gf_count % 10 == 0 and gf_count > 0:
print(f" {gf_count} groupfolders verwerkt...")
print(f" -> {gf_count} groupfolders hebben nu alle velden")
else:
print(" [WARN] Geen field IDs beschikbaar")
total = tf_created + f_created
print(f"\n{'=' * 60}")
print(f"Totaal: {total} metadata-velden created")
print(f"{'=' * 60}")
if __name__ == "__main__":
main()