Feb72010

wp-kougabu 1.12 リリースとぶらりぶらり このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加

雪のち曇 ひろまさ@ 2010年 2月 7日 投稿時の月齢:23.4  月名:真夜中の月  潮汐:小潮

ぼくの密かなたのしみは、MMRT daily life の上部に配置されたランダムポストをクリックして次々と出てくる記事をうししと読むことだった。

いつかぼくもランダムポストを、そう思って早3年。 なにやら twitter を覗くと、 kougabu を利用したランダムポストがにいさんによってつくられている!?、こ、これは…!!

…ということで、にいさんこと、をかもとさんが現在作成中の豪華エフェクト付きランダムポスト・スライドショープラグインに向けて、wp-kougabu をバージョンアップしました。 kougabu の API がいまいちだったのでプラグインに向けて拡張しています。

WordPress Plugins-JSeries » wp-kougabu (画像付きアーカイブ)

wp-kougabu-1.12.zip

kougabu_get_images 関数に新規のオプション array_ext を追加しました。画像属性が分割された形式で配列を取得できプログラムから扱いやすくなりました。

それ以外に変更はありませんので、ダウンロードいまお使いの kougabu に上書きしていただいて、にいさんのリリースを楽しみにしていただければ。 新規の方も使い方かわりません。

うちのサイドバー下でうごいているのが、そうです。 :)

burari01 

うーん、たのしすですね。 ウィジェット、ショートコード、関数から kougabu サムネイルを利用したランダムポスト・スライドショーを呼び出すことができます。

近くリリースされると思いますので、にいさんのブログを要チェックや!  :)

(23:40 追記)

JSeries にリリースされました!

WordPress Plugins-JSeries » Kougaburari ( ランダムポスト・スライドショー )

画像付きアーカイブ表示プラグイン「wp-kougabu」のランダムポスト機能を使用して、スライドショーを表示するプラグインです。

にいさん、ありがとうございます!

Kougaburari  dogmap.jp

てなわけで、前から気になっていた jQuery プラグイン JQuery Cycle Plugin を使用して、wp-kougabu が吐き出したランダムポストイメージをスライドショー表示するプラグインを作りました。

むっふっふ。 :)

Jan262010

携帯電話 Bluetooth + DUN でモバイルインターネットを試す このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加

ひろまさ@ 2010年 1月 26日 投稿時の月齢:10.9  月名:十日余の月  潮汐:若潮

10年前くらいは携帯電話/PHP の回線契約数を 5 回線くらい持っていたりして、モバイル系大好きだったのですが、いつのころからかご無沙汰気味。

昔はこの手のがずいぶんお値段高くて維持費的なものからやめてしまったと思いましたが、最近 ドコモの 128K パケホーダイとかでてきて、お小遣いくらいでまた遊べるようになったので、ちょっと復活して試しに Bluetooth + DUN を使ってノートPC をインターネットにつなぐ準備をしてみました。

こういうの、なにかちょっとした出張とかあったときのためとか、緊急時のインターネット回線用にとかでも用意しておくと便利かもしれません。 :)

bluetooth01

用意したのはノートPC ThinkPad くんと、ドコモの FOMA 携帯電話 SH906i さん。

また、ドコモの FOMA を契約していると、mopera U というドコモがやっている携帯電話接続可能なインターネットプロバイダを使うことができます。 これが現在キャンペーン中で、4末までですが 0円、もしくは 262.5円/月で接続することができます。

キャンペーン|サービス一覧|ドコモの定額データプラン対応のインターネット接続プロバイダ「mopera U (モペラユー)」

2009年12月1日(火)~2010年4月30日(金)

てなわけで、こちらの U スタンダードプランを使ってみることに。 ライトでもいいのでうすが、ドコモの公衆無線LAN Mzone も 0円キャンペーン中なので、こちらも試してみたくてスタンダードにしています。(ライトだとつけられない)

ちなみに mopera U の契約は、携帯電話を使って iMode のお客様メニューからやるのが一番簡単そうでした。 ただ申し込みサイトの説明がちょっと違っていて、

お申込み・契約変更|ドコモの定額データプラン対応のインターネット接続プロバイダ「mopera U (モペラユー)」

「iMenu」⇒「お客様サポート」⇒「お申込・お手続き」⇒「各種お申込・お手続き」⇒「便利なサービスの申込」

とありましたが、なくって、、「便利なサービス」じゃなくて、「MM サービス」というメニューの中にありました。 探したわ。 っていうか MM って久しぶりに聞いた(笑) ここでスタンダード + 公衆無線LAN を申し込みました。

ではでは、まず ThinkPad + SH906i の Bluetooth で Windows から DUN してみます。

どんな PC でも同じですが、先ずは PC 側の Bluetooth を有効に。。 …する方法を忘れて10分を消費しました。。 デバイスマネージャから見えなかったので一瞬、ぼくの ThinkPad に Bluetooth がついていたのが夢だったかと。。(笑)

ThinkPad の場合は Fn + F5 でオンにできます。 :)

bluetooth02

で、デバイスマネージャを確認。 でてきます。

bluetooth04

あとは、携帯電話の Bluetooth メニューから機器検索とかして、PC とペアリングします。 そうすると、PC 側にデバイスが現れます。

bluetooth05

この PC の場合は、携帯電話が COM4 に割り当てられました。 この状態で COM4 にアクセスがあると Bluetooth の無線を経由して接続されます。

で、ここからが mopera U に接続する設定です。 実はドコモからコネクションマネージャというのアプリがでていてオート設定できるのですが、ここは黙って手動設定。(笑)

まず、携帯電話に mopera U の APN を登録します。 ここでは実験なので、インターネットには接続できない、(現在)パケット無料の管理画面表示用のアクセスポイントを追加。

Poderosa でも teraterm でも使って、携帯電話のつながっている COM4 にアクセスします。 Bluetooth 経由で携帯電話のモデムにつながるハズです。 昔みたく PC と携帯をケーブルつながなくていいので便利ですね。 携帯電話はポッケにいれたままでOKです。 :D

でもって、携帯電話モデムの AT コマンド(説明書にでています)を使って、0120.mopera.net という APN を追加します。 番号は 10 にしてみました。

bluetooth03

シリアルなのでコマンドはゆっくり入力しましょう。 文字が遅れてくるよ。

AT+CGDCONT?
+CGDCONT:1,"PPP","mopera.ne.jp",,0,0
+CGDCONT:3,"IP","mopera.net",,0,0
OK
AT+CGDCONT=10,"IP","0120.mopera.net"
OK
AT+CGDCONT?
+CGDCONT:1,"PPP","mopera.ne.jp",,0,0
+CGDCONT:3,"IP","mopera.net",,0,0
+CGDCONT:10,"IP","0120.mopera.net",,0,0
OK

SH906i では APN 追加は、AT+CGDCONT= コマンドです。(真ん中コマンド) 他の携帯電話の方はマニュアルを確認のこと。(たぶんいっしょですが)

できたら、PC からここで登録した APN にダイアルアップします。 番号識別は電話番号の欄で行います。 携帯電話デバイスから右クリックして、ダイアルアップネットーワークの追加。

