// // 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; namespace Yavsc.Services { using System.Collections.Generic; using System.Linq; using Google.Apis.Services; 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 readonly UserManager _userManager; ApplicationDbContext _dbContext; ILogger _logger; public CalendarManager(IOptions settings, UserManager userManager, ApplicationDbContext dbContext, ILoggerFactory loggerFactory) { _ApiKey = settings.Value.ApiKey; _userManager = userManager; _dbContext = dbContext; _logger = loggerFactory.CreateLogger(); } /// /// 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"; /// /// The date format. /// private static string dateFormat = "yyyy-MM-ddTHH:mm:ss"; /// /// The time zone. TODO Fixme with machine time zone /// private string timeZone = "+01:00"; private readonly IDataStore dataStore = new FileDataStore(GoogleWebAuthorizationBroker.Folder); /// /// Gets the calendar list. /// /// The calendars. /// Yavsc user id public async Task GetCalendarsAsync (string userId) { var service = new CalendarService(); var listRequest = service.CalendarList.List(); return await listRequest.ExecuteAsync(); } private ServiceAccountCredential GetServiceAccountCredential() { var creds = GoogleHelpers.GetCredentialForApi(new string[]{scopeCalendar}); if (creds==null) throw new InvalidOperationException("No credential"); return creds; } /// /// 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) { var service = new CalendarService(); var listRequest = service.Events.List(calid); 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); List free = new List (); List busy = new List (); foreach (var ev in eventList.Items) { 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"), p.End.ToString("DD/mm/yyyy") }).Distinct().ToArray(), BusyDates = busy.SelectMany( p => new string [] { p.Start.ToString("DD/mm/yyyy"), p.End.ToString("DD/mm/yyyy") }).Distinct().ToArray() }; } /// /// Creates a event in a calendar /// calendar.events.insert /// /// /// /// /// /// /// /// /// public async Task CreateEventAsync(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 creds = GetServiceAccountCredential(); GoogleCredential credential = await GoogleCredential.GetApplicationDefaultAsync(); var computeService = new BaseClientService.Initializer() { HttpClientInitializer = credential }; computeService.ApiKey = Startup.GoogleSettings.ApiKey; computeService.ApplicationName = "Yavsc"; computeService.Validate(); var service = new CalendarService(); 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; } } }