/// <summary>
        /// Fetches the signatures for the account.
        /// </summary>
        /// <param name="account">The account.</param>
        /// <returns>The signature hash</returns>
        private string FetchSignatures(ZPushAccount account)
        {
            Logger.Instance.Debug(this, "Fetching signatures for account {0}", account);
            using (ZPushConnection connection = account.Connect())
                using (ZPushWebServiceInfo infoService = connection.InfoService)
                {
                    GetSignatures result = infoService.Execute(new GetSignaturesRequest());

                    // Store the signatures
                    Dictionary <object, string> fullNames = new Dictionary <object, string>();
                    using (ISignatures signatures = ThisAddIn.Instance.GetSignatures())
                    {
                        foreach (Signature signature in result.all.Values)
                        {
                            string name = StoreSignature(signatures, account, signature);
                            fullNames.Add(signature.id, name);
                        }
                    }

                    // Set default signatures if available and none are set
                    if (!string.IsNullOrEmpty(result.new_message) && ShouldSetSignature(account.Account.SignatureNewMessage))
                    {
                        account.Account.SignatureNewMessage = fullNames[result.new_message];
                    }
                    if (!string.IsNullOrEmpty(result.replyforward_message) && ShouldSetSignature(account.Account.SignatureReplyForwardMessage))
                    {
                        account.Account.SignatureReplyForwardMessage = fullNames[result.replyforward_message];
                    }

                    return(result.hash);
                }
        }
Beispiel #2
0
        public void SetDeviceOptions(ZPushAccount account, SyncTimeFrame timeFrame)
        {
            try
            {
                Logger.Instance.Debug(this, "Setting sync time frame for {0} to {1}", account, timeFrame);

                // First set the server value.
                using (ZPushConnection connection = account.Connect())
                    using (ZPushWebServiceDevice deviceService = connection.DeviceService)
                    {
                        deviceService.Execute(new SetDeviceOptionsRequest(timeFrame));
                    }

                // And the local value
                account.SyncTimeFrame = timeFrame;
                Logger.Instance.Debug(this, "Set sync time frame for {0} to {1}", account, timeFrame);

                // Sync
                ThisAddIn.Instance.SendReceive(account.Account);
            }
            catch (Exception x)
            {
                Logger.Instance.Warning(this, "Exception setting sync time frame for {0} to {1}: {2}", account, timeFrame, x);
            }
        }
 private void LoadSettings()
 {
     BusyText = Properties.Resources.OOFGet_Label;
     KUITask
     .New((ctx) =>
     {
         using (ZPushConnection con = new ZPushConnection(_account, ctx.CancellationToken))
         {
             _settings = con.Execute(new ActiveSync.SettingsOOFGet());
         }
     })
     .OnSuccess(InitSettings, true)
     .OnError((e) =>
     {
         Logger.Instance.Warning(this, "Exception getting OOF state: {0}", e);
         if (MessageBox.Show(
                 Properties.Resources.OOFGet_Failed,
                 Properties.Resources.OOFGet_Title,
                 MessageBoxButtons.OKCancel,
                 MessageBoxIcon.Error
                 ) != DialogResult.OK)
         {
             DialogResult = DialogResult.Cancel;
         }
         else
         {
             // Initialise default settings
             _settings = new ActiveSync.SettingsOOF(true);
             InitSettings();
         }
     })
     .Start(this)
     ;
 }
        protected override void ProcessRequest()
        {
            string username = Url;
            // Request the data from the ZPush server
            ZPushConnection connection = new ZPushConnection(_freeBusy.FindZPushAccount(username), new System.Threading.CancellationToken(false));

            // Include yesterday in the request, outlook shows it by default
            var request = new ActiveSync.ResolveRecipientsRequest(username,
                                                                  DateTime.Today.AddDays(-1),
                                                                  DateTime.Today.AddMonths(6));
            var response = connection.Execute(request);

            // If there is no FreeBusy data, return 404
            if (response?.FreeBusy == null)
            {
                throw new InvalidOperationException();
            }

            Logger.Instance.Trace(this, "Writing response");
            // Encode the response in vcard format
            Out.WriteLine("HTTP/1.0 200 OK");
            Out.WriteLine("Content-Type: text/vcard");
            Out.WriteLine("Connection: close");
            Out.WriteLine("");


            Out.WriteLine("BEGIN:VCALENDAR");
            Out.WriteLine("PRODID:-//ZPush//EN");
            Out.WriteLine("VERSION:2.0");
            Out.WriteLine("BEGIN:VFREEBUSY");
            Out.WriteLine("ORGANIZER:" + username);
            Out.WriteLine(string.Format("URL:http://127.0.0.1:{0}/{1}/{2}", _freeBusy.Port, FeatureFreeBusy.URL_IDENTIFIER, username));
            Out.WriteLine(string.Format("DTSTAMP:{0:" + Constants.DATE_ISO_8601 + "}", DateTime.Now));
            Out.WriteLine(string.Format("DTSTART:{0:" + Constants.DATE_ISO_8601 + "}", response.FreeBusy.StartTime));
            Out.WriteLine(string.Format("DTEND:{0:" + Constants.DATE_ISO_8601 + "}", response.FreeBusy.EndTime));

            foreach (ActiveSync.FreeBusyData data in response.FreeBusy)
            {
                if (data.Type != ActiveSync.FreeBusyType.Free)
                {
                    string freeBusy = string.Format("FREEBUSY;FBTYPE={2}:{0:" + Constants.DATE_ISO_8601 + "}/{1:" + Constants.DATE_ISO_8601 + "}",
                                                    data.Start, data.End, MapType(data.Type));
                    Out.WriteLine(freeBusy);
                }
            }

            Out.WriteLine("END:VFREEBUSY");
            Out.WriteLine("END:VCALENDAR");
        }
 private void Periodic_Sync(ZPushConnection connection)
 {
     try
     {
         // TODO: merge this into ZPushAccount, allow periodic rechecking of Z-Push confirmation. That was other
         //       features can be updated too, e.g. OOF status. That's pretty easy to do, only need to check if
         //       no other features will break if the ConfirmedChanged event is raised multiple times
         ActiveSync.SettingsOOF oof = connection.Execute(new ActiveSync.SettingsOOFGet());
         SyncSignatures(connection.Account, oof.RawResponse.SignaturesHash);
     }
     catch (System.Exception e)
     {
         Logger.Instance.Error(this, "Error fetching signature hash: {0}", e);
     }
 }