bluetooth06

電話番号に *99***[APN番号]# を設定します。 ここでは先に設定した 10 を。

で、ダイアル。 :)

bluetooth07

ユーザ名とパスワードは、mopera U に加入したときのウエルカムメッセージの URL からネットワーク暗証番号をいれた後の画面で確認できます。(若干わかりにくい)

接続できたら、 http://start.mopera.net/ にアクセスしてみましょう。 つながっているはずです。 この APN ではここのサイト以外はつながりません。(設定確認などをするところです)

ちゃんとインターネットにつながる 128K パケホなどの APN 設定情報はこちらにあります。

設定方法|ドコモの定額データプラン対応のインターネット接続プロバイダ「mopera U (モペラユー)」

ネットワーク設定(アクセスポイント等)やメール設定(POP、IMAP等)など、手動で設定を行う際に必要な各種設定情報をご紹介いたします。

手動設定用詳細情報(PDF形式:735KB)

mopera Uを従量でネットサーフィンやメールを利用する場合のアクセスポイント情報です。

アクセスポイント一覧(PDF形式:1,008KB)

パケホ 128K だと、APN は mpr.ex-pkt.net かな。(必ずサイト/PDF で確認してください) 128K だと使えないですが、フィルタリングフリーアクセスポイントとかあって面白いですね。

実は、ぼくのパケホ契約はまだ昔のやつなので 128K 接続つかえず、インターネット接続は試せていないのですが、後日やってみます。(一応、準備だけしたらしい(笑))

では、最後に mopera u スタンダードで使える、Mzone という公衆無線LAN。 このオプションをつけておくと、携帯電話じゃなくって、普通のそのへんにとんでいる Mzone の 無線 LAN も使えるようになります。

札幌だと、地下街はほぼ全域で使える模様。 あとはホテルとか空港とか、カフェとかですかね。 ぼくは、お昼あの辺の地下街でご飯を食べていることが多いのでためしてがってん。

接続は iPod touch より。 :)

mopera01 

うむうむ。 札幌地下街歩きながら見ていましたが、だいたいつながるようです。 現在 0 円なのでこれはお得。。 ポートは http のみかな、、メールは試しませんでしたが、特殊なポートはふさがれている模様でした。 WEP 接続なので、まぁまぁやることはほどほどに。

iPod touch から http でブラウジングはちゃんとできるので、お昼のオタノシミが増えました(笑)

とりあえず、ダイアルアップ、公衆LAN ともにキャンペーンは 4末までなので、それまでにいろいろ試してみたいと思います。 :)

Jan122010

Eclipse 3.5 wiki エディタのフォント不具合 このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加

曇時々雪 ひろまさ@ 2010年 1月 12日 投稿時の月齢:27.3  月名:二十八日月  潮汐:中潮

Eclipse 3.5 からだとおもうのですが、ファイル拡張子を .mediawiki とか tracwiki とかにして開くと wiki 記法が使えるエディタが開くようになりました。 ちょっとドキュメントを書く機会があったので気分転換に使ってみたり。

新しいものというのは、楽しいものである、、ぼくは、うきうきで wiki の記述を始めた・・・。(←ふり

悲劇は、 tracwiki のコード表記の部分で起きた。

travwiki01

倍角か! 昔のワープロか!(←弱いおち

ぼのを「・・・」

というわけで、Eclipse の Bugzilla を探してみるとどうやら SWT の不具合の模様。

Bug 278959 – setting font height should update font width

Created an attachment (id=138181) [details]

次の Eclipse 3.6 には入るようですが、3.5 で使えないのも寂しいのパッチを SWT 3.5.1 に適応してみました。 といっても1行パッチ。

SWT のソースをコンパイルして、上記不具合 class を plugins の下の

org.eclipse.swt.win32.win32.x86_3.5.1.v3555a.jar

に差し替えただけです。

とう!

travwiki02

なおった、なおった。 :-)

.wiki のファイルは HTML や DocBook などに出力でき、リアルタイムでは HTML で表示できます。 設定画面である程度 CSS も変更できるようです。

travwiki03

まぁ正直、エディタの方はまだまだのできっぽいですが、とりあえず記法をオートコンプリートできるのは、wiki になれていないぼくには便利でした。 こまったら、CTRL + SPACE。

travwiki04

DocBook に書き出せるので、docbook2pdf とか docbook2txt とかでも整形して出力できそうですね。

というわけで、ひさびさのこののりのブログはやっぱり良い・・・。 :-)

Jan22010

Twitter のボットと Platform as a Service このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加

雪 ひろまさ@ 2010年 1月 2日 投稿時の月齢:17.2  月名:居待月  潮汐:中潮

明けましておめでとうございます。 2010 年、ぼくも hiromasa.another もいつもどおりのまったり感かと思いますが、今年もよろしくお願いいたします。 :)

さて去年あたりから、Windows Azure などいわゆるクラウド的なサービスがいろいろでてきて、なんだかちょっとわくわく。 今年の興味はこの辺から・・・。

クラウドというと、ラップするレイアがサービスによっていろいろ違ってなんだかよく分からないですが、ぼくはその中の PaaS というサービスが遊ぶに面白そうかなと思っています。

クラウドと呼ばれているものにはいくつか種類があると思いますが、たとえば Amazon EC2 はサーバの物理存在を隠します。 サーバが 2台ほしければ、2 って画面にいれて起動させれば 2台できる。 増やしたければすぐ増やせる。 サーバの手配とかデータセンターの置き場所とか電源とか考えなくていいわけですね。

たとえば Google Apps。 これはサーバとさらにアプリケーションの運用を隠します。 言うならばメールサーバ落ちた!などと会社の情報システム部門がてんやわんやしなくてよくなるというサービス(笑)

で、PaaS というのはその中間。 物理サーバとアプリケーション動作に無関係な運用部分を請け負ってくれます。 で、のせるアプリケーションは各自つくってすぐデプロイできるように環境が整っている感じです。

今で言うところの、レンタルサーバに PHP のアプリケーションを各自入れて動かすの発展系のイメージ。

たとえば現状のレンタルサーバでは WordPress の MySQL のバックアップとか自分でやらなくてはならなくて結構大変ですが、PaaS の場合はスケジュールで勝手にバックアップをとってくれたり簡単にリストアできたり、各種リソースの使用量が管理画面から見えたり、よりアプリケーションよりのサービスが付随します。

PaaS のひとつである、Windows Azure では、既に WordPress も稼働しているとのことです。

「PDC09」リポート:Microsoftはハイブリッドな戦略で古い殻を脱ぎ捨てる (2/3) – ITmedia +D PC USER

欧米を中心に世界中で広く利用されているブログシステム「WordPress」の開発者であるマット・マレンウェッグ氏が登場し、Windows Azure上でWordPressを動作させるデモを紹介した。

さて、この PaaS ですがもう一つの特徴が、様々なアプリケーションを動かすための環境が整っていること。 簡単に言えば、C# とか Java とかそのへんの言語と、そのアプリケーションサーバ環境周りも使うことができます。

