예제 #1
0
        public void AddAccountAndSetActive(RemoteStorageAccount acc)
        {
            Accounts.Add(acc);
            ActiveAccount = acc;

            OnPropertyChanged("Accounts");
        }
예제 #2
0
        private void OnPluginChanged()
        {
            ConfigurationValidated = false;
            ValidationResultData   = null;
            ValidationResultNotes  = null;

            if (SelectedProvider != null)
            {
                Account = new RemoteStorageAccount(Guid.NewGuid(), SelectedProvider, SelectedProvider.CreateEmptyRemoteStorageConfiguration());
            }
            else
            {
                Account = null;
            }

            if (_syncThread != null && _syncThread.IsAlive)
            {
                _syncThread.Abort();
            }
            if (_progressThread != null && _progressThread.IsAlive)
            {
                _progressThread.Abort();
            }

            SyncProgress = 0;
            SyncInfoText = string.Empty;
        }
예제 #3
0
        private Tuple <IRemoteStorageSyncPersistance, List <INote>, int, int> DoSync(RemoteStorageAccount acc, AlephLogger log)
        {
            var data = SelectedProvider.CreateEmptyRemoteSyncData();

            var conn = acc.Plugin.CreateRemoteStorageConnection(PluginManagerSingleton.Inst.GetProxyFactory().Build(), acc.Config, new HierarchyEmulationConfig(false, "\\", '\\'));

            var resultNotes  = new ConcurrentQueue <INote>();
            var resultErrors = new ConcurrentQueue <string>();

            int fullCount;

            Application.Current.Dispatcher.Invoke(() => { SyncInfoText = "Connect to remote"; });
            conn.StartSync(data, new List <INote>(), new List <INote>());
            {
                Application.Current.Dispatcher.Invoke(() => { SyncInfoText = "List notes from remote"; });
                var missing = conn.ListMissingNotes(new List <INote>());

                fullCount = missing.Count;

                Application.Current.Dispatcher.Invoke(() =>
                {
                    CanAbort = !acc.Plugin.SupportsNewDownloadMultithreading || missing.Count < AppSettings.DEFAULT_INITIALDOWNLOAD_PARALLELISM_THRESHOLD;
                });

                SynchronizationThread.ExecuteInParallel(
                    log,
                    "InitialDownloadNewNotes",
                    acc.Plugin.SupportsNewDownloadMultithreading,
                    missing,
                    AppSettings.DEFAULT_INITIALDOWNLOAD_PARALLELISM_LEVEL,
                    AppSettings.DEFAULT_INITIALDOWNLOAD_PARALLELISM_THRESHOLD,
                    (e, xnoteid) =>
                {
                    resultErrors.Enqueue(xnoteid);
                    return(true);
                },
                    xnoteid =>
                {
                    var msg = $"Download Note {resultNotes.Count}/{missing.Count}";
                    Application.Current.Dispatcher.Invoke(() => { SyncInfoText = msg; });

                    var note = conn.DownloadNote(xnoteid, out var isnewnote);
                    if (isnewnote)
                    {
                        note.SetLocalDirty("Set Note LocalDirty=true after download in Startupmode");
                        note.ResetRemoteDirty("Set Note RemoteDirty=false after download in Startupmode");
                        resultNotes.Enqueue(note);
                    }
                    else
                    {
                        log.Warn("Sync_FirstStart", $"Download new note {{id:'{xnoteid}'}} returned false");
                    }
                });
            }
            Application.Current.Dispatcher.Invoke(() => { SyncInfoText = "Finish synchronization"; });
            conn.FinishSync(out var _);

            return(Tuple.Create(data, resultNotes.ToList(), resultErrors.Count, fullCount));
        }
예제 #4
0
 public void OnAfterDeserialize()
 {
     _activeAccount = _accounts.FirstOrDefault(a => a.ID == _activeAccount.ID);
     if (_activeAccount == null)
     {
         throw new Exception("Deserialization error: ActiveAccount not found in AccountList");
     }
 }
예제 #5
0
        private XElement SerializeRemoteStorageAccount(RemoteStorageAccount rsa, AXMLSerializationSettings opt)
        {
            var x = CreateXElem("Account", SettingObjectTypeEnum.RemoteStorageAccount, null, opt);

            x.Add(CreateXElem("ID", SettingObjectTypeEnum.Guid, rsa.ID.ToString("B"), opt));
            x.Add(CreateXElem("Plugin", SettingObjectTypeEnum.Guid, rsa.Plugin.GetUniqueID().ToString("B"), opt));
            x.Add(CreateXElem("Config", "Generic", rsa.Config.Serialize(opt), opt));
            return(x);
        }
