Пример #1
0
        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);
        }
Пример #3
0
 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);
     });
 }
Пример #4
0
 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);
     });
 }
Пример #5
0
		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);
		}
Пример #6
0
        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);
            }
        }
Пример #7
0
		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;
		}
Пример #8
0
		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;
		}
Пример #9
0
		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);
		}
Пример #10
0
		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);
			});
		}
Пример #11
0
		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);
			});
		}
Пример #12
0
		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;
		}
Пример #13
0
 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);
 }
Пример #14
0
        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;
        }
Пример #16
0
        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;
            }
        }
Пример #17
0
        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;
        }