"""Fetch frozen published photometry directly from its origin; no site mirror.""" from pathlib import Path import argparse import hashlib import json import urllib.parse import urllib.request parser = argparse.ArgumentParser(description=__doc__) parser.add_argument('--manifest', type=Path, default=Path(__file__).with_name('observation-sources.json')) parser.add_argument('--output', type=Path, required=True) arguments = parser.parse_args() manifest = json.loads(arguments.manifest.read_text()) user_agent = 'SandboxPhysics-Public-Tutorial/1.0' assert manifest['ua'] == user_agent arguments.output.mkdir(parents=True, exist_ok=True) receipt = {'scope': 'Actual anonymous HTTP origin fetches or separately identified verified cache; no production SandboxPhysics delivery claimed.', 'userAgent': user_agent, 'files': []} for item in manifest['files']: name = item['name'] if Path(name).name != name: raise ValueError('Non-flat scientific filename') url = urllib.parse.urlsplit(item['url']) if url.scheme != 'https' or url.hostname != 'ogle.astrouw.edu.pl' or not url.path.startswith('/cont/4_main/epl/blg390/'): raise ValueError('Only the five frozen published project files may be fetched') destination = arguments.output / name if destination.exists(): data = destination.read_bytes() mode = 'verified local cache; no HTTP' status = None else: request = urllib.request.Request(item['url'], headers={'User-Agent': user_agent}) with urllib.request.urlopen(request, timeout=30) as response: if response.status != 200 or response.headers.get_content_type() != item['mediaType']: raise ValueError('Unexpected scientific response status or MIME type') data = response.read(item['bytes'] + 1) status = response.status mode = 'anonymous origin HTTP' if len(data) != item['bytes'] or hashlib.sha256(data).hexdigest() != item['sha256']: raise ValueError('Origin data changed; refuse silently updated scientific input: ' + name) if not destination.exists(): destination.write_bytes(data) receipt['files'].append({'name': name, 'url': item['url'], 'mode': mode, 'status': status, 'bytes': len(data), 'sha256': item['sha256']}) (arguments.output / 'download-receipt.json').write_text(json.dumps(receipt, indent=2) + '\n') print('PASS:', len(receipt['files']), 'frozen files verified;', ', '.join(sorted(set(item['mode'] for item in receipt['files']))))