Package: auto-events
Auto EventsReasonsAimsInstallation and setupClone from GitUse pipAzure configurationBasic usageCreating a taskCreating an eventCreating a calendar without sourceCreating a Microsoft sourceCreating a calendar with sourceFetching for new eventsCreating your own sourceFormsCreate a Microsoft formFilling the formCreating your own form classReasonsIsn't annoying to complete repetitive tasks each day?
Well with a bit of programming knowledge this package could make your life just a bit easier and less repetitive.AimsAutomate annoying ad repetitive tasks such as submitting forms to attest attendance, keep track of work hours and more generically just automate tasks based on when they need to be performed.FeaturesFetch events from the calendar (supported: Outlook)Run custom tasks based on trigger datesSubmit forms automatically based on events/or notAuthenticationWhen using the Microsoft API or submitting forms where login is needed, you might be prompted to the console to enter the OTP for 2FA (if enabled). With the default driver the browser (chrome) data is stored (so it should happen rarely).Installation and setupClone from GitTo clone the repo just run the following command in your working directory:git clone https://github.com/fedecech/auto_events.gitUse pipRun the following:pip install auto_eventsAzure configurationIf you intend to use the Microsoft Graph API to fetch the events from your cloud calendar, you should follow these steps:log in to Azure (here) or create an account if you do not have one.UnderAzure Servicessearch forApp RegistrationClick onNew RegistrationGive your app a nameSelectMulti-Tenantunder Supported account typesAsRedirect URIselect web and use the following link:https://login.microsoftonline.com/common/oauth2/nativeclientOnce the app registration is completed, you should be redirected to the main dashboard. There are few things you need to do.Copy the Application (client) ID value somewhere safe. You will need it later.UnderApi Permissions->Add a permission. You should add the followings:Calendars.Read,Calendars.Read.Shared,offline_access,User.Read(if not already selected).The last step is to create a secret token. Click onCertificates & secrets->New client secret-> give it a name and copy it somewhere safe immediately (You will not be able to see it again).Basic UsageIf you are using the Microsoft API to fetch your events you should create a.envfile following the template in.env.example. EMAIL and PASSWORD are your Microsoft account credentials and CLIENT_ID and SECRET are the values retrieved following theAzure configuration process.Creating a taskA task is simply an object which stores a callback function to run (to_run), at what time(datetime) it should run and 2 other callback functions in case the task fails or succeeds (on_successandon_failure`).fromform_automator.TaskimportTaskasAutoTaskdefto_run():print("The task is running")defon_success():print("The task runned with no errors")defon_failure():print("An error occured while running the task")date=datetime.now()date=date+timedelta(seconds=10)task=AutoTask(run_date=date,to_run=to_run,on_success=on_success,on_failure=on_failure)In this example, the task run date is set to be 20 seconds after the task is created.Creating an eventAn event is an object that stores its start and end date, the title of the event, and a list of tasks to be run.fromform_automator.EventimportEventasAutoEventdate=datetime.now()start_date=date+timedelta(minutes=5)end_date=date+timedelta(minutes=10)event=AutoEvent(start_date=start_date,end_date=end_date,title="Event 1",tasks=[task])Creating a calendar without sourceA calendar object is responsible for storing the events and running their tasks when appropriate (based on eachrun_dateof each task). When using an API, in this case, the Microsoft API, Calendar needs a Source to fetch the events (But we'll see that later onhere).fromform_automator.CalendarimportCalendarasAutoCalendarcalendar=AutoCalendar(from_source=False,source=source,events=[event1])calendar.listen()The listen method, activates the scheduler to listen for events happening (tasks to be run).Creating a Microsoft sourceTo fetch events from our Microsoft API we need to create aMicrosoftSourceobject and pass that to our calendar.
The source uses Selenium so you should install the driver for your preferred browser (the default is Chrome).fromform_automator.MicrosoftSourceimportMicrosoftSourcefromdotenv.mainimportload_dotenvload_dotenv('your/path/to/.env')client_id=os.getenv('CLIENT_ID')secret=os.getenv('API_SECRET')email=os.getenv('EMAIL')psw=os.getenv('PASSWORD')credentials=(client_id,secret)# You could also pass a custom driver instead of using the default one (driver=your_driver)... But it still needs to be a selenium webdriversource=MicrosoftSource(path_to_driver='your/path/to/driver',api_credentials=credentials,scopes=['Calendars.Read.Shared','Calendars.Read'],account_cred={'email':email,'password':psw})Creating a calendar with sourceWhen creating a calendar with a source we can use 2 additional functions:filterandmap. After the events are fetched from the API, the first one allows us to filter the event (for instance by date). The second one allows us to modify the events (add tasks to them)fromform_automator.MicrosoftSourceimportMicrosoftSourcedeffilter(event:'AutoEvent')->bool:# return true when we want to keep the eventreturn"Test Automation"inevent.titledefmap(source:'Source',event:'AutoEvent')->'AutoEvent':task=AutoTask(run_date=date,to_run=to_run,on_success=on_success,on_failure=on_failure)event.add_task(task)# returns the modified eventreturneventcalendar=AutoCalendar(source=source,filter=filter,map=map)Fetching for new eventsWhen we are fetching events from our API we want to keep everything up to date. To do that we need to implement an infinite loop.# calendar with sourcecalendar.listen()whileTrue:print('Fetching new data...')calendar.update()sleep(SLEEP_TIME)Creating your own sourceTo create a custom source, for instance, that fetches events from the Google Calendar API, you just need to create a subclass ofSourceand implement the abstract methods.
TheMicrosoftSourceis the perfect example of it.FormsThe package also offers an easy way to automate form submissions (using selenium).Create a Microsoft formCurrently, the only implementation available is for Microsoft forms.
When creating the object it will automatically find the from components (the questions: date pickers, text fields...). In case it does not work for your specific form you could do that manually using your implementation of selenium and pass a list of FormComponent to the form.fromform_automator.form.microsoft.MicrosoftFormimportMicrosoftForm# the source is used to login into your microsoft account (find components automatically)form=MicrosoftForm(url='https://your_form_url',email_confirmation=True,source=source)# retireving web element using selecnium driverdate_picker_el=driver.find_element_by_id('date_picker')# (passing components manually)form=MicrosoftForm(url='https://your_form_url',source=source,components=[DatePicker(web_element=date_picker_el)])Filling the formTo fill in the form we need the answers to each question.
To do that we can call thefill_infunction on the form, passing an array of answers.form.fill_in(['Answer1','22/07/2022','Option1','Text field answer'])Creating your own form classTo create your custom form you just need to create a new subclass ofFormand implement the abstract methods.MicrosoftFormis an example of it.
Other than that you also need to implement your ownFormComponentclass (by creating a subclass ofFormComponent). For instance,MicrosoftFromComponentis an example of it.
If you also want to distinguish between each component you can create subclasses of your customFormComponentclass (for instance,MyCustomDatePickerwhich is a subclass ofMyCustomFormComponent).