ザネリは列車を見送った

ブログという名の備忘録

Dropbox Java API で遊ぶ

アプリケーションの登録

My Appsの[Create an App]を押下する。
「App Name」と「Description」を入力し、Access level を選択する。
「App filder」と「Full Dropbox」があるので今回は Full を選択した。
アプリのインフォメーション画面に遷移するので、App key と App secret を控えておこう。

SDK の入手

Development Kits and Documentationからダウンロードする。
iOS, Android, Python, Ruby, Java があるけれど、Java のチュートリアルはあるようで無い。(Tutorial のリンクは Android のそれに遷移する)
仕方がないので Javadoc 片手に試行錯誤してみよう。

認証

  1. AppKeyPair を元に認証 URL を生成(生成ごとに毎回変わる)
  2. 認証 URL に遷移して認証完了
  3. AccessTokenPair を入手
  4. AccessTokenPair を元に各操作

という流れのようだ。

private static final String APP_KEY = "xxxxx";
private static final String APP_SECRET = "yyyyy";

public void authenticate() throws DropboxException, IOException {
 AppKeyPair appKeys = new AppKeyPair(APP_KEY, APP_SECRET);
 WebAuthSession session = new WebAuthSession(appKeys, AccessType.DROPBOX);
 DropboxAPI mDBApi = new DropboxAPI(session);
 
 WebAuthInfo info = mDBApi.getSession().getAuthInfo();
 
 System.out.println("以下の URL にアクセスしてください。");
 System.out.println(info.url);
 System.in.read(); // URL に遷移して認証を完了するのを待つため
 
 mDBApi.getSession().retrieveWebAccessToken(info.requestTokenPair);
 AccessTokenPair pair = mDBApi.getSession().getAccessTokenPair();
 System.out.println("key=" + pair.key);
 System.out.println("secret" + pair.secret);
}

今回はローカルでテスト的に実行しているけど、Web アプリとかなら getAuthInfo("コールバックURL") を指定して
自サイトに戻してやるなどの処理が必要だろう。
ハマッたのは、認証完了後に retrieveWebAccessToken() しないと、AccessTokenPair には RequestTokenPair と同じ値が入っていて、
それを使おうとすると DropboxUnlinkedException が発生する。
retrieveWebAccessToken() するまでは AccessTokenPair が null とかであれば分かりやすかったかもしれないけど、
何かしらの値があるからそれを使って問題ないのかと思い込んでしまっていた。

ファイル一覧の取得

ここからの操作は AccessTokenPair を設定して行う。

 private static final String APP_KEY = "xxxxx";
 private static final String APP_SECRET = "yyyyy";

 private static final String TOKEN_KEY = "aaaaa";
 private static final String TOKEN_SECRET = "bbbbb";

 private final DropboxAPI api;

 public ZaneliDropbox() {
  AppKeyPair appKeys = new AppKeyPair(APP_KEY, APP_SECRET);
  AccessTokenPair tokens = new AccessTokenPair(TOKEN_KEY, TOKEN_SECRET);
  
  WebAuthSession session = new WebAuthSession(appKeys, AccessType.DROPBOX, tokens);
  api = new DropboxAPI(session);
 }

 protected DropboxAPI getApi() {
  return api;
 }

特定のパス以下のファイル一覧を取得するには以下のようにする。(パスとリビジョンを表示している)
上限やサブディレクトリ取得有無、特定リビジョンなどを指定できるようだ。

 public void getList(String path, int fileLimit, boolean list) throws DropboxException {
  Entry entry = getApi().metadata(path, fileLimit, null, list, null);
  System.out.println(entry.path + " - " + entry.rev);
  if (!list) {
   return;
  }
  for (Entry child : entry.contents) {
   System.out.println(child.path + " - " + child.rev);
  }
 }

ファイルのアップロード

 public void putFile(String path, File file) throws DropboxException, IOException {
  if (!file.exists() || !file.isFile()) {
   throw new FileNotFoundException(file.getAbsolutePath());
  }
  InputStream in = null;
  try {
   in = new BufferedInputStream(new FileInputStream(file));
   ProgressListener listener = new PutFileProgressListener();
   Entry entry = getApi().putFile(path, in, file.length(), null, listener);
   System.out.println(entry.path);
  } finally {
   if (in != null) in.close();
  }
 }

 private static class PutFileProgressListener extends ProgressListener {
  @Override
  public void onProgress(long bytes, long total) {
   System.out.println("bytes=" + bytes + ", total=" + total);
  }
 }

サイズの大きいファイルをアップロードする場合、ProgressListener で一定量アップロードごとに
それを検知して処理を行うことができるようだ。

リビジョンの取得

 public void getRevisions(String path, int revLimit) throws DropboxException {
  List entries = getApi().revisions(path, revLimit);
  for (Entry entry : entries) {
   System.out.println(entry.modified + " - " + entry.rev);
  }
 }

更新日時とリビジョンを取得する。
リビジョンは「4f96019815fa」「4f95019815fa」「4f94019815fa」のような文字列。

特定リビジョンに復元

 public void restore(String path, String revision) throws DropboxException {
  getApi().restore(path, revision);
 }

metadata() や revisions() などで取得したリビジョンを指定して、その時点に戻す。
これは Dropbox ならではの API っぽくて面白かった。