#!/usr/bin/env python3 import requests import json import re with open('states.json') as f: states = json.loads(f.read()) with open("query.graphql") as f: QUERY = f.read() data = {} for state, baseURL in states.items(): PAYLOAD = [ { "query": QUERY, "variables": { "input": { # Cover the whole state (this is pretty overkill, admittedly) "north":90, "south":0, "east":0, "west":-179, "zoom":12, "layerSlugs": ["normalCameras"], "nonClusterableUris": ["dashboard"], }, "plowType":"plowCameras", }, }, ] res = requests.post(f'{baseURL}api/graphql', json=PAYLOAD) res.raise_for_status() camera_views = res.json()[0]['data']['mapFeaturesQuery']['mapFeatures'] cameras = [] viewCount = 0 for c in camera_views: if len(c['features']) != 1: print(c) raise Exception(f"Unexpected number of features: {len(c['features'])}") if re.match(r"Show .* cameras", c['tooltip']): raise Exception(f"Not zoomed in enough! Finding aggregate cameras: {c}") for view in c['views']: if len(view['sources']) != 1 if view['category'] == 'VIDEO' else 0: print(view) raise Exception(f"Unexpected number of sources ({len(view['sources'])})") for source in view['sources'] or []: if source['type'] != 'application/x-mpegURL': raise Exception(f"Unexpected type {source['type']}") viewCount += len(c['views']) cameras.append({ "type": "Feature", "geometry": c['features'][0]['geometry'], "properties": { 'address': c['tooltip'], 'website': c['views'][0]['url'], 'originalData': c, }, }) geojson = { "type": "FeatureCollection", "features": cameras, } with open(f"data/{state}.geojson", "w") as f: f.write(json.dumps(geojson)) print(f"{len(cameras)} locations found for {state}") print(f"{viewCount} total views for {state}") # hack hack hack # # If I write this to one big file, I can't take advantage of any lazy loading # for performance reasons, so I'm constrained to having a bunch of files. I # can't programmatically import those, since es6 imports don't allow for that. # So, codegen it is (and fairly gross codegen at that!). with open('data/states.js', 'w') as f: for state in states: f.write(f"import {state} from './{state}.geojson?url';\n") f.write('\nexport default {\n') for state in states: f.write(f" {state}: {state},\n") f.write("};\n")