+\r
+ \r
+ private void downloadInkNoteImage(String guid, String authToken) {\r
+ String urlBase = noteStoreUrl.replace("/edam/note/", "/shard/") + "/res/"+guid+".ink?slice=";\r
+// urlBase = "https://www.evernote.com/shard/s1/res/52b567a9-54ae-4a08-afc5-d5bae275b2a8.ink?slice=";\r
+ Integer slice = 1;\r
+ Resource r = conn.getNoteTable().noteResourceTable.getNoteResource(guid, false);\r
+ conn.getInkImagesTable().expungeImage(r.getGuid());\r
+ int sliceCount = 1+((r.getHeight()-1)/480);\r
+ HttpClient http = new DefaultHttpClient();\r
+ for (int i=0; i<sliceCount; i++) {\r
+ String url = urlBase + slice.toString();\r
+ HttpPost post = new HttpPost(url);\r
+ post.getParams().setParameter("auth", authToken);\r
+ List <NameValuePair> nvps = new ArrayList <NameValuePair>();\r
+ nvps.add(new BasicNameValuePair("auth", authToken));\r
+\r
+ try {\r
+ post.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));\r
+ } catch (UnsupportedEncodingException e1) {\r
+ e1.printStackTrace();\r
+ }\r
+ try {\r
+ HttpResponse response = http.execute(post);\r
+ HttpEntity resEntity = response.getEntity();\r
+ InputStream is = resEntity.getContent();\r
+ QByteArray data = writeToFile(is);\r
+ conn.getInkImagesTable().saveImage(guid, slice, data);\r
+ } catch (ClientProtocolException e) {\r
+ e.printStackTrace();\r
+ } catch (IOException e) {\r
+ e.printStackTrace();\r
+ }\r
+\r
+ slice++;\r
+ }\r
+ http.getConnectionManager().shutdown(); \r
+ noteSignal.noteChanged.emit(r.getNoteGuid(), null); // Signal to ivalidate note cache\r
+ }\r
+ \r
+ \r
+ public QByteArray writeToFile(InputStream iStream) throws IOException {\r
+\r
+ File temp = File.createTempFile("nn-inknote-temp", ".png");\r
+\r
+ // Save InputStream to the file.\r
+ BufferedOutputStream fOut = null;\r
+ try {\r
+ fOut = new BufferedOutputStream(new FileOutputStream(temp));\r
+ byte[] buffer = new byte[32 * 1024];\r
+ int bytesRead = 0;\r
+ while ((bytesRead = iStream.read(buffer)) != -1) {\r
+ fOut.write(buffer, 0, bytesRead);\r
+ }\r
+ }\r
+ finally {\r
+ iStream.close();\r
+ fOut.close();\r
+ }\r
+ QFile tempFile = new QFile(temp.getAbsoluteFile().toString());\r
+ tempFile.open(OpenModeFlag.ReadOnly);\r
+ QByteArray data = tempFile.readAll();\r
+ tempFile.close();\r
+ tempFile.remove();\r
+ return data;\r
+ }\r
+ \r
+ \r
+ //******************************************\r
+ //* Begin syncing shared notebooks \r
+ //******************************************\r
+ private void syncLinkedNotebooks() {\r
+ logger.log(logger.MEDIUM, "Authenticating Shared Notebooks");\r
+ status.message.emit(tr("Synchronizing shared notebooks."));\r
+ List<LinkedNotebook> books = conn.getLinkedNotebookTable().getAll();\r
+\r
+ for (int i=0; i<books.size(); i++) {\r
+ try {\r
+ long lastSyncDate = conn.getLinkedNotebookTable().getLastSequenceDate(books.get(i).getGuid());\r
+ int lastSequenceNumber = conn.getLinkedNotebookTable().getLastSequenceNumber(books.get(i).getGuid());\r
+\r
+ // Authenticate to the owner's shard\r
+ String linkedNoteStoreUrl = noteStoreUrlBase + books.get(i).getShardId();\r
+ THttpClient linkedNoteStoreTrans = new THttpClient(linkedNoteStoreUrl);\r
+ TBinaryProtocol linkedNoteStoreProt = new TBinaryProtocol(linkedNoteStoreTrans);\r
+ Client linkedNoteStore = new NoteStore.Client(linkedNoteStoreProt, linkedNoteStoreProt); \r
+ \r
+ linkedAuthResult = linkedNoteStore.authenticateToSharedNotebook(books.get(i).getShareKey(), authToken);\r
+ SyncState linkedSyncState = \r
+ linkedNoteStore.getLinkedNotebookSyncState(linkedAuthResult.getAuthenticationToken(), books.get(i));\r
+ if (linkedSyncState.getUpdateCount() > lastSequenceNumber) {\r
+ if (lastSyncDate < linkedSyncState.getFullSyncBefore()) {\r
+ lastSequenceNumber = 0;\r
+ } \r
+ syncLinkedNotebook(linkedNoteStore, books.get(i), lastSequenceNumber, linkedSyncState.getUpdateCount());\r
+ }\r
+ \r
+ // Synchronize local changes\r
+ syncLocalLinkedNoteChanges(linkedNoteStore, books.get(i));\r
+ \r
+ } catch (EDAMUserException e) {\r
+ e.printStackTrace();\r
+ } catch (EDAMNotFoundException e) {\r
+ status.message.emit(tr("Error synchronizing \" " +\r
+ books.get(i).getShareName()+"\". Please verify you still have access to that shared notebook."));\r
+ error = true;\r
+ e.printStackTrace();\r
+ } catch (EDAMSystemException e) {\r
+ logger.log(logger.LOW, "System error authenticating against shared notebook. "+\r
+ "Key: "+books.get(i).getShareKey() +" Error:" +e.getMessage());\r
+ e.printStackTrace();\r
+ } catch (TException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ \r
+ // Cleanup tags\r
+ conn.getTagTable().removeUnusedLinkedTags();\r
+ conn.getTagTable().cleanupTags();\r
+ tagSignal.listChanged.emit();\r
+ }\r
+\r
+ \r
+ //**************************************************************\r
+ //* Linked notebook contents (from someone else's account)\r
+ //*************************************************************\r
+ private void syncLinkedNotebook(Client linkedNoteStore, LinkedNotebook book, int usn, int highSequence) {\r
+ if (ignoreLinkedNotebooks.contains(book.getGuid()))\r
+ return;\r
+ List<Note> dirtyNotes = conn.getNoteTable().getDirtyLinkedNotes();\r
+ if (dirtyNoteGuids == null) \r
+ dirtyNoteGuids = new Vector<String>();\r
+\r
+ for (int i=0; i<dirtyNotes.size() && keepRunning; i++) {\r
+ dirtyNoteGuids.add(dirtyNotes.get(i).getGuid());\r
+ }\r
+ boolean fullSync = false;\r
+ if (usn == 0)\r
+ fullSync = true;\r
+ while (usn < highSequence) {\r
+ refreshNeeded = true;\r
+ try {\r
+ SyncChunk chunk = \r
+ linkedNoteStore.getLinkedNotebookSyncChunk(authToken, book, usn, 10, fullSync);\r
+ \r
+ // Expunge notes\r
+ syncExpungedNotes(chunk);\r
+\r
+ syncRemoteNotes(linkedNoteStore, chunk.getNotes(), fullSync, linkedAuthResult.getAuthenticationToken());\r
+ findNewLinkedTags(linkedNoteStore, chunk.getNotes(), linkedAuthResult.getAuthenticationToken());\r
+ // Sync resources\r
+ for (int i=0; i<chunk.getResourcesSize(); i++) {\r
+ syncRemoteResource(linkedNoteStore, chunk.getResources().get(i), linkedAuthResult.getAuthenticationToken());\r
+ }\r
+ syncRemoteLinkedNotebooks(linkedNoteStore, chunk.getNotebooks(), false, book);\r
+ SharedNotebook s = linkedNoteStore.getSharedNotebookByAuth(linkedAuthResult.getAuthenticationToken());\r
+ syncLinkedTags(chunk.getTags(), s.getNotebookGuid());\r
+ \r
+ // Go through & signal any notes that have changed so we can refresh the user's view\r
+ for (int i=0; i<chunk.getNotesSize(); i++) \r
+ noteSignal.noteChanged.emit(chunk.getNotes().get(i).getGuid(), null);\r
+\r
+ // Expunge Notebook records\r
+ for (int i=0; i<chunk.getExpungedLinkedNotebooksSize(); i++) {\r
+ conn.getLinkedNotebookTable().expungeNotebook(chunk.getExpungedLinkedNotebooks().get(i), false);\r
+ }\r
+ \r
+ usn = chunk.getChunkHighUSN();\r
+ conn.getLinkedNotebookTable().setLastSequenceDate(book.getGuid(),chunk.getCurrentTime());\r
+ conn.getLinkedNotebookTable().setLastSequenceNumber(book.getGuid(),chunk.getChunkHighUSN());\r
+ } catch (EDAMUserException e) {\r
+ e.printStackTrace();\r
+ } catch (EDAMSystemException e) {\r
+ e.printStackTrace();\r
+ } catch (EDAMNotFoundException e) {\r
+ e.printStackTrace();\r
+ } catch (TException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ }\r
+ // Sync remote tags\r
+ private void syncLinkedTags(List<Tag> tags, String notebookGuid) {\r
+ logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteTags");\r
+ if (tags != null) {\r
+ for (int i=0; i<tags.size() && keepRunning; i++) {\r
+ conn.getTagTable().syncLinkedTag(tags.get(i), notebookGuid, false);\r
+ }\r
+ }\r
+ logger.log(logger.EXTREME, "Leaving SyncRunner.syncRemoteTags");\r
+ }\r
+ \r
+ // Sync notebooks from a linked notebook\r
+ private void syncRemoteLinkedNotebooks(Client noteStore, List<Notebook> notebooks, boolean readOnly, LinkedNotebook linked) {\r
+ logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteNotebooks");\r
+ if (notebooks != null) {\r
+ for (int i=0; i<notebooks.size() && keepRunning; i++) {\r
+ try {\r
+ SharedNotebook s = noteStore.getSharedNotebookByAuth(linkedAuthResult.getAuthenticationToken());\r
+ conn.getLinkedNotebookTable().setNotebookGuid(s.getShareKey(), s.getNotebookGuid());\r
+ readOnly = !s.isNotebookModifiable();\r
+ notebooks.get(i).setName(linked.getShareName());\r
+ notebooks.get(i).setDefaultNotebook(false);\r
+ conn.getNotebookTable().syncLinkedNotebook(notebooks.get(i), false, readOnly); \r
+ } catch (EDAMUserException e) {\r
+ readOnly = true;\r
+ e.printStackTrace();\r
+ } catch (EDAMNotFoundException e) {\r
+ readOnly = true;\r
+ e.printStackTrace();\r
+ } catch (EDAMSystemException e) {\r
+ readOnly = true;\r
+ e.printStackTrace();\r
+ } catch (TException e) {\r
+ readOnly = true;\r
+ e.printStackTrace();\r
+ }\r
+\r
+ }\r
+ } \r
+ logger.log(logger.EXTREME, "Leaving SyncRunner.syncRemoteNotebooks");\r
+ }\r
+\r
+ private void findNewLinkedTags(Client noteStore, List<Note> newNotes, String token) {\r
+ if (newNotes == null)\r
+ return;\r
+ for (int i=0; i<newNotes.size(); i++) {\r
+ Note n = newNotes.get(i);\r
+ for (int j=0; j<n.getTagGuidsSize(); j++) {\r
+ String tag = n.getTagGuids().get(j);\r
+ if (!conn.getTagTable().exists(tag)) {\r
+ Tag newTag;\r
+ try {\r
+ newTag = noteStore.getTag(token, tag);\r
+ conn.getTagTable().addTag(newTag, false);\r
+ } catch (EDAMUserException e) {\r
+ e.printStackTrace();\r
+ } catch (EDAMSystemException e) {\r
+ e.printStackTrace();\r
+ } catch (EDAMNotFoundException e) {\r
+ e.printStackTrace();\r
+ } catch (TException e) {\r
+ e.printStackTrace();\r
+ }\r
+ \r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ // Synchronize changes locally done to linked notes\r
+ private void syncLocalLinkedNoteChanges(Client noteStore, LinkedNotebook book) {\r
+ String notebookGuid = conn.getLinkedNotebookTable().getNotebookGuid(book.getGuid());\r
+ List<Note> notes = conn.getNoteTable().getDirtyLinked(notebookGuid);\r
+ for (int i=0; i<notes.size(); i++) {\r
+ syncLocalNote(noteStore, notes.get(i), linkedAuthResult.getAuthenticationToken());\r
+ }\r
+ }\r
+\r