diff --git a/CovidVaccineChecker/__init__.py b/CovidVaccineChecker/__init__.py index f4b9aa8..47ce2de 100644 --- a/CovidVaccineChecker/__init__.py +++ b/CovidVaccineChecker/__init__.py @@ -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}: ") @@ -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) @@ -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 @@ -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 @@ -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) diff --git a/README.md b/README.md index 85bbbd3..13d57cb 100644 --- a/README.md +++ b/README.md @@ -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')* @@ -150,7 +151,7 @@ As it's a difficult task to schedule an appointment for CoVid-Vaccine with only ### 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. @@ -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/). diff --git a/dist/CovidVaccinationAppointmentScheduler-Setup-v2.2.exe b/dist/CovidVaccinationAppointmentScheduler-Setup-v2.3.exe similarity index 73% rename from dist/CovidVaccinationAppointmentScheduler-Setup-v2.2.exe rename to dist/CovidVaccinationAppointmentScheduler-Setup-v2.3.exe index 5d8e100..a89395b 100644 Binary files a/dist/CovidVaccinationAppointmentScheduler-Setup-v2.2.exe and b/dist/CovidVaccinationAppointmentScheduler-Setup-v2.3.exe differ diff --git a/schedule_vaccination_appointment.py b/schedule_vaccination_appointment.py index d1e8ddb..944d238 100644 --- a/schedule_vaccination_appointment.py +++ b/schedule_vaccination_appointment.py @@ -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: @@ -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}") @@ -228,7 +230,7 @@ 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 @@ -236,7 +238,7 @@ 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) diff --git a/scheduler_form.py b/scheduler_form.py index cc6ca40..840fd3e 100644 --- a/scheduler_form.py +++ b/scheduler_form.py @@ -12,6 +12,7 @@ date_now = dt.datetime.today() pincode_pattern = re.compile("^[1-9][0-9]{5}$") mobile_number_pattern = re.compile("^[6-9][0-9]{9}$") +# beneficiary_index_pattern = re.compile("^[1-4]$") def create_window(finalize=False): @@ -77,7 +78,7 @@ def create_window(finalize=False): [simpleGUI.Frame('Booking Details', font='Any 8', title_color='yellow', element_justification='center', layout=[ [simpleGUI.Text(simpleGUI.SYMBOL_RIGHT_ARROWHEAD, key='arrow_11', text_color='Red', size=(1,1)), - simpleGUI.Text('Enter Beneficiaries (Index) 🛈', size=(22, 1), tooltip="Choices: 1/2/3/4 (comma-separated in case of multiple).Enter '0' to select all"), + simpleGUI.Text('Enter Beneficiaries (Index) 🛈', size=(22, 1), tooltip="Choices: 1/2/3/4 (comma-separated in case of multiple). Enter '0' to select all"), simpleGUI.Input(key='reference_ids', size=(28, 1), enable_events=True, text_color='Black', background_color='White', disabled_readonly_background_color='Grey'), simpleGUI.Button('Next', key='next_reference_ids')], [simpleGUI.Text(simpleGUI.SYMBOL_RIGHT_ARROWHEAD, key='arrow_12', text_color='Red', size=(1,1)), @@ -87,7 +88,11 @@ def create_window(finalize=False): [simpleGUI.Text(simpleGUI.SYMBOL_RIGHT_ARROWHEAD, key='arrow_13', text_color='Red', size=(1,1)), simpleGUI.Text('Select Minimum Age Group', size=(22, 1)), simpleGUI.Combo(key='min_age_limit', values=['18+ Age Group', '45+ Age Group'], default_value='-select-', size=(26, 1)), - simpleGUI.Button('Next', key='next_min_age_limit')] + simpleGUI.Button('Next', key='next_min_age_limit')], + [simpleGUI.Text(simpleGUI.SYMBOL_RIGHT_ARROWHEAD, key='arrow_14', text_color='Red', size=(1,1)), + simpleGUI.Text('Select Vaccine Type', size=(22, 1)), + simpleGUI.Combo(key='vaccine_preference', values=['-any-', 'Covaxin', 'Covishield'], default_value='-any-', size=(26, 1)), + simpleGUI.Button('Next', key='next_vaccine_preference')] ])], [simpleGUI.Text('Made with ' + u'\u2665' + ' (https://github.com/divagicha/\nCoWIN-Vaccine-Appointment-Booking)', auto_size_text=True, font='Courier 8'), @@ -95,7 +100,7 @@ def create_window(finalize=False): simpleGUI.Exit('Exit', size=(11, 1), button_color='Yellow', pad=(10,0))]] colR1C2 = [[simpleGUI.Frame('Output', font='Any 8', layout=[ - [simpleGUI.Output(size=(80, 35), key='console_output', font='Courier 10', echo_stdout_stderr=True)] + [simpleGUI.Output(size=(80, 36), key='console_output', font='Courier 10', echo_stdout_stderr=True)] ])]] layout = [[simpleGUI.Column(colR1C1, background_color='', element_justification='left', key='col1'), @@ -196,12 +201,6 @@ def is_input_field_active(key): return window[key].TKEntry['state'] != 'readonly' -def is_appointment_date_valid(): - today = dt.datetime.today().strftime('%d-%m-%Y') - - return bool(dt.datetime.strptime(cowinAPI.appointment_date, '%d-%m-%Y') >= dt.datetime.strptime(today, '%d-%m-%Y')) - - def attempt_to_schedule_appointment(): global next_operation, attempts, all_centres # simpleGUI.popup("Attempting to schedule appointment (every 3 seconds for next 4 minutes, i.e., total 80 attempts)\n\nNote: keep an " @@ -227,28 +226,8 @@ def attempt_to_schedule_appointment(): next_operation = 'schedule_appointment' return - - # if answer.lower().strip() == 'y': - # # cowinAPI.use_existing_user_config(user_config_file) - # print("\n[+] Continuing with existing configuration", end="") - # break - # elif answer.lower().strip() == 'c': - # cowinAPI.changeAppointmentDate(user_config_file, load_values_from_existing_config_first=False) - # print("\n[+] Appointment date changed successfully", end="") - # break - # elif answer.lower().strip() == 's': - # cowinAPI.changeSearchCriteria(user_config_file, load_values_from_existing_config_first=False) - # print("\n[+] Search criteria changed successfully", end="") - # break - # else: - # print("\nInvalid input! Please enter a valid option to continue") else: next_operation = '' - # centres_list = [{"Name": centre['name'], "District": centre['district_name'], "Pincode": centre['pincode'], "Vaccine Name": centre['vaccine'], - # "Fee Type": centre['fee_type'], "Min Age": centre['min_age_limit'], "Available Capacity": centre['available_capacity'], - # "Slots": "\n".join(centre['slots'])} for centre in all_centres] - # - # cowinAPI.display_table(centres_list) print(f"\nTotal Centres Found: {len(all_centres)}", end="") @@ -269,7 +248,8 @@ def call_schedule_appointment(): print(f"\n\nATTEMPT {attempts + 1}:") appointment_booked_flag, appointment_id = cowinAPI.schedule_appointment(all_centres, reference_ids, dose_number, min_age_limit, - user_config_file, is_app_gui=True) + vaccine_preference, user_config_file, + is_app_gui=True) if appointment_booked_flag: break @@ -305,13 +285,7 @@ def call_schedule_appointment(): print("\n(FAILED: Scheduling interrupted by user)") exit(1) - if not appointment_booked_flag: - print("\nour appointment could not be scheduled, as no valid slot found to be available.\n\n" - "Please try again after 1 minute...") - simpleGUI.popup(f"Your appointment could not be scheduled, as no valid slot found to be available.\n\n" - f"Please try again after 1 minute...", - title='Appointment Not Scheduled') - else: + if appointment_booked_flag: print(f"Hurray!! Your appointment has been successfully scheduled. Following are the details:\n\n" f"Apt. ID: {appointment_id}\n" f"Centre: {cowinAPI.appointment_centre_booked}\n" @@ -323,6 +297,11 @@ def call_schedule_appointment(): f"Date: {cowinAPI.appointment_date}\n" f"Slot: {cowinAPI.appointment_slot_selected}", title='Appointment Successfully Booked') + else: + print("\nYour appointment could not be scheduled, as no valid slot found to be available.\n\n" + "Please try again after 1 minute...") + simpleGUI.popup(f"Your appointment could not be scheduled, as no valid slot found to be available.\n\n" + f"Please try again after 1 minute...", title='Appointment Not Scheduled') if __name__ == "__main__": @@ -337,7 +316,8 @@ def call_schedule_appointment(): key_list = list(window.key_dict.keys()) keys_to_remove = ['col1', 'col2', 'console_output', 'clear_values', 'Exit'] - arrow_keys = ['arrow_1', 'arrow_2', 'arrow_3', 'arrow_4', 'arrow_5', 'arrow_6', 'arrow_7', 'arrow_8', 'arrow_9', 'arrow_10', 'arrow_11', 'arrow_12', 'arrow_13'] + arrow_keys = ['arrow_1', 'arrow_2', 'arrow_3', 'arrow_4', 'arrow_5', 'arrow_6', 'arrow_7', 'arrow_8', + 'arrow_9', 'arrow_10', 'arrow_11', 'arrow_12', 'arrow_13', 'arrow_14'] # enable_event_element_keys = ['mobile', 'otp', 'pincode_preferences', 'reference_ids'] for key in keys_to_remove + arrow_keys: key_list.remove(key) @@ -477,7 +457,7 @@ def call_schedule_appointment(): disable_element(['y', 'n', 'c', 's', 't', 'continue']) if values['y']: - if not is_appointment_date_valid(): + if not cowinAPI.is_appointment_date_valid(): simpleGUI.popup("Kindly choose 'Change appointment date' option and select a valid date " "(can be today's date or of the future)", title="Invalid Appointment Date") continue @@ -751,27 +731,47 @@ def call_schedule_appointment(): last_operation = 'next_centre_preferences' elif event == 'reference_ids': if values['reference_ids'].strip() != "" and is_input_field_active('reference_ids'): - reference_ids = values['reference_ids'].strip().replace(" ", "").split(",") - # print(f"reference_ids: {reference_ids}") - try: - areValidIndexes = [bool(0 <= int(index) <= len(beneficiaries)) for index in reference_ids if index != ''] - if False not in areValidIndexes: - reference_ids = [int(index) for index in reference_ids if index != ''] - enable_element('next_reference_ids') - else: - disable_element('next_reference_ids') - except Exception as e: - print("\nInvalid character found!! Enter only comma-separated numbers") + if values['reference_ids'].strip() == '0': + reference_ids = 0 + enable_element('next_reference_ids') + elif '0' in values['reference_ids'].strip(): + print(f"\n[+] Please enter correct indexes to proceed to booking. Don't club '0' with any other option") disable_element('next_reference_ids') + else: + reference_ids = values['reference_ids'].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) + try: + areValidIndexes = [bool(beneficiary_index_pattern.match(index)) for index in reference_ids] + if False not in areValidIndexes and len(areValidIndexes) != 0: + reference_ids = list(map(int, reference_ids)) + enable_element('next_reference_ids') + else: + disable_element('next_reference_ids') + except Exception as e: + print("\nInvalid character found!! Enter only comma-separated numbers") + disable_element('next_reference_ids') else: disable_element('next_reference_ids') last_operation = 'reference_ids' elif event == 'next_reference_ids': - if reference_ids[0] == 0: - reference_ids = [beneficiary['beneficiary_reference_id'] for beneficiary in beneficiaries] + beneficiary_ids = list() + beneficiary_names = list() + + if reference_ids == 0: + for beneficiary in beneficiaries: + beneficiary_ids.append(beneficiary['beneficiary_reference_id']) + beneficiary_names.append(beneficiary['name']) else: - reference_ids = [beneficiaries[index-1]['beneficiary_reference_id'] for index in reference_ids if 0 < index <= len(beneficiaries)] + for index in reference_ids: + beneficiary_ids.append(beneficiaries[index-1]['beneficiary_reference_id']) + beneficiary_names.append(beneficiaries[index-1]['name']) + print(f"\nBeneficiaries selected: {', '.join(beneficiary_names)}") + reference_ids = beneficiary_ids + del beneficiary_ids enable_element(['dose_number', 'next_dose_number'], update_others=True) show_arrow('arrow_12') @@ -779,6 +779,7 @@ def call_schedule_appointment(): elif event == 'next_dose_number': if values['dose_number'] != '-select-': dose_number = 1 if values['dose_number'] == 'Dose 1' else 2 + print(f"Dose selected: {dose_number}") enable_element(['min_age_limit', 'next_min_age_limit'], update_others=True) show_arrow('arrow_13') @@ -786,19 +787,27 @@ def call_schedule_appointment(): elif event == 'next_min_age_limit': if values['min_age_limit'] != '-select-': min_age_limit = 18 if values['min_age_limit'] == '18+ Age Group' else 45 - disable_element(['min_age_limit', 'next_min_age_limit']) - - if is_appointment_date_valid(): - show_arrow('') - attempt_to_schedule_appointment() - else: - simpleGUI.popup("Kindly choose 'Change appointment date' option and select a valid date " - "(can be today's date or of the future)", title="Invalid Appointment Date") - enable_element(['y', 'c', 'continue'], update_others=True) - show_arrow('arrow_3') - window['c'].update(value=True) - next_operation = 'change_date_and_schedule_appointment' + print(f"Age group selected: {min_age_limit}+") + enable_element(['vaccine_preference', 'next_vaccine_preference'], update_others=True) + show_arrow('arrow_14') last_operation = 'next_min_age_limit' + elif event == 'next_vaccine_preference': + vaccine_preference = '' if values['vaccine_preference'] == '-any-' else 'covaxin' if values['vaccine_preference'] == 'Covaxin' else 'covishield' + print(f"Vaccine preference: {'Any' if not vaccine_preference else vaccine_preference.title()}") + disable_element(['vaccine_preference', 'next_vaccine_preference']) + show_arrow('') + + if cowinAPI.is_appointment_date_valid(): + attempt_to_schedule_appointment() + else: + simpleGUI.popup("Kindly choose 'Change appointment date' option and select a valid date " + "(can be today's date or of the future)", title="Invalid Appointment Date") + enable_element(['y', 'c', 'continue'], update_others=True) + show_arrow('arrow_3') + window['c'].update(value=True) + next_operation = 'change_date_and_schedule_appointment' + + last_operation = 'next_vaccine_preference' window.close()