PHP では少し無理があったことも簡単にできるようになる・・・。 実はここがぼくの最大の関心事。 大昔 CGI が無料で使える海外サーバがでてきたようなどきどきが(笑)

PaaS のサービスは Google App Engine とか Stax Networks とかありますが、ここでは後者を使ってみました。 Stax のほうがサンドボックスの制限が緩いので遊びやすいのです。

とりあえずつくってみたのは、twitter ボット。

 stax02

PHP でももちろんボットはつくれますが、一般的な PHP の環境はプログラムから動き出すことができないという制約があります。 人のアクセスとか別系の cron とか外的要因からプログラムをキックする必要がありますが、ここでは Java のスレッドスケジューラを使って自分から定期起動するようにしています。

いろんなライブラリが簡単に使えるのもいいところで、このボットは twitter クライアントに twitter4j、また スケジューラ に Quartz というライブラリを使っています。

Twitter4J – A Java library for the Twitter API

Twitter4J は TwitterAPI の Java ラッパです。 Twitter4J を使うと XML や HTTP に詳しくなくても容易に Twitter とインタラクトするアプリケーションを書くことが出来ます。

Quartz Scheduler – Home

Quartz is a full-featured, open source job scheduling service that can be integrated with, or used along side virtually any Java EE or Java SE application – from the smallest stand-alone application to the largest e-commerce system.

ちなみに、Google App Engine はスレッド禁止っぽいので、Quatz は残念ながら動作しないと思われます。 http の通信もなにか特別なことをしなくてはいけなそうでした。(たぶん)

で、とりあえずライブラリや web.xml を配置します。 Stax Networks は Tomcat を使っているようで、また一般的な WAR も配置できるので基本的になにも考えずにいつも通りにつくれます。

stax04

web.xml を以下のように。

<?xml version="1.0" encoding="UTF-8"?>
<web-app>
  <display-name>Desyura</display-name>
  <servlet>
    <servlet-name>QuartzInitializer</servlet-name>
    <servlet-class>
    org.quartz.ee.servlet.QuartzInitializerServlet</servlet-class>
    <init-param>
      <param-name>shutdown-on-unload</param-name>
      <param-value>true</param-value>
    </init-param>
    <init-param>
      <param-name>start-scheduler-on-load</param-name>
      <param-value>false</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet>
    <display-name>RobotInitializer</display-name>
    <servlet-name>RobotInitializer</servlet-name>
    <servlet-class>
    net.maple4ever.desyura.RobotInitializer</servlet-class>
    <load-on-startup>2</load-on-startup>
  </servlet>
</web-app>

QuartzInitializerServlet と、スケジューラの起動の Servlet を順番に登録。

あとはソースを書くだけです。 動作できるかどうかのサンプルでかいただけなので、いんちきをたくさん含んでいることをあらかじめご了承ください。

RobotInitializer.java。 スケジュールのインスタンスをもらって、Job を行うクラスを登録する感じです。 CronTriger を使うと cron みたいな形式で時間を指定できます。

package net.maple4ever.desyura;
 
import java.text.ParseException;
import java.util.Calendar;
import java.util.Locale;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
 
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;
 
public class RobotInitializer extends HttpServlet {
    
    public static final String START_TIME = "START_TIME";
    private static final long serialVersionUID = 1L;
 
    public RobotInitializer() {
        super();
    }
 
    @Override
    public void init() throws ServletException {
        // QuartzInitializerServlet で作成したスケジューラを取得
        Scheduler sched = null;
        try {
            sched = (new StdSchedulerFactory()).getScheduler();
        } catch (SchedulerException e) {
            throw new ServletException(e);
        }
        // Cron 形式のトリガー作成(とりあえず 5分)
        Trigger trigger = new CronTrigger("trigger1", "group1");
        try {
            ((CronTrigger) trigger).setCronExpression("0 0/5 * * * ?");
        } catch (ParseException e) {
            throw new ServletException(e);
        }
        // JobDetail にコールバッククラス登録
        JobDetail jobDetail = new JobDetail(
                "Twitter Bot"
                , "Twitter Bot"
                , TwitterBotService.class
                , true
                , true
                , true);
        // 起動時間を JobDataMap に格納(twitter のロケールも日本にすること)
        jobDetail.getJobDataMap().put(START_TIME,
                Calendar.getInstance(Locale.JAPAN));
        // スケジュール開始
        try {
            sched.scheduleJob(jobDetail, trigger);
            sched.start();
        } catch (SchedulerException e) {
            throw new ServletException(e);
        }
    }
    
}

 

TwitterBotService.java。 時間がきたら twitter をみてつぶやく Job クラスです。 スケジュールごとに new されるので手を抜いて static で値を保持しています。(本当は context にシリアライズできる形で値をいれるのが良いと思われます)

package net.maple4ever.desyura;
 
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;
import java.util.Date;
 
import org.quartz.JobExecutionContext;
import org.quartz.StatefulJob;
 
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
 
public class TwitterBotService implements StatefulJob {
    
    // StatefulJob は同時実行されないが手抜き synchronized しておく
    static private List<Long> read = (List<Long>) Collections
            .synchronizedList(new ArrayList<Long>());
    static private final int PAGE_COUNT = 20;
    
    public void execute(JobExecutionContext context) {
        // スケジュールイベント
        System.out.println("Fire! " + context.getScheduledFireTime());
        // 初回起動時間取得
        Date fistTime = ((Calendar) context.getMergedJobDataMap().get(
                RobotInitializer.START_TIME)).getTime();
        // twitter 接続
        Twitter tw = new Twitter("ユーザ名", "パスワード");
        
        String tweet;
        try {
            // twitter から Mentions をもらう
            List<Status> status = tw.getMentions();
            for(Status stat : status) {
                // 起動時より前の返信は答えない
                if(fistTime.after(stat.getCreatedAt())) continue;
                // すでに返信していたら答えない
                if(read.contains(stat.getId())) continue;
                // 自分のスクリーンネームを相手に置換してつぶやく
                tweet = stat.getText().replaceAll(
                        stat.getInReplyToScreenName(),
                        stat.getUser().getScreenName());
                tw.updateStatus(tweet, stat.getId());
                System.out.println(tweet);
                // 読んだリストに入れておく
                read.add(stat.getId());
            }
            // getMentions() は 20件取得なのでそれを超えたら忘れる
            if(read.size() > PAGE_COUNT) {
                read.remove(0);
            }
        } catch (TwitterException e) {
            // 投稿失敗しても次に期待する
            System.out.println(e.getStackTrace());
        }
    }
    
}

(あ!!、if の位置間違っていることをブログかきながら発見。。(笑))

ひとつしかスケジュールもアカウントも制御できないエコーなボットですが、100 ステップくらいでできちゃうのはお手軽すぎです。

これは実験なのであれですが、スケジュールも twitter も意識させずに文字列操作部分だけ外だしにできるようにプログラムをかえていけばいいかなという感じですね。 Jython とか JRuby とか Groovy とかの Java の上で動くスクリプト言語にその部分をプラグインのように渡すのも面白いかもしれません。

