[WebAPI]Google Chart APIがQRコードも吐けるようになった

Written by uechoco 7月 15

Developer’s Guide – Google Chart API – Google Code

Google Code Blog: QR Codes now available on the Google Chart API

ボーっとねっとサーフィンしてたら、Google Chart APIがQRコード対応していることに気がついた!よく見たら、5日前とか。

これってアレですよね。自前でQRコードライブラリ持たなくてもいいってことですよね。Google様様。

ぁ、ブログのほうみてたら、出力オプションでShift_JISにも対応しているような記述がありますね。ブログの執筆者が日本人だけに、QRコードのニーズはしっかりと理解されてるってことですかね。

[php][PEAR]Services_MixiAPIとXML_Feed_Parserを使ってみた

Written by uechoco 1月 25

id:shimookaさんが持ちネタを放出したとのことで、CodeReposに追加されたようなので、Services_MixiAPIを使ってみました。

とりあえず、参考にしたサイトを先にまとめておきます。

まずはライブラリの入手。CodeReposのServices_MixiAPIディレクトリをチェックアウトします。Subversionがない方はmixiのAPIが増えていたので、Services_MixiAPI作ってみたにPEARパッケージにしたものがおいてあるようなので、pearコマンドでインストールできます。もちろん、おすすめはCodeReposの方です。チェックアウトしたら、/src/Servicesディレクトリをinclude_pathで通っている場所にエクスポートします。あるいは、http://svn.coderepos.org/share/lang/php/Services_MixiAPI/src/Servicesを直接エクスポートしてもいいのかな。

私がとってきたバージョンは0.0.1でした。現時点では、Services_MixiAPIは、実行環境がWindowsだと動きません。Services_MixiAPI_AbstractAPIクラスのbuildWSSEAuthメソッドががPOSIX関数を用いているためです。XAMPPerな私はWindowsの実行環境で開発したいので、たぶん一意なハッシュを得るのに必要なんだろうなと適当に解釈して、uniqid()関数でこんな感じで書き換えました。

PHP:
  1. private function buildWSSEAuth($user, $pass) {
  2.         // ----> uechoco modified begin
  3.         //$nonce = pack('H*', sha1(md5(time().rand().posix_getpid())));
  4.         $nonce = pack('H*', sha1(md5(time().rand().uniqid(rand(), true))));
  5.         // <---- uechoco modified end
  6.         $created = date('Y-m-dTH:i:s') . 'Z';
  7.         $digest = base64_encode(pack('H*', sha1($nonce . $created . $pass)));
  8.         $wsse_header = sprintf('UsernameToken Username="%s", PasswordDigest="%s", Nonce="%s", Created="%s"', $user, $digest, base64_encode($nonce), $created);
  9.         return $wsse_header;
  10.     }

あと、今回はXML_Feed_ParserというPEARのライブラリも使っています。shimookaさんのサンプルだとSimpleXMLElementを使っているので、同じの使ったら記事にする意味ないかなと思って、XML_Feed_Parserに挑戦してみました。

説明が面倒なので、CYでお願いします。CY?「コード読め」ですよ。取得したAtomを眺めてたら、mixiの拡張フォーマットが指定してあって、ユーザーの画像と、マイミクなのかどうかが取得できるようなので一緒に取得してみました。

