ザネリは列車を見送った

ブログという名の備忘録

Evernote Java API で遊ぶ

ちょこちょこ調べたことの備忘。

Consumer Key, Consumer Secretの入手

http://www.evernote.com/about/developer/api/にアクセスし、「Request an API Key」フォームに必要事項記入の上送信。
しばらくすると(1~2日かかる様子)記入したメールアドレスにキーの組み合わせが送信されてくる。
このキーはサンドボックス用らしく、これでは本物の Evernote へアクセスすることはできない。
まずお試しでサンドボックスAPIを使ってみて、その後再度申請すれば本サービスへアクセスできるキーがもらえる、
という流れらしい。

Java SDK の入手

上記の同 URL の「Download the API SDK」からダウンロード。(執筆時点でバージョン 1.19 だった)
Java, C++, Perl, Python, Ruby など色んな言語が全部入り。
Java ディレクトリの中身は evernote-api-1.19.jar, libthrift,jar, log4j-1.2.14.jar の 3 つ。

とりあえずアクセスしてみる

sample のソースが同梱されているのでひと通りの事はこれを眺めればできそう。

private final String authToken;
private final NoteStore.Client noteStore;

EvernoteOperation(
 String username, String password, String consumerKey, String consumerSecret)
  throws EDAMUserException, EDAMSystemException, TException {
 String userStoreUrl = " THttpClient userStoreTrans = new THttpClient(userStoreUrl); TBinaryProtocol userStoreProt = new TBinaryProtocol(userStoreTrans); UserStore.Client userStore = new UserStore.Client(userStoreProt); AuthenticationResult authResult = userStore.authenticate(username, password, consumerKey, consumerSecret); String noteStoreUrlBase = " User user = authResult.getUser(); String noteStoreUrl = noteStoreUrlBase + user.getShardId(); THttpClient noteStoreTrans = new THttpClient(noteStoreUrl); TBinaryProtocol noteStoreProt = new TBinaryProtocol(noteStoreTrans); authToken = authResult.getAuthenticationToken(); noteStore = new NoteStore.Client(noteStoreProt); } 

こんな感じでユーザ名,パスワード,入手したキーを元に authToken と NoteStore を作成し、これを使ってアクセスする。
(URL の sandbox の部分は本サービスへアクセスする際は変更する必要があるんだろう。)

ノートの内容を取得する

作成日でソートしてタイトルと作成日,更新日を 100 件まで表示するにはこんな感じ。

void getAllNotes() throws EDAMUserException, EDAMSystemException, EDAMNotFoundException, TException {
 List notebooks = noteStore.listNotebooks(authToken);
 for (Notebook notebook : notebooks) {
  NoteFilter filter = new NoteFilter();
  filter.setNotebookGuid(notebook.getGuid());
  filter.setOrder(NoteSortOrder.CREATED.getValue());
  filter.setAscending(true);
  NoteList noteList = noteStore.findNotes(authToken, filter, 0, 100);
  List notes = noteList.getNotes();
  for (Note note : notes) {
   String title = note.getTitle();
   System.out.println("[title]" + title);
   System.out.println("[create]" + new Date(note.getCreated()));
   System.out.println("[update]" + new Date(note.getUpdated()));
  }
 }
}

ちなみに Note クラスには getContent(), getTagNames() といったメソッドがあるけれど、
上記のように取得した場合には値が入っておらず null が帰ってくるので、 内容やタグを取得するには

System.out.println("[content]" + noteStore.getNoteContent(authToken, note.getGuid()));
System.out.println("[tagnames]" + noteStore.getNoteTagNames(authToken, note.getGuid()));

というように、一意の ID をもとに別途取得する必要がある。
ノートに「test」とのみ入力している場合、内容は

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE en-note SYSTEM " <en-note> <div>test</div> </en-note> 

という Evernote 独自のタグをルートに持つ HTML として取得されるようだ。

ノートの添付ファイルを取得する

ノートに添付ファイルがある場合、getNoteContent() の一部として

<en-media hash="e47b94c2ac0627207522ab8cb3ffe439" type="image/jpeg"/>

とキーとファイルタイプのみ返ってくる。
添付ファイルの取得は別途このようにする。

void getResources(Note note, File dir) {
 for (Resource resource : note.getResources()) {
  String name = resource.getAttributes().getFileName();
  byte[] body = resource.getData().getBody();
  InputStream in = null;
  try {
   in = new ByteArrayInputStream(body);
   OutputStream out = null;
   try {
    out = new BufferedOutputStream(new FileOutputStream(new File(dir, name)));
    IOUtils.copy(in, out);
   } finally {
    if (out != null) out.close();
   }
  } finally {
   if (in != null) in.close();
  }
 }
}
ノートを作成する

取得した内容をみるに、ルート要素が en-note タグであればよさそうなのでこんな感じかな。
とりあえず作成には成功した。

void create(String title, String text) throws EDAMUserException, EDAMSystemException, EDAMNotFoundException, TException {
 Note note = new Note();
 note.setTitle(title);
 String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + 
  "<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\">" + 
  "<en-note><div>" + text + "</div></en-note>";
 note.setContent(content);
 Note createdNote = noteStore.createNote(authToken, note);
 System.out.println("[guid]" + createdNote.getGuid());
}

参考:moco β版 更新ログ Evernote API を使ってみる (1) 準備