できた WAR は Stax Networks にそのままデプロイできます。 ant タスクがあるのでコマンド一発。 FTP クライアントとかいりませぬ。

hiromasa.another :o ) » Blog Archive » Stax Networks への JavaEE アプリのデプロイ

あとは、ドキュメントにかいてあるとおり build.xml にユーザ名とかパスワード、war の stax-application.xml パスをかきます。

stax-application.xml はとりあえず適当に Stax Networks の管理画面で BASIC Servlet and JSP なアプリを作成しておいて、それをダウンロードしてきてそのまんま使うのが楽かもしれません。

さて、twitter は昔 Jabber をサポートしていたので、たとえば Stax Networks とソケットつなぎっぱなしにして、リアルタイムに反応するボットとかもつくれたと思うのですが、もうできなくて残念。

でも、最近は websocket とかそれっぽい技術もできてきていますので、こういったアプリケーションサーバがあると、いままで http な Web ではできなかったようなことも実現できそうです。

いろいろこのへんの技術で遊んでみたいな、と思った1年の始まりでした。 :)

Dec312009

大晦日と WordPress 2.9.1 RC1 このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加

雪 ひろまさ@ 2009年 12月 31日 投稿時の月齢:15.1  月名:満月  潮汐:大潮

いろいろありました 2009年もあっというまに、日本は大晦日です :)

師走の中、WordPress 2.9.1 の準備も着々と進み、WordPress 2.9.1 RC1 が 30日にでております。 2.9.1 で修正される不具合で、いくつかプラグインの動作が直るものがありますので、紹介したいと思います。

まずはブログでもアナウンスがありました、wp-cron が動かない問題です。

WordPress | 日本語 » WordPress 2.9.1-1

残念なことに、先日の 2.9 リリースと一部のバージョンの PHP 組み合わせで cURL 拡張に関するバグが起こることが判明しました。該当するバージョンの cURL では、予約投稿およびピンバックが正しく処理されません。

wp-cron は WordPress のスケジュールイベント系を司るモジュールのことですが、これのタイムアウト待ち時間の設定が一部のサーバで速くなりすぎるため、スケジュール実行が発動しないという問題です。

予約投稿やピンバック、またスケジュールを使っているプラグインも影響を受けますが、WordPress Related Post for WordPress もそのひとつで、該当サーバでは関連が取得できなくなっていると思います。(このプラグインは辞書作成で投稿時間や過去記事の閲覧が遅くならないように wp-cron によるバックグラウンド処理を行っています)

とりあえず辞書作成について、2.9.1 までは http://www.example.com/wp-cron.php に手動でブラウザからアクセスすることで対処できます。(www.example.com はお使いのサーバスペースにあわせてください)

次はタイムゾーン問題。

以前書きましたとおり、2.9 より PHP のタイムゾーンの設定を WordPress が UTC に変更する動作が加わりました。

その後、もう少しプログラムを追っていくと、(wp_)options の gmt_offset という値を取得しようとするとフックにより、UTC に設定したタイムゾーンを、timezone_string 値(Asia/Tokyo とか)で再設定する動作があることが分かりました。

影響をうけたのが、 current_time() という WordPress コアの関数で、timezone_string が存在するとタイムゾーンの再設定により、日本であれば +9 +9 の時間 (2回ずらしてしまう)を返してしまうようです。 wp-kyodeki プラグインが正しく日またがりで値がクリアされないケースがこの件です。

パラ見ですが、xmlrpc 経由の投稿日付、ファイルアップロード時に作成される年月ディレクトリ、テンプレートタグのカレンダーのめくりの処理などの時間が +9 ずれる可能性がありそうです。

で、最初現象が分からなかったのがなる人とならない人がいることで、どうも昔から WordPress を使っている人で、最近、管理画面の general setting の更新をしてない方は timezone_string 値が入っていなくて、gmt_offset だけが入っている状態。 この場合は current_time() はうまく動作します。 ぼくとかおでさんとか(笑)

General Setting で都市名で値を設定すると、timezone_string に値が入るため current_time() がうまく動作しなくなります。

timezone01

幸いなことに、WordPress 2.9.1 より UTC 形式での細かい値を設定できるようになりました。 この設定を使った場合、timezone_string に値が入らなくなり、うまいこと current_time() が正しい値を返してきますので、不具合で困ったことになっている方は、2.9.1 がでてアップグレードした後、日本のタイムゾーンの方は

timezone02

こうしてください。(ドロップダウンの下の方に追加されています) これで修正されると思います。

current_time() の件については、Nao さんにご協力(ぼくは英語が書けません。。)をいただきましてチケットをきってあります。 Nao さん、お忙しいところありがとうございました! :)

3.0 にまわされていますが、おそらく修正されると思います。 それまでは、UTC な Timezone 設定でしのぐ方向で。 :)

#11672 (current_time() does not correctly retrun localized time) – WordPress Trac

When you set you set timezone using a city name, current_time() function in functions.php does not return correct local time.

てなわけで、 +9 の日本は粛々と除夜の鐘が鳴る時間に進んでおります。

みなさま、良いお年を・・・!!

Dec262009

マルチプラットフォームの GUI アプリケーション このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加

雪 ひろまさ@ 2009年 12月 26日 投稿時の月齢:10.4  月名:十日余の月  潮汐:若潮

たまぁになんですが、自作のちょっとしたアプリで GUI を使いたいときがあります。 ほいでもって、ぼくは家で大抵は Linux を使っているのですが、せっかくつくったアプリなのでたまに使う Windows でも使いたい、、。 ということで、マルチプラットフォームで動く GUI アプリ。

Mono + GTK、Mono + Windows.Forms、 Java + Swing、 Java + GTK(あるのかな?)、などなど思いつきますが、今回は Java + SWT をやってみました。 :-)

GTK は各種プラットフォームで動作する GUI ツールキットですが、自前で描画をしているので特に Linux 以外で動かすとやっぱりほんのすこーし、違う。 まぁ特別問題があるわけではないのですが、Pidgin や GIMP を Windows などで動作させたことがある方ならなんとなく分かるのではないでしょうか。

Swing は逆に Windows で動かす分にはそれなりなのですが、Linux で動かすとフォント系が厳しい。。 Swing は TrueType も自前で描画するので特にアンチエイリアスがある環境ではなにか違う感じを醸し出します(笑) (フォントレンダラがあんまりよくないのかな)

てなわけで、やっぱネイティブだよねってことで Java + SWT です。

Standard Widget Toolkit – Wikipedia

SWT は Java で書かれている。GUI部品を表示するため、SWT はそのオペレーティングシステムが提供するGUIライブラリを JNI(Java Native Interface)経由で使用する(これはシステム固有のAPIを使う一般的手法である)。SWT を使うプログラムは移植性があるが、ツールキット自体の実装は Java でかかれているにも関わらず、各プラットフォーム固有である。

ネイティブライブラリですが、Windows、Linux、Mac OS X などなどいろんなプラットフォームに移植されていますので、実行ファイルこそ変われど同じアプリケーション(ソース)が動作します。 Eclipse などの巨大なアプリケーションが SWT で動作していますので、ライブラリ自体もかなり枯れていると思われます。

