public virtual IDictionary <string, NoteUpdate> GetNoteUpdatesSince(int revision) { Dictionary <string, NoteUpdate> noteUpdates = new Dictionary <string, NoteUpdate> (); string tempPath = Path.Combine(cachePath, "sync_temp"); if (!Directory.Exists(tempPath)) { Directory.CreateDirectory(tempPath); } else { // Empty the temp dir try { foreach (string oldFile in Directory.GetFiles(tempPath)) { File.Delete(oldFile); } } catch {} } if (IsValidXmlFile(manifestPath)) { // TODO: Permissions errors using (FileStream fs = new FileStream(manifestPath, FileMode.Open)) { XmlDocument doc = new XmlDocument(); doc.Load(fs); string xpath = string.Format("//note[@rev > {0}]", revision.ToString()); XmlNodeList noteNodes = doc.SelectNodes(xpath); Logger.Debug("GetNoteUpdatesSince xpath returned {0} nodes", noteNodes.Count); foreach (XmlNode node in noteNodes) { string id = node.SelectSingleNode("@id").InnerText; int rev = Int32.Parse(node.SelectSingleNode("@rev").InnerText); if (noteUpdates.ContainsKey(id) == false) { // Copy the file from the server to the temp directory string revDir = GetRevisionDirPath(rev); string serverNotePath = Path.Combine(revDir, id + ".note"); string noteTempPath = Path.Combine(tempPath, id + ".note"); File.Copy(serverNotePath, noteTempPath, true); // Get the title, contents, etc. string noteTitle = string.Empty; string noteXml = null; using (StreamReader reader = new StreamReader(noteTempPath)) { noteXml = reader.ReadToEnd(); } NoteUpdate update = new NoteUpdate(noteXml, noteTitle, id, rev); noteUpdates [id] = update; } } } } Logger.Debug("GetNoteUpdatesSince ({0}) returning: {1}", revision, noteUpdates.Count); return(noteUpdates); }
public IDictionary <string, NoteUpdate> GetNoteUpdatesSince(int revision) { IDictionary <string, NoteUpdate> updatedNotes = new Dictionary <string, NoteUpdate>(); Evernote.EDAM.NoteStore.SyncState syncState = _noteStore.getSyncState(_authToken); // see if anything has changed // TODO - this check might be redundant, as Tomboy calls LatestRevision() beforehand if (syncState.UpdateCount <= revision) { return(updatedNotes); } if (revision < 0) { revision = 0; } //if we got this far, then Something has changed Evernote.EDAM.NoteStore.SyncChunk syncChunk; try { syncChunk = _noteStore.getSyncChunk(_authToken, revision, Int32.MaxValue, false); } catch (Exception e) { Logger.Error("[Evernote] Failure in getSyncChunk: " + e); return(updatedNotes); } if (syncChunk.Notes == null) { return(updatedNotes); } //every note we have should be new or updated, so tell Tomboy about it foreach (Evernote.EDAM.Type.Note note in syncChunk.Notes) { if (note.NotebookGuid != _tomboyNotebook.Guid) { continue; } string content = ""; try { content = CreateTomboyNoteContent(note); } catch (XmlSchemaValidationException e) { content = "Evernote had invalid XML"; } catch (Exception e) { Logger.Error("[Evernote] Unknown error creating Tomboy Note from Evernote:" + e + "\nEvernote: " + note); } string guid = GetCorrectGuid(note); NoteUpdate update = new NoteUpdate(content, note.Title, guid, note.UpdateSequenceNum); updatedNotes.Add(note.Guid, update); } return(updatedNotes); }
private static void UpdateNoteInMainThread(Note existingNote, NoteUpdate noteUpdate) { // Note update may affect the GUI, so we have to use the // delegate to run in the main gtk thread. // To be consistent, any exceptions in the delgate will be caught // and then rethrown in the synchronization thread. GuiUtils.GtkInvokeAndWait(() => { UpdateLocalNote(existingNote, noteUpdate, NoteSyncType.DownloadModified); }); }
private static void CreateNoteInMainThread(NoteUpdate noteUpdate) { // Note creation may affect the GUI, so we have to use the // delegate to run in the main gtk thread. // To be consistent, any exceptions in the delgate will be caught // and then rethrown in the synchronization thread. GuiUtils.GtkInvokeAndWait(() => { Note existingNote = NoteMgr.CreateWithGuid(noteUpdate.Title, noteUpdate.UUID); UpdateLocalNote(existingNote, noteUpdate, NoteSyncType.DownloadNew); }); }
public void NoteConflictDetected (NoteManager manager, Note localConflictNote, NoteUpdate remoteNote, IList<string> noteUpdateTitles) { Logger.Debug ("SilentUI: NoteConflictDetected, overwriting without a care"); // TODO: At least respect conflict prefs // TODO: Implement more useful conflict handling if (localConflictNote.Id != remoteNote.UUID) GuiUtils.GtkInvokeAndWait (() => { manager.Delete (localConflictNote); }); SyncManager.ResolveConflict (SyncTitleConflictResolution.OverwriteExisting); }
private static void UpdateLocalNote(Note localNote, NoteUpdate serverNote, NoteSyncType syncType) { // In each case, update existingNote's content and revision try { localNote.LoadForeignNoteXml(serverNote.XmlContent, ChangeType.OtherDataChanged); } catch {} // TODO: Handle exception in case that serverNote.XmlContent is invalid XML client.SetRevision(localNote, serverNote.LatestRevision); // Update dialog's sync status if (syncUI != null) { syncUI.NoteSynchronized(localNote.Title, syncType); } }
public IDictionary<string, NoteUpdate> GetNoteUpdatesSince (int revision) { Dictionary<string, NoteUpdate> updates = new Dictionary<string, NoteUpdate> (); int? latestRevision; IList<NoteInfo> serverNotes = user.GetNotes (true, revision, out latestRevision); VerifyLatestSyncRevision (latestRevision); foreach (NoteInfo noteInfo in serverNotes) { string noteXml = NoteConvert.ToNoteXml (noteInfo); NoteUpdate update = new NoteUpdate (noteXml, noteInfo.Title, noteInfo.Guid, noteInfo.LastSyncRevision.Value); updates.Add (noteInfo.Guid, update); } return updates; }
public void NoteConflictDetected (NoteManager manager, Note localConflictNote, NoteUpdate remoteNote, IList<string> noteUpdateTitles) { SyncTitleConflictResolution savedBehavior = SyncTitleConflictResolution.Cancel; object dlgBehaviorPref = Preferences.Get (Preferences.SYNC_CONFIGURED_CONFLICT_BEHAVIOR); if (dlgBehaviorPref != null && dlgBehaviorPref is int) // TODO: Check range of this int savedBehavior = (SyncTitleConflictResolution)dlgBehaviorPref; SyncTitleConflictResolution resolution = SyncTitleConflictResolution.OverwriteExisting; // This event handler will be called by the synchronization thread // so we have to use the delegate here to manipulate the GUI. // To be consistent, any exceptions in the delgate will be caught // and then rethrown in the synchronization thread. Exception mainThreadException = null; Gtk.Application.Invoke (delegate { try { SyncTitleConflictDialog conflictDlg = new SyncTitleConflictDialog (localConflictNote, noteUpdateTitles); Gtk.ResponseType reponse = Gtk.ResponseType.Ok; bool noteSyncBitsMatch = SyncManager.SynchronizedNoteXmlMatches (localConflictNote.GetCompleteNoteXml (), remoteNote.XmlContent); // If the synchronized note content is in conflict // and there is no saved conflict handling behavior, show the dialog if (!noteSyncBitsMatch && savedBehavior == 0) reponse = (Gtk.ResponseType) conflictDlg.Run (); if (reponse == Gtk.ResponseType.Cancel) resolution = SyncTitleConflictResolution.Cancel; else { if (noteSyncBitsMatch) resolution = SyncTitleConflictResolution.OverwriteExisting; else if (savedBehavior == 0) resolution = conflictDlg.Resolution; else resolution = savedBehavior; switch (resolution) { case SyncTitleConflictResolution.OverwriteExisting: if (conflictDlg.AlwaysPerformThisAction) savedBehavior = resolution; // No need to delete if sync will overwrite if (localConflictNote.Id != remoteNote.UUID) manager.Delete (localConflictNote); break; case SyncTitleConflictResolution.RenameExistingAndUpdate: if (conflictDlg.AlwaysPerformThisAction) savedBehavior = resolution; RenameNote (localConflictNote, conflictDlg.RenamedTitle, true); break; case SyncTitleConflictResolution.RenameExistingNoUpdate: if (conflictDlg.AlwaysPerformThisAction) savedBehavior = resolution; RenameNote (localConflictNote, conflictDlg.RenamedTitle, false); break; } } Preferences.Set (Preferences.SYNC_CONFIGURED_CONFLICT_BEHAVIOR, (int) savedBehavior); // TODO: Clean up conflictDlg.Hide (); conflictDlg.Destroy (); // Let the SyncManager continue SyncManager.ResolveConflict (/*localConflictNote, */resolution); } catch (Exception e) { mainThreadException = e; } }); if (mainThreadException != null) throw mainThreadException; }
private static void UpdateLocalNote (Note localNote, NoteUpdate serverNote, NoteSyncType syncType) { // In each case, update existingNote's content and revision try { localNote.LoadForeignNoteXml (serverNote.XmlContent, ChangeType.OtherDataChanged); } catch {} // TODO: Handle exception in case that serverNote.XmlContent is invalid XML client.SetRevision (localNote, serverNote.LatestRevision); // Update dialog's sync status if (syncUI != null) syncUI.NoteSynchronized (localNote.Title, syncType); }
private static void RecreateNoteInMainThread (Note existingNote, NoteUpdate noteUpdate) { // Note deletion may affect the GUI, so we have to use the // delegate to run in the main gtk thread. // To be consistent, any exceptions in the delgate will be caught // and then rethrown in the synchronization thread. GuiUtils.GtkInvokeAndWait (() => { NoteMgr.Delete (existingNote); // Create note with existing content existingNote = NoteMgr.CreateWithGuid (noteUpdate.Title, noteUpdate.UUID); UpdateLocalNote (existingNote, noteUpdate, NoteSyncType.DownloadNew); }); }
private static void UpdateNoteInMainThread (Note existingNote, NoteUpdate noteUpdate) { // Note update may affect the GUI, so we have to use the // delegate to run in the main gtk thread. // To be consistent, any exceptions in the delgate will be caught // and then rethrown in the synchronization thread. GuiUtils.GtkInvokeAndWait (() => { UpdateLocalNote (existingNote, noteUpdate, NoteSyncType.DownloadModified); }); }
public virtual IDictionary<string, NoteUpdate> GetNoteUpdatesSince (int revision) { Dictionary<string, NoteUpdate> noteUpdates = new Dictionary<string, NoteUpdate> (); string tempPath = Path.Combine (cachePath, "sync_temp"); if (!Directory.Exists (tempPath)) { Directory.CreateDirectory (tempPath); } else { // Empty the temp dir try { foreach (string oldFile in Directory.GetFiles (tempPath)) { File.Delete (oldFile); } } catch {} } if (IsValidXmlFile (manifestPath)) { // TODO: Permissions errors using (FileStream fs = new FileStream (manifestPath, FileMode.Open)) { XmlDocument doc = new XmlDocument (); doc.Load (fs); string xpath = string.Format ("//note[@rev > {0}]", revision.ToString ()); XmlNodeList noteNodes = doc.SelectNodes (xpath); Logger.Debug ("GetNoteUpdatesSince xpath returned {0} nodes", noteNodes.Count); foreach (XmlNode node in noteNodes) { string id = node.SelectSingleNode ("@id").InnerText; int rev = Int32.Parse (node.SelectSingleNode ("@rev").InnerText); if (noteUpdates.ContainsKey (id) == false) { // Copy the file from the server to the temp directory string revDir = GetRevisionDirPath (rev); string serverNotePath = Path.Combine (revDir, id + ".note"); string noteTempPath = Path.Combine (tempPath, id + ".note"); File.Copy (serverNotePath, noteTempPath, true); // Get the title, contents, etc. string noteTitle = string.Empty; string noteXml = null; using (StreamReader reader = new StreamReader (noteTempPath)) { noteXml = reader.ReadToEnd (); } NoteUpdate update = new NoteUpdate (noteXml, noteTitle, id, rev); noteUpdates [id] = update; } } } } Logger.Debug ("GetNoteUpdatesSince ({0}) returning: {1}", revision, noteUpdates.Count); return noteUpdates; }
public void NoteConflictDetected(NoteManager manager, Note localConflictNote, NoteUpdate remoteNote, IList <string> noteUpdateTitles) { Logger.Debug("SilentUI: NoteConflictDetected, overwriting without a care"); // TODO: At least respect conflict prefs // TODO: Implement more useful conflict handling if (localConflictNote.Id != remoteNote.UUID) { GuiUtils.GtkInvokeAndWait(() => { manager.Delete(localConflictNote); }); } SyncManager.ResolveConflict(SyncTitleConflictResolution.OverwriteExisting); }
public virtual IDictionary <string, NoteUpdate> GetNoteUpdatesSince(int revision) { Dictionary <string, NoteUpdate> noteUpdates = new Dictionary <string, NoteUpdate>(); if (IsValidXmlFile(manifestPath)) { // TODO: Permissions errors using (FileStream fs = new FileStream(manifestPath, FileMode.Open)) { Stream plainStream; { bool ok; plainStream = SecurityWrapper.DecryptFromStream(manifestPath, fs, myKey, out ok); if (!ok) { throw new Exception("ENCRYPTION ERROR!"); } } XmlDocument doc = new XmlDocument(); doc.Load(plainStream); string xpath = string.Format("//note[@rev > {0}]", revision.ToString()); XmlNodeList noteNodes = doc.SelectNodes(xpath); Logger.Debug("GetNoteUpdatesSince xpath returned {0} nodes", noteNodes.Count); foreach (XmlNode node in noteNodes) { string id = node.SelectSingleNode("@id").InnerText; int rev = Int32.Parse(node.SelectSingleNode("@rev").InnerText); if (noteUpdates.ContainsKey(id) == false) { // Copy the file from the server to the temp directory string revDir = GetRevisionDirPath(rev); string serverNotePath = Path.Combine(revDir, id + ".note"); //string noteTempPath = Path.Combine(tempPath, id + ".note"); // DON'T ENCRYPT HERE because we are getting the already encrypted file from the server //SecurityWrapper.CopyAndEncrypt(serverNotePath, noteTempPath, myKey); //File.Copy(serverNotePath, noteTempPath, true); // Get the title, contents, etc. string noteTitle = string.Empty; string noteXml = null; { // decrypt the note: bool ok; CryptoFormat ccf = CryptoFormatProviderFactory.INSTANCE.GetCryptoFormat(); byte[] contents = ccf.DecryptFile(serverNotePath, myKey, out ok); noteXml = Util.FromBytes(contents); // solve nasty BOM problem -__- int index = noteXml.IndexOf('<'); if (index > 0) { noteXml = noteXml.Substring(index, noteXml.Length - index); } } NoteUpdate update = new NoteUpdate(noteXml, noteTitle, id, rev); noteUpdates[id] = update; } } } } Logger.Debug("GetNoteUpdatesSince ({0}) returning: {1}", revision, noteUpdates.Count); return(noteUpdates); }
public virtual IDictionary<string, NoteUpdate> GetNoteUpdatesSince(int revision) { Dictionary<string, NoteUpdate> noteUpdates = new Dictionary<string, NoteUpdate>(); if (IsValidXmlFile(manifestPath)) { // TODO: Permissions errors using (FileStream fs = new FileStream(manifestPath, FileMode.Open)) { Stream plainStream; { bool ok; plainStream = SecurityWrapper.DecryptFromStream(manifestPath, fs, myKey, out ok); if (!ok) throw new Exception("ENCRYPTION ERROR!"); } XmlDocument doc = new XmlDocument(); doc.Load(plainStream); string xpath = string.Format("//note[@rev > {0}]", revision.ToString()); XmlNodeList noteNodes = doc.SelectNodes(xpath); Logger.Debug("GetNoteUpdatesSince xpath returned {0} nodes", noteNodes.Count); foreach (XmlNode node in noteNodes) { string id = node.SelectSingleNode("@id").InnerText; int rev = Int32.Parse(node.SelectSingleNode("@rev").InnerText); if (noteUpdates.ContainsKey(id) == false) { // Copy the file from the server to the temp directory string revDir = GetRevisionDirPath(rev); string serverNotePath = Path.Combine(revDir, id + ".note"); //string noteTempPath = Path.Combine(tempPath, id + ".note"); // DON'T ENCRYPT HERE because we are getting the already encrypted file from the server //SecurityWrapper.CopyAndEncrypt(serverNotePath, noteTempPath, myKey); //File.Copy(serverNotePath, noteTempPath, true); // Get the title, contents, etc. string noteTitle = string.Empty; string noteXml = null; { // decrypt the note: bool ok; CryptoFormat ccf = CryptoFormatProviderFactory.INSTANCE.GetCryptoFormat(); byte[] contents = ccf.DecryptFile(serverNotePath, myKey, out ok); noteXml = Util.FromBytes(contents); // solve nasty BOM problem -__- int index = noteXml.IndexOf('<'); if (index > 0) { noteXml = noteXml.Substring(index, noteXml.Length - index); } } NoteUpdate update = new NoteUpdate(noteXml, noteTitle, id, rev); noteUpdates[id] = update; } } } } Logger.Debug("GetNoteUpdatesSince ({0}) returning: {1}", revision, noteUpdates.Count); return noteUpdates; }
public void NoteConflictDetected(NoteManager manager, Note localConflictNote, NoteUpdate remoteNote, IList <string> noteUpdateTitles) { SyncTitleConflictResolution savedBehavior = SyncTitleConflictResolution.Cancel; object dlgBehaviorPref = Preferences.Get(Preferences.SYNC_CONFIGURED_CONFLICT_BEHAVIOR); if (dlgBehaviorPref != null && dlgBehaviorPref is int) // TODO: Check range of this int { savedBehavior = (SyncTitleConflictResolution)dlgBehaviorPref; } SyncTitleConflictResolution resolution = SyncTitleConflictResolution.OverwriteExisting; // This event handler will be called by the synchronization thread // so we have to use the delegate here to manipulate the GUI. // To be consistent, any exceptions in the delgate will be caught // and then rethrown in the synchronization thread. Exception mainThreadException = null; Gtk.Application.Invoke(delegate { try { SyncTitleConflictDialog conflictDlg = new SyncTitleConflictDialog(localConflictNote, noteUpdateTitles); Gtk.ResponseType reponse = Gtk.ResponseType.Ok; bool noteSyncBitsMatch = SyncManager.SynchronizedNoteXmlMatches(localConflictNote.GetCompleteNoteXml(), remoteNote.XmlContent); // If the synchronized note content is in conflict // and there is no saved conflict handling behavior, show the dialog if (!noteSyncBitsMatch && savedBehavior == 0) { reponse = (Gtk.ResponseType)conflictDlg.Run(); } if (reponse == Gtk.ResponseType.Cancel) { resolution = SyncTitleConflictResolution.Cancel; } else { if (noteSyncBitsMatch) { resolution = SyncTitleConflictResolution.OverwriteExisting; } else if (savedBehavior == 0) { resolution = conflictDlg.Resolution; } else { resolution = savedBehavior; } switch (resolution) { case SyncTitleConflictResolution.OverwriteExisting: if (conflictDlg.AlwaysPerformThisAction) { savedBehavior = resolution; } // No need to delete if sync will overwrite if (localConflictNote.Id != remoteNote.UUID) { manager.Delete(localConflictNote); } break; case SyncTitleConflictResolution.RenameExistingAndUpdate: if (conflictDlg.AlwaysPerformThisAction) { savedBehavior = resolution; } RenameNote(localConflictNote, conflictDlg.RenamedTitle, true); break; case SyncTitleConflictResolution.RenameExistingNoUpdate: if (conflictDlg.AlwaysPerformThisAction) { savedBehavior = resolution; } RenameNote(localConflictNote, conflictDlg.RenamedTitle, false); break; } } Preferences.Set(Preferences.SYNC_CONFIGURED_CONFLICT_BEHAVIOR, (int)savedBehavior); // TODO: Clean up conflictDlg.Hide(); conflictDlg.Destroy(); // Let the SyncManager continue SyncManager.ResolveConflict(/*localConflictNote, */ resolution); } catch (Exception e) { mainThreadException = e; } }); if (mainThreadException != null) { throw mainThreadException; } }
public IDictionary<string, NoteUpdate> GetNoteUpdatesSince(int revision) { IDictionary<string, NoteUpdate> updatedNotes = new Dictionary<string, NoteUpdate>(); Evernote.EDAM.NoteStore.SyncState syncState = _noteStore.getSyncState(_authToken); // see if anything has changed // TODO - this check might be redundant, as Tomboy calls LatestRevision() beforehand if (syncState.UpdateCount <= revision) { return updatedNotes; } if (revision < 0) revision = 0; //if we got this far, then Something has changed Evernote.EDAM.NoteStore.SyncChunk syncChunk; try { syncChunk = _noteStore.getSyncChunk(_authToken, revision, Int32.MaxValue, false); } catch (Exception e) { Logger.Error("[Evernote] Failure in getSyncChunk: " + e); return updatedNotes; } if (syncChunk.Notes == null) { return updatedNotes; } //every note we have should be new or updated, so tell Tomboy about it foreach (Evernote.EDAM.Type.Note note in syncChunk.Notes) { if (note.NotebookGuid != _tomboyNotebook.Guid) { continue; } string content = ""; try { content = CreateTomboyNoteContent(note); } catch (XmlSchemaValidationException e) { content = "Evernote had invalid XML"; } catch (Exception e) { Logger.Error("[Evernote] Unknown error creating Tomboy Note from Evernote:" + e + "\nEvernote: " + note); } string guid = GetCorrectGuid(note); NoteUpdate update = new NoteUpdate(content, note.Title, guid, note.UpdateSequenceNum); updatedNotes.Add(note.Guid, update); } return updatedNotes; }