Beispiel #6
0
        private void CheckSyncState(ZPushAccount account)
        {
            // TODO: we probably want one invocation for all accounts
            using (ZPushConnection connection = account.Connect())
            {
                // Check total size
                CheckTotalSize(connection);

                // Update sync state
                using (ZPushWebServiceDevice deviceService = connection.DeviceService)
                {
                    // Fetch
                    DeviceDetails details = deviceService.Execute(new GetDeviceDetailsRequest());
                    if (details != null)
                    {
                        bool wasSyncing = false;

                        // Create or update session
                        SyncSession session = account.GetFeatureData <SyncSession>(this, null);
                        if (session == null)
                        {
                            session = new SyncSession(this, account);
                        }
                        else
                        {
                            wasSyncing = session.IsSyncing;
                        }

                        session.Add(details);

                        // Store with the account
                        account.SetFeatureData(this, null, session);

                        if (wasSyncing != session.IsSyncing)
                        {
                            // Sync state has changed, update the schedule
                            Watcher.Sync.SetTaskSchedule(_task, account, session.IsSyncing ? CheckPeriodSync : (TimeSpan?)null);
                        }
                    }
                }
            }

            // Update the total for all accounts
            UpdateTotalSyncState();

            // Check for stalls
            CheckSyncStalled(account);
        }
Beispiel #7
0
        private void AdditionalFolders_Sync(ZPushConnection connection)
        {
            using (SharedFoldersManager manager = Manage(connection.Account))
            {
                Logger.Instance.Debug(this, "Starting sync for account {0}", connection.Account);

                // Fetch the current shares
                ICollection <SharedFolder> shares = manager.GetCurrentShares(null);
                Logger.Instance.Trace(this, "AdditionalFolders_Sync: {0}", shares.Count);

                // Convert to dictionary
                Dictionary <SyncId, SharedFolder> dict = shares.ToDictionary(x => x.SyncId);
                Logger.Instance.Trace(this, "AdditionalFolders_Sync2: {0}", shares.Count);

                // Store with the account
                connection.Account.SetFeatureData(this, KEY_SHARES, dict);
            }
        }
