Skip to content

Commit

Permalink
fixes: 1. added vaccine preference option to search for centres provi…
Browse files Browse the repository at this point in the history
…ding only that particular vaccine

2. minor bug fixes and improvements
  • Loading branch information
divagicha committed Jun 11, 2021
1 parent 66ce67b commit f2c8273
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 121 deletions.
37 changes: 22 additions & 15 deletions CovidVaccineChecker/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,9 @@ def create_new_user_config(self, user_config_file):
f"or 'swami ram, centre name 2', etc.{TextColors.ENDC}")
input("\nPress 'Enter' to get a list of all available centres in your district and then input your centre preference...")
self.getCalendarByDistrict(user_config_file)
print(f"\n{TextColors.BOLD}Note: The above mentioned values for 'Min Age, Available Capacity and Slots' are for one of the sessions "
f"at that centre only. You can still enter a centre's name below as your preference as there might be other sessions as well in "
f"the same centre with different 'Min Age, Available Capacity and Slots' value.{TextColors.ENDC}")
# print(f"\n{TextColors.BOLD}Note: The above mentioned values for 'Min Age, Available Capacity and Slots' are for one of the sessions "
# f"at that centre only. You can still enter a centre's name below as your preference as there might be other sessions as well in "
# f"the same centre with different 'Min Age, Available Capacity and Slots' value.{TextColors.ENDC}")
centre_preferences = input(f"\n-->\tEnter short/full centre name for centre preference "
f"{TextColors.WARNING}(comma-separated in case of multiple), CAN BE BLANK AS WELL{TextColors.ENDC}: ")

Expand Down Expand Up @@ -583,12 +583,13 @@ def getCalendarByDistrict(self, user_config_file):
print(f"\n{TextColors.FAIL}Invalid input!{TextColors.ENDC}")
else:
centres_list = [
{"Name": centre['name'], "District": centre['district_name'], "Pincode": centre['pincode'],
"Vaccine Name": centre['sessions'][0]['vaccine'],
{"Centre Name": centre['name'], "District": centre['district_name'], "Pincode": centre['pincode'],
"Vaccine Available": "\n".join(sorted(set([session['vaccine'] for session in centre['sessions']]))),
"Fee Type": centre['fee_type'],
"Min Age": centre['sessions'][0]['min_age_limit'],
"Available Capacity": f"Dose 1: {centre['sessions'][0]['available_capacity_dose1']}\nDose 2: {centre['sessions'][0]['available_capacity_dose2']}",
"Slots": "\n".join(centre['sessions'][0]['slots'])} for centre in all_centres]
"Accepted Age Groups": ", ".join(sorted(list(map(lambda x: str(x)+'+', set([session['min_age_limit'] for session in centre['sessions']]))))),
# "Available Capacity": f"Dose 1: {centre['sessions'][0]['available_capacity_dose1']}\nDose 2: {centre['sessions'][0]['available_capacity_dose2']}",
# "Slots": "\n".join(centre['sessions'][0]['slots'])
} for centre in all_centres]

self.display_table(centres_list)

Expand Down Expand Up @@ -717,8 +718,8 @@ def get_appointment_details(appointment_dict):
# time.sleep(1)


def isValidCentre(self, centre, min_age_limit):
isValidPincode, isValidInstitute, isValidMinAgeSelected = False, False, False
def isValidCentre(self, centre, min_age_limit, vaccine_preference):
isValidPincode, isValidInstitute, isValidMinAgeSelected, isValidVaccine = False, False, False, True

if self.search_criteria == 1:
isValidPincode = True if centre['pincode'] == self.pincode_preferences[0] else False
Expand All @@ -735,12 +736,16 @@ def isValidCentre(self, centre, min_age_limit):

isValidMinAgeSelected = True if centre['min_age_limit'] == min_age_limit else False

isValidCentre = isValidPincode and isValidInstitute and isValidMinAgeSelected
if vaccine_preference:
isValidVaccine = True if centre['vaccine'].lower() == vaccine_preference else False

isValidCentre = isValidPincode and isValidInstitute and isValidMinAgeSelected and isValidVaccine