で、SWT にかぶる形で GUI のフレームワークとして JFace というのがあって今回はこれも使ってみました。

とりあえず、SWT と JFace のライブラリを持ってきます。 JFace は Eclipse の plugins に入っているものをほげってきました。(外部 Jar 追加で参照してもいいのですが、なんとなくコピーして自分のおなかに)

jface02

こんな感じにライブラリをいれておきます。 これは Linux の場合。

詳しくはこちらが参照になります。

SWTとJFaceに必要な外部JARファイルを特定する – Identify the Required External JAR Files for SWT and JFace – 何かしらの言語による記述を解析する日記

JFaceプロジェクトには、SWTのクラスとJFaceのクラス、その他JFaceが依存するEclipseのクラスが必要です。SWTプロジェクトのウェブサイトから、SWTのクラスを含むファイルをダウンロードできます。JFaceのファイルとJFaceが依存するファイルは、プロジェクトに手動で追加する必要があります。

ほいでもってソースをかきます。

あちこちのサイト様を参照しました。 JFace は ApplicationWindow から extends して開始です。 (未来の自分用へのメモ)

JFaceSample.java

package net.maple4ever.sample.jface;
 
import java.io.File;
 
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
 
public class JFaceSample extends ApplicationWindow {
    
    public JFaceSample() {
        super(null);
    }
    
    @Override
    protected Control createContents(Composite parent) {
        // ウインドウタイトル設定
        parent.getShell().setText("JFaceSample");        
        // ウインドウサイズ設定
        parent.getShell().setSize(480, 320);
        
        // 親の下にさらに Composite をつくる
        Composite child = new Composite(parent, SWT.NONE);
        // レイアウトマネージャ設定
        child.setLayout(new GridLayout());
        // テーブル作成
        TableViewer table = new TableViewer(child);
        table.getTable().setLayoutData(new GridData(GridData.FILL_BOTH));
        // テーブルにプロバイダ設定
        table.setContentProvider(new FileTableContentProvider());
        table.setInput(new File(System.getProperty("user.home")));
        
        return parent;
    }
    
    @Override
    protected MenuManager createMenuManager() {
        // 親メニュー作成
        MenuManager bar = new MenuManager();
        MenuManager fileMenu = new MenuManager("ファイル(&F)");
        // Action クラスを継承したインスタンスを渡す
        fileMenu.add(new ActionExit(this));
        // 追加メニューを返却
        bar.add(fileMenu);
        
        return bar;
    }
    
    public static void main(String[] args) {
        // ApplicationWindow インスタンス生成
        JFaceSample window = new JFaceSample();
        // メニューバー追加(createMenuManagerメソッド が呼ばれる)
        window.addMenuBar();
        // ウインドウクローズまでイベントループブロック指定
        window.setBlockOnOpen(true);
        // イベントループ開始(終わるまでここでブロック)
        window.open();
        // イベントループ終わったらリソース解放
        Display.getCurrent().dispose();
    }
    
}

ActionExit.java

package net.maple4ever.sample.jface;
 
import org.eclipse.jface.action.Action;
import org.eclipse.jface.window.ApplicationWindow;
 
class ActionExit extends Action {
    
    private ApplicationWindow window = null;
    
    public ActionExit(ApplicationWindow win) {
        // ApplicationWindow もらっておく
        window = win;
        setText("終了(&X)@Ctrl+W");
    }
    
    @Override
    public void run() {
        // Action の処理を run にかく
        // ApplicationWindow 呼んじゃえ
        window.close();
    }
    
}

FileTableContentProvider.java

package net.maple4ever.sample.jface;
 
import java.io.File;
 
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.Viewer;
 
class FileTableContentProvider implements IStructuredContentProvider {
    @Override
    public Object[] getElements(Object element) {
        File currentDir = (File) element;
        File[] files = currentDir.listFiles();
        return files == null ? new Object[0] : files;
    }
    
    @Override
    public void inputChanged(Viewer arg0, Object arg1, Object arg2) {
    }
    
    @Override
    public void dispose() {
    }
}

で、まずは Linux。 実行~ :)

jface03

うむうむ。 Linux SWT の GTK 版なのであたりまえですが、GTK で描画されています。 Linux の場合、GTK のテーマでみんないろいろ画面をかえているので、何にもしなくても追随してくれるのはやっぱりいいですね。 :)

同様に Windows でも Windows 用の SWT ライブラリをあつめて、同じアプリケーションのソースを実行!

jface01

エアローってことで、 Windows 7 で動かしたの図ですが同じソースでネイティブ描画してくれております。 よい、よい。 :D

JFace は、普通の GUI フレームワークとちょこっと趣向が違うところがあったりして面白いですね。 スレッドの中からの GUI 描画方法とかまだ全然分かっていない部分もあって本気で使いこなすには時間がかかりそうですが、小物ならなんとかいけそうです。

ちなみにできたアプリの配布ですが、小さいアプリであれば Eclipse のエクスポートウイザードの実行形式 jar で ant 書き出してもらうのが楽そうです。

jface04

で、できた jar 玉を JRE が入っていれば通常ダブルクリックで実行できます。

jface05

gjc で JRE なしのまじネイティブ (.exe 版とか)もできるのかなぁ。 Eclipse の gjc 版はあるのでできると思いますが、ちょっとそこまでは調べていません。

swt 、JFace とも Eclipse Public License 系のライセンスなのでこういった配布形態も問題ないとおもいますが、やる方がいたら各自よくご確認ください。 ぼくは配布するまではなさそうなので、、(笑)

てなわけで、画面系はやっぱりネイティブがいいよね、という方は試してみるといいかもしれません。 :)

Dec202009

WordPress 2.9 リリースと 2.9 対応版 wp-kyodeki とタイムゾーンと このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加

ひろまさ@ 2009年 12月 20日 投稿時の月齢:3.6  月名:黄昏月  潮汐:中潮

というわけで、まさに日本時間で昨日になりますが WordPress 2.9 がリリースされました。 めでたい。 いろいろ新機能もあるようで使うのが楽しみです :)