Beispiel #8
0
        /// <summary>
        /// Handles a new account.
        /// </summary>
        /// <param name="account">The account.</param>
        internal void OnAccountDiscovered(ZPushAccount account)
        {
            // Notify any account listeners
            AccountDiscovered?.Invoke(account);

            // Register any events
            HandleFolderWatchers(account);

            if (account.Account.HasPassword)
            {
                // Send an OOF request to get the OOF state and capabilities
                Tasks.Task(null, null, "ZPushCheck: " + account.DisplayName, () =>
                {
                    // TODO: if this fails, retry?
                    ActiveSync.SettingsOOF oof;
                    using (ZPushConnection connection = new ZPushConnection(account, new System.Threading.CancellationToken(false)))
                    {
                        oof = connection.Execute(new ActiveSync.SettingsOOFGet());
                    }

                    account.OnConfirmationResponse(oof.RawResponse);

                    // [ZO-109] Always update the current selection, it might have changed.
                    Explorer_SelectionChange();

                    // Notify the OOF feature.
                    // TODO: this coupling is pretty hideous
                    ThisAddIn.Instance.GetFeature <FeatureOutOfOffice>()?.OnOOFSettings(account, oof);
                });
            }
            else
            {
                ThisAddIn.Instance.InvokeUI(() =>
                {
                    Logger.Instance.Warning(this, "Password not available for account: {0}", account);
                    System.Windows.Forms.MessageBox.Show(ThisAddIn.Instance.Window,
                                                         string.Format(Properties.Resources.AccountNoPassword_Body, account.DisplayName),
                                                         Properties.Resources.AccountNoPassword_Title,
                                                         System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Information
                                                         );
                });
            }
        }
Beispiel #9
0
            /// <summary>
            /// Returns the task for execution.
            /// </summary>
            /// <param name="schedule">The schedule that triggered the task execution, or null if this is a sync.</param>
            /// <param name="account">The account for which the tasks are requested.</param>
            /// <returns>The task instance, or null if there is no task to execute in this schedule.</returns>
            public AcaciaTask GetInstance(Schedule schedule, ZPushAccount account)
            {
                if (!IsTaskScheduleApplicable(schedule, account))
                {
                    return(null);
                }

                if (_actionConnection != null)
                {
                    return(new AcaciaTask(null, _owner, _name, () =>
                    {
                        // TODO: reuse connections
                        using (ZPushConnection con = account.Connect())
                        {
                            _actionConnection(con);
                        }
                    }));
                }
                else
                {
                    return(new AcaciaTask(null, _owner, _name, () => _action(account)));
                }
            }
 private void AdditionalFolders_Sync(ZPushConnection connection)
 {
     SyncShares(connection.Account);
 }
        private void _buttons_Apply(object sender, EventArgs e)
        {
            BusyText = Properties.Resources.OOFSet_Label;
            ActiveSync.SettingsOOF currentSettings = GetSettings();
            KUITask
            .New((ctx) =>
            {
                using (ZPushConnection connection = new ZPushConnection(_account, ctx.CancellationToken))
                {
                    // Set the OOF state. This always seems to return ok, so we fetch the settings
                    // again, to see what happend
                    connection.Execute(new ActiveSync.SettingsOOFSet(currentSettings));

                    // Fetch the OOF state
                    return(connection.Execute(new ActiveSync.SettingsOOFGet()));
                }
            })
            .OnSuccess((appliedSettings) =>
            {
                // Store them for later use
                _feature.StoreOOFSettings(_account, appliedSettings);

                // Check what happened
                string message;
                MessageBoxIcon messageIcon;
                if (currentSettings.State == ActiveSync.OOFState.Disabled)
                {
                    // Tried to disable.
                    if (appliedSettings.State != ActiveSync.OOFState.Disabled)
                    {
                        // It's an error if its not actually disabled
                        message     = Properties.Resources.OOFSet_DisableFailed;
                        messageIcon = MessageBoxIcon.Error;
                    }
                    else
                    {
                        // All good
                        message     = Properties.Resources.OOFSet_Disabled;
                        messageIcon = MessageBoxIcon.Information;
                    }
                }
                else if (appliedSettings.State == ActiveSync.OOFState.Disabled)
                {
                    // It's an error if the state is set to disabled when we tried to enable
                    message     = Properties.Resources.OOFSet_EnableFailed;
                    messageIcon = MessageBoxIcon.Error;
                }
                else
                {
                    // All good
                    if (appliedSettings.State == ActiveSync.OOFState.EnabledTimeBased)
                    {
                        message = string.Format(Properties.Resources.OOFSet_EnabledTimeBased,
                                                appliedSettings.From, appliedSettings.Till);
                    }
                    else
                    {
                        message = Properties.Resources.OOFSet_Enabled;
                    }
                    messageIcon = MessageBoxIcon.Information;

                    // It's okay if the state is not the same, but it deserves a message
                    if (appliedSettings.State != currentSettings.State)
                    {
                        message     = Properties.Resources.OOFSet_DifferentState + message;
                        messageIcon = MessageBoxIcon.Warning;
                    }
                }

                Logger.Instance.Debug(this, "OOF state updated: {0}, {1}", message, messageIcon);
                MessageBox.Show(message,
                                Properties.Resources.OOFSet_Title,
                                MessageBoxButtons.OK,
                                messageIcon
                                );

                if (messageIcon == MessageBoxIcon.Information)
                {
                    // All good, close the dialog
                    _buttons.IsDirty = false;
                    DialogResult     = DialogResult.OK;
                }
                else
                {
                    // There was a problem, initialise the dialog to what's set.
                    _settings = appliedSettings;
                    InitSettings();
                    CheckDirty();
                }
            }, true)
            .OnError((x) =>
            {
                ErrorUtil.HandleErrorNew(this, "Exception in OOFSet", x,
                                         Properties.Resources.OOFSet_Title, Properties.Resources.OOFSet_Failed);
            })
            .Start(this)
            ;
        }
