Exemple #1
0
        private void DoSync()
        {
            _log.Info("Sync", "Starting remote synchronization");

            List <Tuple <string, Exception> > errors = new List <Tuple <string, Exception> >();

            dispatcher.BeginInvoke(() => { foreach (var l in listener)
                                           {
                                               l.StartSync();
                                           }
                                   });

            try
            {
                var data = repo.GetSyncData();

                List <Tuple <INote, INote> > allNotes = new List <Tuple <INote, INote> >();           // <real, clone>
                List <INote> notesToDelete            = new List <INote>();
                dispatcher.Invoke(() =>
                {
                    allNotes      = repo.Notes.Select(p => Tuple.Create(p, p.Clone())).ToList();
                    notesToDelete = repo.LocalDeletedNotes.ToList();
                });

                _log.Info("Sync", string.Format("Found {0} alive notes and {1} deleted notes", allNotes.Count, notesToDelete.Count));

                repo.Connection.StartSync(data, allNotes.Select(p => p.Item2).ToList(), notesToDelete);
                {
                    // plugin says 'upload'
                    var notesToUpload = allNotes.Where(p => repo.Connection.NeedsUpload(p.Item2)).ToList();
                    // plugin says 'download'
                    var notesToDownload = allNotes.Where(p => repo.Connection.NeedsDownload(p.Item2)).ToList();
                    // we think 'upload', but provider doesn't say so
                    var notesToResetDirty = allNotes.Where(p => !p.Item2.IsRemoteSaved && !notesToUpload.Contains(p)).ToList();

                    _log.Info("Sync", string.Format("Found {0} notes for upload and {1} notes for download", notesToUpload.Count, notesToDownload.Count));

                    UploadNotes(notesToUpload, notesToResetDirty, ref errors);

                    DownloadNotes(notesToDownload, ref errors);

                    DeleteNotes(notesToDelete, ref errors);

                    DownloadNewNotes(allNotes, ref errors);
                }
                repo.Connection.FinishSync();

                repo.WriteSyncData(data);
            }
            catch (RestException e)
            {
                errors.Add(Tuple.Create <string, Exception>("Execption while syncing notes: " + e.ShortMessage, e));
            }
            catch (Exception e)
            {
                errors.Add(Tuple.Create("Execption while syncing notes: " + e.Message, e));
            }

            if (errors.Any())
            {
                dispatcher.BeginInvoke(() => { foreach (var l in listener)
                                               {
                                                   l.SyncError(errors);
                                               }
                                       });
            }
            else
            {
                dispatcher.BeginInvoke(() => { foreach (var l in listener)
                                               {
                                                   l.SyncSuccess(DateTimeOffset.Now);
                                               }
                                       });
            }

            _log.Info("Sync", "Finished remote synchronization");
        }
        private void DoSync(bool isImmediateResync)
        {
            _log.Info("Sync", $"Starting remote synchronization (immediate={isImmediateResync})");

            List <Tuple <string, Exception> > errors = new List <Tuple <string, Exception> >();

            _dispatcher.BeginInvoke(() => { foreach (var l in _listener)
                                            {
                                                l.StartSync();
                                            }
                                    });

            bool doImmediateResync = false;

            try
            {
                var data = _repo.GetSyncData();

                List <Tuple <INote, INote> > allNotes = new List <Tuple <INote, INote> >();           // <real, clone>
                List <INote> notesToDelete            = new List <INote>();
                _dispatcher.Invoke(() =>
                {
                    allNotes      = _repo.Notes.Select(p => Tuple.Create(p, p.Clone())).ToList();
                    notesToDelete = _repo.LocalDeletedNotes.ToList();
                });

                _log.Info(
                    "Sync",
                    $"Found {allNotes.Count} alive notes and {notesToDelete.Count} deleted notes",
                    $"Alive:\n{string.Join("\n", allNotes.Select(n => $"{n.Item2.UniqueName}    {n.Item2.Title}"))}\n\n\n" +
                    $"Deleted:\n{string.Join("\n", notesToDelete.Select(n => $"{n.UniqueName}    {n.Title}"))}");

                _repo.Connection.StartSync(data, allNotes.Select(p => p.Item2).ToList(), notesToDelete);
                {
                    // plugin says 'upload'
                    var notesToUpload = allNotes.Where(p => _repo.Connection.NeedsUpload(p.Item2)).ToList();
                    // plugin says 'download'
                    var notesToDownload = allNotes.Where(p => _repo.Connection.NeedsDownload(p.Item2)).ToList();
                    // we think 'upload', but provider doesn't say so
                    var notesToResetDirty = allNotes.Where(p => !p.Item2.IsRemoteSaved && !notesToUpload.Contains(p)).ToList();

                    _log.Info(
                        "Sync",
                        $"Found {notesToUpload.Count} notes for upload and {notesToDownload.Count} notes for download",
                        $"Upload:\n{string.Join("\n", notesToUpload.Select(n => $"{n.Item2.UniqueName}    {n.Item2.Title}"))}\n\n\n" +
                        $"Download:\n{string.Join("\n", notesToDownload.Select(n => $"{n.Item2.UniqueName}    {n.Item2.Title}"))}");

                    UploadNotes(notesToUpload, notesToResetDirty, errors);

                    DownloadNotes(notesToDownload, errors);

                    DeleteNotes(notesToDelete, errors);

                    DownloadNewNotes(allNotes, errors);
                }
                _repo.Connection.FinishSync(out doImmediateResync);

                _repo.WriteSyncData(data);
            }
            catch (RestException e)
            {
                errors.Add(Tuple.Create <string, Exception>("Execption while syncing notes: " + e.ShortMessage, e));
            }
            catch (Exception e)
            {
                errors.Add(Tuple.Create("Execption while syncing notes: " + e.Message, e));
            }

            if (errors.Any())
            {
                _dispatcher.BeginInvoke(() => { foreach (var l in _listener)
                                                {
                                                    l.SyncError(errors);
                                                }
                                        });
            }
            else
            {
                _dispatcher.BeginInvoke(() => { foreach (var l in _listener)
                                                {
                                                    l.SyncSuccess(DateTimeOffset.Now);
                                                }
                                        });
            }

            _log.Info("Sync", "Finished remote synchronization");

            if (doImmediateResync)
            {
                if (isImmediateResync)
                {
                    _log.Warn("Sync", "Sync triggered an immediate resync. This was preventeed because past sync event was already immediate (prevent endless sync)");
                }
                else
                {
                    _log.Info("Sync", "Sync triggered an immediate resync. Next sync will be executed now.");
                    DoSync(true);
                }
            }
        }