/// <summary> /// Get vacant time slots from Italki, shredded as sessions /// </summary> /// <returns></returns> public static async Task <IEnumerable <SessionDto> > GetOfferedSchedules(DateTime startDate, DateTime endDate, bool forceRealTime) { // Load all the HTML pages simultaneously. var tasks = ItalkiTeachers.Select(i => GetTeacherPeriods(i.UserId, forceRealTime)); var teacherPeriodsArray = await Task.WhenAll(tasks); // italki does not allow booking in less than 24 hour. var threshold = GetBookingTimeThreshold(); var allPeriods = teacherPeriodsArray // Flatten all lists .SelectMany(i => i) // Filter .Where(i => (i.Start < endDate) && (i.End > startDate) && // There may be 30-minute "left over" slots available. We filter them out. Our sessions are 60 minutes. (i.Duration >= SessionDuration) && (i.End >= threshold + SessionDuration) ) ; // Merge all periods for display. ITimePeriodCollection periodCollection = new TimePeriodCollection(); var periodCombiner = new TimePeriodCombiner <TeacherTimeRange>(); periodCollection.AddAll(allPeriods); periodCollection = periodCombiner.CombinePeriods(periodCollection); var offeredSessions = periodCollection .Select(i => new SessionDto { Start = i.Start >= threshold ? i.Start : threshold, End = i.End, }); return(offeredSessions); }
public void GetFreeBusyRequestTimePeriodIntersectorTest() { //取得會議室資訊 var calendarAttributes = "fullName,email"; var searchMeetingRooms = new SearchCalendarResourcesRequest(calendarAttributes); ZmailRequest.ApiRequest = searchMeetingRooms; var zResquestRoom = ZmailDispatcher.SendRequest(ZmailRequest); var respRoom = zResquestRoom.ApiResponse as SearchCalendarResourcesResponse; var crList = respRoom?.CalendarResourceList; if (crList != null) { var crEmails = crList.Select(cr => cr.AttributesList.Where(ar => ar.Key.Equals("email")).Select(ar => ar.Value).FirstOrDefault()); var sdate = DateTime.Now; var edate = sdate.AddDays(7); //多人請用逗號隔開 var crEmailStrings = string.Join(",", crEmails.ToArray()); var searchNames = "[email protected],[email protected]," + crEmailStrings; ZmailRequest.ApiRequest = new GetFreeBusyRequest(sdate, edate, searchNames); var zResquest = ZmailDispatcher.SendRequest(ZmailRequest); var resp = zResquest.ApiResponse as GetFreeBusyResponse; var wkHours = resp?.Workinghours; if (wkHours != null) { var periods = new Dictionary <string, TimePeriodCollection>(); var users = wkHours.Users.Where(u => !crEmails.Contains(u.id)); //找出所有人的共同時間 var periodIntersector = new TimePeriodIntersector <TimeRange>(); var resultPeriods = new TimePeriodCollection(); var idx = 0; foreach (var user in users) { Console.WriteLine(user.id); Console.WriteLine("Free"); var userPeriods = new TimePeriodCollection(); foreach (var f in user.Fs) { Console.WriteLine($" {f.s} - {f.e}"); userPeriods.Add(new TimeRange(f.s, f.e)); } periods.Add(user.id, userPeriods); if (idx == 0) { resultPeriods.AddAll(user.Fs.Select(f => new TimeRange(f.s, f.e))); } else { resultPeriods.AddAll(user.Fs.Select(f => new TimeRange(f.s, f.e))); if (resultPeriods.Any()) { var intersectedPeriods = periodIntersector.IntersectPeriods(resultPeriods, false); resultPeriods.Clear(); resultPeriods.AddAll(intersectedPeriods.Select(p => new TimeRange(p.Start, p.End))); } } } Console.WriteLine("...共同的時間..."); foreach (var intersectedPeriod in resultPeriods) { Console.WriteLine("所有人共同的的時間 Period: " + intersectedPeriod); } //對應到會議室 var crs = wkHours.Users.Where(u => crEmails.Contains(u.id)); foreach (var cr in crList) { var email = cr.AttributesList.Where(ar => ar.Key.Equals("email")) .Select(ar => ar.Value) .FirstOrDefault(); var fullName = cr.AttributesList.Where(ar => ar.Key.Equals("fullName")) .Select(ar => ar.Value) .FirstOrDefault(); Console.WriteLine($"{fullName}:{email}"); var crHour = wkHours.Users.FirstOrDefault(u => u.id.Equals(email)); if (crHour != null) { var crPeriods = new TimePeriodCollection(); crPeriods.AddAll(resultPeriods.Select(p => new TimeRange(p.Start, p.End))); crPeriods.AddAll(crHour.Fs.Select(f => new TimeRange(f.s, f.e))); var intersectedPeriods = periodIntersector.IntersectPeriods(crPeriods, false); Console.WriteLine($"{fullName}:{email}...共同的時間..."); foreach (var intersectedPeriod in intersectedPeriods) { Console.WriteLine(" Period: " + intersectedPeriod); } } } } } }