File size: 3,035 Bytes
f108d90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
"""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()