Files
triliumnext-korean-patch/updates/2026-09-05/work/trilium/deploy-phase4.py
T

43 lines
3.0 KiB
Python

import pathlib,subprocess,datetime,shutil,time,urllib.request,hashlib,json,sqlite3
base=pathlib.Path('/www/dk_project/dk_app/trilium');release=pathlib.Path('/tmp/trilium-korean-phase4')
manifest=json.loads((release/'manifest.json').read_text());digest=lambda p:hashlib.sha256(p.read_bytes()).hexdigest()
for rel,expected in manifest['files'].items():assert digest(release/rel)==expected,rel
assert digest(base/'patched/main.cjs')==manifest['previousMainSha256'],'Main changed'
pending=base/'data/korean-phase4-pending.json';assert not pending.exists()
backup=base/'backups'/('before-korean-phase4-'+datetime.datetime.now().strftime('%Y%m%d-%H%M%S'));backup.mkdir(parents=True,mode=0o700)
for rel in ['patched/main.cjs','i18n_ko/server.json']:
target=backup/rel;target.parent.mkdir(parents=True,exist_ok=True);shutil.copy2(base/rel,target)
source=sqlite3.connect('file:'+str(base/'data/document.db')+'?mode=ro',uri=True)
with sqlite3.connect(str(backup/'document.db')) as target:source.backup(target)
source.close()
try:
(base/'patched/main.cjs').write_bytes((release/'main.cjs').read_bytes())
(base/'i18n_ko/server.json').write_bytes((release/'server.json').read_bytes())
pending.write_bytes((release/'korean-phase4-pending.json').read_bytes())
subprocess.run(['docker','restart','trilium'],check=True)
for attempt in range(40):
try:
with urllib.request.urlopen('http://127.0.0.1:18082/api/health-check',timeout=2) as response:assert response.status==200
assert not pending.exists(),'Migration pending'
break
except Exception:
if attempt==39:raise
time.sleep(1)
plan=json.loads((release/'korean-phase4-pending.json').read_text())
db=sqlite3.connect('file:'+str(base/'data/document.db')+'?mode=ro',uri=True)
for c in plan['changes']:
result=db.execute('SELECT b.content FROM notes n JOIN blobs b ON b.blobId=n.blobId WHERE n.noteId=?',(c['noteId'],)).fetchone()[0]
if isinstance(result,bytes):result=result.decode('utf8')
assert result==c['content'],c['noteId']
for c in plan['attributes']:assert db.execute('SELECT value FROM attributes WHERE attributeId=?',(c['attributeId'],)).fetchone()[0]==c['value']
for c in plan['branches']:assert db.execute('SELECT prefix FROM branches WHERE branchId=?',(c['branchId'],)).fetchone()[0]==c['prefix']
assert db.execute('SELECT title FROM notes WHERE noteId=?',('_lbMobileRoot',)).fetchone()[0]=='모바일 실행 도구 모음'
db.close()
result={'status':'verified','backup':str(backup),'notes':len(plan['changes']),'attributes':len(plan['attributes']),'branches':len(plan['branches']),'mobileLauncherTitle':'모바일 실행 도구 모음'}
(base/'i18n_ko/phase4-result.json').write_text(json.dumps(result,ensure_ascii=False,indent=2));print(json.dumps(result,ensure_ascii=False))
except Exception:
if pending.exists():pending.rename(backup/'korean-phase4-disabled.json')
for rel in ['patched/main.cjs','i18n_ko/server.json']:(base/rel).write_bytes((backup/rel).read_bytes())
subprocess.run(['docker','restart','trilium'],check=True)
print('Previous application restored. Database backup: '+str(backup));raise