2010年11月20日土曜日

Evernote API を使ってみる (4) ノート作成・取得・更新・削除

ノートを作成・取得・更新・削除するには、基本的にはノートブックの場合と一緒でNoteStoreサービスのメソッド(プロシージャ)をコールすればよい。削除(delete)は本当にデータを削除するわけではなく、Inactiveフラグを立てる(Evernoteサイトやデスクトップアプリでいう、Trashへ移動された状態)だけなので注意。データ自体を削除するには、expungeNotes()などを使う。

ノート作成・取得・更新・削除を行うテストプログラム。
public class NoteTest {

    private static String consumerKey = "consumer key";
    private static String consumerSecret = "consumer secret";
    private static String evernoteHost = "sandbox.evernote.com";
    private static String userName = "user name";
    private static String password = "password";

    private static NoteStore.Client setupNoteStore(String evernoteHost, User user) throws TException {
        // NoteStore クライアントのセットアップ
        String noteStoreUrl = "https://" + evernoteHost + "/edam/note/" + user.getShardId();
        THttpClient trans = new THttpClient(noteStoreUrl);
        TBinaryProtocol prot = new TBinaryProtocol(trans);
        NoteStore.Client noteStore = new NoteStore.Client(prot, prot);
        return noteStore;
    }

    public static void main(String[] args) {
        UserStore.Client userStore = null;
        NoteStore.Client noteStore = null;
        AuthenticationResult authResult = null;
        try {
            userStore = AuthUtil.setupUserStore(evernoteHost);
            authResult = AuthUtil.authenticate(userStore, consumerKey, consumerSecret, evernoteHost, userName, password);
            User user = authResult.getUser();
            String authToken = authResult.getAuthenticationToken();
            
            noteStore = setupNoteStore(evernoteHost, user);
            
            Notebook notebook = noteStore.getDefaultNotebook(authToken);
            
            // 新規ノート作成
            System.out.println("** CREATE **");
            Note note1 = new Note();
            note1.setTitle("testnote1");
            String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
                + "<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml.dtd\">"
                + "<en-note>Hello Evernote.</en-note>";
            note1.setContent(content);
            note1.setNotebookGuid(notebook.getGuid());
            Note created1 = noteStore.createNote(authToken, note1);
            System.out.println("ノート \"" + created1.getTitle() + "\" が作成されました。(guid=" + created1.getGuid() + ")");
            Note note2 = new Note();
            note2.setTitle("testnote2");
            note2.setContent(content);
            note2.setNotebookGuid(notebook.getGuid());
            Note created2 = noteStore.createNote(authToken, note2);
            System.out.println("ノート \"" + created2.getTitle() + "\" が作成されました。(guid=" + created1.getGuid() + ")");
            
            // ノート取得
            System.out.println("** GET **");
            Note note1_1 = noteStore.getNote(authToken, created1.getGuid(), true, false, false, false);
            System.out.println("ノート \"" + note1_1.getTitle() + "\" を取得しました。(Update Sequence Number: " + note1_1.getUpdateSequenceNum() + ")");
            System.out.println("コンテンツ: " + note1_1.getContent());
            
            // ノート更新
            System.out.println("** UPDATE **");
            String content2 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
                + "<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml.dtd\">"
                + "<en-note>My First Note.</en-note>";
            note1_1.setContent(content2);
            noteStore.updateNote(authToken, note1_1);
            Note updated = noteStore.getNote(authToken, note1_1.getGuid(), true, false, false, false);
            System.out.println("ノート \"" + updated.getTitle() + "\" を更新しました。(Update Sequence Number: " + updated.getUpdateSequenceNum() + ")");
            System.out.println("コンテンツ: " + updated.getContent());
            
            // ノート削除 (Trashに移動)
            System.out.println("** DELETE **");
            int usn = noteStore.deleteNote(authToken, created2.getGuid());
            System.out.println("ノート\"" + created2.getTitle() + "\"が削除されました。");
            
            // ノートリストを取得
            System.out.println("** FIND **");
            NoteFilter filter = new NoteFilter();
            filter.setNotebookGuid(notebook.getGuid());
            NoteList noteList = noteStore.findNotes(authToken, filter, 0, 100);
            List<Note> notes = noteList.getNotes();
            System.out.println("(Active Notes)");
            for (Note note : notes) {
                System.out.println(" - " + note.getTitle());
            }
            
            // Trashに移動されたノートリストを取得
            filter.setInactive(true);
            NoteList noteList2 = noteStore.findNotes(authToken, filter, 0, 100);
            List<Note> notes2 = noteList2.getNotes();
            System.out.println("(Inactive Notes)");
            for (Note note : notes2) {
                System.out.println(" - " + note.getTitle());
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}

実行例。
** CREATE **
ノート "testnote1" が作成されました。(guid=19ebdb55-c36b-47b5-8ce6-7ef9474b79aa)
ノート "testnote2" が作成されました。(guid=19ebdb55-c36b-47b5-8ce6-7ef9474b79aa)
** GET **
ノート "testnote1" を取得しました。(Update Sequence Number: 201)
コンテンツ: Hello Evernote.
** UPDATE **
ノート "testnote1" を更新しました。(Update Sequence Number: 203)
コンテンツ: My First Note.
** DELETE **
ノート"testnote2"が削除されました。
** FIND **
(Active Notes)
 - testnote1
(Inactive Notes)
 - testnote2

ノートのコンテンツは、Evernote Markup Language (ENML) で厳密に記述する必要がある(DTDがここ)。保存前にバリデーションがかかり、妥当なXMLでなければはじかれてしまうため、DOMなりのツールを使ってきちんと構築しないといけない。

ノートブックや、他のタイプでもそうなのだけれど、特定のオブジェクトを指定する場合にGUIDを指定しないといけないのがけっこう面倒くさい&通信が多くなる(ノートの場合はGUID以外に一意に特定できる属性がないから仕方ないけれど)。実際、アプリを作ろうという場合はGUIDをメモリなりにキャッシュしておくレイヤーをかぶせるのだと思う。

0 件のコメント:

コメントを投稿