2009/09/06

AppEngine for JavaでTwitter4Jを使ってみる

Twitter4JはTwitter APIをJavaでラップしたライブラリです。
こちらのサイト↓で提供されています。
http://yusuke.homeip.net/twitter4j/ja/index.html

普通に使う分にはzip版をダウンロードして「twitter4j-x.x.x.jar」を利用すればよいでしょう。

もし、自分でコードを変更してビルドしたい場合はantを使ってビルドすることができます。
以下のようにEclipseのプラグインに入っているantを利用すると簡単です。

> set PATH=%PATH%;C:\Program Files\eclipse3.5\eclipse\\plugins\org.apache.ant_1.7.0.v200803061910\bin
> set ANT_OPTS=-Dfile.encoding=UTF8
> ant

使い方はいたって簡単、ID,パスワードを指定してTwitterクラスのインスタンスを作成して、getUserTimeLine()だとかgetFriendsTimeline()を呼び出すだけです。

Twitter twitter = new Twitter(id, password);
for (Status status : twitter.getUserTimeline()) {
System.out.println(status.getCreatedAt().toLocaleString());
System.out.println(status.getText());
}

さて、今回はこれをGoogle App Engine for Javaで利用してみたいと思います。

App Engine for Javaで開発するにはEclipse + GAE pluginという組み合わせを強くお勧めします。
解説については本家のUsing the Google Plugin for Eclipseスタートガイドを読むとよいでしょう。

GWTも同時に入れた時の注意点としては、アプリケーションの雛型作成のときに「GWTを使用する」のチェックボックスをオフにすることです。
GWTを使うと雛型が複雑になってしまうので今回のアプリには必要ありません。

App Engineでthird partyライブラリであるTwitter4Jを使うには、jarファイルをプログラムと一緒にデプロイするように設定する必要があります。
設定手順は以下のとおりです。

  1. twitter4j-x.x.x.jarをwar\WEB-INF\libにコピーする

  2. EclipseのProject Explorerでwar\WEB-INF\libを開き、Refresh(F5)してjarファイルが表示されることを確認する

  3. EclipseでProject Propertyを開き、Java Build Path - LibrariesにおいてAdd Jarsでtwitter4j-x.x.x.jarを追加する


これでTwitter4JをApp Engineで使う準備が整いました。

とりあえず、自分のタイムラインを整形して表示してみようと思います。
最新20件だけでは簡単すぎるので次ページ、前ページでリンクを表示して履歴が見えるようにしてみます。

タイムラインのページを操作するにはgetUserTimeline()にPagingというパラメータを与えて次のように呼び出します。

Twitter twitter = new Twitter(id, password);
List statuses = twitter.getUserTimeline(new Paging(page, numPage));


また、このページ数をCGI parameterで処理するようにします。
CGI parameterの取得、解釈及び、prev/nextのリンク表示は以下のようになります。

int page = 0;
try {
page = Integer.parseInt(req.getParameter("page"));
} catch(Exception e) {
// do nothing
}
page = (page > 0) ? page : 1;
//
// some code
//
if (page > 1) {
out.println("<a href=\"" + req.getContextPath() + "?page=" + integer.toString(page - 1) + "\">prev</a>");
}
out.println("<a href=\"" + req.getContextPath() + "?page=" + Integer.toString(page + 1) + "\">next</a>");


Timelineの整形部分を含めた最終的なコードは次のようになります。

package yourpackage;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.TimeZone;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import twitter4j.Paging;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;

@SuppressWarnings("serial")
public class TwitterTimelineServlet extends HttpServlet {
private static final String TWITTER_ID = "your twitter ID";
private static final String TWITTER_PASSWORD = "your twitter password";

List<Status> getTwitterTimeline(String id, String password, int page, int numPage) {
try {
Twitter twitter = new Twitter(id, password);
return twitter.getUserTimeline(new Paging(page, numPage));
} catch (TwitterException e) {
e.printStackTrace();
}
return new ArrayList<Status>();
}

String formatTimeline(List<Status> statuses) {
StringBuffer sb = new StringBuffer();

SimpleDateFormat dateFmt = new SimpleDateFormat("yyyy/MM/dd");
SimpleDateFormat timeFmt = new SimpleDateFormat("HH:mm");
dateFmt.setTimeZone(TimeZone.getTimeZone("JST"));
timeFmt.setTimeZone(TimeZone.getTimeZone("JST"));

Collections.reverse(statuses);
String prevDate = null;
for (Status status : statuses) {
String currDate = dateFmt.format(status.getCreatedAt());
if (!currDate.equals(prevDate)) {
sb.append((prevDate != null) ? "\n" : "");
sb.append(currDate + "\n");
}
sb.append("  " + timeFmt.format(status.getCreatedAt())
+ " " + status.getText().replaceAll("\n", "\n      ") + "\n");
prevDate = currDate;
}

return sb.toString();
}

public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
resp.setContentType("text/html");
resp.setCharacterEncoding("UTF-8");

int page = 0;
try {
page = Integer.parseInt(req.getParameter("page"));
} catch(Exception e) {
// do nothing
}
page = (page > 0) ? page : 1;

PrintWriter out = resp.getWriter();
out.println("<html>" +
"<head>" +
"<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\" />" +
"</head>" +
"<body><pre>");

String timeline = formatTimeline(getTwitterTimeline(TWITTER_ID, TWITTER_PASSWORD, page, 20));

out.println("Twitter timeline for " + TWITTER_ID);
out.println(timeline);

out.println("</pre>");
if (page > 1) {
out.println("<a href=\"" + req.getContextPath() + "?page=" + Integer.toString(page - 1) + "\">prev</a>");
}
out.println("<a href=\"" + req.getContextPath() + "?page=" + Integer.toString(page + 1) + "\">next</a>");
out.println("</body></html>");
}
}

