private static async Task WriteTimetableAsync(Person person, Settings settings, int line) { var service = new GoogleCalendarService(person.Email); var calendar = await service.GetTimetableCalendarIdAsync() ?? await service.CreateTimetableCalendarAsync(); ConsoleHelper.WriteProgress(line, 1); var fields = "id,summary,location,start(dateTime),end(dateTime)"; var existing = await service.GetFutureEvents(calendar, DateTime.Today, fields); var expected = CreateExpectedEvents(person, settings); ConsoleHelper.WriteProgress(line, 2); var comparer = new EventComparer(); var obsolete = existing.Except(expected, comparer); var missing = expected.Except(existing, comparer); await service.InsertEventsAsync(calendar, missing); await service.DeleteEventsAsync(calendar, obsolete); ConsoleHelper.WriteProgress(line, 3); }
private static async Task MainAsync() { #if !DEBUG try { #endif Console.Clear(); Console.CursorVisible = false; Console.WriteLine("TIMETABLE CALENDAR GENERATOR\n"); var settings = await LoadSettingsAsync(); var students = await LoadStudentsAsync(); var teachers = await LoadTeachersAsync(); GoogleCalendarService.Configure(settings.ServiceAccountKey); Console.WriteLine("\nSetting up calendars:"); var tasks = new List <Task>(); var throttler = new SemaphoreSlim(initialCount: simultaneousRequests); var people = students.Concat(teachers).ToList(); Console.SetBufferSize(Console.BufferWidth, Math.Max(headerHeight + people.Count + 1, Console.BufferHeight)); for (var i = 0; i < people.Count; i++) { var countLocal = i; await Task.Delay(10); await throttler.WaitAsync(); var person = people[countLocal]; tasks.Add(Task.Run(async() => { try { var line = countLocal + headerHeight; ConsoleHelper.WriteDescription(line, $"({countLocal + 1}/{people.Count}) {person.Email}"); ConsoleHelper.WriteProgress(line, 0); for (var attempt = 1; attempt <= maxAttempts; attempt++) { try { await WriteTimetableAsync(person, settings, line); break; } catch (Google.GoogleApiException) when(attempt < maxAttempts) { var backoff = retryFirst * (int)Math.Pow(retryExponent, attempt - 1); ConsoleHelper.WriteStatus(line, $"Error. Retrying ({attempt} of {maxAttempts - 1})...", ConsoleColor.DarkYellow); await Task.Delay(backoff); } catch (Exception exc) { ConsoleHelper.WriteStatus(line, $"Failed. {exc.Message}", ConsoleColor.Red); break; } } } finally { throttler.Release(); } })); } await Task.WhenAll(tasks); Console.SetCursorPosition(0, headerHeight + people.Count); Console.WriteLine("\nCalendar generation complete.\n"); #if !DEBUG } catch (Exception exc) { ConsoleHelper.WriteError(exc.Message); } #endif if (waitForInput) { Console.ReadKey(); } }