LingrAPI でいくつかバグ修正+α

  • setCounter:(observer経由でCallされたとき)カウンタがリセットされることがあるので修正
  • getRoomInfo:(パラメータにapikeyが無い為)動かないのを修正
  • observer:メッセージを返すことを想定していないので修正
  • setCounterDirect:追加(必要になったので。以下のスクリプト参照)

/arbo/network/services/LingrAPI.php(rev11)

<?php
Rhaco:import('network.http.ServiceRestAPIBase');
Rhaco:import('tag.model.TemplateFormatter');
Rhaco:import('tag.model.SimpleTag');
Rhaco:import('lang.Variable');
/**
 * Lingr API 使用ライブラリ
 *
 * @author  SHIGETA Takeshiro <shigepon0@gmail.com>
 * @license New BSD License
 */
class LingrAPI extends ServiceRestAPIBase {

    var $apikey = '';
    var $baseurl = 'http://www.lingr.com/api/';
    var $session;
    var $ticket;
    var $counter;
    var $method;
    var $url;
    var $errorcode;

    function LingrAPI($apikey=''){
        parent:ServiceRestAPIBase();
        if($apikey) $this->apikey = $apikey;
        $this->__init__();
    }

    function __init__(){
        $this->createSession();
    }

    function createSession(){
        $this->url = Url:parseAbsolute($this->baseurl,./session/create/');
        $response = $this->sendPostCommand(array('api_key'=>$this->apikey));
        if($this->isOk($response)){
            $this->session = $response->getInValue('session');
            return true;
        }else{
            $this->getError($response);
            return false;
        }
    }

    function setTicket($response){
        $this->ticket = $response->getInValue('ticket');
    }

    function setCounter($response){
//      $this->counter = $response->getInValue('counter');
// <status>ok</status> であっても <counter> タグが必ず存在するとは限らないので存在しているときのみ
// カウンタ更新するよう変更した。(observerがタイムアウトで返ってきたときを想定)
$counter = $response->getInValue('counter');
if(!empty($counter)) $this->counter = $counter;
    }

// 外部から明示的にカウンタを設定する為に追加
function setCounterDirect($counter){
    $this->counter = $counter;
}

    function login($id,$password){
        $this->url = Url::parseAbsolute($this->baseurl,'./auth/login/');
        $response = $this->sendPostCommand(array('email'=>$id,'password'=>$password));
        return $this->isOk($response);
    }

    function logout(){
        $this->url = Url::parseAbsolute($this->baseurl,'./auth/logout/');
        $response = $this->sendPostCommand();
        return $this->isOk($response);
    }

    function setNickname($nickname){
        $this->url = Url::parseAbsolute($this->baseurl,'./room/set_nickname/');
        $response = $this->sendPostCommand(array('nickname'=>$nickname));
        return $this->isOk($response);
    }

    function enterRoom($roomid,$nickname='',$passwd='',$itempotent=false){
        $this->url = Url::parseAbsolute($this->baseurl,'./room/enter/');
        $param = array('id'=>$roomid);
        if($passwd) $param['password'] = $passwd;
        if($nickname) $param['nickname'] = $nickname;
        if($itempotent) $param['itempotent'] = true;
        $response = $this->sendPostCommand($param);
        if($this->isOk($response)){
            $this->setTicket($response);
            $this->setCounter($response);
            return array('occupants'=>$this->_getOccupants($response));
        }else{
            return false;
        }
    }

    function getUserInfo(){
        $this->url = Url::parseAbsolute($this->baseurl,'./user/get_info/');
        $response = $this->sendGetCommand();
        if($result = $this->isOk($response)){
            $result =  array('user'=>array(
            'id'=>$response->getInValue('user_id'),
            'email'=>$response->getInValue('email'),
            'defaultNickname'=>$response->getInValue('default_nickname'),
            'description'=>$response->getInValue('description'),
            'counter'=>$response->getInValue('counter')
            ),
            'owenedRoom'=>$this->_getRooms($response,'owned_'),
            'favoriteRoom'=>$this->_getRooms($response,'favorite_'),
            'monitoredRoom'=>$this->_getRooms($response,'monitored_'),
            'visitedRoom'=>$this->_getRooms($response,'visited_'),
            'occupiedRoom'=>$this->_getRooms($response,'occupied_')
            );
        }
        return $result;
    }

    function getRoomInfo($roomid,$counter='',$user_messages_only=false,$passwd=''){
        $this->url = Url::parseAbsolute($this->baseurl,'./room/get_info/');
        $param = array('id'=>$roomid);
        if($counter) $param['counter'] = $counter;
        if($user_messages_only) $param['user_messages_only'] = true;
        if($passwd) $param['password'] = $passwd;
$param['api_key'] = $this->apikey;
//DD(array('getRoomInfo:aram'=>$param));
        $response = $this->sendGetCommand($param);
//DD(array('getRoomInfo:esponse'=>$response));
        if($result = $this->isOk($response)){
            $result =  array(
            'id'=>$response->getInValue('id'),
            'name'=>$response->getInValue('name'),
            'description'=>$response->getInValue('description'),
            'url'=>$response->getInValue('url'),
            'icon_url'=>$response->getInValue('icon_url'),
            'counter'=>$response->getInValue('counter'),
            'max_user_message_id'=>$response->getInValue('max_user_message_id')
            );
            return array('room'=>$this->_getRooms($response),'messages'=>$this->_getMessages($response),'occupants'=>$this->_getOccupants($response));
        }
        return $result;
    }

    function startObserving(){
        $this->url = Url::parseAbsolute($this->baseurl,'./user/start_observing/');
        $response = $this->sendPostCommand();
        if($this->isOk($response)){
            $this->setCounter($response);
            return true;
        }else{
            return false;
        }
    }

    function observe(){
        $this->url = Url::parseAbsolute($this->baseurl,'./room/observe/');
//      $response = $this->sendGetCommand(array('session'=>$this->session,'ticket'=>$this->ticket));
        $response = $this->sendGetCommand(array('session'=>$this->session,'ticket'=>$this->ticket,'counter'=>$this->counter));
//echo "<pre>";
//echo TemplateFormatter::htmlencode(print_r($response,true));
//echo "</pre>";
            if($this->isOk($response)){
            $this->setCounter($response);
//          return true;
return array(
'messages'=>$this->_getMessages($response),
'occupants'=>$this->_getOccupants($response)
);
        }else{
            return false;
        }
    }

    function stopObserving(){
        $this->url = Url::parseAbsolute($this->baseurl,'./user/stop_observing/');
        $response = $this->sendPostCommand();
        if($this->isOk($response)){
            return array(
                'messages'=>$this->_getMessages($response),
                'occupants'=>$this->_getOccupants($response)
            );
        }else{
            return false;
        }
    }

    function getMessages($user_messages_only=false){
        $this->url = Url::parseAbsolute($this->baseurl,'./room/get_messages/');
        $param = array('session'=>$this->session,'ticket'=>$this->ticket,'counter'=>$this->counter);
        if($user_messages_only) $param['user_messages_only'] = $user_messages_only;
//DD(array('getMessages:aram'=>$param));
        $response = $this->sendGetCommand($param);
//DD(array('getMessages:esponse'=>$response));
        if($this->isOk($response)){
            $this->setCounter($response);
            return array(
                'messages'=>$this->_getMessages($response),
                'occupants'=>$this->_getOccupants($response)
            );
        }else{
            return false;
        }
    }

検証に使ったスクリプト

<?php
include_once dirname(__FILE__) . '/__init__.php';
Rhaco::import('network.services.LingrAPI');
Rhaco::import('DD');

Rhaco::constant('LINGR_API_KEY',  'apikey');
Rhaco::constant('LINGR_ACCOUNT',  'mailaddress');
Rhaco::constant('LINGR_PASSWORD', 'password');
Rhaco::constant('LINGR_ROOMID',   'roomname');
Rhaco::constant('LINGR_NICKNAME', 'nickname');

// ログイン
$lingr = new LingrAPI(Rhaco::constant('LINGR_API_KEY'));
DD($lingr->login(Rhaco::constant('LINGR_ACCOUNT'), Rhaco::constant('LINGR_PASSWORD')));

// roomに入る
DD($lingr->enterRoom(Rhaco::constant('LINGR_ROOMID'), Rhaco::constant('LINGR_NICKNAME')));

// room情報を取得
DD($room_info = $lingr->getRoomInfo(Rhaco::constant('LINGR_ROOMID')));

// 自分が最後に発言したカウンタをセット
$lingr->setCounterDirect($room_info['room'][0]['max_user_message_id']);

// 発言を読み続ける
while(true){
    echo "*".date("H:i:s")." ".$lingr->counter."<br/>\n";

    // 新規発言がされるか、タイムアウト(2分)まで待ち状態。
    DD($message = $lingr->observe());

    // タイムアウトではない&&メッセージが1件以上あるとき、メッセージをecho
    if($message !== false && isset($message['messages'])){
        foreach($message['messages'] as $msg){
            $buf = '';
            $buf .= $msg['id'].':;
            $buf .= $msg['timestamp'].':';
            $buf .= $msg['nickname'].':';
            $buf .= $msg['text'];
            echo TemplateFormatter:htmlencode($buf) . "<br/>\n";

            // 発言にbyeが含まれるとき、break
            if(preg_match('/bye/',$msg['text']) > 0) break;
        }
    }
}

// ログアウト
DD($lingr->logout());
echo "*".date("H::")."<br/>\n";

?>

2008-07-16追記

http://fixdap.com/p/rhacolibs/14719/
で改修してもらいました。