// // CalendarApi.cs // // Author: // Paul Schneider // // Copyright (c) 2015 - 2017 Paul Schneider // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with this program. If not, see . using System; using System.Threading.Tasks; using Microsoft.AspNet.Identity; using Microsoft.Extensions.Logging; using Microsoft.Extensions.OptionsModel; using Google.Apis.Auth.OAuth2; using Google.Apis.Util.Store; using Google.Apis.Calendar.v3; using Google.Apis.Calendar.v3.Data; using System.Collections.Generic; using System.Linq; using Google.Apis.Services; namespace Yavsc.Services { using System.Threading; using Google.Apis.Auth.OAuth2.Flows; using Yavsc.Helpers; using Yavsc.Models; using Yavsc.Models.Calendar; using Yavsc.ViewModels.Calendar; /// /// Google Calendar API client. /// public class CalendarManager : ICalendarManager { public class ExpiredTokenException : Exception { } protected static string scopeCalendar = "https://www.googleapis.com/auth/calendar"; private string _ApiKey; private IAuthorizationCodeFlow _flow; private readonly UserManager _userManager; ApplicationDbContext _dbContext; IDataStore _dataStore; ILogger _logger; public CalendarManager(IOptions settings, UserManager userManager, ApplicationDbContext dbContext, IDataStore dataStore, ILoggerFactory loggerFactory) { _ApiKey = settings.Value.ApiKey; _userManager = userManager; _dbContext = dbContext; _logger = loggerFactory.CreateLogger(); _dataStore = dataStore; _flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer { ClientSecrets = new ClientSecrets { ClientId = Startup.GoogleSettings.ClientId, ClientSecret = Startup.GoogleSettings.ClientSecret }, Scopes = new[] { scopeCalendar }, DataStore = dataStore }); } /// /// The get cal list URI. /// protected static string getCalListUri = "https://www.googleapis.com/calendar/v3/users/me/calendarList"; /// /// The get cal entries URI. /// protected static string getCalEntriesUri = "https://www.googleapis.com/calendar/v3/calendars/{0}/events"; /// /// Gets the calendar list. /// /// The calendars. /// Yavsc user id public async Task GetCalendarsAsync(string userId, string pageToken) { if (string.IsNullOrWhiteSpace(userId)) throw new Exception("the user id is not specified"); var service = await CreateUserCalendarServiceAsync(userId); CalendarListResource.ListRequest calListReq = service.CalendarList.List (); calListReq.PageToken = pageToken; return calListReq.Execute (); } /// /// Gets a calendar event list, between the given dates. /// /// The calendar. /// Calendar identifier. /// Mindate. /// Maxdate. /// credential string. public async Task GetCalendarAsync(string calid, DateTime minDate, DateTime maxDate, string pageToken) { var service = await GetServiceAsync(); var listRequest = service.Events.List(calid); listRequest.PageToken = pageToken; listRequest.TimeMin = minDate; listRequest.TimeMax = maxDate; listRequest.SingleEvents = true; return await listRequest.ExecuteAsync(); } public async Task CreateViewModelAsync( string inputId, string calid, DateTime mindate, DateTime maxdate) { if (calid == null) return new DateTimeChooserViewModel { InputId = inputId, MinDate = mindate, MaxDate = maxdate }; var eventList = await GetCalendarAsync(calid, mindate, maxdate, null); List free = new List(); List busy = new List(); foreach (var ev in eventList.Items) { if (ev.Start.DateTime.HasValue && ev.End.DateTime.HasValue ) { DateTime start = ev.Start.DateTime.Value; DateTime end = ev.End.DateTime.Value; if (ev.Transparency == "transparent") { free.Add(new Period { Start = start, End = end }); } else busy.Add(new Period { Start = start, End = end }); } } return new DateTimeChooserViewModel { InputId = inputId, MinDate = mindate, MaxDate = maxdate, Free = free.ToArray(), Busy = busy.ToArray(), FreeDates = free.SelectMany(p => new string[] { p.Start.ToString("dd/MM/yyyy HH:mm"), p.End.ToString("dd/MM/yyyy HH:mm") }).Distinct().ToArray(), BusyDates = busy.SelectMany(p => new string[] { p.Start.ToString("dd/MM/yyyy HH:mm"), p.End.ToString("dd/MM/yyyy HH:mm") }).Distinct().ToArray() }; } /// /// Creates a event in a calendar /// calendar.events.insert /// /// /// /// /// /// /// /// /// public async Task CreateEventAsync(string userId, string calid, DateTime startDate, int lengthInSeconds, string summary, string description, string location, bool available) { if (string.IsNullOrWhiteSpace(calid)) throw new Exception("the calendar identifier is not specified"); var service = await GetServiceAsync(); Event ev = new Event { Start = new EventDateTime { DateTime = startDate }, End = new EventDateTime { DateTime = startDate.AddSeconds(lengthInSeconds) }, Summary = summary, Description = description }; var insert = service.Events.Insert(ev, calid); var inserted = await insert.ExecuteAsync(); return inserted; } CalendarService _service = null; public async Task GetServiceAsync() { if (_service==null) { GoogleCredential credential = await GoogleCredential.GetApplicationDefaultAsync(); var baseClientService = new BaseClientService.Initializer() { HttpClientInitializer = credential }; if (credential.IsCreateScopedRequired) { credential = credential.CreateScoped(new string [] { scopeCalendar }); }/* var credential = await GoogleHelpers.GetCredentialForApi(new string [] { scopeCalendar }); if (credential.IsCreateScopedRequired) { credential = credential.CreateScoped(scopeCalendar); } _service = new CalendarService(new BaseClientService.Initializer() { HttpClientInitializer = credential, ApplicationName = "Yavsc" }); }*/ _service = new CalendarService(new BaseClientService.Initializer() { HttpClientInitializer = credential, ApplicationName = "Yavsc" }); } return _service; } /// /// Creates Google User Credential /// /// Yavsc use id /// public async Task CreateUserCalendarServiceAsync(string userId) { var login = await _dbContext.GetGoogleUserLoginAsync(userId); var token = await _flow.LoadTokenAsync(login.ProviderKey, CancellationToken.None); UserCredential cred = new UserCredential(_flow,login.ProviderKey,token); return new CalendarService(new BaseClientService.Initializer() { HttpClientInitializer = cred, ApplicationName = "Yavsc" }); } } }