Beispiel #12
0
 /// <summary>
 /// Creates an instance on an explicit connection.
 /// </summary>
 /// <param name="connection">The connection.</param>
 /// <param name="dispose">Controls whether the connection will be disposed when the API is disposed.</param>
 public SharedFoldersAPI(ZPushConnection connection, bool dispose = false)
 {
     this._connection = connection;
     this._dispose    = dispose;
 }
Beispiel #13
0
        private void CheckTotalSize(ZPushConnection connection)
        {
            if (!CheckStoreSize || _checkedStoreSize)
            {
                return;
            }

            // Only works on 2.5
            // If we don't have the version yet, try again later
            if (connection.Account.ZPushVersion == null)
            {
                return;
            }

            // Only check once
            _checkedStoreSize = true;

            // If it's not 2.5, don't check again
            if (!connection.Account.ZPushVersion.IsAtLeast(2, 5))
            {
                return;
            }

            try
            {
                Logger.Instance.Debug(this, "Fetching size information for account {0}", connection.Account);
                using (ZPushWebServiceInfo infoService = connection.InfoService)
                {
                    UserStoreInfo info = infoService.Execute(new GetUserStoreInfoRequest());
                    Logger.Instance.Debug(this, "Size information: {0}", info);
                    SyncTimeFrame suggested = SuggestSyncTimeFrame(info);

                    if (suggested.IsShorterThan(connection.Account.SyncTimeFrame))
                    {
                        // Suggest shorter time frame, if not already done
                        string lastCheckedSize = connection.Account.Account[KEY_CHECKED_SIZE];
                        if (!string.IsNullOrWhiteSpace(lastCheckedSize))
                        {
                            try
                            {
                                SyncTimeFrame old = (SyncTimeFrame)int.Parse(lastCheckedSize);
                                if (old >= suggested)
                                {
                                    Logger.Instance.Trace(this, "Not suggesting reduced sync time frame again: {0}: {2} -> {1}", info, suggested, old);
                                    return;
                                }
                            }
                            catch (Exception e)
                            {
                                Logger.Instance.Warning(this, "Invalid lastCheckedSize: {0}: {1}", lastCheckedSize, e);
                            }
                        }

                        Logger.Instance.Debug(this, "Suggesting reduced sync time frame: {0}: {2} -> {1}", info, suggested, connection.Account.SyncTimeFrame);

                        // Suggest a shorter timeframe
                        DialogResult result = MessageBox.Show(ThisAddIn.Instance.Window,
                                                              string.Format(Properties.Resources.SyncState_StoreSize_Body,
                                                                            info.storesize.ToSizeString(SizeUtil.Size.MB),
                                                                            suggested.ToDisplayString()),
                                                              Properties.Resources.SyncState_StoreSize_Caption,
                                                              MessageBoxButtons.OKCancel, MessageBoxIcon.Information);

                        if (result == DialogResult.OK)
                        {
                            // Set the sync time frame
                            Logger.Instance.Debug(this, "Applying reduced sync time frame: {0}: {2} -> {1}", info, suggested, connection.Account.SyncTimeFrame);
                            connection.Account.SyncTimeFrame = suggested;
                        }
                    }

                    connection.Account.Account[KEY_CHECKED_SIZE] = ((int)suggested).ToString();
                }
            }
            catch (Exception e)
            {
                Logger.Instance.Warning(this, "Error suggesting size: {0}", e);
            }
        }