txqz memo

はてブのAtomAPIからまとめてブクマ

はてブはたまにどうしようもなく重いときがあり、タブが30とかあるのにこれ全部ブクマするまでどれだけ待たせるのか不明だし何か手元のOperaだとJavaScriptが重くてそもそもコメントがかけるようになるまで30秒くらい待ち続ける必要があったりしたので2006年に書いたやつのJava版を作った。

package net.txqz.client;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;

public class HatebClient {
  private HttpClient client;
  private String user;
  private String pass;

  public HatebClient(String user, String pass) {
    client = new HttpClient();
    this.user = user;
    this.pass = pass;
  }

  public void post(String fileName) throws IOException {
    String format = "<entry xmlns=\"http://purl.org/atom/ns#\"><title>dummy</title><link rel=\"related\" type=\"text/html\" href=\"%s\" /><summary type=\"text/plain\">%s</summary></entry>\n";
    String url = "http://b.hatena.ne.jp/atom/post";
    String contentType = "application/x.atom+xml";
    String encode = "UTF-8";

    BufferedReader in = new BufferedReader(new FileReader(fileName));
    String line;
    while((line = in.readLine()) != null) {
      if(!line.startsWith("http")) continue;
      PostMethod post = new PostMethod(url);
      post.setRequestHeader("Content-Type", contentType);
      post.addRequestHeader("X-WSSE", getWsseHeaderValue(user, pass));
      Object[] args = line.split(" ", 2);
      String request = args.length == 2
                     ? String.format(format, args)
                     : String.format(format, args[0], " ");

      post.getParams().setContentCharset(encode);
      post.setRequestEntity(new StringRequestEntity(request, contentType, encode));
      int status = client.executeMethod(post);
      System.out.println(status);
    }
  }

  protected final String getWsseHeaderValue(String username, String password) {
    // 省略。[Java からはてなフォトライフAtomAPIを使う](http://yohei-y.blogspot.com/2005/04/java-atomapi.html) からコピペ。
  }

  public static void main(String[] args) {
    HatebClient client = new HatebClient("aidhi", "pasuwa-do");
    String file = "path/to/filename";
    try {
      client.post(file);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

どこかのファイルに

http://example.com/bukuma_suru_URI [tag1][tag2]comment
http://example.com/bukuma_subeki_URI [tag3][tag4]komento

みたいな感じに書いてスクリプトを実行させればおkで、何をブクマしたかの情報がローカルにも残って一石二鳥ですね。


totteに指摘されるまで気づかなかったのだけれど、いま現在これを実行すると403が帰ってくる。最近調子いいんで、ずっと Ctrl+l でアドレスバーにフォーカスをあわせてブックマークレットを動かしていたので気づかなかった。検索してみると似たようなことを書いている人がいた。確かにリニューアルに伴う不具合かなーとも思ったけど、もっと探してみると、どうやらユーザーエージェントを見てリクエストを受け取るかどうかを判断しているらしいことがわかった。ということで、43行目あたりに:

post.addRequestHeader("User-Agent", "Sun Java/5.0");

とでも追加しておけば元通り動くようになります。