예제 #6
0
        private RemoteStorageAccount DeserializeRemoteStorageAccount(XElement e, AXMLSerializationSettings opt)
        {
            var rsa = new RemoteStorageAccount();

            rsa.ID     = XHelper.GetChildValue(e, "ID", Guid.Empty);
            rsa.Plugin = PluginManagerSingleton.Inst.GetPlugin(XHelper.GetChildValue(e, "Plugin", Guid.Empty));
            rsa.Config = rsa.Plugin.CreateEmptyRemoteStorageConfiguration();
            rsa.Config.Deserialize(XHelper.GetChildOrThrow(e, "Config").Elements().Single(), opt);
            return(rsa);
        }
예제 #7
0
        public void RemoveAccount(RemoteStorageAccount acc)
        {
            if (_activeAccount == acc)
            {
                ActiveAccount = Accounts.Except(new[] { acc }).FirstOrDefault();
            }

            Accounts.Remove(acc);

            OnPropertyChanged("Accounts");
        }
예제 #8
0
        private Tuple <IRemoteStorageSyncPersistance, List <INote> > DoSync(RemoteStorageAccount acc, AlephLogger log)
        {
            var data = SelectedProvider.CreateEmptyRemoteSyncData();

            var conn = acc.Plugin.CreateRemoteStorageConnection(PluginManagerSingleton.Inst.GetProxyFactory().Build(), acc.Config, new HierachyEmulationConfig(false, "\\", '\\'));

            var resultNotes = new List <INote>();

            Application.Current.Dispatcher.Invoke(() => { SyncInfoText = "Connect to remote"; });
            conn.StartSync(data, new List <INote>(), new List <INote>());
            {
                Application.Current.Dispatcher.Invoke(() => { SyncInfoText = "List notes from remote"; });
                var missing = conn.ListMissingNotes(new List <INote>());

                int idx = 0;
                foreach (var xnoteid in missing)
                {
                    var noteid = xnoteid;
                    idx++;

                    try
                    {
                        string msg = $"Download Note {idx}/{missing.Count}";
                        Application.Current.Dispatcher.Invoke(() => { SyncInfoText = msg; });

                        var note = conn.DownloadNote(noteid, out var isnewnote);
                        if (isnewnote)
                        {
                            note.SetLocalDirty("Set Note LocalDirty=true after download in Startupmode");
                            note.ResetRemoteDirty("Set Note RemoteDirty=false after download in Startupmode");
                            resultNotes.Add(note);
                        }
                        else
                        {
                            log.Warn("Sync_FirstStart", string.Format("Download new note {{id:'{0}'}} returned false", noteid));
                        }
                    }
                    catch (ThreadAbortException)
                    {
                        throw;
                    }
                    catch (Exception e)
                    {
                        throw new Exception(string.Format("Could not download new note '{0}' on remote cause of {1}", noteid, e.Message));
                    }
                }
            }
            Application.Current.Dispatcher.Invoke(() => { SyncInfoText = "Finish synchronization"; });
            conn.FinishSync();

            return(Tuple.Create(data, resultNotes));
        }
예제 #9
0
        public void ApplyNewAccountData(RemoteStorageAccount acc, IRemoteStorageSyncPersistance data, List <INote> notes)
        {
            var localFolder = Path.Combine(_pathLocalBase, acc.ID.ToString("B"));
            var localData   = Path.Combine(_pathLocalBase, acc.ID.ToString("B") + ".xml");

            if (!Directory.Exists(localFolder))
            {
                _logger.Info("Repository", "Create local note folder: " + localFolder);
                Directory.CreateDirectory(localFolder);
            }

            WriteSyncData(data, localData);

            foreach (var n in notes)
            {
                SaveNote(n, localFolder, false);
            }
        }
