Files

66 lines
4.2 KiB
Python

import json,zipfile,pathlib,collections,re,posixpath,hashlib
repo=pathlib.Path(__file__).resolve().parents[1];b=repo/'tools/demo-source';out=repo/'release';out.mkdir(exist_ok=True)
z=zipfile.ZipFile(b/'original-demo.zip');meta=json.loads(z.read('!!!meta.json'));old=json.loads((b/'scoped/notes.json').read_text(encoding='utf-8'));edges=json.loads((b/'demo-edges.json').read_text());byold={n['noteId']:n for n in old};parents=collections.defaultdict(set)
for n,p in edges:parents[n].add(p)
root='lq5FhqEInunb';archive={};apaths=collections.defaultdict(set);afiles={}
def walk(nodes,parent='',titles=()):
for n in nodes:
if 'title' not in n:continue
ident=n['noteId'];seq=titles+(n['title'],)
if not n.get('isClone'):
archive[ident]=n
if n.get('dataFileName'):afiles[ident]=posixpath.join(parent,n['dataFileName'])
apaths[ident].add(seq)
walk(n.get('children',[]),posixpath.join(parent,n.get('dirFileName','')),seq)
walk(meta['files'])
def sourcepaths(n,seen=frozenset()):
if n==root:return {('root','Trilium Demo')}
if n in seen:return set()
return {p+(byold[n]['title'],) for parent in parents[n] for p in sourcepaths(parent,seen|{n})}
mapping={};ambiguities=[]
for n in old:
candidates=[i for i,a in archive.items() if (a.get('title'),a.get('type'),a.get('mime'))==(n['title'],n['type'],n['mime'])]
if n['noteId']==root:candidates=[i for i,a in archive.items() if a.get('title')=='Trilium Demo']
if len(candidates)>1:candidates=[i for i in candidates if apaths[i]&sourcepaths(n['noteId'])]
if len(candidates)!=1:ambiguities.append((n['noteId'],n['title'],candidates))
else:mapping[n['noteId']]=candidates[0]
assert not ambiguities,ambiguities
assert len(set(mapping.values()))==170
changes={c['noteId']:c for c in json.loads((b/'release/demo-migration.json').read_text(encoding='utf-8'))['changes']}
for c in json.loads((b/'phase4/korean-phase4-pending.json').read_text(encoding='utf-8'))['changes']:changes[c['noteId']]={**changes.get(c['noteId'],{}),**c}
files={n:z.read(n) for n in z.namelist() if not n.endswith('/')};count=0
for oldid,newid in mapping.items():
a=archive[newid];n=byold[oldid];c=changes.get(oldid)
if not c:continue
a['title']=c['title'];count+=1
if 'content' not in c:continue
content=c['content'];filename=afiles[newid]
if a.get('type')=='text' or a.get('mime')=='text/html':
original=files[filename].decode('utf-8');oldsrc=re.findall(r'\bsrc="([^"]+)"',n.get('content') or '');newsrc=re.findall(r'\bsrc="([^"]+)"',original)
if oldsrc and len(oldsrc)==len(newsrc):
for x,y in zip(oldsrc,newsrc):content=content.replace('src="'+x+'"','src="'+y+'"')
def link(m):
target=m.group(1).split('/')[-1]
if target in mapping and mapping[target] in afiles:return 'href="'+posixpath.relpath(afiles[mapping[target]],posixpath.dirname(filename))+'"'
return m.group(0)
content=re.sub(r'href="#root/([^"#?]+)"',link,content)
for x,y in mapping.items():content=content.replace(x,y)
files[filename]=content.encode('utf-8')
phase4=json.loads((b/'phase4/korean-phase4-pending.json').read_text(encoding='utf-8'))
for c in phase4['attributes']:
for a in archive[mapping[c['noteId']]].get('attributes',[]):
if a['name']==c['name']:a['value']=c['value']
def prefixes(nodes):
for n in nodes:
if n.get('prefix') in ['TODO','DONE','28. 11. 2017']:n['prefix']={'TODO':'할 일','DONE':'완료','28. 11. 2017':'2017년 11월 28일'}[n['prefix']]
prefixes(n.get('children',[]))
prefixes(meta['files'])
for a in archive.values():
if a.get('title')=='root':a['title']='내 노트'
if a.get('title')=='Journal':a['title']='일지'
pdfid=mapping['swKGGdlek7o6'];files[afiles[pdfid]]=(b/'phase5/마지막-질문-한국어.pdf').read_bytes() if (b/'phase5/마지막-질문-한국어.pdf').exists() else next((b/'phase5').glob('*.pdf')).read_bytes()
files['!!!meta.json']=json.dumps(meta,ensure_ascii=False,indent=2).encode('utf-8')
with zipfile.ZipFile(out/'demo-ko.zip','w',zipfile.ZIP_DEFLATED) as dest:
for info in z.infolist():dest.writestr(info,b'' if info.is_dir() else files[info.filename])
(out/'demo-map.json').write_text(json.dumps(mapping,indent=2),encoding='utf-8');print(json.dumps({'mappedNotes':len(mapping),'translatedNotes':count,'archiveFiles':len(files),'sha256':hashlib.sha256((out/'demo-ko.zip').read_bytes()).hexdigest()}))