"""Validate relative assets and media hashes; optionally refresh the release index.""" from pathlib import Path import argparse,hashlib,json,re from html.parser import HTMLParser ROOT=Path(__file__).resolve().parents[1] class Links(HTMLParser): def __init__(self):super().__init__();self.links=[];self.ids=[] def handle_starttag(self,tag,attrs): attrs=dict(attrs) if 'id' in attrs:self.ids.append(attrs['id']) for key in ['href','src']: if key in attrs:self.links.append(attrs[key]) def main(): p=argparse.ArgumentParser();p.add_argument('--index',action='store_true');args=p.parse_args() html=(ROOT/'index.html').read_text();parsed=Links();parsed.feed(html) assert len(parsed.ids)==len(set(parsed.ids)),'Duplicate element IDs' for link in parsed.links: if link.startswith(('http:','https:','data:')):continue if link.startswith('#'): assert link=='#' or link[1:] in parsed.ids,link continue assert (ROOT/link).is_file(),link app=(ROOT/'app.js').read_text() for id in re.findall(r"\$\(['\"]#([\w-]+)['\"]\)",app):assert id in parsed.ids,id manifest=json.loads((ROOT/'assets/manifest.json').read_text()) for e in manifest['examples']: assert (ROOT/e['data']).is_file() for source in [e['sourceA'],e['sourceB']]: if source.get('video'):assert(ROOT/source['video']).is_file() if e.get('meshes'):assert (ROOT/e['meshes']).is_file() if e.get('recognition'): r=e['recognition'];assert all(k in r for k in ['dataset','metric','unit','baseline','augmented','source']) assert r['source'].startswith('https://') assert e['frames']>1 and e['previewFps']>0 for archive in manifest['archive']: assert set(archive['clips'])==set(map(str,range(11))) for file in archive['clips'].values():assert(ROOT/file).is_file() for media in json.loads((ROOT/'assets/media-provenance.json').read_text()): b=(ROOT/media['path']).read_bytes();assert hashlib.sha256(b).hexdigest()==media['sha256'],media['path'] records=[] for file in sorted(ROOT.rglob('*')): if not file.is_file() or any(x in file.parts for x in ['.venv','.git','__pycache__']):continue if file.name in ['RELEASE_FILES.json','.DS_Store'] or file.name.endswith('-publish-receipt.json'):continue rel=str(file.relative_to(ROOT));assert not file.name.startswith('.env'),'Secret-like file in release' records.append({'path':rel,'bytes':file.stat().st_size,'sha256':hashlib.sha256(file.read_bytes()).hexdigest()}) if args.index:(ROOT/'RELEASE_FILES.json').write_text(json.dumps(records,indent=2)+'\n') elif (ROOT/'RELEASE_FILES.json').exists():assert records==json.loads((ROOT/'RELEASE_FILES.json').read_text()),'Stale release index' print(f'Validated {len(records)} files, {len(manifest["examples"])} pose examples and {sum(len(x["clips"]) for x in manifest["archive"])} archive clips.') if __name__=='__main__':main()