PHP:
  1. <?php
  2. /**
  3. * Services_MixiAPIとXML_Feed_Parserを用いてMixiの足跡を取得するサンプル
  4. *
  5. * PHP version 5
  6. *
  7. * @author    Yusuke Ueno (uechoco)
  8. * @license   http://www.php.net/license/3_01.txt The PHP License, version 3.01
  9. * @see       http://pear.php.net/package/Services_MixiAPI
  10. */
  11.  
  12. // クラスの読み込み
  13. require_once 'Services/MixiAPI/Factory.php';
  14. require_once 'XML/Feed/Parser.php';
  15.  
  16. // mixiの個人情報を定義
  17. class Mixi_Info {
  18.     // mixiのログインID
  19.     const LOGIN_ID = '自分のmixiのログインID';
  20.     // mixiのパスワード
  21.     const PASSWORD = '自分のmixiのログインパスワード';
  22.     // mixiのユーザーID
  23.     const USER_ID  = '自分のmixiのユーザーID';
  24. }
  25.  
  26. // 足跡オブジェクトの作成
  27. $service = Services_MixiAPI_Factory::getInstance(
  28.     Services_MixiAPI_Factory::API_MODE_FOOTPRINT, // 足跡
  29.     Mixi_Info::LOGIN_ID,    // ログインID
  30.     Mixi_Info::PASSWORD,    // パスワード
  31.     Mixi_Info::USER_ID        // ユーザーID
  32. );
  33.  
  34. // 足跡の取得
  35. $service->execute();
  36.  
  37. // とりあえず表示
  38. try {
  39.     $feed = new XML_Feed_Parser($service->get());
  40. } catch (XML_Feed_Parser_Exception $e) {
  41.     die('フィードが無効です:'.$e->getMessage());
  42. }
  43.  
  44. // 足跡情報の整形
  45. $footprints = array();
  46. foreach ($feed as $k => $entry) {
  47.  
  48.     // 通常のAtomフィールドを取得する
  49.     $id = str_replace('http://mixi.jp/show_friend.pl?id=', '', $entry->link);
  50.     $footprints[] = array(
  51.         'id'       => $id,
  52.         'name'     => $entry->author,
  53.         'link'     => $entry->link,
  54.         'date'     => date('Y-m-d H:i:s', $entry->updated),
  55.         'unixtime' => $entry->updated,
  56.     );
  57.  
  58.     // 拡張情報を取得する
  59.     $model = $entry->model;
  60.     $tracks = array('image', 'relation');
  61.     foreach ($tracks as $localName) {
  62.         $nodes = $model->getElementsByTagNameNS('http://mixi.jp/atom/ns#tracks', $localName);
  63.         foreach ($nodes as $node) {
  64.             $footprints[$k][$localName] = $node->nodeValue;
  65.         }
  66.     }
  67. }
  68. ?>
  69. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  70. <html xmlns="http://www.w3.org/1999/xhtml">
  71. <head>
  72. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  73. <title>足跡一覧</title>
  74. <style type="text/css">
  75. <!--
  76. ul#footprint {
  77.     list-style-type: none;
  78. }
  79.  
  80. ul#footprint li {
  81.     display: block;
  82.     border: solid 1px gray;
  83.     padding-left: 100px;
  84.     height: 76px;
  85.     background-repeat: no-repeat;
  86. }
  87.  
  88. ul#footprint li .friend {
  89.     color: green;
  90. }
  91. -->
  92. </style>
  93. </head>
  94. <body>
  95. <h1>足跡一覧</h1>
  96. <ul id="footprint">
  97. <?php
  98. foreach ($footprints as $footprint) {
  99.     printf(
  100.         '<li style="background-image: url(%s)"><a href="%s" title="%s">%s</a>さん (%s 訪問、%s)'."\n",
  101.         $footprint['image'],
  102.         $footprint['link'],
  103.         $footprint['name'],
  104.         $footprint['name'],
  105.         $footprint['date'],
  106.         $footprint['relation'] === 'friend' ? '<span class="friend">お友達</span>' : '他人'
  107.     );
  108. }
  109. ?>
  110. </ul>
  111. </body>
  112. </html>

で、出力画面はこんな感じ。
Services_MixiAPIのサンプル

モザイクが面倒だったので、名前だけにmd5かけてちょんぎってます。

で、この足跡のリストをどうするの?って言われると、なんとも困るんですが、適当にTwitterとかとあわせてみたりしてください。私の目的はServices_MixiAPIを使ってみたかっただけなのです。

[php][CakePHP]日英・英日翻訳コンポーネント

Written by uechoco 12月 23

ようやくCakePHPの勉強を開始しました。『CakePHPガイドブック』と『PHPフレームワーク完全マスター』で勉強しています。

以前[php][WebAPI]EJ, JE translation APIは翻訳WebAPIとして使えるで紹介したEJ, JE translation APIを用いてなんか変なもの作っています。CakePHPの作法がよくわからないのですが、コントローラの中に書くのは良くなさそうなので、適当に本を見てコンポーネントにしてみました。phpのバージョンやライブラリの依存については[php][WebAPI]EJ, JE translation APIは翻訳WebAPIとして使えるを参照してください。