# print(f"centre vaccine: {centre['vaccine']}, is vaccine valid? {isValidVaccine}, is centre valid? {isValidCentre}")
return isValidCentre


def schedule_appointment(self, all_centres, ref_ids, dose_number, min_age_limit, user_config_file, is_app_gui=False):
def schedule_appointment(self, all_centres, ref_ids, dose_number, min_age_limit, vaccine_preference, user_config_file, is_app_gui=False):
appointment_booked_flag = False
appointment_id = None

Expand All @@ -750,13 +755,15 @@ def schedule_appointment(self, all_centres, ref_ids, dose_number, min_age_limit,

print(f"\nRef. IDs to schedule booking for: {ref_ids}")

for centre in all_centres:
print(f"\ntrying centre '{centre['name']}'\t{TextColors.BOLD}{TextColors.WARNING}(Min Age Limit: {centre['min_age_limit']}){TextColors.ENDC}...", end=" ")
total_centres = len(all_centres)

for idx, centre in enumerate(all_centres):
print(f"\n[+] trying centre ({idx+1}/{total_centres}) '{centre['name']}'\n\t{TextColors.BOLD}{TextColors.WARNING}(Vaccine Available: {centre['vaccine']}, Accepted Age Group: {centre['min_age_limit']}+){TextColors.ENDC}...", end=" ")

dummy_centre_check = False
# dummy_centre_check = 'aiims' in centre['name'].lower()

if self.isValidCentre(centre, min_age_limit) or dummy_centre_check:
if self.isValidCentre(centre, min_age_limit, vaccine_preference) or dummy_centre_check:
print(f"{TextColors.BOLD}{TextColors.WARNING}(VALID CENTRE FOUND - Booking Appointment...){TextColors.ENDC}")
if centre['available_capacity_dose'+str(dose_number)] >= len(ref_ids):
# captcha = self.generate_captcha(user_config_file, is_app_gui)
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ As it's a difficult task to schedule an appointment for CoVid-Vaccine with only
8. Beneficiaries *(which beneficiaries to schedule appointment for, among all the registered benficiaries(max. 4) in the account)*
9. Dose Number *(which dose number (1 or 2) appointment to schedule. Must be same for all the selected beneficiaries)*
10. Min Age Limit *(minimum age limit of the selected beneficiaries. All selected beneficiaries must belong to the same minimum age group, either 18+ or 45+)*
11. Vaccine Preference *(vaccine preference for the selected beneficiaries. Once appointment gets scheduled, all selected beneficiaries will receive the selected vaccine. Available options: 'Any', 'Covaxin', 'Covishield')*


<a name="screenshots-of-gui-app"></a>
Expand Down Expand Up @@ -150,7 +151,7 @@ As it's a difficult task to schedule an appointment for CoVid-Vaccine with only
<a name="installation-via-exe-file"></a>
### Installation (via EXE file)

1. Navigate to the **'dist'** directory for the setup file or click [here](https://github.com/DivAgicha/CoWIN-Vaccine-Appointment-Booking/raw/master/dist/CovidVaccinationAppointmentScheduler-Setup-v2.2.exe) to download the same for Windows.
1. Navigate to the **'dist'** directory for the setup file or click [here](https://github.com/DivAgicha/CoWIN-Vaccine-Appointment-Booking/raw/master/dist/CovidVaccinationAppointmentScheduler-Setup-v2.3.exe) to download the same for Windows.
2. Double-click the installer file and follow the instructions to install the program.
3. Upon successful installation you will find `Covid Vaccination Appointment Scheduler` folder in your `C:\Program Files (x86)\` directory.
4. Open the folder and run `schedule_vaccination_appointment.exe` (Console App) or `scheduler_form.exe` (GUI App) file.
Expand All @@ -161,8 +162,8 @@ As it's a difficult task to schedule an appointment for CoVid-Vaccine with only
## Important Points to Keep In Mind
- This is a proof of concept project. I do NOT endorse or condone, in any shape or form, automating any monitoring/booking tasks. **Developed for Educational Purpose; USE IT AT YOUR OWN RISK. I SHOULD NOT BE DEEMED RESPONSIBLE FOR ANY LEGAL CONCERNS.**
- This goes without saying but, once you get your shot, please do help out any underprivileged people around you who may not have a laptop or the know-how. For instance any sort of domestic help, or the staff in your local grocery store, or literally the thousands of people who don't have the knowledge or luxury we do.
- If you accidentally book a slot, don't worry. You can always login to the [Official portal](https://selfregistration.cowin.gov.in/) and cancel or re-schedule the booking. There is no option available for rescheduling or cancellation of Booking Slot in the Application. There will be an X symbol on the right-top corner for each beneficiary to cancel from CoWIN Portal.
- There is no option to register new mobile or add beneficiaries. This can be used only after beneficiary has been added through the Official WebApp of [CoWIN](https://cowin.gov.in/).
- If you accidentally book a slot, don't worry. You can always login to the [Official portal](https://selfregistration.cowin.gov.in/) and cancel or re-schedule the booking. There is no option available for rescheduling or cancellation of Booking Slot in the Application. There will be an X symbol on the top-right corner for each beneficiary to cancel from CoWIN Portal.
- There is no option to register new mobile or add beneficiaries. This application can be used only after beneficiary has been added through the Official WebApp of [CoWIN](https://cowin.gov.in/).



Expand Down
Binary file not shown.
78 changes: 40 additions & 38 deletions schedule_vaccination_appointment.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,14 @@
""")

mobile_number_pattern = re.compile("^[6-9][0-9]{9}$")
# beneficiary_index_pattern = re.compile("^[1-4]$")
dose_and_min_age_pattern = re.compile("^[1-2]$")
vaccine_preference_pattern = re.compile("^[1-3]$")

while True:
mobile = input("\n-->\tEnter mobile: ")

if mobile is not None and mobile.strip() != "" and mobile_number_pattern.match(mobile.strip()):
if mobile.strip() and mobile_number_pattern.match(mobile.strip()): # checks for None and empty string value first
mobile = mobile.strip()
break
else:
Expand Down Expand Up @@ -109,63 +112,62 @@
while True:
ids_input = input(f"\nEnter comma-separated index of beneficiaries to schedule appointment for {TextColors.WARNING}(Enter '0' to select all or 'q' to quit and try after sometime){TextColors.ENDC}: ")

if ids_input is None or ids_input.strip() == "":
print(f"\n{TextColors.FAIL}Please enter correct indexes to proceed to booking{TextColors.ENDC}")
if not ids_input.strip(): # checks for None and empty string value
print(f"\n{TextColors.FAIL}Please enter correct indexes to proceed to booking. This value can't be empty{TextColors.ENDC}")
continue

if ids_input.strip().lower() == 'q':
elif ids_input.strip().lower() == 'q':
print("\nExiting program...")
exit(0)

reference_ids = ids_input.strip().replace(" ", "").split(",")

if ids_input.strip().lower() != '0':
# beneficiary_index_pattern = re.compile("^[1-4]$")
areValidIds = [bool(0 < int(id) <= len(beneficiaries)) for id in reference_ids if id != '']
if False in areValidIds:
print(f"\n{TextColors.FAIL}Please enter correct indexes to proceed to booking{TextColors.ENDC}")
continue

if not isinstance(reference_ids[0], int):
reference_ids = [int(id) for id in reference_ids if id != '']
if reference_ids[0] == 0:
elif ids_input.strip() == '0':
reference_ids = [beneficiary['beneficiary_reference_id'] for beneficiary in beneficiaries]
break
elif '0' in ids_input.strip() or 'q' in ids_input.strip().lower():
print(f"\n{TextColors.FAIL}Please enter correct indexes to proceed to booking. Don't club '0' or 'q' with any other option{TextColors.ENDC}")
continue
else:
# correct_ids_entered_flag = True
reference_ids = [id-1 for id in reference_ids if 0 < id <= len(beneficiaries)]
reference_ids = [beneficiary['beneficiary_reference_id'] for idx, beneficiary in enumerate(beneficiaries) if idx in reference_ids]

if len(reference_ids) == 0:
reference_ids = ids_input.strip().replace(" ", "").split(",")
reference_ids = list(filter(None, reference_ids)) # to filter out all empty strings
# beneficiary_index_pattern = re.compile("^[1-4]$")
regex_pattern = f"^[1-{len(beneficiaries)}]$"
beneficiary_index_pattern = re.compile(regex_pattern)
areValidIndexes = [bool(beneficiary_index_pattern.match(index)) for index in reference_ids]
if False in areValidIndexes or len(areValidIndexes) == 0:
print(f"\n{TextColors.FAIL}Please enter correct indexes to proceed to booking{TextColors.ENDC}")
else:
break
continue

reference_ids = list(map(lambda x: int(x)-1, reference_ids))
reference_ids = [beneficiaries[index]['beneficiary_reference_id'] for index in reference_ids]
break

while True:
dose_number = input(f"\nEnter dose number for selected beneficiaries {TextColors.WARNING}(SELECT ONE) ['1' for Dose 1, '2' for Dose 2]{TextColors.ENDC}: ")

if dose_number is not None or dose_number.strip() != "":
if dose_number.strip() and dose_and_min_age_pattern.match(dose_number.strip()): # checks for None and empty string value first
dose_number = int(dose_number.strip())
if dose_number in [1, 2]:
break
else:
print(f"\n{TextColors.FAIL}Invalid input! Please enter one of the above two choices{TextColors.ENDC}")
break
else:
print(f"\n{TextColors.FAIL}Invalid input! Please enter one of the above two choices{TextColors.ENDC}")

while True:
min_age_limit = input(f"\nEnter min age limit for selected beneficiaries {TextColors.WARNING}(SELECT ONE) ['1' for 18+, '2' for 45+]{TextColors.ENDC}: ")

if min_age_limit is not None or min_age_limit.strip() != "":
if min_age_limit.strip() and dose_and_min_age_pattern.match(min_age_limit.strip()): # checks for None and empty string value first
min_age_limit = int(min_age_limit.strip())
if min_age_limit in [1, 2]:
min_age_limit = 18 if min_age_limit == 1 else 45
break
else:
print(f"\n{TextColors.FAIL}Invalid input! Please enter one of the above two choices{TextColors.ENDC}")
min_age_limit = 18 if min_age_limit == 1 else 45
break
else:
print(f"\n{TextColors.FAIL}Invalid input! Please enter one of the above two choices{TextColors.ENDC}")

while True:
vaccine_preference = input(f"\nEnter vaccine preference for selected beneficiaries {TextColors.WARNING}(SELECT ONE) ['1' for '-ANY-', '2' for 'COVAXIN', '3' for 'COVISHIELD']{TextColors.ENDC}: ")

if vaccine_preference.strip() and vaccine_preference_pattern.match(vaccine_preference.strip()): # checks for None and empty string value first
vaccine_preference = int(vaccine_preference.strip())
vaccine_preference = '' if vaccine_preference == 1 else 'covaxin' if vaccine_preference == 2 else 'covishield'
break
else:
print(f"\n{TextColors.FAIL}Invalid input! Please enter one of the above three choices{TextColors.ENDC}")

print(f"\n-->\tAttempting to book appointment {TextColors.WARNING}(every 3 seconds for next 4 minutes, i.e., total 80 attempts)"
f"{TextColors.ENDC}")

Expand Down Expand Up @@ -228,15 +230,15 @@
try:
if attempts < 80:
print(f"\n\n{TextColors.UNDERLINE}{TextColors.BOLD}ATTEMPT {attempts+1}:{TextColors.ENDC}")
appointment_booked_flag, appointment_id = cowinAPI.schedule_appointment(all_centres, reference_ids, dose_number, min_age_limit, user_config_file)
appointment_booked_flag, appointment_id = cowinAPI.schedule_appointment(all_centres, reference_ids, dose_number, min_age_limit, vaccine_preference, user_config_file)

if appointment_booked_flag:
break

attempts += 1
time.sleep(1)

print(f"\n\n{TextColors.WARNING}[+]{TextColors.ENDC} Updating all_centres list to refresh "
print(f"\n\n[+] Updating all_centres list to refresh "
f"available_capacity value for each centre before next attempt", flush=True)
sys.stdout.flush()
time.sleep(1)
Expand Down
Loading

0 comments on commit f2c8273

Please sign in to comment.