さてさて、昔はつくっていたプラグインがバージョンアップでよく動かなくなっていたりしていたのでベータでチェックとかしていたのですが、最近わりと動くのでさぼってたら、ふと wp-kyodeki がおかしくなっているよう、、その動作を見てコアにとある変化があったのに気がつくぼく・・・。(←遅い

というわけでとりあえず wp-kyodeki。

このプラグインはアクセスカウンタみたいなもんですが、日付をまたぐとカウントがクリアされる仕様になっております。(もともとアクセスデータを蓄積しないようにつくったプラグインでした)

夜行性のぼくは 2.9 にアップデートされた我がサイトのサイドバーをみて、日付をまたいだのにカウントがクリアされていないことに気がついたのです。。

というわけで不具合がありましたので、 JSeries にリリースしました。お使いの方は更新ください。

WordPress Plugins-JSeries » wp-kyodeki (本日人気の記事表示ウィジェット)

タイムゾーンでの日付変更クリアとならない不具合が修正されます。

さて、なんでだろうという話ですが、コアの wp-settings.php に以下のコードが追加されていました。

if ( function_exists('date_default_timezone_set') )
    date_default_timezone_set('UTC');

PHP の date 関数の戻り値などに影響する、timezone の設定でこれが標準時間になるようになっています。 というわけで、これがなかった今までは日本時間が戻ってきていたのですが、UTC になったので標準時間がもどってくるようになった、ということでした。

wp-kyodeki の不具合です。 冷静に考えたら海外サーバだと WordPress のタイムゾーンを日本に設定していてもあちらの時間で更新されていましたね。すいません(笑)

で、そういやコアがどうなっているのかあんまり考えたことなかったなぁとちらほらソースをみていると、結構 date を生でつかっているところがあるようです。

まぁ、いまも日本タイムゾーン設定で海外サーバ使われている方も多くて問題になっていないようなのでコアは大丈夫かと思いますが、プラグインは考慮漏れているものがあるかもしれない(あんまりないと思いますが)ので、万が一 2.9 の日付系で問題があったら疑ってみてください。 :)

Dec132009

WordPress プラグイン管理画面を簡単につくる非実用なフレームワーク このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加

曇時々晴 ひろまさ@ 2009年 12月 13日 投稿時の月齢:26.3  月名:二十七日月  潮汐:中潮

WordPress プラグインをつくるときにぼくが結構大変に思うのは、実は管理画面をつくること・・・。

なにげに自分のプラグインのソースを眺めると実ロジックより大きいこともあったりして笑ってしまいます。 というわけで、既存の管理画面のないプラグインにポンとつける用途を念頭に試しに(本当に試しに)フレームワーク的なものをかいてみました :-)

といっても、PHP 的に厳しい部分もあったりしてごにゃごにゃしなきゃいけない部分もありであまり実用的ではなく、まぁまぁこんな作り方もできるよねって話でみてもらえたらと思います。 PHP 5 系専用です。

まずはサンプル。 なにかしら管理画面の持たない既存のプラグインがあることにします。(以下、ソラでかいているので間違っているかもなのでイメージで)

なんでもいいですがおなじみ the_content フィルターで何か追加する感じのやつにしてみましょう。

   1: function addContent($content) {
   2:     $header = "ほげ";  
   3:     $content = "<p>$header</p>" . $content;
   4:     return $content;
   5: }
   6: add_filter('the_content', 'addContent');

記事の頭に「ほげ」ってつけるプラグインです。。 まぁサンプルってことでごかんべんを。(笑 プラグインヘッダなどは省略です。

ここでは固定値「ほげ」を管理画面から設定できるようにしたいと思います。

とりあえず、こいつを「クラス」にします。 っていってもほぼ機械的な置き換えです。

可変にしたい部分をフィールド(メンバ)においているところと「コンストラクタ」で初期化しているところに注目してください。

   1: class example {
   2:     
   3:     var $header;
   4:     
   5:     function __construct() {
   6:         $this->header = "ほげ";
   7:     }
   8:     
   9:     function addContent($content) {
  10:         $content = "<p>{$this->header}</p>" . $content;
  11:         return $content;
  12:     }
  13:     
  14: }
  15: $example = new example();
  16: add_filter('the_content', array($example, 'addContent'));

$header 変数が外にいきフィールド(メンバ)になりました。

__construct は new ってやったとき(15行目)に勝手に動く特別なメソッドだと思ってください。(ちなみに PHP はコンストラクタもメソッド扱いらしい)

変数を初期化して、あとは WordPress からの the_content の呼び出しを待っているイメージのプログラムです。

さてここからが本題。

今回つくってみたフレームワークというのは DolphinPanel という名前のプログラムで、こいつをつかうとこの手のプラグインに管理画面をつけられます。 “Dolphin” にはなんら意味はないです。 たまたまエコーザドルフィンを思い出しただけです。。(古)

まずプラグインのあたまで、このプログラムを require してあげます(1行目)。 で、プラグインのクラスに dolphin のインターフェースを “implements” します。

まぁかくだけです。 :-)

   1: require_once('dolphin-panel.php');
   2:  
   3: class example implements Dolphinable {
   4:     
   5:     var $header;
   6:     
   7:     function __construct() {
   8:         $this->header = "ほげ";
   9:     }
  10:     
  11:     function addContent($content) {
  12:         $content = "<p>{$this->header}</p>" . $content;
  13:         return $content;
  14:     }
  15:     
  16: }
  17: $example = new example();
  18: add_dolphin($example, 'example');
  19: add_filter('the_content', array($example, 'addContent'));

implements Dolphinable したクラス(3行目)は Dolphin 管轄の WordPress 管理画面を持つことができます。 権利をもったクラスを add_dolphin します。(18行目)

さて Dolphinable であるためには 3つの管理画面に関する決められたメソッド(onActive、onBind、onDispose)が必要になります。 これを実装していきます。

といっても単純にテキストボックスをひとつつけて、値を保存したいだけなら onActive だけ実装すればいいです。 onBind には return true; 、onDispose は空実装してください。

   1: require_once('dolphin-panel.php');
   2:  
   3: class example implements Dolphinable {
   4:     
   5:     var $header;
   6:     
   7:     function __construct() {
   8:         $this->header = "ほげ";
   9:     }
  10:     
  11:     function addContent($content) {
  12:         $content = "<p>{$this->header}</p>" . $content;
  13:         return $content;
  14:     }
  15:     
  16:     function onActive(DolphinForm $form) {
  17:         $form->add(new DolphinTextBox('$header', 'ヘッダ'));
  18:     }
  19:     
  20:     function onBind(DolphinForm $form) {
  21:         return true;
  22:     }
  23:     
  24:     function onDispose() { }
  25:     
  26: }
  27: $example = new example();
  28: add_dolphin($example, 'example');
  29: add_filter('the_content', array($example, 'addContent'));

17行目が Dolphin のキモで、この書き方で変数(フィールド)と管理画面のテキストボックスを結びつけます。 HTML フォームとの値変換、変数へのバインドをこの記述だけでやってくれます。(配列渡すと複数テキストボックスがでてきたりします)

おしまい!。

dolphinpanel02

なんだかここだけみると不思議かもしれませんが、このコードだけでめでたく管理画面がつきます。 簡単あるね。 もちろんプラグインはこの設定値で動きます。 :)

一応、もうちょっといじるとユーザ対話などもできるようになっています。 追加処理を書くとこんな感じになります。

dolphinpanel01

ここではサンプルだったので極力短くしていますが、onBind は値検査が必要な場合に実装するメソッドで、onDispose はプラグインが非活性になった場合に実装するメソッドです。 入力値に必須が入っていなかった場合のメッセージ出力や、プラグイン非活性時のデータベースからの削除などができます。

もうちょっと詳しいコメント付きサンプルと Dolphin のソースを JSeries の CVS にコミットしてあります。 気になる方は(いるのか?!)みてみてください。

http://sourceforge.jp/cvs/view/wppluginsj/dolphin-panel/

