Files
999/scripts/import_user_edits.py
T

165 lines
5.6 KiB
Python
Executable File

#!/usr/bin/env python3
"""
scripts/import_user_edits.py
Imports custom edits made on a mobile device (exported from Oracle 999 app)
into the desktop repository:
- Updates the respective dossiers in oracle_enricher/out/dossiers/
- Updates oracle_enricher/out/oracle_kb.json
- Automatically regenerates assets/data/oracle_kb.json via sync_kb_asset.py
- Preserves git traceability with timestamps and user_edited flags
Usage:
# From a file:
python3 scripts/import_user_edits.py edits.json
# Interactive paste:
python3 scripts/import_user_edits.py
"""
import sys
import json
import subprocess
from pathlib import Path
from datetime import datetime, timezone
ROOT = Path(__file__).resolve().parent.parent
ENRICHER = ROOT / 'oracle_enricher'
DOSSIERS_DIR = ENRICHER / 'out' / 'dossiers'
KB_FILE = ENRICHER / 'out' / 'oracle_kb.json'
SYNC_SCRIPT = ROOT / 'scripts' / 'sync_kb_asset.py'
def load_input_json():
if len(sys.argv) > 1 and sys.argv[1] not in ('-', '--stdin'):
p = Path(sys.argv[1])
if not p.exists():
print(f"Error: File not found: {p}")
sys.exit(1)
return json.loads(p.read_text(encoding='utf-8'))
if not sys.stdin.isatty():
return json.loads(sys.stdin.read())
print("=== Импорт пользовательских правок из Оракула 999 ===")
print("Вставьте JSON с телефона (скопированный через кнопку 'Скопировать JSON правок')")
print("После вставки введите строку с 'EOF' или нажмите Ctrl+D:")
lines = []
try:
while True:
line = input()
if line.strip() == 'EOF':
break
lines.append(line)
except EOFError:
pass
raw = '\n'.join(lines).strip()
if not raw:
print("Отмена: входные данные пусты.")
sys.exit(0)
return json.loads(raw)
def main():
data = load_input_json()
if not isinstance(data, dict):
print("Ошибка: ожидался словарь вида { 'слово': { ... } }")
sys.exit(1)
print(f"Найдено правок для импорта: {len(data)} слов")
# Index existing dossiers
word_to_dossier = {}
if DOSSIERS_DIR.exists():
for p in DOSSIERS_DIR.glob('*.json'):
try:
d = json.loads(p.read_text(encoding='utf-8'))
w = d.get('word')
if w:
word_to_dossier[w.lower().strip()] = p
except Exception:
pass
kb = json.loads(KB_FILE.read_text(encoding='utf-8')) if KB_FILE.exists() else {}
now_iso = datetime.now(timezone.utc).isoformat()
updated_words = []
for raw_word, edits in data.items():
w = raw_word.lower().strip()
if not isinstance(edits, dict):
continue
core = edits.get('core', '').strip()
oracle = edits.get('oracle', '').strip()
shadow = edits.get('shadow', '').strip()
asks = edits.get('asks', '').strip()
step = edits.get('step', '').strip()
# 1. Update dossier if exists
p = word_to_dossier.get(w)
if p and p.exists():
try:
dossier = json.loads(p.read_text(encoding='utf-8'))
except Exception:
dossier = {'word': w}
else:
p = DOSSIERS_DIR / f"{w}.json"
dossier = {'word': w}
if 'canon' not in dossier or not isinstance(dossier['canon'], dict):
dossier['canon'] = {'word': w}
canon = dossier['canon']
if core:
canon['core'] = core
if oracle:
canon['oracle'] = oracle
if shadow:
canon['shadow'] = shadow
if asks:
canon['asks'] = asks
if step:
canon['step'] = step
canon['user_edited'] = True
canon['via'] = 'user_edit'
canon['updated_at'] = edits.get('updatedAt') or now_iso
p.parent.mkdir(parents=True, exist_ok=True)
p.write_text(json.dumps(dossier, ensure_ascii=False, indent=2), encoding='utf-8')
# 2. Update oracle_kb.json
if w not in kb or not isinstance(kb[w], dict):
kb[w] = canon
else:
kb[w].update({
'core': canon.get('core', ''),
'oracle': canon.get('oracle', ''),
'shadow': canon.get('shadow', ''),
'asks': canon.get('asks', ''),
'step': canon.get('step', ''),
'user_edited': True,
'via': 'user_edit',
'updated_at': canon.get('updated_at'),
})
updated_words.append(w)
KB_FILE.parent.mkdir(parents=True, exist_ok=True)
KB_FILE.write_text(json.dumps(kb, ensure_ascii=False, indent=2), encoding='utf-8')
print(f"Обновлено досье и KB для {len(updated_words)} слов: {', '.join(updated_words[:10])}{'...' if len(updated_words) > 10 else ''}")
# 3. Synchronize assets/data/oracle_kb.json
print("Синхронизация assets/data/oracle_kb.json...")
subprocess.run([sys.executable, str(SYNC_SCRIPT)], check=True)
print("\n✅ УСПЕШНО! Все правки зафиксированы в кодовой базе.")
print("Теперь они станут частью базового канона во всех будущих релизах приложения.")
print("Чтобы закоммитить в git:")
print(" git add oracle_enricher/ assets/data/oracle_kb.json")
print(" git commit -m 'feat: import user canon edits from mobile app'")
if __name__ == '__main__':
main()