# Ashwin V
# Build Your Own Co-WIN Vaccine Slot Notifier in less than 30 min (Instructable)
# June 2021

############################################################################
# '400004' or '400703'
PINCODE = '160009'

# '12-6-2021' or 'NA'
DATE = 'NA'

# 'available_capacity_dose1' or 'available_capacity_dose2'
DOSE_OPTION = 'available_capacity_dose1'

# '18' or '45'
AGE = '18'

# 'Free' or 'Paid' or 'NA'
FEE = 'Free'

# Add the vaccine names you want to search or leave it []
VACCINE_OPTIONS = ['COVISHIELD', 'COVAXIN' , 'SPUTNIKV']
#VACCINE_OPTIONS = []

# Search interval
# Can only make 100 queries to COWIN servers in 5 minutes (government restrictions) [3 seconds interval makes roughly 90 to 100 calls in 5 Minutes]
SER_INT = 3.1
############################################################################



#The program uses these modules during execution so we are importing them
from urllib.request import urlopen, Request #for making a request COWIN server
import json #for reading the JSON response from Telegram server
from datetime import datetime #for getting current time
import pytz #for getting current time (timezone)
import time #for creating a delay
import os #for getting current directory path

#For QPython
from androidhelper import Android     #$$$
droid = Android()                     #$$$


###-------------------------CoWIN section------------------------------------------
global KEEP_SEARCHING
KEEP_SEARCHING = True # flag which will be made False inside CowinSearch() when a slot if found
counter = 0

def CowinSearch():
    global counter
    
    # get the date
    DATE_TEMP = ''
    if DATE == 'NA':
        IST = pytz.timezone('Asia/Kolkata')
        datetime_ist = datetime.now(IST)
        DATE_TEMP = datetime_ist.strftime('%d-%m-%Y')
    else:
        DATE_TEMP = DATE #if date was already mentioned, use that

    print("Date: " + str(DATE_TEMP) + '\nNumber of retries: ' + str(counter) + '\n---------------------')
    counter += 1 # increment the counter

    finalUrl = (f"https://cdn-api.co-vin.in/api/v2/appointment/sessions/public/findByPin?pincode={PINCODE}&date={DATE_TEMP}") #API link created

    #some high level stuff....
    req = Request(finalUrl, headers={'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'})
    response = urlopen(req)
    data_json = json.loads(response.read())
    dataRaw = "{'sessions': []}"
    #print(f"The data received from the server is \n\n {data_json} \n")

    if str(data_json) == dataRaw:
        # no slots
        print('No slots found!\n---------------------')
    else:
        for center in data_json['sessions']:
            outputText =  str(center[DOSE_OPTION]) # dose count check
            if int(outputText) > 0:
                print('Number of slots: ' + outputText)

                if AGE == str(center['min_age_limit']): # check age
                    print('Age filter passed')
                    
                    if  (FEE == str(center['fee_type']) or FEE == 'NA'): # check fee
                        print('Fee filter passed')

                        if (str(center['vaccine']) in VACCINE_OPTIONS or VACCINE_OPTIONS == []): # check if vaccine is there in the list
                            print('Vaccine filter passed\nFound slot!\n')

                            #----------------Print slot info---------------------
                            fnd_info = str(json.dumps(center))
                            temp = fnd_info.translate(str.maketrans(
                                {',': '\n',
                                 '"': '',
                                 '[': '\n',
                                 ']': '',
                                 '{': '',
                                 '{': ''})) # remove JSON characters
                            print(temp + '\n---------------------')
                            #----------------------------------------------------
                            

                            #-------------Create Android status bar notification--------------------
                            droid.notify(center['name'],'Slot found!')    #$$$
                            
                            global KEEP_SEARCHING
                            KEEP_SEARCHING = False # flag made false
                            
                        else:
                            print('Could not pass Vaccine filter\n---------------------')
                    else:
                        print('Could not pass Fee filter\n---------------------')
                else:
                    print('Could not pass Age filter\n---------------------')
            else:
                print('0 slots\n---------------------')

while KEEP_SEARCHING: #keeps looping every SER_INT seconds untill KEEP_SEARCHING is made False
    
    time.sleep(SER_INT) # wait
    
    CowinSearch() # call the funtion and check for slots

droid.mediaPlay(os.getcwd() + '/scripts3/sound.wav', play=True) #play sound.wav file on Android   #$$$

for vib_times in range (4): #vibrates for 6 seconds and create toast notification on Android

    #-------------Create Android Toast notification----------------
    droid.makeToast('Slot found!')                                             #$$$
    #--------------------------------------------------------------

    droid.vibrate(1000) # vibrate for 1 second                                 #$$$
    time.sleep(1.5)# wait 1.5 second                                           #$$$
    
    pass

print('Exit')