PHP:
  1. require_once 'HTTP/Client.php';
  2. /**
  3.  * EJ, JE translation APIを用いて翻訳を行うコンポーネント
  4.  *
  5.  * @author uechoco
  6.  * @see    http://muumoo.jp/news/2007/05/09/0translationapi.html
  7.  */
  8.  
  9. class TranslateComponent extends Object
  10. {
  11.     /**
  12.      * 固定ID定数
  13.      */
  14.     const ID_EJ = 'ZM5oVmX92xGrFWiRJhOy0Q';
  15.     const ID_JE = 'ohZnaGr92xG36xIFyzUFzw';
  16.  
  17.     /**
  18.      * コントローラを保持
  19.      */
  20.     var $controller = null;
  21.  
  22.  
  23.  
  24.     /**
  25.      * HTTP_Clientの初期化パラメータ
  26.      *
  27.      * @access private
  28.      */
  29.     var $http_client_default_param = array(
  30.         'timeout' => 10,
  31.         'allowRedirects' => true,
  32.         'maxRedirects' => 3
  33.     );
  34.     var $http_client_default_header = array(
  35.         'Accept-Language' => 'ja-JP,ja;q=0.9,en;q=0.8'
  36.         );
  37.  
  38.     /**
  39.      * POSTする先のURI
  40.      *
  41.      * @access private
  42.      */
  43.     var $uri = 'http://pipes.yahoo.com/pipes/pipe.run';
  44.  
  45.  
  46.     /**
  47.      * POSTするパラメータ(固定部分)
  48.      *
  49.      * @access private
  50.      */
  51.     var $param = array(
  52.     '_run' => 1,
  53.     '_render' => 'json', // or rss
  54.     );
  55.  
  56.     function
  57.     __construct()
  58.     {
  59.         parent::__construct();
  60.     }
  61.  
  62.     function
  63.     startup(&$controller)
  64.     {
  65.         $this->controller =& $controller;
  66.     }
  67.  
  68.  
  69.     /**
  70.      * 英日翻訳
  71.      */
  72.     function translate_ej(&$word)
  73.     {
  74.         return $this->_translate(TranslateComponent::ID_EJ, $word);
  75.     }
  76.  
  77.  
  78.     /**
  79.      * 日英翻訳
  80.      */
  81.     function translate_je(&$word)
  82.     {
  83.         return $this->_translate(TranslateComponent::ID_JE, $word);
  84.     }
  85.  
  86.  
  87.     /**
  88.      * 翻訳本体
  89.      */
  90.     function _translate($_id, &$word)
  91.     {
  92.         $text = urlencode($word);
  93.         $p = am($this->param, array('_id'=>$_id, 'text'=>$text));
  94.  
  95.         // レスポンスの発行
  96.         $client =& new HTTP_Client($this->http_client_default_param, $this->http_client_default_header);
  97.         $client->post($this->uri, $p);
  98.         $response = $client->currentResponse();
  99.  
  100.         // JSON形式をPHPで操作可狽ネ形式にデコード
  101.         $ret = json_decode($response['body']);    //>= php 5.2.0
  102.         $tuple = $ret->value->items[0];
  103.  
  104.         // 翻訳結果
  105.         return urldecode($tuple->description);
  106.     }
  107. }

[php][PEAR]Services_Amazonが1年ぶりにマイナーバージョンアップ

Written by uechoco 12月 18

 AmazonのWebAPIを使いやすくするPEAR::Services_Amazonが2007/12/17に0.7.1にマイナーバージョンアップしました。一部のメソッドのバグの修正と、いくつかの機能追加の要望に対応したようです。ChangeLogにはServices_AmazonECS4.phpがプロキシをサポートしたとも書いてありますね。

 Services_AmazonECS4.phpはオプションをいろいろと追加していくことで、Amazon WebAPIのバージョンアップによって新しく取得できるようになった項目などにも対応できています。個人的にはServices_Amazon.phpのような、特定の取得項目(たとえばISBNとか)にあわせたメソッドを量産しておいてほしいような気もします。まぁ・・・自分でWrapper作ってやれよってことですよね。はい。

