2008/07/30 (Wed)
MixiAPIのテスト
atom/MixiTest.java
package atom;
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.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
/**
* @author tex
*
*/
public class MixiTest {
private HttpClient client;
public MixiTest() {
this.client = new HttpClient();
}
public void post(String url, String username, String password)
throws HttpException, IOException {
PostMethod method = new PostMethod(url);
method.addRequestHeader("X-WSSE",
getWsseHeaderValue(username, password));
String body = ""
+ "<?xml version='1.0' encoding='utf-8'?>"
+ "<entry xmlns='http://purl.org/atom/ns#'>"
+ " <title>Test</title>"
+ " <summary>Post diary from Mixi API</summary>"
+ "</entry>";
StringRequestEntity re =
new StringRequestEntity(body, "application/atom+xml", "UTF-8");
method.setRequestEntity(re);
this.client.executeMethod(method);
System.out.println(method.getStatusLine().toString());
Header[] headers = method.getResponseHeaders();
int len = headers.length;
for (int i = 0; i < len; i++) {
System.out.print(headers[i].toString());
}
System.out.println(method.getResponseBodyAsString());
}
protected final String getWsseHeaderValue(String username, String password) {
try {
byte[] nonceB = new byte[8];
SecureRandom.getInstance("SHA1PRNG").nextBytes(nonceB);
SimpleDateFormat zulu =
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
zulu.setTimeZone(TimeZone.getTimeZone("GMT"));
Calendar now = Calendar.getInstance();
now.setTimeInMillis(System.currentTimeMillis());
String created = zulu.format(now.getTime());
byte[] createdB = created.getBytes("utf-8");
byte[] passwordB = password.getBytes("utf-8");
byte[] v = new byte[nonceB.length
+ createdB.length + passwordB.length];
System.arraycopy(nonceB, 0, v, 0, nonceB.length);
System.arraycopy(createdB, 0, v, nonceB.length, createdB.length);
System.arraycopy(passwordB, 0, v, nonceB.length
+ createdB.length, passwordB.length);
MessageDigest md = MessageDigest.getInstance("SHA1");
md.update(v);
byte[] digest = md.digest();
StringBuffer buf = new StringBuffer();
buf.append("UsernameToken Username=\"");
buf.append(username);
buf.append("\", PasswordDigest=\"");
buf.append(new String(Base64.encodeBase64(digest)));
buf.append("\", Nonce=\"");
buf.append(new String(Base64.encodeBase64(nonceB)));
buf.append("\", Created=\"");
buf.append(created);
buf.append('"');
return buf.toString();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) throws Exception {
MixiTest test = new MixiTest();
test.post("http://mixi.jp/atom/diary/member_id=xxxx", "xxx@xxxxxxx",
"xxxxxxxxxxxx");
}
}
2008/07/08 (Tue)
CABviaActiveSync
PC上に保存されたCABファイルを右クリックからインストールするためのソフト。 1.2ぐらいの時はXPまでだったが、既に1.5にまであがっていて、Vistaにも対応していた。
これを使用するとWindowsMobile端末へのソフトのインストールが格段に楽になる。
.NET Framework 3.0とActiveSyncもしくはWMDC (Windows Mobile Device Center)が必要。
Download --> modaco
2008/07/07 (Mon)
OpenPNE
OpenPNE構成ディレクトリ
.
|-- config.php 設定ファイル
|-- bin/ Cron、メール処理等コンソールで行うスクリプト
|-- lib/ OpenPNE外ライブラリの格納場所
| |-- include/ PEAR等ライブラリの格納場所
| `-- smarty_plugins/ Smarty用プラグインの格納場所
|-- public_html Apacheで公開されるドキュメントルート
| |-- cmd/ 小窓用JS格納ディレクトリ
| |-- flash/ Flash格納用ディレクトリ。フレンドリスト用SWFのみ
| |-- img/ 公開画像ディレクトリ
| |-- js/ 公開JavaScriptディレクトリ
| |-- modules/ モジュール別公開ファイル
| |-- openid/ OpenID用コントローラ
| |-- skin/ スキン格納ファイル
| |-- cap.php キャプチャ作成PHP
| |-- config.inc.php 初期設定用PHP
| |-- img.php 画像用フィルタ
| |-- img_skin.php スキン用フィルタ
| |-- index.php フロントコントローラ
| `-- xhtml_style.php カスタムCSS用PHP
|-- setup セットアップ用
| |-- script
| `-- sql セットアップ用SQLファイル
| |-- mysql40 MySQL4.0用SQL
| |-- mysql41 MySQL4.1用SQL(大幅に変更があったため)
| | |-- install インストール用SQL、テーブル、初期データ
| | |-- option オプション等(Biz等)SQL
| | |-- update マイナーバージョンアップ用
| | `-- upgrade メジャーバージョンアップ用
| `-- postgres74 PostgreSQL用
|-- var 一時ファイル置き場(適時削除してもよい)
| |-- function_cache 関数キャッシュ用(ランキング等逐次実行の必要のないもの)
| |-- img_cache 画像キャッシュ用
| |-- log ログ用
| |-- rss_cache RSSキャッシュ用(cronから生成)
| |-- templates_c Smartyテンプレートコンパイル済みPHP用
| `-- tmp 一時ファイル用(ファイルアップロード用)
|-- webapp OpenPNEアプリケーション
| |-- lib/ アプリケーション用ライブラリ(OpenPNE用カスタム等)
| |-- modules/ モジュールディレクトリ
| | |-- admin/ 管理画面モジュール
| | | |-- init.inc 初期設定ファイル
| | | |-- do/ 処理実行系PHP格納ディレクトリ
| | | |-- lib/ 管理画面モジュール用ライブラリ格納ディレクトリ
| | | |-- page/ ページ系PHP格納ディレクトリ
| | | |-- templates/ Smartyテンプレート格納ディレクトリ
| | | `-- validate/ 妥当性検証用INIファイルの格納ディレクトリ
| | |-- api API用
| | |-- ktai 携帯用
| | |-- openid OpenID用
| | |-- pc PC用
| | |-- portal SNSポータル用
| | `-- setup セットアップ用
| |-- templates テンプレート
| |-- validate 妥当性検証
| |-- init.inc 初期設定用
| `-- version.php バージョン情報
|-- webapp_biz BIZ機能(予定表、グループウェア、施設管理、ToDo)
`-- webapp_ext 拡張モジュールの格納ディレクトリ
OpenPNEの基本構成
- public_html/index.php を使用したフロントコントローラパターン
テンプレート名とアクション名の規約 /{module}/{type}/{action}.php
- module モジュール名 例: admin, pc, ktai, api, openid, portal, setup 等 パラメータ: m
- type アクションタイプ名 例: page, do パラメータ a prefix
- action アクション名
例:
csv_member
,delete_c_admin_user
等 パラメータ a suffix
webapp_ext
による拡張モジュール対応webapp_ext
に置いたファイルは同名のwebappのファイルの代替ファイルとなり 優先的に実行される。Smartyによるテンプレートエンジンの使用 テンプレートファイルにSmartyを仕様。JavaScriptの括弧と競合するため デリミタを変更している {} -> ({})
ライブラリの内包 PEARやSmartyのライブラリを内包し環境依存をなくしているため、 OpenPNE外に依存するライブラリがほぼ存在しない。
小窓機能による他サイトAPIとのMashup 小窓機能と呼ばれるURL自動変換スクリプトにより 外部サイトのプレイヤー等をOpenPNE内にマッシュアップ可能となる
アクション
- OpenPNE_Actionを継承し、execute関数をオーバーライドする。
- 認証外のアクションを作りたい場合はisSecureがfalseを返すようにする。デフォルトtrue
page系 ページ遷移系のアクションの処理を定義する。画面遷移先はファイル名等同名の Smartyテンプレートによって処理される。 Smartyテンプレートで処理するパラメータはexecute($request)関数で作り、 処理に問題がなければ関数は"success"を返すようにする。
do系 処理実行系のアクションを定義する。画面遷移先が決まっていないので、 execute関数の最後で、openpne_forwardで遷移先を指定し、 ブラウザにLocationヘッダを返し、クライアントリダイレクトを指示する。