예제 #1
0
        public void Sync_Requested(object sender = null, EventArgs e = null)
        {
            ManualForceCompare = false;
            if (sender != null && sender.GetType().ToString().EndsWith("Timer"))   //Automated sync
            {
                Forms.Main.Instance.NotificationTray.UpdateItem("delayRemove", enabled: false);
                if (Forms.Main.Instance.bSyncNow.Text == "Start Sync")
                {
                    Timer aTimer = sender as Timer;
                    log.Info("Scheduled sync started (" + aTimer.Tag.ToString() + ").");
                    if (aTimer.Tag.ToString() == "PushTimer")
                    {
                        Sync.Engine.Instance.Start(updateSyncSchedule: false);
                    }
                    else if (aTimer.Tag.ToString() == "AutoSyncTimer")
                    {
                        Sync.Engine.Instance.Start(updateSyncSchedule: true);
                    }
                }
                else if (Forms.Main.Instance.bSyncNow.Text == "Stop Sync")
                {
                    log.Warn("Automated sync triggered whilst previous sync is still running. Ignoring this new request.");
                    if (bwSync == null)
                    {
                        log.Debug("Background worker is null somehow?!");
                    }
                    else
                    {
                        log.Debug("Background worker is busy? A:" + bwSync.IsBusy.ToString());
                    }
                }
            }
            else     //Manual sync
            {
                if (Forms.Main.Instance.bSyncNow.Text == "Start Sync" || Forms.Main.Instance.bSyncNow.Text == "Start Full Sync")
                {
                    log.Info("Manual sync requested.");
                    if (SyncingNow)
                    {
                        log.Info("Already busy syncing, cannot accept another sync request.");
                        MessageBox.Show("A sync is already running. Please wait for it to complete and then try again.", "Sync already running", MessageBoxButtons.OK, MessageBoxIcon.Hand);
                        return;
                    }
                    if (Control.ModifierKeys == Keys.Shift)
                    {
                        if (Settings.Instance.SyncDirection == Direction.Bidirectional)
                        {
                            MessageBox.Show("Forcing a full sync is not allowed whilst in 2-way sync mode.\r\nPlease temporarily chose a direction to sync in first.",
                                            "2-way full sync not allowed", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                            return;
                        }
                        log.Info("Shift-click has forced a compare of all items");
                        ManualForceCompare = true;
                    }
                    Sync.Engine.Instance.Start(updateSyncSchedule: false);
                }
                else if (Forms.Main.Instance.bSyncNow.Text == "Stop Sync")
                {
                    GoogleOgcs.Calendar.Instance.Authenticator.CancelTokenSource.Cancel();
                    if (!SyncingNow)
                    {
                        return;
                    }

                    if (!bwSync.CancellationPending)
                    {
                        Forms.Main.Instance.Console.Update("Sync cancellation requested.", Console.Markup.warning);
                        bwSync.CancelAsync();
                    }
                    else
                    {
                        Forms.Main.Instance.Console.Update("Repeated cancellation requested - forcefully aborting sync!", Console.Markup.warning);
                        try {
                            bwSync.Abort();
                            bwSync.Dispose();
                            bwSync = null;
                        } catch { }
                    }
                }
            }
        }
예제 #2
0
        public void Start(Boolean updateSyncSchedule = true)
        {
            Forms.Main mainFrm = Forms.Main.Instance;
            try {
                DateTime syncStarted   = DateTime.Now;
                String   cacheNextSync = mainFrm.lNextSyncVal.Text;

                mainFrm.Console.Clear();

                if (Settings.Instance.UseGoogleCalendar == null ||
                    Settings.Instance.UseGoogleCalendar.Id == null ||
                    Settings.Instance.UseGoogleCalendar.Id == "")
                {
                    MessageBox.Show("You need to select a Google Calendar first on the 'Settings' tab.");
                    return;
                }

                if (Settings.Instance.MuteClickSounds)
                {
                    Console.MuteClicks(true);
                }

                //Check network availability
                if (!System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
                {
                    mainFrm.Console.Update("There does not appear to be any network available! Sync aborted.", Console.Markup.error, notifyBubble: true);
                    setNextSync(syncStarted, false, updateSyncSchedule, cacheNextSync);
                    return;
                }
                //Check if Outlook is Online
                try {
                    if (OutlookOgcs.Calendar.Instance.IOutlook.Offline() && Settings.Instance.AddAttendees)
                    {
                        mainFrm.Console.Update("<p>You have selected to sync attendees but Outlook is currently offline.</p>" +
                                               "<p>Either put Outlook online or do not sync attendees.</p>", Console.Markup.error, notifyBubble: true);
                        setNextSync(syncStarted, false, updateSyncSchedule, cacheNextSync);
                        return;
                    }
                } catch (System.Exception ex) {
                    mainFrm.Console.UpdateWithError(null, ex, notifyBubble: true);
                    OGCSexception.Analyse(ex, true);
                    return;
                }
                GoogleOgcs.Calendar.APIlimitReached_attendee = false;
                Forms.Main.Instance.SyncNote(Forms.Main.SyncNotes.QuotaExhaustedInfo, null, false);
                Forms.Main.Instance.bSyncNow.Text = "Stop Sync";
                Forms.Main.Instance.NotificationTray.UpdateItem("sync", "&Stop Sync");

                Forms.Main.Instance.lNextSyncVal.Text = "In progress...";

                StringBuilder sb = new StringBuilder();
                Forms.Main.Instance.Console.BuildOutput("Sync version: " + System.Windows.Forms.Application.ProductVersion, ref sb);
                Forms.Main.Instance.Console.BuildOutput((ManualForceCompare ? "Full s" : "S") + "ync started at " + syncStarted.ToString(), ref sb);
                Forms.Main.Instance.Console.BuildOutput("Syncing from " + Settings.Instance.SyncStart.ToShortDateString() +
                                                        " to " + Settings.Instance.SyncEnd.ToShortDateString(), ref sb);
                mainFrm.Console.BuildOutput(Settings.Instance.SyncDirection.Name, ref sb);

                //Make the clock emoji show the right time
                int minsPastHour = DateTime.Now.Minute;
                minsPastHour = (int)minsPastHour - (minsPastHour % 30);
                sb.Insert(0, ":clock" + DateTime.Now.ToString("hh").TrimStart('0') + (minsPastHour == 00 ? "" : "30") + ":");
                mainFrm.Console.Update(sb);

                if (Settings.Instance.OutlookPush)
                {
                    OutlookOgcs.Calendar.Instance.DeregisterForPushSync();
                }

                SyncResult syncResult     = SyncResult.Fail;
                int        failedAttempts = 0;
                Social.TrackSync();
                try {
                    GoogleOgcs.Calendar.Instance.GetCalendarSettings();
                } catch (System.AggregateException ae) {
                    OGCSexception.AnalyseAggregate(ae);
                    syncResult = SyncResult.AutoRetry;
                } catch (System.Exception ex) {
                    log.Warn(ex.Message);
                    syncResult = SyncResult.AutoRetry;
                }
                while (syncResult == SyncResult.Fail)
                {
                    if (failedAttempts > 0)
                    {
                        if (MessageBox.Show("The synchronisation failed - check the Sync tab for further details.\r\nDo you want to try again?", "Sync Failed",
                                            MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == System.Windows.Forms.DialogResult.No)
                        {
                            syncResult = SyncResult.Abandon;
                            break;
                        }
                        else
                        {
                            log.Info("User opted to retry sync straight away.");
                        }
                    }

                    //Set up a separate thread for the sync to operate in. Keeps the UI responsive.
                    bwSync = new AbortableBackgroundWorker();
                    //Don't need thread to report back. The logbox is updated from the thread anyway.
                    bwSync.WorkerReportsProgress      = false;
                    bwSync.WorkerSupportsCancellation = true;

                    //Kick off the sync in the background thread
                    bwSync.DoWork += new DoWorkEventHandler(
                        delegate(object o, DoWorkEventArgs args) {
                        BackgroundWorker b = o as BackgroundWorker;
                        try {
                            syncResult = synchronize();
                        } catch (System.Exception ex) {
                            sb = new StringBuilder();
                            mainFrm.Console.BuildOutput("The following error was encountered during sync:-", ref sb);
                            if (ex.Data.Count > 0 && ex.Data.Contains("OGCS"))
                            {
                                mainFrm.Console.BuildOutput(ex.Data["OGCS"].ToString(), ref sb);
                                mainFrm.Console.Update(sb, Console.Markup.error, notifyBubble: true);
                                if (ex.Data["OGCS"].ToString().Contains("Please try again"))
                                {
                                    syncResult = SyncResult.AutoRetry;
                                }
                            }
                            else
                            {
                                OGCSexception.Analyse(ex, true);
                                mainFrm.Console.UpdateWithError(null, ex, notifyBubble: true);
                                syncResult = SyncResult.Fail;
                            }
                        }
                    }
                        );

                    bwSync.RunWorkerAsync();
                    while (bwSync != null && (bwSync.IsBusy || bwSync.CancellationPending))
                    {
                        System.Windows.Forms.Application.DoEvents();
                        System.Threading.Thread.Sleep(100);
                    }
                    try {
                        //Get Logbox text - this is a little bit dirty!
                        if (syncResult != SyncResult.OK && mainFrm.Console.DocumentText.Contains("The RPC server is unavailable."))
                        {
                            mainFrm.Console.Update("Attempting to reconnect to Outlook...");
                            try { OutlookOgcs.Calendar.Instance.Reset(); } catch { }
                        }
                    } finally {
                        failedAttempts += (syncResult != SyncResult.OK) ? 1 : 0;
                    }
                }

                if (syncResult == SyncResult.OK)
                {
                    Settings.Instance.CompletedSyncs++;
                    consecutiveSyncFails = 0;
                    mainFrm.Console.Update("Sync finished with success!", Console.Markup.checkered_flag);
                }
                else if (syncResult == SyncResult.AutoRetry)
                {
                    consecutiveSyncFails++;
                    mainFrm.Console.Update("Sync encountered a problem and did not complete successfully.<br/>" + consecutiveSyncFails + " consecutive syncs failed.", Console.Markup.error, notifyBubble: true);
                }
                else
                {
                    consecutiveSyncFails += failedAttempts;
                    mainFrm.Console.Update("Operation aborted after " + failedAttempts + " failed attempts!", Console.Markup.error);
                }

                setNextSync(syncStarted, syncResult == SyncResult.OK, updateSyncSchedule, cacheNextSync);
                mainFrm.CheckSyncMilestone();
            } finally {
                mainFrm.bSyncNow.Text = "Start Sync";
                mainFrm.NotificationTray.UpdateItem("sync", "&Sync Now");
                if (Settings.Instance.MuteClickSounds)
                {
                    Console.MuteClicks(false);
                }

                if (Settings.Instance.OutlookPush)
                {
                    OutlookOgcs.Calendar.Instance.RegisterForPushSync();
                }

                //Release Outlook reference if GUI not available.
                //Otherwise, tasktray shows "another program is using outlook" and it doesn't send and receive emails
                OutlookOgcs.Calendar.Instance.Disconnect(onlyWhenNoGUI: true);
            }
        }