[php][WebAPI]EJ, JE translation APIは翻訳WebAPIとして使える

Written by uechoco 11月 21

前回のWebserviceX.NET Translation Engineに引き続き、翻訳WebAPIの調査。今回はEJ, JE translation APIの調査です。

EJ, JE translation APIは、Yahoo! Babel FishYahoo! Pipes経由で呼び出すことによって文章を翻訳するAPIです。下記が本家APIのURLとMASHAPEDIAの紹介記事です。

英語←→日本語の翻訳APIとして使えるYahoo Pipesを作った
http://muumoo.jp/news/2007/05/09/0translationapi.html

JSON形式で翻訳「EJ, JE translation API」 : WEBAPI一覧 : MASHUPEDIA - マッシュペディア - : Web API x Mashup
http://www.mashupedia.jp/webapis/view/292

概要としては、REST形式でAPIにアクセスし、翻訳結果をRSS/JSON/JSONPで返す感じです。

  • APIのURL
    • http://pipes.yahoo.com/pipes/pipe.run
  • パラメータ
    • _id
      • 翻訳の種類
      • EJ(英語→日本語)なら、「ZM5oVmX92xGrFWiRJhOy0Q」
      • JE(日本語→英語)なら、「ohZnaGr92xG36xIFyzUFzw」
    • _run
      • 「1」で固定
    • _render
      • レスポンス形式
      • 「rss」または「json」
    • _callback
      • _render = jsonのとき、JSONP用のコールバック関数名
    • text
      • 翻訳する文章(エンコード済み)
      • JavaScriptから実行する場合、encodeURIComponent()関数をかける必要がある
      • phpから実行する場合、urlencode()関数をかける必要がある

さきほどの本家のページにはJavaScriptのみで実装するサンプルが公開されています。今回はphpでJSONを分解するサンプルを試してみました。

PHP:
  1. require_once 'HTTP/Client.php';
  2.  
  3. // 翻訳したいテキスト
  4. $text = 'This is a pen.';
  5. // HTTP_Clientの初期化パラメータ
  6. $http_client_default_param = array(
  7.     'timeout' => 10,
  8.     'allowRedirects' => true,
  9.     'maxRedirects' => 3
  10. );
  11.  
  12. $http_client_default_header = array(
  13.     'Accept-Language' => 'ja-JP,ja;q=0.9,en;q=0.8'
  14. );
  15. // POSTする先のURIとそのパラメータ
  16. $uri = 'http://pipes.yahoo.com/pipes/pipe.run';
  17. $param = array(
  18.     '_id' => 'ZM5oVmX92xGrFWiRJhOy0Q', // EJ
  19.     //'_id' => 'ohZnaGr92xG36xIFyzUFzw', // JE
  20.     '_run' => 1,
  21.     '_render' => 'json', // or rss
  22.     //'_callback' => 'example20070509callback', // JSONP
  23.     'text' => urlencode($text)
  24. );
  25. // レスポンスの発行
  26. $client =& new HTTP_Client($http_client_default_param, $http_client_default_header);
  27. $client->post($uri, $param);
  28. $response = $client->currentResponse();
  29. // JSON形式をPHPで操作可狽ネ形式にデコード
  30. $ret = json_decode($response['body']);    //>= php 5.2.0
  31. $tuple = $ret->value->items[0];
  32. // 表示
  33. echo sprintf("Title: %s<br />", urldecode($tuple->title));
  34. echo sprintf("Description: %s<br />", urldecode($tuple->description));

実行結果のサンプルは以下のようになります。

Title: This is a pen.
Description: これはペンである。

いくつかプログラムの補足をしておきます。

1. レスポンスの発行にはPEAR::HTTP_Clientライブラリを使用しました。簡単なライブラリなので何をしているのかはすぐにわかると思います。

2. json_decode()関数は、php 5.2.0から標準で組み込まれるようになったJSON 拡張モジュールに依存しています。それ以前のバージョンの方は、PEAR::Services_JSONphp-jsonなどの拡張ライブラリをインストールしてください。

これなら簡単な文章を翻訳するのに十分使えますね!