どうだったでしょうか。
Twitter4Jのおかげでとても簡単にTwitterから情報を取得できました。

今度はTwitter4Jは使って応用的なプログラムを作ってみようと思います。

Syntax Highlighterでコードをきれいに魅せる

ブログにコードを載せる時、普通にpre, tableタグなどで囲って表示するより、その言語のsyntaxをハイライトして表示する方がはるかに見やすくなります。

以下のJavaコードを見てもらうとわかりますが、public, class, static, voidといったJava特有のキーワードがハイライトされている上、行番号もついているのでコードについて解説するときも便利かと思います。

public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World");
}
}

この機能を提供してくれるライブラリが以下のSyntax Highlighterです。
http://alexgorbatchev.com/wiki/SyntaxHighlighter

GoogleCodeにもプロジェクトがありますがなぜかバージョンが1.5で止まっています。

Syntax HighlighterはJava ScriptとStyle Sheetからなっていて、HTMLソース中に

<pre class="brush: java">
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
</pre>

のようなタグを見つけると、指定されているclassの値に応じてその内容をデコレーションしてくれます。

まずはローカルのHTMLファイルで実験してみます。
以下のHTMLをファイルとして保存してブラウザで開いてみてください。
コード領域にカーソルを合わせた時に右上にアイコンが表示されますが、これのview sourceまたはcopy to clipboardを利用するとよいでしょう。

<html>
<head>
<script type="text/javascript" src="http://alexgorbatchev.com/pub/sh/2.0.320/scripts/shCore.js"></script>
<script type="text/javascript" src="http://alexgorbatchev.com/pub/sh/2.0.320/scripts/shBrushJava.js"></script>
<script type="text/javascript">
SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/2.0.320/scripts/clipboard.swf';
SyntaxHighlighter.all();
</script>
<link type="text/css" rel="stylesheet" href="http://alexgorbatchev.com/pub/sh/2.0.320/styles/shCore.css"/>
<link type="text/css" rel="stylesheet" href="http://alexgorbatchev.com/pub/sh/2.0.320/styles/shThemeDefault.css" id="shTheme"/>
</head>

<body>
<pre class="brush: java">
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
</pre>
</body>
</html>

ここでは、shBrushJava.jsのみ読み込んでいますが、他にもC++,C#,PHP,Perl,Python,JScript,XML,HTML,Plain textなどなど、多くの言語に対応しています。

対応している言語の一覧は以下にあります。
http://alexgorbatchev.com/wiki/SyntaxHighlighter:Brushes

HTML中で参照されるscripts, stylesについてはまとめてダウンロードできるので、自分のコンテンツとともにサイトにアップロードして使うこともできます。
今回はブログで使用するので配布元でホストしているものを使用しています。

今度はこれをBloggerに組み込んでみます。
BloggerのアカウントSign Inして、Layout - Edit HTMLを選択するとテンプレートを編集することができます。
ここで、テンプレートの最後の方の<!-- end outer-wrapper -->と</body>の間に以下のHTMLを埋め込んでください。

<script src='http://alexgorbatchev.com/pub/sh/2.0.320/scripts/shCore.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.0.320/scripts/shBrushBash.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.0.320/scripts/shBrushCpp.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.0.320/scripts/shBrushJava.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.0.320/scripts/shBrushJScript.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.0.320/scripts/shBrushPlain.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.0.320/scripts/shBrushPython.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.0.320/scripts/shBrushXml.js' type='text/javascript'/>
<script type='text/javascript'>
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.config.clipboardSwf = &#39;http://alexgorbatchev.com/pub/sh/2.0.320/scripts/clipboard.swf&#39;;
SyntaxHighlighter.all();
</script>
<link href='http://alexgorbatchev.com/pub/sh/2.0.320/styles/shCore.css' rel='stylesheet' type='text/css'/>
<link href='http://alexgorbatchev.com/pub/sh/2.0.320/styles/shThemeDefault.css' id='shTheme' rel='stylesheet' type='text/css'/>

そしてブログ本文中に

<pre class="brush: java">
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
</pre>

のように記述するとコードがハイライトされて表示されます。
注意点としてはPreview画面ではハイライトが有効にならないので、確認するにはPublishする必要があります。

さて、これでコードをブログに載せる準備が整いました。
これから趣味のコードを紹介していきたいと思います。

2009/09/05

Bloggerについて

ブログシステムはいっぱいあるけれど、とりあえずgmailアカウントあるし、中立的でデータのImport/ExportしやすそうなBlogger選んでみました。

でも日本語対応はちょっと残念。
この日付、時間のフォーマットは日本人からするとありえません。

一番まともそうなのを選んだ結果が「9/05/2009 06:44:00 午後」って。。。

これからBloggerを根城にしていくことを考える「どげんかせんといかん」ですね。
時間のある時に調べてみます。。。

ブログをはじめてみるなり

社会人9年目。
紆余曲折の末、ソフトウェアエンジニアやってます。

昔から趣味&バイトで新しい技術を追いかけたり、プログラム書いていて、学生時代にはブログもなかったのでブログ的なシステムを自作して日記やら、技術ネタを書いていたんですが、社会人になってから仕事のプログラムが中心ですっかりそういうことに時間を使わなくなってしまっていました。

最近仕事も落ち着いてきたので趣味のプログラムを再開中です。

このブログでは技術系、あと趣味の金融系のネタを書いていきます。