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); } } }