Files
SHiNE-server/tools/test-publisher/v2/prepare/prepare_queue.py
T

42 lines
2.5 KiB
Python

#!/usr/bin/env python3
import argparse,json,hashlib,mimetypes,sys,time
from pathlib import Path
import requests
try:
import arweave
except ImportError:
arweave=None
def atomic(path,obj):
p=Path(path); t=p.with_suffix(p.suffix+'.tmp'); t.write_text(json.dumps(obj,ensure_ascii=False,indent=2),encoding='utf8'); t.replace(p)
def main():
ap=argparse.ArgumentParser(description='Upload all queue images to Arweave and build prepared queue')
ap.add_argument('--config',default='prepare.config.json'); a=ap.parse_args()
cfg=json.load(open(a.config,encoding='utf8')); base=Path(a.config).resolve().parent
def rp(s):
p=Path(s); return p if p.is_absolute() else (base/p).resolve()
rawp=rp(cfg['queue_file']); outp=rp(cfg['prepared_queue_file']); walletp=rp(cfg['arweave']['wallet_file']); gateway=cfg['arweave'].get('gateway','https://arweave.net').rstrip('/')
statep=rp(cfg.get('upload_state_file','upload-state.json')); state=json.loads(statep.read_text()) if statep.exists() else {'files':{}}
if arweave is None: raise SystemExit('Install requirements first: pip install -r requirements.txt')
wallet=arweave.Wallet(str(walletp))
items=json.loads(rawp.read_text(encoding='utf8')); prepared=[]
for n,item in enumerate(items,1):
urls=[]; ids=[]
for rel in item.get('images',[]):
fp=(rawp.parent/rel).resolve(); data=fp.read_bytes(); sha=hashlib.sha256(data).hexdigest(); old=state['files'].get(sha)
if old: txid=old['id']; print(f'[{n}] cached {fp.name} -> {txid}')
else:
ctype=mimetypes.guess_type(fp.name)[0] or 'application/octet-stream'
tx=arweave.Transaction(wallet, data=data); tx.add_tag('Content-Type',ctype); tx.add_tag('App-Name','SHiNE-Test-Publisher'); tx.add_tag('SHA-256',sha); tx.sign(); tx.send(); txid=tx.id
state['files'][sha]={'id':txid,'file':fp.name,'uploaded_at':int(time.time())}; atomic(statep,state); print(f'[{n}] uploaded {fp.name} -> {txid}')
ids.append(txid); urls.append(f'{gateway}/{txid}')
text=item['text'].rstrip()
if urls:
# Current SHiNE POST payload is text, so URLs are appended as ordinary lines.
text += '\n\n' + '\n'.join(urls)
prepared.append({'id':item.get('id',str(n)),'text':text,'images':[{'arweave_id':i,'url':u} for i,u in zip(ids,urls)]})
atomic(outp,prepared)
print(f'Ready: {outp} ({len(prepared)} posts)')
if __name__=='__main__': main()