実は管理画面でつかえる HTML コンポーネントがまだテキストボックスとチェックボックスだけだったり実用にはほど遠いのですが、まぁプラグインのサービスクラスに管理画面の意識がなくなるのは楽かなと思います。 また、ここではサービスクラスにつけていますが、単純な VO のクラスに implements  して、上に親のサービスクラスをつくってプラグインを実装するのもいいかもです。

さて、お気づきの方もいらっしゃると思いますが、requre している関係でフレームワークとかいいつつクラス名称がかぶったりして、そのままだと Dolphinable な管理画面をもつプラグインがひとつしか作れなかったり、、、 namespace 使おうと思っても PHP 5.3 からだったりけっこう八方ふさがりなところがあったりします。

一応コントローラ自体は、ひとつで複数の Dolphinable を扱えるようにしているので、myhack.php とかにいれればいいんですが、もうないし(笑) __autoload とかで気合いで最新を読むような制御も考えましたが、hackish すぎるのでやめました。。 運用対処ということで(笑)

あとあと、PHP 5.3 じゃないと private プロパティがこじあけられないので、プラグインのフィールドは public にしてください。。 まぁスコープつけなきゃよいです。(お察しの通りリフレクションを使って変数をバインドしています)

というわけで、いろいろあって途中何度か企画倒れにしようかと思ったのですが、まぁせっかくつくったので話のネタに。 たぶんバグってると思うので、実用よりプログラム的な動きだけ楽しんでもらえればと思います。 :)

Nov142009

Moblin 2.1 の研究 このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加

雨 ひろまさ@ 2009年 11月 14日 投稿時の月齢:27.7  月名:二十八日月  潮汐:中潮

以前から気になっていました、解像度の低いコンピュータ向けの UI をもつ Moblin を試してみました。 とりあえず ライブ USB で ThinkPad / IdeaPad で起動してみることに。

最近ネットブックとかに Windows とは別に、起動選択でブラウザとメールくらいが高速起動でつかえる機能がついているものがありますが、あれのすごいやつだと思ってもらえれば正解です。 :)

HOME | moblin.org/jp

Moblin は、The Linux Foundationが主催するモバイル端末向けのLinuxディストリビューションで、ネットブックやMobile Internet Device(MID)、In-Vehicle Infotainment(IVI)向けのソフトウェア技術、アイデア、プロジェクト、コード、アプリケーションを共有するオープン・ソース・コミュニティです。

いまのとろこ、ネットブック/ネットトップ向けのリリースが成果物の中心となっていますが、これらをカスタマイズして MID など小型コンピュータにいれていくのだと思います。

ベースは Linux で、その上に OpenGL を使った描画ライブラリの Clutter や、解像度が低い PC 用への UI ツールキットなどの Moblin のキモがのっていくイメージに見えました。 このうわものを各ディストリビューションに移植した Ubuntu Moblin や Fedora Moblin などもあるようです。(本家の Moblin は Fedora ベースの for Intel ってな感じでしょうか)

てなわけで、

ごう、もぶりん!

moblin01

噂通りの超高速起動で、 USB メモリからですが、おそらく BIOS から 12,3 秒くらいで起動してしまっている気がします。 とりあえずアニメしたりしてめんこいです。 :)

moblin02

しばらく使っているとトップ画面はこんな風に。 おもしろいのがデータを使った履歴がサムネイルで真ん中の縦列に表示されることです。 見た Web ページや画像、動画などなど。 アプリ指向ではなくデータ指向でつくられていることが伺えます。

右の縦列は外部的な時系列なデータの動きがでるようになっているようです。 Last.fm と twitter がとりあえず標準で対応していました。 左の縦列は登録していた未来、予定や TODO などが出るようです。

基本的に Linux/GTK ベースなので一般的な UNIX アプリは動きそうですが、本領を発揮するのが Clutter と Moblin UI をつかってできているアプリだとおもいます。 基本はフル画面。 iPhone のアプリを想像してもらうといいかもですね。

まずはブラウザ。 Firefox ベースですが、小さい画面でうごくように UI が再設計されています。 2.1 からアドインも使えるようになっているようです。

moblin03 

でもってメーラです。 ベースは不明。。(笑)

moblin04 

タブがつかえる模様。

アプリのランチャーです。 GNOME DO みたくアプリ名入力でしぼっていけます。

moblin06

当然マルチタスク対応ですのでアプリのスイッチャーがあります。

moblin07

仮想デスクトップみたいになっていて、フル画面じゃないアプリも(普通の GTK っぽいアプリ)を配置できます。 スクリーンショットでは画面1(左)で動画を再生していますが、スイッチング中の縮小表示でもちゃんと動いているのはさすがといったところです。 :)

まだ Moblin ネイティブ(?)的なアプリが少ないようで、ブラウザ、メーラ、メディア再生がそれっぽくなっていて、残念ながら TODO やスケジューラはいまいちな感じでした。 もちろん Evolution とかも動くのだと思いますが、今後各アプリとも UI を Moblin にあわせたものがそろって本領発揮といったところだと思います。

アプリの開発環境も(なんとなくの予想ですが) Python バインディングもでてきそうな雰囲気なので、できたら手軽におしゃれなアニメ UI がつくれるようになりそうですね。

ちなみにこのネットブック版、完成度ははっきりいってしまうとまだまだです。 特に日本語環境は、本気で使おうと思うと対応はしていますがやばめっぽい。 あとメディアが DNLA サーバみてくれなかったんです~。 対応しているハズなんですが。。 あと、IdeaPad では無線LAN が使えませんでした、ThinkPad X61 は OK。

まぁまぁネットブック向けにリリースされているものはコンセプトモデルも兼ねていると思いますので、これを各社カスタマイズしてコンピュータにいれて出荷するのが本流かと思います。 さっくり起動してきれいに動く感覚はこれで十分わかりそうです。

とりあえず紹介動画とかみてたのしげな夢を見てみることにします。

かわいすなぁ。 :)

Nov82009

Stax Networks への JavaEE アプリのデプロイ このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加

曇り ひろまさ@ 2009年 11月 8日 投稿時の月齢:21.6  月名:二十二日月  潮汐:小潮

慣れの問題もあるかもですが、ぼくはちょっとした自分でしか使わないような Web アプリをつくるのに PHP とかより Java を使った方が早い場合があります。 言語的な問題というより環境、、便利なライブラリがたくさんあって、いれるのも lib に jar 入れるだけだし~、みたいな(笑)

問題はインターネット上にデプロイする先があまりないことですが、クラウドがでてきてくれたので最近はいくつか無料で使わせてくれるところがでてきています。

昔 Morph AppSpace を使って遊んでいましたが、Stax Networks というのも良さそうなので実験してみました〜 Google App Engine なんてのもありますね。:-P

stax01

Stax Networks – Home

The fastest way for Java EE developers to build, manage and scale applications in the Cloud.

というわけで、早速適当なものをつくってデプロイ。

以前から iアプリ用の Java の twitter クライアントがほしいなぁとおもっていて、この場合サーバサイドのプロキシがないと実装できないので、それをつくるのを見据えて、とりあえず REST すると public タイムラインとってくるのをやってみようと思いました。

