def getParticipantData(timeWindow, emails): if emails is not None: # use test data emailList = emails else: # use user data emailInput = ui.getEmailAddr() emailList = emailInput.split() # create email list delimited by space character participants = list() startTimestamp = func.createRfcTimestamp(timeWindow[0]) endTimestamp = func.createRfcTimestamp(timeWindow[1]) # Get Google API data for idxEmail, eleEmail in enumerate(emailList): # for each email address (Participant) events = list() try: response = urllib2.urlopen( "https://www.googleapis.com/calendar/v3/calendars/" + emailList[idxEmail] + "/events?timeMin=" + startTimestamp + "&timeMax=" + endTimestamp + "&key=AIzaSyB7IsERaXNIMiRgMAB_tujhdzNVmxpq0KA" ).read() except urllib2.HTTPError, e: print "\nERROR: We could not retrieve the calendar for", emailList[idxEmail] print "Please make sure the email address is valid and the calendar is public\n" exit(1) responseJson = json.loads(response) # converts to JSON object # startTime = responseJson['items'][0]['start'] # Find Participant's scheduled meetings during timeWindow # print responseJson['items'][0]['start']['dateTime'] # print responseJson['items'] recurringEvent = list() if len(responseJson["items"]) > 0: # if events exist for idxEvent, eleEvent in enumerate(responseJson["items"]): # for each event if ( eleEvent["status"] == "confirmed" and "dateTime" in responseJson["items"][idxEvent]["start"] # ignore cancelled appointments ): # ignore all day events eventStartRfcTimestamp = responseJson["items"][idxEvent]["start"]["dateTime"] eventEndRfcTimestamp = responseJson["items"][idxEvent]["end"]["dateTime"] eventSummary = responseJson["items"][idxEvent]["summary"] email = responseJson["items"][idxEvent]["organizer"]["email"] # print eventStartRfcTimestamp, eventSummary # Convert RFC timestamp to Google timestamp format eventStartGoogleTimestamp = func.rfcToGoogleTimestamp(eventStartRfcTimestamp) eventEndGoogleTimestamp = func.rfcToGoogleTimestamp(eventEndRfcTimestamp) # Determine if event is recurring # If googleTS is < timeWindow start, it's a recurring event. Change event date eventStartPosixTimestamp = func.timeStrToPosix(eventStartGoogleTimestamp) eventEndPosixTimestamp = func.timeStrToPosix(eventEndGoogleTimestamp) timeWindowStartPosix = func.timeStrToPosix(timeWindow[0]) timeWindowEndPosix = func.timeStrToPosix(timeWindow[1]) if eventStartPosixTimestamp < timeWindowStartPosix: additionalSlots = list() # if event duration > 30 mins # Add recurring event to each day of the time window timeWindowDays = func.numOfTimeWindowDays(timeWindowStartPosix, timeWindowEndPosix) for i in range(0, timeWindowDays + 1): # days to add if i == 0: eventStart = func.changeEventDate(timeWindow[0], eventStartGoogleTimestamp) eventEnd = func.changeEventDate(timeWindow[0], eventEndGoogleTimestamp) event = [email, eventSummary, eventStart, eventEnd] events.append(event) else: eventPosix = func.timeStrToPosix(eventStart) eventPosix += 86400 # add one day in seconds eventStart = func.posixToTimeStr(eventPosix) eventEnd = func.changeEventDate(eventStart, eventEndGoogleTimestamp) event = [email, eventSummary, eventStart, eventEnd] events.append(event) # print i, eventStart, eventSummary else: # event is not recurring event = [email, eventSummary, eventStartGoogleTimestamp, eventEndGoogleTimestamp] events.append(event) # Add additional 30 minute slots # If event duration > 30 mins, add additional 30 min slots for idxEvent, event in enumerate(events): startTimePosix = func.timeStrToPosix(event[2]) endTimePosix = func.timeStrToPosix(event[3]) duration = endTimePosix - startTimePosix email = event[0] summary = event[1] startTime = event[2] endTime = event[3] if duration > 1800: # duration > 30 minutes slotCount = int(duration / 1800) - 1 # number of 30 minute slots to add increase = 0 for i in range(slotCount): # print 'start = ', startTime, summary posixTime = func.timeStrToPosix(startTime) # Google TS to Posix increase = increase + 1800 posixTime = posixTime + increase # increment by 30 minutes startTime = func.posixToTimeStr(posixTime) event = [email, summary, startTime, endTime] events.append(event) # print 'end = ', startTime, summary increase = 0 else: # no events exists. Participant is available for the entire time window event = [eleEmail, None, None, None] events.append(event) # Sort events by start date eventsSorted = sorted(events, key=lambda startDate: startDate[2]) # print '\n========== Un-Sorted ====================' # for idx, ele in enumerate(events): # print ele[2], ele[1] print "\n============ Sorted ==================" for idx, ele in enumerate(eventsSorted): print ele[2], ele[1] # Store participant's event data to Participant object participants.append(Participant(eventsSorted))
def createMeetingMatrix(): #args are for test suite only #print "Test Arg length: ", len(sys.argv) #print "Test Args: ", str(sys.argv) if len(sys.argv) >= 4: #run program with test data startTimeWindow = str(sys.argv[1]) endTimeWindow = str(sys.argv[2]) timeWindowData = google.getTimeWindowData(startTimeWindow, endTimeWindow) #get timeWindow w/ test data #Create list of test emails from command line emailList = list() if len(sys.argv)>= 4: for x in range(3, len(sys.argv)): emailList.append(sys.argv[x]) participantData = google.getParticipantData(timeWindowData, emailList) else: #run program with user data timeWindowData = google.getTimeWindowData(None, None) #get time window data from Google API call #Get participants data from Google API call participantData = google.getParticipantData(timeWindowData, None) # parseGoogleTime returns class object for getday - getYear #Parse start and end times of timeWindow provided by Actor and store in object GoogleTime timeWindowStart = func.parseGoogleTime(timeWindowData[0]) timeWindowEnd = func.parseGoogleTime(timeWindowData[1]) #Calculate the number of 30 minute slots in timeWindow minutesRange = func.hoursRange(timeWindowStart, timeWindowEnd) #Create Actor's timeWindow slots for meeting times in Posix format timeWindowSlots = func.createTimeSlots(timeWindowStart, timeWindowEnd, 30) numOfWindowSlots = len(timeWindowSlots) numOfParticipants = len(participantData) #Create meeting matrix for each timeWindowSlot and participant meetingMatrix = list() #binary matrix displaying availability for all participants for i in range(0, numOfParticipants): meetingMatrix.append('Null') #initiate matrix to null idxActor = 0 idxEvent = 0 for idxPartpnt, elePartpntm in enumerate(participantData): #Each participant timeSlots = list() #temp storage for each participant's time slot #print '----------------------------' #print elePartpntm.getName() numOfParticipantSlots = len(participantData[idxPartpnt].getBusyTimeSlot()) #print 'numOfParticipantSlots = ', numOfParticipantSlots if participantData[idxPartpnt].getBusyTimeSlot()[0] is None: #participant available during all timeWindow for x in range(0, numOfWindowSlots): #Actor's desired meeting slots timeSlots.append(0) #participant available during time slot meetingMatrix[idxPartpnt] = timeSlots else: #participant has scheduled events during time window while(idxActor < numOfWindowSlots): #Actor's desired meeting slots windowSlot = timeWindowSlots[idxActor] participantSlot = participantData[idxPartpnt].getBusyTimeSlot() #Compare participant's time slot to Actor's desired meeting slots #print 'idxEvent = ', idxEvent #print 'idxActor = ', idxActor if(idxEvent < numOfParticipantSlots): #Participant time slot participantPosix = func.timeStrToPosix(participantSlot[idxEvent]) #print func.posixToPST(participantPosix) #print func.posixToPST(windowSlot) if(participantPosix == windowSlot): #print 'equal' timeSlots.append(1) #participant not available in meeting slot idxActor += 1 #next Actor's meeting slot idxEvent += 1 #next participant's time slot #continue if(participantPosix < windowSlot): #print 'less' timeSlots.append(0) #participant available in meeting slot idxEvent += 1 #next participant's time slot #continue if(participantPosix > windowSlot): #print 'more' timeSlots.append(0) #participant available in meeting slot idxActor += 1 #next Actor's meeting slot #continue #Go to next participant if all participant time slots is checked if(idxEvent == numOfParticipantSlots or idxActor == numOfWindowSlots): #Set remainding meetingMatrix to 0, indicating participant is available for j in range(idxActor, numOfWindowSlots): timeSlots.append(0) #mark remainder as unvailable idxActor = 0 #reset iterator to first Actor's meeting slot idxEvent = 0 #reset iterator to first time slot for next participant #Store participant availability in meeting matrix meetingMatrix[idxPartpnt] = timeSlots #print meetingMatrix break #got to next participant #store meetingMatrix in MeetingAvailability object meetingAvailability = MeetingAvailability(meetingMatrix, participantData, numOfWindowSlots, timeWindowSlots) #print 'Fun starts here' #print meetingAvailability.getMeetingMatrix() #print meetingAvailability.getParticipants() #print meetingAvailability.getNumOfWindowSlots() #print meetingAvailability.getTimeWindowSlots() return meetingAvailability