예제 #10
0
        public NoteRepository(string path, ISynchronizationFeedback fb, AppSettings cfg, RemoteStorageAccount acc, IAlephDispatcher disp)
        {
            _pathLocalBase   = path;
            _pathLocalFolder = Path.Combine(path, acc.ID.ToString("B"));
            _pathLocalData   = Path.Combine(path, acc.ID.ToString("B") + ".xml");
            _conn            = acc.Plugin.CreateRemoteStorageConnection(cfg.CreateProxy(), acc.Config, cfg.GetHierachicalConfig());
            _account         = acc;
            _appconfig       = cfg;
            _listener        = fb;
            _dispatcher      = disp;
            _thread          = new SynchronizationThread(this, new[] { this, fb }, cfg, _dispatcher);

            _invSaveNotesLocal     = DelayedCombiningInvoker.Create(() => _dispatcher.BeginInvoke(SaveAllDirtyNotes), 10 * 1000, 1 * 60 * 1000);
            _invSaveNotesRemote    = DelayedCombiningInvoker.Create(() => _dispatcher.BeginInvoke(SyncNow), 45 * 1000, 15 * 60 * 1000);
            _invSaveNotesGitBackup = DelayedCombiningInvoker.Create(() => _dispatcher.BeginInvoke(CommitToLocalGitBackup), 10 * 1000, 15 * 60 * 1000);

            _rawFilesystemRepo = new RawFolderRepository(this, disp, cfg);

            _notes.CollectionChanged += NoteCollectionChanged;
        }
예제 #11
0
        public void StartSync()
        {
            if (SelectedProvider == null)
            {
                return;
            }
            if (Account == null)
            {
                return;
            }

            if (_syncThread != null && _syncThread.IsAlive)
            {
                _syncThread.Abort();
            }
            if (_progressThread != null && _progressThread.IsAlive)
            {
                _progressThread.Abort();
            }

            SyncInfoText = "Starting Synchronization";
            var acc = new RemoteStorageAccount(Account.ID, Account.Plugin, Account.Config);

            _syncThread = new Thread(() =>
            {
                try
                {
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        IsValidating = true;

                        ConfigurationValidated = false;
                        ValidationResultData   = null;
                        ValidationResultNotes  = null;

                        SyncProgress = 0;
                        SyncInfoText = string.Empty;

                        CanAbort = true;
                    });

                    var r = DoSync(acc, App.Logger);
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        ConfigurationValidated = true;
                        ValidationResultData   = r.Item1;
                        ValidationResultNotes  = r.Item2;
                        SyncProgress           = r.Item3 == 0 ? -100 : -66;
                        SyncInfoText           = r.Item3 == 0 ? string.Empty : $"({r.Item3}/{r.Item4} notes had download errors)";
                    });
                }
                catch (ThreadAbortException)
                {
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        ConfigurationValidated = false;
                        ValidationResultData   = null;
                        ValidationResultNotes  = null;
                        SyncProgress           = 0;
                        SyncInfoText           = string.Empty;
                    });
                    return;
                }
                catch (Exception e)
                {
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        ConfigurationValidated = false;
                        ValidationResultData   = null;
                        ValidationResultNotes  = null;
                        SyncProgress           = -66;
                        SyncInfoText           = string.Empty;
                    });
                    Application.Current.Dispatcher.BeginInvoke(new Action(() =>
                    {
                        SyncProgress = -66;
                        SyncErrorDialog.Show(_owner, e);
                    }));
                }
                finally
                {
                    Application.Current.Dispatcher.BeginInvoke(new Action(() =>
                    {
                        IsValidating = false;
                        SyncInfoText = string.Empty;
                    }));
                }
            });
            _progressThread = new Thread(() =>
            {
                Thread.Sleep(350);
                for (;;)
                {
                    if (!_syncThread.IsAlive)
                    {
                        break;
                    }
                    Thread.Sleep(150);
                    Application.Current.Dispatcher.Invoke(() => { SyncProgress++; });
                }
                Application.Current.Dispatcher.Invoke(() =>
                {
                    if (ConfigurationValidated)
                    {
                        SyncProgress = -100;
                    }
                    else
                    {
                        SyncProgress = -66;
                    }
                    SyncInfoText = string.Empty;
                });
            });

            _syncThread.Start();
            _progressThread.Start();
        }
예제 #12
0
        public void AddAccount(IRemotePlugin p)
        {
            var acc = new RemoteStorageAccount(Guid.NewGuid(), p, p.CreateEmptyRemoteStorageConfiguration());

            Settings.AddAccountAndSetActive(acc);
        }