/// <summary> /// Get the Outlook category colour from the name given to the category /// </summary> /// <param name="categoryName">The user named Outlook category</param> /// <returns>The Outlook category type</returns> public Outlook.OlCategoryColor?OutlookColour(String categoryName) { if (string.IsNullOrEmpty(categoryName)) { log.Warn("Category name is empty."); } try { if (this.categories != null && this.categories.Count > 0) { } } catch (System.Exception ex) { OGCSexception.Analyse("Categories are not accessible!", OGCSexception.LogAsFail(ex)); this.categories = null; } if (this.categories == null || OutlookOgcs.Calendar.Categories == null) { OutlookOgcs.Calendar.Instance.IOutlook.RefreshCategories(); this.categories = Calendar.Categories.categories; } foreach (Outlook.Category category in this.categories) { if (category.Name == categoryName.Trim()) { return(category.Color); } } log.Warn("Could not convert category name '" + categoryName + "' into Outlook category type."); return(null); }
private void ogcsPushTimer_Tick(object sender, EventArgs e) { if (Forms.ErrorReporting.Instance.Visible) { return; } log.Fine("Push sync triggered."); try { System.Collections.Generic.List <Microsoft.Office.Interop.Outlook.AppointmentItem> items = OutlookOgcs.Calendar.Instance.GetCalendarEntriesInRange(true); if (items.Count < this.lastRunItemCount || items.FindAll(x => x.LastModificationTime > this.lastRunTime).Count > 0) { log.Debug("Changes found for Push sync."); Forms.Main.Instance.NotificationTray.ShowBubbleInfo("Autosyncing calendars: " + Settings.Instance.SyncDirection.Name + "..."); if (!Sync.Engine.Instance.SyncingNow) { Forms.Main.Instance.Sync_Click(sender, null); } else { log.Debug("Busy syncing already. No need to push."); } } else { log.Fine("No changes found."); } failures = 0; } catch (System.Exception ex) { failures++; log.Warn("Push Sync failed " + failures + " times to check for changed items."); String hResult = OGCSexception.GetErrorCode(ex); if ((ex is System.InvalidCastException && hResult == "0x80004002" && ex.Message.Contains("0x800706BA")) || //The RPC server is unavailable (ex is System.Runtime.InteropServices.COMException && ( ex.Message.Contains("0x80010108(RPC_E_DISCONNECTED)") || //The object invoked has disconnected from its clients hResult == "0x800706BE" || //The remote procedure call failed hResult == "0x800706BA")) //The RPC server is unavailable ) { OGCSexception.Analyse(OGCSexception.LogAsFail(ex)); try { OutlookOgcs.Calendar.Instance.Reset(); } catch (System.Exception ex2) { OGCSexception.Analyse("Failed resetting Outlook connection.", ex2); } } else { OGCSexception.Analyse(ex); } if (failures == 10) { Forms.Main.Instance.Console.UpdateWithError("Push Sync is failing.", ex, notifyBubble: true); } } }
public Boolean UserSubscriptionCheck() { List <Event> result = new List <Event>(); Events request = null; String pageToken = null; Int16 pageNum = 1; log.Debug("Retrieving all subscribers from past year."); try { do { EventsResource.ListRequest lr = GoogleOgcs.Calendar.Instance.Service.Events.List("*****@*****.**"); lr.PageToken = pageToken; lr.SingleEvents = true; lr.OrderBy = EventsResource.ListRequest.OrderByEnum.StartTime; lr.Q = (Settings.Instance.GaccountEmail == null) ? "" : HashedGmailAccount; request = lr.Execute(); log.Debug("Page " + pageNum + " received."); if (request != null) { pageToken = request.NextPageToken; pageNum++; if (request.Items != null) { result.AddRange(request.Items); } } } while (pageToken != null); if (String.IsNullOrEmpty(Settings.Instance.GaccountEmail)) //This gets retrieved via the above lr.Execute() { log.Warn("User's Google account username is not present - cannot check if they have subscribed."); return(false); } } catch (Google.Apis.Auth.OAuth2.Responses.TokenResponseException ex) { OGCSexception.AnalyseTokenResponse(ex); } catch (Google.GoogleApiException ex) { switch (GoogleOgcs.Calendar.HandleAPIlimits(ref ex, null)) { case Calendar.ApiException.throwException: throw; case Calendar.ApiException.freeAPIexhausted: OGCSexception.LogAsFail(ref ex); OGCSexception.Analyse(ex); System.ApplicationException aex = new System.ApplicationException(GoogleOgcs.Calendar.Instance.SubscriptionInvite); OGCSexception.LogAsFail(ref aex); GoogleOgcs.Calendar.Instance.Service = null; throw aex; } } catch (System.Exception ex) { log.Error(ex.Message); throw new ApplicationException("Failed to retrieve subscribers - cannot check if they have subscribed."); } log.Debug("Searching for subscription for: " + Settings.Instance.GaccountEmail_masked()); List <Event> subscriptions = result.Where(x => x.Summary == HashedGmailAccount).ToList(); if (subscriptions.Count == 0) { log.Fine("This user has never subscribed."); Settings.Instance.Subscribed = DateTime.Parse("01-Jan-2000"); return(false); } else { Boolean subscribed; Event subscription = subscriptions.Last(); DateTime subscriptionStart = (subscription.Start.DateTime ?? DateTime.Parse(subscription.Start.Date)).Date; log.Debug("Last subscription date: " + subscriptionStart.ToString()); Double subscriptionRemaining = (subscriptionStart.AddYears(1) - DateTime.Now.Date).TotalDays; if (subscriptionRemaining >= 0) { if (subscriptionRemaining > 360) { Forms.Main.Instance.SyncNote(Forms.Main.SyncNotes.RecentSubscription, null); } if (subscriptionRemaining < 28) { Forms.Main.Instance.SyncNote(Forms.Main.SyncNotes.SubscriptionPendingExpire, subscriptionStart.AddYears(1)); } subscribed = true; } else { if (subscriptionRemaining > -14) { Forms.Main.Instance.SyncNote(Forms.Main.SyncNotes.SubscriptionExpired, subscriptionStart.AddYears(1)); } subscribed = false; } DateTime prevSubscriptionStart = Settings.Instance.Subscribed; if (subscribed) { log.Info("User has an active subscription."); Settings.Instance.Subscribed = subscriptionStart; } else { log.Info("User has no active subscription."); Settings.Instance.Subscribed = DateTime.Parse("01-Jan-2000"); } //Check for any unmigrated entries if (subscriptions.Where(s => s.ExtendedProperties != null && s.ExtendedProperties.Shared != null && s.ExtendedProperties.Shared.ContainsKey("migrated") && s.ExtendedProperties.Shared["migrated"] == "true").Count() < subscriptions.Count()) { Forms.Main.Instance.Console.CallGappScript("subscriber"); } if (prevSubscriptionStart != Settings.Instance.Subscribed) { if (prevSubscriptionStart == DateTime.Parse("01-Jan-2000") || //No longer a subscriber Settings.Instance.Subscribed == DateTime.Parse("01-Jan-2000")) //New subscriber { ApiKeyring.ChangeKeys(); } } return(subscribed); } }
private async Task <bool> getAuthenticated(ClientSecrets cs) { log.Debug("Authenticating with Google calendar service..."); FileDataStore tokenStore = new FileDataStore(Program.UserFilePath); tokenFullPath = Path.Combine(tokenStore.FolderPath, TokenFile); log.Debug("Google credential file location: " + tokenFullPath); if (!tokenFileExists) { log.Info("No Google credentials file available - need user authorisation for OGCS to manage their calendar."); } string[] scopes = new[] { "https://www.googleapis.com/auth/calendar", "email" }; UserCredential credential = null; try { //This will open the authorisation process in a browser, if required credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(cs, scopes, "user", CancelTokenSource.Token, tokenStore); if (tokenFileExists) { log.Debug("User has provided authorisation and credential file saved."); } } catch (Google.Apis.Auth.OAuth2.Responses.TokenResponseException ex) { //OGCSexception.AnalyseTokenResponse(ex); if (ex.Error.Error == "access_denied") { String noAuthGiven = "Sorry, but this application will not work if you don't allow it access to your Google Calendar :("; log.Warn("User did not provide authorisation code. Sync will not be able to work."); OgcsMessageBox.Show(noAuthGiven, "Authorisation not given", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); throw new ApplicationException(noAuthGiven); } else { Forms.Main.Instance.Console.UpdateWithError("Unable to authenticate with Google. The following error occurred:", ex); } } catch (OperationCanceledException) { Forms.Main.Instance.Console.Update("Unable to authenticate with Google. The operation was cancelled.", Console.Markup.warning); } catch (System.Exception ex) { OGCSexception.Analyse(ex); Forms.Main.Instance.Console.UpdateWithError("Unable to authenticate with Google. The following error occurred:", ex); } if (credential.Token.AccessToken != "" && credential.Token.RefreshToken != "") { log.Info("Refresh and Access token successfully retrieved."); log.Debug("Access token expires " + credential.Token.IssuedUtc.AddSeconds(credential.Token.ExpiresInSeconds.Value).ToLocalTime().ToString()); } GoogleOgcs.Calendar.Instance.Service = new CalendarService(new Google.Apis.Services.BaseClientService.Initializer() { HttpClientInitializer = credential }); if (Settings.Instance.Proxy.Type == "Custom") { GoogleOgcs.Calendar.Instance.Service.HttpClient.DefaultRequestHeaders.Add("user-agent", Settings.Instance.Proxy.BrowserUserAgent); } if (credential.Token.IssuedUtc.AddSeconds(credential.Token.ExpiresInSeconds.Value) < DateTime.UtcNow.AddMinutes(-1)) { log.Debug("Access token needs refreshing."); //This will happen automatically when using the calendar service //But we need a valid token before we call getGaccountEmail() which doesn't use the service int backoff = 0; while (backoff < Calendar.BackoffLimit) { try { GoogleOgcs.Calendar.Instance.Service.Settings.Get("useKeyboardShortcuts").Execute(); break; } catch (Google.GoogleApiException ex) { switch (Calendar.HandleAPIlimits(ref ex, null)) { case Calendar.ApiException.throwException: throw; case Calendar.ApiException.freeAPIexhausted: OGCSexception.LogAsFail(ref ex); OGCSexception.Analyse(ex); System.ApplicationException aex = new System.ApplicationException(Calendar.Instance.SubscriptionInvite); OGCSexception.LogAsFail(ref aex); authenticated = false; return(authenticated); case Calendar.ApiException.backoffThenRetry: backoff++; if (backoff == Calendar.BackoffLimit) { log.Fail("API limit backoff was not successful. Retrieving useKeyboardShortcuts setting failed."); authenticated = false; return(authenticated); } else { log.Warn("API rate limit reached. Backing off " + backoff + "sec before retry."); System.Threading.Thread.Sleep(backoff * 1000); } break; } } catch (System.Exception ex) { if (ex is Google.Apis.Auth.OAuth2.Responses.TokenResponseException) { OGCSexception.AnalyseTokenResponse(ex as Google.Apis.Auth.OAuth2.Responses.TokenResponseException, false); } else { OGCSexception.Analyse(ex); Forms.Main.Instance.Console.Update("Unable to communicate with Google services. " + (ex.InnerException != null ? ex.InnerException.Message : ex.Message), Console.Markup.warning); } authenticated = false; return(authenticated); } } log.Debug("Access token refreshed."); } getGaccountEmail(credential.Token.AccessToken); authenticated = true; Forms.Main.Instance.Console.Update("Handshake successful.", verbose: true); return(authenticated); }