Java EE に JAX-RS という REST の仕様がありますが、その実装である JBoss の RESTEasy と、twitter にアクセスするために twitter4j を使ってみます。

JBoss、JAX-RS実装「RESTEasy 1.0」正式版リリース – SourceForge.JP Magazine

JAX-RS(JSR 311)は、JavaでRESTアーキテクチャを利用してWebアプリケーションを作成するためのJCP仕様。RESTEasyはJBossのJAX- RS実装で、開発者に容易に開発できるフレームワークを提供する。Tomcatなど、JDK 5以上をベースとしたサーブレットコンテナで動作するが、「JBoss Application Server」と蜜に統合することで、ユーザーエクスペリエンスを改善できるという。

Twitter4J – A Java library for the Twitter API

Twitter4J は TwitterAPI の Java ラッパです。 Twitter4J を使うと XML や HTTP に詳しくなくても容易に Twitter とインタラクトするアプリケーションを書くことが出来ます。

Eclipse で動的 Web プロジェクトを新規作成して、WebContent/WEB-INF/lib に各ライブラリ jar を放り込みます。

WebCOntent/WEB-INF/web.xml で RESTEasy をサーブレット登録して URL にマッピングします。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
    <display-name>DJOdekoServer</display-name>
    <context-param>
        <param-name>resteasy.scan</param-name>
        <param-value>true</param-value>
    </context-param>
    <context-param>
       <param-name>resteasy.servlet.mapping.prefix</param-name>
       <param-value>/api</param-value>
    </context-param>
    <servlet>
        <servlet-name>Resteasy</servlet-name>
        <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Resteasy</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

これでアプリをかく準備完了です。 ソースを適当にかきます。 :-)

RESTEasy は resteasy.scan を true にしておくと、@Path のアノテーションをもつクラス(?)を勝手にスキャンしてくれてクラスロードしてくれるようです。

ということで、@Path で URI を指定しておけばエントリポイントが勝手にできます。 便利ですね。

package net.maple4ever.djodeko.server.rest;
 
import java.util.HashSet;
import java.util.List;
import java.util.Set;
 
import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
 
import org.jboss.resteasy.annotations.providers.jaxb.Wrapped;
 
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
 
@Path("/public")
public class TimeLine {
 
    @GET
    @Produces("application/xml")
    @Wrapped(element="public")
    public Set<PublicTimeLine> getPublic() {
        Twitter twitter = new Twitter();
        List<Status> statuses = null;
        try {
            statuses = twitter.getPublicTimeline();
        } catch (TwitterException e) {
            e.printStackTrace();
        }
        
        HashSet<PublicTimeLine> publicTimeLine = new HashSet<PublicTimeLine>();
        for (Status status : statuses) {
            publicTimeLine.add(new PublicTimeLine(
                    status.getUser().getName(),
                    status.getText()));            
        }
        return publicTimeLine;
    }
 
}
 
@XmlRootElement(name = "tweet")
class PublicTimeLine {
    
    @XmlElement
    String account;
    @XmlElement
    String tweet;
    
    public PublicTimeLine() { }
    
    public PublicTimeLine(String account, String tweet) {
        this.account = account;
        this.tweet = tweet;
    }
 
    public String getAccount() {
        return account;
    }
 
    public String getTweet() {
        return tweet;
    }
    
}

その try cache はおかしーじゃねーかというつっこみはなしで。。(笑)

twitter4j を使ってパブリックタイムラインをもらって XML で出力する例です。  @Path("/public") を指定しているので、コンテキストルート/public にメソッドがマップされます。 メソッドにさらにアノテーションでパスを指定したり引数をもらうこともできます。

まぁまぁここまではできるひとなら 15分仕事です。 PHP より楽じゃねっすかね。 ローカルではうまくうごくことでしょう。 :)

で、これを Stax Networks にデプロイするわけですが、、はて、WAR玉 ってデプロイできるかな。 なにか専用の SDK あるみたいですが。。(笑)

Deploying WAR Files – Stax

If you have an a Java web application packaged as a WAR file, you can use the Stax Deploy ANT task from the Stax SDK to deploy your WAR file to the Stax Cloud using an ANT script.

というわけで、ちゃんとドキュメントがありました。 SDK に ant タスクがあるようです。 とりあえず、SDK をどっかにいれてあと ant もいれておきましょう。 (Ubuntu には ant のバイナリパッケージにあるんですが、念のため本家版をつかっています。 Eclipse 内蔵の ant でもいいかもです。)

Ubuntu の場合は、 ~/.profile に以下を書いておくといいかもです。

#Stax Setting
export STAX_HOME=/home/hiromasa/Application/stax/stax-sdk-0.3.6
export ANT_HOME=/home/hiromasa/Application/stax/apache-ant-1.7.1/
export PATH=$PATH:$STAX_HOME:$ANT_HOME/bin

あとは、ドキュメントにかいてあるとおり build.xml にユーザ名とかパスワード、war の stax-application.xml パスをかきます。

stax-application.xml はとりあえず適当に Stax Networks の管理画面で BASIC Servlet and JSP なアプリを作成しておいて、それをダウンロードしてきてそのまんま使うのが楽かもしれません。

stax03

WAR ファイルはとりあえず面倒なので Eclipse のプロジェクトエクスポートでつくっています。 これで ant すればネットワーク越しにデプロイしてくれます。  Morph AppSpace と違ってすぐデプロイしてくれるようです。 URL にアクセスしてみましょう。 :)

http://djodeko.hiromasa.staxapps.net/api/public

ちゃんと動いていますね。 :)

さて、Stax Networks は素敵なことにドメインマッピングに対応しています。 とりあえず、自分のドメインの CNAME を設定しておきます。

cname djodeko djodeko.hiromasa.staxapps.net.

最後にドットいれるのを忘れないよう。。

で、名前がひけるようになるまで我慢の子です。 Stax Networks 的に DNS が引ける状態でないとうまく登録してくれません。 もし管理画面で save しても値が空になるようならこの状態です。 ややまってからしましょう。 うまく保存できたら、、

http://djodeko.maple4ever.net/api/public

素敵ですね。 :)

実験的につくったものなので、まぁ URI かえるといろいろエラーでますが、どうやら Tomcat 使っているみたいです。

ファイルの書き込みがなければほとんどのフレームワーク/ライブラリは素直にうごくような雰囲気です。

DB (MySQL が使える)のほうはまだためしていませんが、JNDI 設定してしまえばあとは同じでしょう。 S2JDBC とか Hibernate とか動くんだと思います。

ふと思い立って、CMS とかも Java 製のものあるのかなとおもって検索してみると、エンタープライズ向けにいくつかあるようですね。 アプリケーションコンテナいるとコネクションプールとかシングルトンつかえるから性能的にはやっぱり有利な部分もあると思います。 PaaS が増えてくるとすればこれらも要チェックかもですね。

とりあえず、Stax は何もしなくてもいろいろ動きそう。 いろんなアプリをデプロイして実験してみるのも面白いかもしれません。

Next »