def merge_single_list(busylist): """ Merges the overlapping TimeSlots in the list of TimeSlots """ # Sorts the timeslots by start time sorted_list = timeslot.sort_by_begin_time(busylist, timeslot.ASCENDING) # TimeSlots that can no longer be merged with any of the other TimeSlots still # on the sorted_list. finalized_blobs = [] # A TimeSlot that still has the possibility of being merged with other TimeSlots # still on the sorted_list potential_blob = sorted_list[0] for i in range(1, len(sorted_list)): merged = potential_blob.merge(sorted_list[i]) if merged == None: # Unable to merge finalized_blobs.append(potential_blob) potential_blob = sorted_list[i] else: # Merged potential_blob = merged # Endfor: finish loose ends finalized_blobs.append(potential_blob) return finalized_blobs
def test_intersectlist(): list_a = [ TimeSlot('2017-04-10T06:00:00+00:00', '2017-04-10T07:00:00+00:00'), TimeSlot('2017-04-10T08:30:00+00:00', '2017-04-10T09:00:00+00:00'), TimeSlot('2017-04-10T10:30:00+00:00', '2017-04-10T11:30:00+00:00'), TimeSlot('2017-04-10T15:00:00+00:00', '2017-04-10T16:00:00+00:00') ] list_b = [ TimeSlot('2017-04-10T08:30:00+00:00', '2017-04-10T11:00:00+00:00'), TimeSlot('2017-04-10T14:00:00+00:00', '2017-04-10T15:15:00+00:00'), TimeSlot('2017-04-10T15:30:00+00:00', '2017-04-10T16:00:00+00:00'), TimeSlot('2017-04-10T22:00:00+00:00', '2017-04-10T23:00:00+00:00') ] ans = [ TimeSlot('2017-04-10T08:30:00+00:00', '2017-04-10T09:00:00+00:00'), TimeSlot('2017-04-10T10:30:00+00:00', '2017-04-10T11:00:00+00:00'), TimeSlot('2017-04-10T15:00:00+00:00', '2017-04-10T15:15:00+00:00'), TimeSlot('2017-04-10T15:30:00+00:00', '2017-04-10T16:00:00+00:00'), ] ab_intersect = intersect_two_lists(list_a, list_b) ab_intersect = timeslot.sort_by_begin_time(ab_intersect, timeslot.ASCENDING) assert len(ans) == len(ab_intersect) for i in range(0, len(ab_intersect)): assert ans[i].equals(ab_intersect[i])
def render_display(): """ Gets all the information needed to display on the page. On the first submission, it gets the calenders from Google, authorizing if needed. It then renders the page. On second submission, when the user has checked the calendars to use, it gets the correct event instances, then renders the page. """ app.logger.debug("Getting Calendars. Checking Google Calendar credentials") credentials = valid_credentials() if not credentials: return flask.redirect(flask.url_for("authorize")) else: app.logger.debug("Have Google Calendar credentials") gcal_service = get_gcal_service(credentials) app.logger.debug("Returned from get_gcal_service. Getting Calendars") flask.session['calendars'] = list_calendars(gcal_service) if not flask.session['selected_cal']: # In the first submit, user has not yet selected calendars. Renders the page to let them select app.logger.debug("No calendars already selected") flask.session['busytimes'] = [] pass # End of first submit else: # In the second submit, if user has selected calendars. begin/end_datetimes in cookies are already in the client tz app.logger.debug( "Getting busy event instances from these selected calendars: {}". format(flask.session['selected_cal'])) # Getting the periods of free time per date raw_frees = calc.init_frees_by_date(flask.session['begin_datetime'], flask.session['end_datetime']) # Getting event instances from the selected calendars, within a datetime range raw_busys = list_instances_btwn_datetimes( gcal_service, flask.session['selected_cal'], flask.session['begin_datetime'], flask.session['end_datetime']) all_times = [] for free in raw_frees: # For the free period of each date, find the free and busy times within that app.logger.debug('Trying {} to {}'.format(free.begin_datetime, free.end_datetime)) result = free.find_freebusy_from(raw_busys) app.logger.debug('Free times: {}'.format(result[0])) app.logger.debug('Busy times: {}'.format(result[1])) freebusy = result[0] + result[1] # Process data to display sorted_fb = timeslot.sort_by_begin_time(freebusy, timeslot.ASCENDING) ser_fb = timeslot.serialize_list(sorted_fb) all_times.append({ 'date': free.begin_datetime.split('T')[0], 'freebusy': ser_fb }) flask.session['busytimes'] = all_times # End of second submit return render_template('index.html')
def get_inviter_data(self, mtg_id, user_id): result = self.collection.find_one({'_id': ObjectId(mtg_id)}) if result == None: # Invalid meeting id return None if user_id == result['inviter']['inv_id']: # Valid inviter. Get all inviter and invitee free times # Encoding freetimes into TimeSlot objects to allow for calculations raw_freetimes = result['inviter']['freetimes'] inviter_freetimes = [] for raw_ft in raw_freetimes: inviter_freetimes.append(TimeSlot(raw_ft['begin_datetime'], raw_ft['end_datetime'])) invitee_freetimes = [] for invitee in result['invitees']: # Encoding invitees data if not invitee['responded']: # Ignores invitees that have not responded from the calculations print('{} did not respond, skipping...'.format(invitee['email'])) continue raw_freetimes = invitee['freetimes'] print('raw freetimes {}'.format(raw_freetimes)) temp = [] for raw_ft in raw_freetimes: temp.append(TimeSlot(raw_ft['begin_datetime'], raw_ft['end_datetime'])) invitee_freetimes.append(temp) # Finding the intersection of all user freetimes curr_inter = inviter_freetimes print('Inviter freetimes: {}'.format(curr_inter)) for each_invitee in invitee_freetimes: print('Invitee freetimes: {}'.format(each_invitee)) curr_inter = calc.intersect_two_lists(curr_inter, each_invitee) print('Intersection: {}'.format(curr_inter)) # Putting together data data = {} data['desc'] = result['desc'] data['duration'] = result['duration'] data['begin_datetime'] = result['begin_datetime'] data['end_datetime'] = result['end_datetime'] data['freetimes'] = timeslot.serialize_list(timeslot.sort_by_begin_time(curr_inter, timeslot.ASCENDING)) data['invitees'] = [] for invitee in result['invitees']: temp = {} temp['email'] = invitee['email'] temp['responded'] = invitee['responded'] data['invitees'].append(temp) return data # Invalid user id return None
def test_sort(): A = TimeSlot('A', '2017-11-12T09:00:00+00:00', '2017-11-12T17:00:00+00:00') B = TimeSlot('B', '2017-11-13T09:00:00+00:00', '2017-11-13T17:00:00+00:00') C = TimeSlot('C', '2017-11-14T00:00:00-08:00', '2017-11-15T00:00:00-08:00') D = TimeSlot('D', '2017-11-15T09:00:00+00:00', '2017-11-15T17:00:00+00:00') E = TimeSlot('E', '2017-11-15T21:00:00-08:00', '2017-11-16T10:00:00-08:00') F = TimeSlot('F', '2017-11-17T00:00:00-08:00', '2017-11-19T00:00:00-08:00') unsorted = [A, B, C, D, E, F] shuffle(unsorted) # Begin time, ascending ans = [A, B, C, D, E, F] sort = sort_by_begin_time(unsorted, timeslot.ASCENDING) assert len(sort) == len(ans) for i in range(0, len(ans)): assert ans[i].equals(sort[i]) # End time, descending ans = [F, E, D, C, B, A] sort = sort_by_end_time(unsorted, timeslot.DESCENDING) assert len(sort) == len(ans) for i in range(0, len(ans)): assert ans[i].equals(sort[i])
def free_times(raw_frees, raw_busys, duration): """ Returns the free times of a single user, calculated from the given time/date range, and the calendars selected by the user. The times of busy events in the selected calendars will not be considered as free times. Free times less than the duration of the meeting will also not be returned Args: raw_frees: list of TimeSlot objects, representing the raw free timeslots raw_busys: list of TimeSlot objects, representing the raw busy times pulled from all the selected calendars. Accepts [] as an argument, if there were no selected calendars or no busy times in selected calendars duration: str, h:mm of meeting duration Returns: A list of serialized timeslots dictionaries, containing: begin_datetime: str, isoformatted datetime end_datetime: str, isoformatted datetime """ result = [] if raw_busys == []: # No busy times, so return raw free times as the resultant free times result = timeslot.serialize_list(raw_frees) else: # Has busy times, so calculate resultant free times. for free in raw_frees: # For the raw free time of each date, find the free times print('Trying {} to {}'.format(free.begin_datetime, free.end_datetime)) freebusy = free.find_freebusy_from(raw_busys, duration) freetimes = freebusy[0] print('Free times: {}'.format(freetimes)) sorted_ft = timeslot.sort_by_begin_time(freetimes, timeslot.ASCENDING) result.extend(timeslot.serialize_list(sorted_ft)) return result