|
#!/usr/bin/python3 |
|
# -*- coding: utf-8 -*- |
|
|
|
import sys |
|
import os |
|
import time |
|
import json |
|
import random |
|
from urllib import request, parse |
|
from seleniumwire import webdriver |
|
from selenium.webdriver.chrome.options import Options as ChromeOptions |
|
|
|
if len(sys.argv) < 3: |
|
print('Usage: python3 vaccine.py <zipcode> <threshold in miles>') |
|
exit(1) |
|
|
|
ZIPCODE = sys.argv[1] |
|
THRESHOLD_IN_MILES = int(sys.argv[2]) |
|
|
|
INTERVAL = 30 |
|
DOB = '1990-01-01' |
|
|
|
|
|
def run_prescreen(): |
|
url = 'https://am-i-eligible.covid19vaccine.health.ny.gov/api/submit' |
|
data = { |
|
'person': { |
|
'acknowledge': 'true', |
|
'address': { |
|
'zip': ZIPCODE |
|
}, |
|
'zip': ZIPCODE, |
|
'dob': DOB, |
|
'name': "", |
|
'nyresident': "Y", |
|
'nyworker': "Y", |
|
}, |
|
} |
|
req = request.Request(url, data=parse.urlencode(data).encode()) |
|
|
|
resp = request.urlopen(req) |
|
body = resp.read().decode('utf-8') |
|
applicationId = json.loads(body)['applicationId'] |
|
|
|
return applicationId |
|
|
|
|
|
def get_distance(s): return float(s['address']['distanceInMiles']) |
|
|
|
|
|
def get_address_string(s): |
|
address = s['address'] |
|
address_parts = [ |
|
address['line1'], |
|
address['city'], |
|
address['state'], |
|
str(address['zipcode']), |
|
] |
|
return ', '.join([s.strip() for s in address_parts]) |
|
|
|
|
|
def is_available(s): |
|
return s['availableAppointments'] == 'AA' |
|
|
|
|
|
def print_success_message(site): |
|
print("\n".join([ |
|
"π¨ π¨ π¨ π¨ π¨", |
|
f"Vaccines available {get_distance(site)} miles away!", |
|
site['providerName'], |
|
get_address_string(site), |
|
'', |
|
'Opening headless Chrome...', |
|
'', |
|
])) |
|
|
|
|
|
def print_failure_message(site): |
|
dist = get_distance(site) |
|
emojis = ["π", "π", "π ", "π©", "π", "π₯", "π"] |
|
emoji = emojis[random.randint(0, len(emojis) - 1)] |
|
|
|
print(f"{emoji} nearest vaccine appointments are {dist} miles away") |
|
print(f"(Waiting {INTERVAL}s to try again.)") |
|
print("") |
|
|
|
|
|
def check_for_vaccines(applicationId): |
|
url = 'https://am-i-eligible.covid19vaccine.health.ny.gov/api/get-providers' |
|
data = { |
|
'address': ZIPCODE, |
|
'applicationId': applicationId, |
|
'dob': DOB, |
|
'miles': 100, |
|
} |
|
req = request.Request(url, data=parse.urlencode(data).encode()) |
|
|
|
resp = request.urlopen(req) |
|
body = resp.read().decode('utf-8') |
|
vaccine_sites = json.loads(body) |
|
|
|
sites_with_appointments = filter(is_available, vaccine_sites) |
|
sorted_by_distance = sorted(sites_with_appointments, key=get_distance) |
|
nearest_site = sorted_by_distance[0] |
|
|
|
if get_distance(nearest_site) < THRESHOLD_IN_MILES: |
|
print_success_message(nearest_site) |
|
return nearest_site['3rdPartyURL'] |
|
|
|
print_failure_message(nearest_site) |
|
|
|
|
|
def open_page_with_referer(url): |
|
def interceptor(request): |
|
request.headers['Referer'] = 'https://am-i-eligible.covid19vaccine.health.ny.gov/' |
|
|
|
chrome_options = ChromeOptions() |
|
chrome_options.add_argument("--incognito") |
|
chrome_options.add_experimental_option("detach", True) |
|
|
|
# For older ChromeDriver under version 79.0.3945.16 |
|
chrome_options.add_experimental_option( |
|
"excludeSwitches", ["enable-automation"]) |
|
chrome_options.add_experimental_option('useAutomationExtension', False) |
|
|
|
# For ChromeDriver version 79.0.3945.16 or over |
|
chrome_options.add_argument( |
|
'--disable-blink-features=AutomationControlled') |
|
|
|
driver = webdriver.Chrome(chrome_options=chrome_options) |
|
|
|
driver.request_interceptor = interceptor |
|
driver.get(url) |
|
|
|
input("Press Enter when finished in the browser.") |
|
|
|
|
|
def main(): |
|
applicationId = run_prescreen() |
|
|
|
while True: |
|
success_url = check_for_vaccines(applicationId) |
|
if success_url: |
|
open_page_with_referer(success_url) |
|
break |
|
time.sleep(INTERVAL) |
|
|
|
|
|
if __name__ == '__main__': |
|
main() |