From e5c1bea03075f4815f7ba34ee1f42a317d599b2f Mon Sep 17 00:00:00 2001 From: Zen Date: Tue, 8 Dec 2020 18:30:18 +0800 Subject: [PATCH] changes --- autocalendar.egg-info/PKG-INFO | 115 +++++++++++++++++++++ autocalendar.egg-info/SOURCES.txt | 12 +++ autocalendar.egg-info/dependency_links.txt | 1 + autocalendar.egg-info/not-zip-safe | 1 + autocalendar.egg-info/requires.txt | 9 ++ autocalendar.egg-info/top_level.txt | 1 + dist/autocalendar-0.0.1.tar.gz | Bin 0 -> 10656 bytes setup.cfg | 2 + setup.py | 2 +- 9 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 autocalendar.egg-info/PKG-INFO create mode 100644 autocalendar.egg-info/SOURCES.txt create mode 100644 autocalendar.egg-info/dependency_links.txt create mode 100644 autocalendar.egg-info/not-zip-safe create mode 100644 autocalendar.egg-info/requires.txt create mode 100644 autocalendar.egg-info/top_level.txt create mode 100644 dist/autocalendar-0.0.1.tar.gz create mode 100644 setup.cfg diff --git a/autocalendar.egg-info/PKG-INFO b/autocalendar.egg-info/PKG-INFO new file mode 100644 index 0000000..7735cdb --- /dev/null +++ b/autocalendar.egg-info/PKG-INFO @@ -0,0 +1,115 @@ +Metadata-Version: 2.1 +Name: autocalendar +Version: 0.0.1 +Summary: A Python automation scheduling system based on the Google Calendar API. +Home-page: https://github.com/zen-juen/AutoCalendar +Author: Zen Juen Lau +Author-email: lauzenjuen@gmail.com +License: MIT license +Download-URL: https://github.com/zen-juen/AutoCalendar/archive/v_01.tar.gz +Description: # AutoCalendar :calendar: + **AutoCalendar** is a Python scheduling automation system based on the Google Calendar API ideal for **scheduling research participants**. + + Running `autocalendar.py` adds events into Google Calendar by extracting the relevant information from an excel sheet containing participants' details, such as *date*, *time*, and *location*. + + Check out [AutoRemind](https://github.com/zen-juen/AutoRemind) too! + + ## Code Structure + + - **Schedule Participants**: `autoallocate()` + - Parses a doodle poll spreadsheet and automatically allocates participants to an available slot (Useful if participants are told to choose as many available slots as they can) + + - **Access Google API**: `setup_oauth()` + - Sets up OAuth 2.0 + - You would need a `client_secret.json` file: you can do this by going to https://console.developers.google.com/apis/credentials. Click on the 'credentials' tab and then download the client secret file. + - **Extract event details and create event**: + - `preprocess_file()`: preprocesses the input excel sheet (containing participants' scheduled slots) + - `extract_info()`: extracts date, time and location based on header column names in the participants file. Argument `filter_column` can also be activated to select only some participants to be added into google calendar. + - `create_event()`: prepares event details ready for execution. Argument `calendar_id` (defaults to 'primary') can also be modified according to which active google calendar to use by simply specifying the name of the calendar. + - `add_event()`: executes adding of event into calendar. + + + ## How to Use + + ### 1) Try it yourself: Automatic Scheduling of Participants + + Download your doodle poll into an excel spreadsheet, like so: + + ![Screenshot1](images/pollxls.PNG) + + ``` + import autocalendar as autocalendar + + autocalendar.autoallocate('scheduled.xlsx') + All participants successfully allocated. + ``` + A 'scheduled.xlsx' file containing participants' final allocated slots is exported with one line of code. + Feedback is provided on whether participants are successfully allocated or not, and the name of any participant who is not allocated will be printed. + + ### 2) Try it yourself: Adding Events + + You will first need to start with a xlsx file containing information on participants' scheduled slots. For example: + + ![Screenshot](images/inputxlsx.PNG) + + ``` + import autocalendar as autocalendar + + # Set up Oauth to access Google API + service = autocalendar.setup_oath(token_path='../../token.pkl', + client_path='../../client_secret.json') + + # Read and tidy excel sheet + participants = autocalendar.preprocess_file('../../../Participants Scheduling/Master_Participant_List.xlsx', header_row=2) + + # Extract info + dates, start_points, end_points, locations, to_add = autocalendar.extract_info(participants, date_col='Date_Session1', time_col='Timeslot_Session1', location_col='Location_Session1', filter_column='Calendar_Event', select='No') + + # Execute + autocalendar.add_event(service, dates, start_points, end_points, locations, to_add, + event_name='MRI study Session 1', description='', timezone='Asia/Singapore', + creator_email='mristudy@gmail.com', calendar_id='NTU Calendar', + silent=False, name_col='Participant Name', date_col='Date_Session1', + location_col='Location_Session1', time_col='Timeslot_Session1') + + ``` + + If `silent` in `add_event()` is set to False, you will also get **printed output** on each participant's appointment that is added into Google Calendar! + ``` + Adding calendar event for Subject1 at 11-8-2020, 11.00am-11.30am, B1-26 + Adding calendar event for Subject2 at 11-8-2020, 10.30am-11.00am, B1-26 + Adding calendar event for Subject3 at 11-8-2020, 4.00pm-4.30pm, B1-26 + Adding calendar event for Subject4 at 13-8-2020, 9.30am-10.00am, B1-26 + Adding calendar event for Subject5 at 12-8-2020, 11.30am-12.00pm, B1-26 + Adding calendar event for Subject6 at 12-8-2020, 12.00pm-12.30pm, B1-26 + + ``` + + + + + ## Future Direction + - [x] Printed feedback on each event that has been successfully added into calendar + - [ ] Accessibility for longitudinal studies + - [ ] Greater functionality for customizing events by adding arguments from https://developers.google.com/calendar/v3/reference/events + + + News + ----- + + + 0.0.1 (2020-10-21) + ^^^^^^^^^^^^^^^^^^^ + + * First release on PyPI. + +Keywords: automation,calendar events,google calendar api,automatic scheduling,Python +Platform: UNKNOWN +Classifier: Development Status :: 2 - Pre-Alpha +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Natural Language :: English +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Description-Content-Type: text/markdown diff --git a/autocalendar.egg-info/SOURCES.txt b/autocalendar.egg-info/SOURCES.txt new file mode 100644 index 0000000..3cb8fbe --- /dev/null +++ b/autocalendar.egg-info/SOURCES.txt @@ -0,0 +1,12 @@ +README.md +setup.cfg +setup.py +autocalendar/__init__.py +autocalendar/autocalendar.py +autocalendar/example.py +autocalendar.egg-info/PKG-INFO +autocalendar.egg-info/SOURCES.txt +autocalendar.egg-info/dependency_links.txt +autocalendar.egg-info/not-zip-safe +autocalendar.egg-info/requires.txt +autocalendar.egg-info/top_level.txt \ No newline at end of file diff --git a/autocalendar.egg-info/dependency_links.txt b/autocalendar.egg-info/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/autocalendar.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/autocalendar.egg-info/not-zip-safe b/autocalendar.egg-info/not-zip-safe new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/autocalendar.egg-info/not-zip-safe @@ -0,0 +1 @@ + diff --git a/autocalendar.egg-info/requires.txt b/autocalendar.egg-info/requires.txt new file mode 100644 index 0000000..caa5452 --- /dev/null +++ b/autocalendar.egg-info/requires.txt @@ -0,0 +1,9 @@ +numpy +pandas +pickle +os +dateutil +datetime +apiclient +google +google_auth_oauthlib diff --git a/autocalendar.egg-info/top_level.txt b/autocalendar.egg-info/top_level.txt new file mode 100644 index 0000000..a445694 --- /dev/null +++ b/autocalendar.egg-info/top_level.txt @@ -0,0 +1 @@ +autocalendar diff --git a/dist/autocalendar-0.0.1.tar.gz b/dist/autocalendar-0.0.1.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..2de570926439e65e74bda57c081da64077c9add1 GIT binary patch literal 10656 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