目次

2008年11月26日水曜日

RubyでSocket通信

KRYM logсино Блогと、その中の人の協力により、WiPortデビューを果たす事が出来ました。

いまはRubyの勉強中。
KRYMさんのBlogからソースを拝借。


require 'socket'

client = TCPSocket.open('192.168.0.123', 10001)
//ここで自分でWiPortに割り振ったIPアドレスとポート

//ここから下は無限ループ
while true do
//trueの間はずっと実行=Falseなんてここにはないので、無限になりますね。

client.write('a')
//クライアント=WiPortにaを送り続けます
p client.gets.chomp
//p = print
//client = 上で記述した“TCPSocket~・・・”のこと
//gets = 入力データを文字列オブジェクトとして返します
//chomp = 改行を取り除いた文字列を生成して返します。
sleep(1)
//上の出力が終わった後、停止する
client.write('b')
p client.gets.chomp
sleep(1)
//上の三行と同じ

end


一行ずつ見て行くとこんな感じでした。

2008年11月16日日曜日

Orb APIで曲を探してみよう〜search.media編〜

曲再生のためにはmediumIdが必要。それを調べるには、search.mediaを活用というわけです。

たとえばAshの曲だけ調べたい時
http://api.orb.com/orb/xml/media.search?sid=(セッションID)&q=mediaType%3Daudio.file%20artist%5E%3DAsh

&qの後、条件を並列させるにはスペースでよいみたいですが、きちんとエンコードします。
こんなふうに→%20
そうするとこんな結果


<orb version="1.0" action="media.search" login="yasuko_yaka">
<status code="0"/>

<response>

<searchResult searchId="17" groupCount="0" itemCount="15">
<pagination>
</pagination>






<item orbMediumId="O82JqAce">
<field name="title">Shark</field>
<field name="description">0</field>
<field name="album">Free All Angels</field>
<field name="artist">Ash</field>
<field name="rating">0</field>
</item>

<item orbMediumId="OFTEbgfD">
<field name="title">Gabriel</field>
<field name="description">0</field>
<field name="album">Free All Angels</field>
<field name="artist">Ash</field>
<field name="rating">0</field>
</item>
</searchResult>
</response>
</orb>


全部の情報出て来て、うざいっす!って思ったら、fieldsで出したい情報だけ出します。
例えば、タイトルだけでいいってときは
http://api.orb.com/orb/xml/media.search?sid=(セッションID)&q=mediaType%3Daudio.file%20artist%5E%3DAsh&fields=title
こうすると、シンプルになって扱いやすいデータになるわけです。



<orb version="1.0" action="media.search" login="yasuko_yaka">
<status code="0"/>

<response>

<searchResult searchId="18" groupCount="0" itemCount="15">
<pagination>
</pagination>

<item orbMediumId="OAsr3j0A">
<field name="title">Walking Barefoot</field>
</item>

<item orbMediumId="O80WxSm3">
<field name="title">Shining Light</field>
</item>

<item orbMediumId="ORVcABGh">
<field name="title">Burn Baby Burn</field>
</item>

<item orbMediumId="OpO18BL2">
<field name="title">Candy</field>
</item>

<item orbMediumId="OROBI4d0">
<field name="title">Cherry Bomb</field>
</item>

<item orbMediumId="OGF6FKp1">
<field name="title">Submission</field>
</item>

<item orbMediumId="OLG6kFUL">
<field name="title">Someday</field>
</item>

<item orbMediumId="Ojc3FJaP">
<field name="title">Pacific Palisades</field>
</item>

<item orbMediumId="O82JqAce">
<field name="title">Shark</field>
</item>

<item orbMediumId="OObc8b2R">
<field name="title">Sometimes</field>
</item>

<item orbMediumId="OKBHcCFf">
<field name="title">Nicole</field>
</item>

<item orbMediumId="OF82CbGd">
<field name="title">There's A Star</field>
</item>

<item orbMediumId="OBCe1SO1">
<field name="title">World Domination</field>
</item>

<item orbMediumId="OFTF0Gc4">
<field name="title">Warmer Than Fire</field>
</item>

<item orbMediumId="OFTEbgfD">
<field name="title">Gabriel</field>
</item>
</searchResult>
</response>
</orb>

Orb APIで音楽ファイルを再生してみよう

なんだかしらないけど、昨日一日がんばって出来なかったstream.sdpというAPIが急に呼び出せるようになってテンションがあがりまくりました。

https://api.orb.com/orb/data/(セッショID)/(メディアID)/stream.sdp
昨日さんざこれをうっても反応してなかったくせに、ふっとできましたw
テンションがぐっとあがりました。

補足:
ログイン&セッションIDをサンプルのものはアラートで表示していたので、コピペできないのが難点でした。なので、自分で、結果からセッションIDを抜き出してHTMLの部分に表示するプログラムを作っちゃいました。

<html>
<head>
<meta name = "viewport" content = "width = device-width">
<!-- We use the Prototype library. Get it at: http://prototypejs.org -->
<script src="prototype.js" type="text/javascript"></script>
</head>
<body>
<script language="javascript">
// End point url of the Orb Api.エンド ポイントURIとは、ローカル又はリモートの資源及びサービスを特定するためのアドレスです
var orbApiUrl = 'http://api.orb.com/orb/';
// API key. If you want to run this sample, paste your API key below.ここにはAPIKey入れます
var apiKey = '3o7hgfvmof7jb';
// To go around Javascript's cross domain restriction, we use a local proxy.
var proxyUrl = 'ajaxProxy.php';

/*
* Authenticate
*/
function authenticate() {
var login = $('login').value;
var password = $('password').value;
// We make an ajax request to the login method, through the local proxy.
var url = orbApiUrl + 'xml/session.login?apiKey=' + apiKey +
'&l=' + encodeURIComponent(login) +
'&password=' + encodeURIComponent(password);
new Ajax.Request(proxyUrl + '?url=' + escape(url), {
method: 'get',
onSuccess: authenticateSuccessCallback,
onFailure: orbApiFailureCallback
});
};

/*
* authenticateSuccessCallback
* Called when the login ajax request was successful.
*/
function authenticateSuccessCallback(transport) {
// Access the XML dom object within the response.
var dom = transport.responseXML.documentElement;
// Check that the Orb response is OK.
if (checkOrbResponseStatus(dom)) {
// Retrieve the session id from the XML dom object.
sessionId = dom.getElementsByTagName('orbSessionId')[0].firstChild.nodeValue;
//セッションIDの表示
  // document.write(sessionId,"がセッションIDです。");
$('results').innerHTML = sessionId + '<br/>' +"セッションIDです";
// Hide the login panel and display the search panel on the page.
Element.hide('loginPanel');
Element.show('mainPanel');
}
};

/*
* orbApiFailureCallback
* Called when an ajax request failed.
* (this is not a failure from the API method itself).
*/
function orbApiFailureCallback(transport) {
alert('Error contacting Orb server (' + transport.status + '): ' + transport.responseText);
};

/*
* checkOrbResponseStatus
* This is a generic function that looks into the XML response sent by Orb to see if the status code is 0 (OK).
*/
function checkOrbResponseStatus(dom) {
var error = '';
try {
// Get the XML 'status' node.
var statusNode = dom.getElementsByTagName('status')[0];
// Get the XML 'status' node's 'code' attribute.
var statusCode = statusNode.attributes.getNamedItem('code').value;
if (statusCode != '0') {
// Code different from 0 means there was a problem.
var statusDesc = statusNode.attributes.getNamedItem('desc').value;
// Get the description corresponding to the error.
// WARNING: the description is just for development purposes.
// The text it contains is not intended to be displayed to the end-user.
// You should provide your own text/error messages depending on the error codes.
error = 'Error (' + statusCode + ') : ' + statusDesc;
}
} catch (e) {
error = 'Unknown error.';
}
if (error !== '') {
alert(error);
}
// Return true (boolean) if there was no error.
return (error === '');
}


</script>

<div id="loginPanel" style="border:1px;">
Login: <input type="text" id="login" value="" />
<br/>
Password: <input type="password" id="password" value="" />
<br/>
<input type="button" onclick="authenticate();" value="Login"/>
</div>


<div id="mainPanel" style="display:none;">
You are logged in!ログインしましたよよよよよよ。
<div id="results">
</div>
</div>
</body>
</html>

2008年11月14日金曜日

とてもやさしいAPI (自己流なので、違っているかも)~orbAPIの場合

夜中におなかが痛くて目が覚めてしまいました。なので、ソースコードをじっくり、一行ずつ読んでいました。すると、なんだか分からなかったOrbのAPIがなんとなく分かって来たような気がしました。おそらくDOM形式のAPI全般で、このように使用するのだと思います。Flickrとかもね。

OrbのAPIはURLを入力すると、XMLでデータがかえってくるものだと前に書きました。
例えばログインするときは

https://api.orb.com/orb/xml/session.login?apiKey=ohla9ocejeen&l=john&password=foo&speed=250

と入力すると

<orbSession>
<orbSessionId>...</orbSessionId>
<maxInactiveInterval>...</maxInactiveInterval>
<orbVersion>...</orbVersion>
</orbSession>

こんな結果が帰ってきました。
後は、この結果から、欲しい情報をゲットすればよいのです。 JavaScriptの場合、
dom.getElementsByTagName('orbSessionId')[0].firstChild.nodeValue;

こんな感じでとってきてます。
あとは

var sessionID = dom.getElementsByTagName('orbSessionId')[0].firstChild.nodeValue;

こんなふうにかけば、html上で表示するもよし、新しくAPIを引っ張ってくるためのURLに代入するもよし。

手順を整理してみると
1,APIを用いるためのURLを作る
2,タグから情報を引き出す
3,またAPIを用いるためのURLを作る(もしくは別なメソッドに活かす)
行うことはこれだけなんです。なんかカンタンなのかもって思えませんか?もちろん、URLを作るためにプログラミング言語が必要なんですが、どんな言語だって作れればいいのです。JavaScriptでもRubyでもPythonでもなんでも。

さて、補足。
Q:DOMってなんだ?

dom.getElementsByTagNameの後半は分かるとしても、domってなんなんでしょう。

A:XMLパーサが提供するアクセスの手段です。

DOMが知りたければ、XMLパーサをしらねばなりません。
XMLパーサとは XML文書を、アプリケーションソフトが利用しやすい形に変換するソフトウェアだそうです。
DOM(Document Object Model)とはW3C で勧告されている仕様の一つで、様々なソフトウェアがXML文書を読み取ったり、表示形式を変更して表示する事などを可能にする、XMLパーサのAPIなのです。
DOMはXML文書中のデータをXMLパーサが読み込むと、データをツリー構造としてメモリ上に展開します。最初に見た「結果」を表示していたのはDOMだったのです。

とまあ、googleのある時代に生まれて本当によかった3時間を過ごしました。

2008年11月9日日曜日

iPhone Webアプリ 備忘録



「iPhoneシュミレーターで見ると、字の大きさがヒドい事になる」という問題を抱えておりましたが、解決してるでしょ?


<meta name = "viewport" content = "width = device-width">

これを書き込めば解決!iPhoneSafariを使った人なら知っているでしょうが、iPhoneSafariではページをデフォで縮小表示してしまうらしい。
なので、上のタグを書き込めば一見落着と相成ります。

あと、Appleから配布されてたiPhone用のCSSが良いですね。

ネイティブアプリみたいなボタンとかリストが作れます。

OrbAPIを使ってみた~SearchMedhia編~

朝起きて、今日ものびのびと勉強中。
自分のOrbサーバーにログインして、メディアファイルを検索するものを作りました。

なんか字が大きくて見づらいのですが、iPhoneシュミレーター上で表示してみました。

用意したファイルは前と同じく、ajaxProxy.phpとprototype.jsにhtmlの3つ。
前述の二つは以前のものをそのまま使います。
で、htmlファイル。


<html>
<head>
<!-- We use the Prototype library. Get it at: http://prototypejs.org -->
<script src="prototype.js" type="text/javascript"></script>
</head>
<body>
<script language="javascript">
// End point url of the Orb Api.エンド ポイントURIとは、ローカル又はリモートの資源及びサービスを特定するためのアドレスです
var orbApiUrl = 'http://api.orb.com/orb/';
// API key. If you want to run this sample, paste your API key below.ここにはAPIKey入れます
var apiKey = 'ここにAPIKeyです';
// To go around Javascript's cross domain restriction, we use a local proxy.
var proxyUrl = 'ajaxProxy.php';

/*
* Authenticate
*/
function authenticate() {
var login = $('login').value;
var password = $('password').value;
// We make an ajax request to the login method, through the local proxy.
var url = orbApiUrl + 'xml/session.login?apiKey=' + apiKey +
'&l=' + encodeURIComponent(login) +
'&password=' + encodeURIComponent(password);
new Ajax.Request(proxyUrl + '?url=' + escape(url), {
method: 'get',
onSuccess: authenticateSuccessCallback,
onFailure: orbApiFailureCallback
});
};

/*
* authenticateSuccessCallback
* Called when the login ajax request was successful.
*/
function authenticateSuccessCallback(transport) {
// Access the XML dom object within the response.
var dom = transport.responseXML.documentElement;
// Check that the Orb response is OK.
if (checkOrbResponseStatus(dom)) {
// Retrieve the session id from the XML dom object.
sessionId = dom.getElementsByTagName('orbSessionId')[0].firstChild.nodeValue;
// Hide the login panel and display the search panel on the page.
Element.hide('loginPanel');
Element.show('mainPanel');
}
};

/*
* orbApiFailureCallback
* Called when an ajax request failed.
* (this is not a failure from the API method itself).
*/
function orbApiFailureCallback(transport) {
alert('Error contacting Orb server (' + transport.status + '): ' + transport.responseText);
};

/*
* checkOrbResponseStatus
* This is a generic function that looks into the XML response sent by Orb to see if the status code is 0 (OK).
*/
function checkOrbResponseStatus(dom) {
var error = '';
try {
// Get the XML 'status' node.
var statusNode = dom.getElementsByTagName('status')[0];
// Get the XML 'status' node's 'code' attribute.
var statusCode = statusNode.attributes.getNamedItem('code').value;
if (statusCode != '0') {
// Code different from 0 means there was a problem.
var statusDesc = statusNode.attributes.getNamedItem('desc').value;
// Get the description corresponding to the error.
// WARNING: the description is just for development purposes.
// The text it contains is not intended to be displayed to the end-user.
// You should provide your own text/error messages depending on the error codes.
error = 'Error (' + statusCode + ') : ' + statusDesc;
}
} catch (e) {
error = 'Unknown error.';
}
if (error !== '') {
alert(error);
}
// Return true (boolean) if there was no error.
return (error === '');
}

/*
* searchMedia
* This function looks for media on the Orb computer.
*/
function searchMedia() {
// Build URL to call search method.
var searchFor = $('searchFor').value;
var mediaType = $('mediaType').value;
var query = 'mediaType=' + mediaType + ' title^=' + searchFor;
var url = orbApiUrl + 'xml/media.search?sid=' + sessionId +
'&q=' + encodeURIComponent(query) +
'&fields=title&count=10';
// Send request.
new Ajax.Request(proxyUrl + '?url=' + escape(url), {
method: 'get',
onSuccess: searchMediaSuccessCallback,
onFailure: orbApiFailureCallback
});
}

/*
* searchMediaSuccessCallback
* Called when the search ajax request was successful.
*/
function searchMediaSuccessCallback(transport) {
// Access the XML dom object within the response.
var dom = transport.responseXML.documentElement;
// Check that the Orb response is OK.
if (checkOrbResponseStatus(dom)) {
// Get the items from the XML response.
var items = dom.getElementsByTagName('item');
// This will hold the html showing the results.
var html = '';
// Number of items found.
var itemCount = items.length;
if (itemCount == 0) {
html = 'No item found.';
} else {
for (var i = 0; i < itemCount; i++) {
// List of fields for the current item.
var fields = items[i].getElementsByTagName('field');
var fieldCount = fields.length;
// Iterate through fields to find the 'title' one, and retrieve its value.
for (var j = 0; j < fieldCount; j++) {
var fieldName = fields[j].attributes.getNamedItem('name').value;
if (fieldName == 'title') {
html += fields[j].firstChild.nodeValue + '<br/>';
break;
}
}
}
}
$('results').innerHTML = html;
}
};
</script>
<div id="loginPanel" style="border:1px;">
Login: <input type="text" id="login" value="" />
<br/>
Password: <input type="password" id="password" value="" />
<br/>
<input type="button" onclick="authenticate();" value="Login"/>
</div>
<div id="mainPanel" style="display:none;">
Return media which title start with: <input type="text" id="searchFor" value="" />
<br/>
In:
<select id="mediaType">
<option value="audio.file">Audio</option>
<option value="video.file">Video</option>
<option value="photo.file">Photo</option>
<option value="document.file">Document</option>
</select>
<br/>
<input type="button" onclick="searchMedia();" value="Search"/>
<div id="results">
<div>
</div>
</body>
</html>



PC上で見ますと、こんな感じ。


できました!パチパチ

2008年11月8日土曜日

Orb APIを使ってみた~ログイン(session.login)編〜

今日一日、OrbのAPIと格闘した私です。初心者にはきついんですよ。
全部英語だし!んぎゃぎゃ。
で苦労した結果のまとめ&How To でございます。

1,始めに
まずOrbAPIを使うには、ほとんどの場合authenticateが必要なんだそうな。それを行うための“session.login”なんであります。

2,まずはサンプルを試してみる。
https://api.orb.com/orb/xml/session.login?apiKey=※ここにはOrbから発行してもらったAPIKeyを入れます&login=ログイン名&password=パスワード

このURLを入れてみます。すると


<orb version="1.0" action="session.login" login="yasuko_yaka">
<status code="0"/>
−<response>
−<orbSession>
<orbSessionId>01234*****</orbSessionId>
<maxInactiveInterval>120</maxInactiveInterval>
<orbVersion>2.01.0015</orbVersion>
</orbSession>
</response>
</orb>


こんな結果が出力されます。01234*****が私のsessionIdになります!

3,自分でも作ってみましょう。
・サンプルソース(html)
・ajaxProxy.php
・prototype.js
この3つを用意して、同じ階層に置いてあげます。
ajaxProxy.php

<?php
header("Content-Type: text/xml");
if ( substr($_GET['url'], 0, 7) == 'http://' ) {
$handle = fopen($_GET['url'], "rb");
while ( !feof($handle) ) {
echo fread($handle, 8192);
}
fclose($handle);
}
?>

Orbにあったサンプルを利用しました。


prototype.js
こちらから、ソースコードがあるのでコピペ

htmlファイル

<html>
<head>
<!-- We use the Prototype library. Get it at: http://prototypejs.org -->
<script src="prototype.js" type="text/javascript"></script>
</head>
<body>
<script language="javascript">
// End point url of the Orb API.エンドポイントURIとは、ローカル又はリモートの資源及びサービスを特定するためのアドレスです
var orbApiUrl = 'http://api.orb.com/orb/';
// API key. If you want to run this sample, paste your API key below.
var apiKey = '以前習得したOrbAPIkeyを入れます';
// To go around Javascript's cross domain restriction, we use a local proxy.ajaxProxy.phpファイルソースはOrbのサイトに掲載されてるものを利用
var proxyUrl = 'ajaxProxy.php';

/*
* Authenticate
*/
function authenticate(login, password) {
// We make an ajax request to the login method, through the local proxy.
var url = orbApiUrl + 'xml/session.login?apiKey=' + apiKey +
'&l=' + encodeURIComponent(login) +
'&password=' + encodeURIComponent(password);
new Ajax.Request(proxyUrl + '?url=' + escape(url), {
method: 'get',
onSuccess: authenticateSuccessCallback,
onFailure: authenticateFailureCallback
});
};

/*
* authenticateSuccessCallback
* Called when the login ajax request was successful.
*/
function authenticateSuccessCallback(transport) {
// Access the XML dom object within the response.
var dom = transport.responseXML.documentElement;
// Check that the Orb response is OK.
if (checkOrbResponseStatus(dom)) {
// Retrieve the session id from the XML dom object.
sessionId = dom.getElementsByTagName('orbSessionId')[0].firstChild.nodeValue;
// That's it! We have the session id, we can now make call to methods that require authentication.
alert('User is logged in! The session id is: ' + sessionId);
}
};

/*
* authenticateFailureCallback
* Called when the login ajax request failed.
* (this is different from a failure on the Orb side, like if the login/password are incorrect for instance).
*/
function authenticateFailureCallback(transport) {
alert('Error contacting Orb server (' + transport.status + '): ' + transport.responseText);
};

/*
* checkOrbResponseStatus
* This is a generic function that looks into the XML response sent by Orb to see if the status code is 0 (OK).
*/
function checkOrbResponseStatus(dom) {
var error = '';
try {
// Get the XML 'status' node.
var statusNode = dom.getElementsByTagName('status')[0];
// Get the XML 'status' node's 'code' attribute.
var statusCode = statusNode.attributes.getNamedItem('code').value;
if (statusCode != '0') {
// Code different from 0 means there was a problem.
var statusDesc = statusNode.attributes.getNamedItem('desc').value;
// Get the description corresponding to the error.
// WARNING: the description is just for development purposes.
// The text it contains is not intended to be displayed to the end-user.
// You should provide your own text/error messages depending on the error codes.
error = 'Error (' + statusCode + ') : ' + statusDesc;
}
} catch (e) {
error = 'Unknown error.';
}
if (error !== '') {
alert(error);
}
// Return true (boolean) if there was no error.
return (error === '');
}

// Authenticate the user!
authenticate('ログイン名', 'パスワード');
</script>
</body>
</html>


できたら、上のhtmlにアクセス。
成功するとsessionIDが書かれたポップアップが出てきます♪

2008年11月6日木曜日

最近してたこと&設計変更

なんだかいろいろと忙しくなっており、マイルストーンが守れておりません。しかもいろいろと発見があったので、そのマイルストーンも変更せねば!

なにをしていたかというと、Orbを使って、家のPCをメディアサーバーにしておりました。
これが相当使える!iPhoneアプリでは音楽ライブラリに入り込むことが出来なかったので、音どうしよう、、、問題が一気に解決!!!

私のWinPCに入っている曲が聞けるし、PCで接続した時はプレイリストも作れます。だからいろんな問題が解決!
さらにさらに、OrbはAPIも公開してるんです。わ〜い♪

さて、じゃあどうしようと考え直した結果、Webアプリとしてまずは作ってみようではないかという結論に至りました。使う言語はRubyです。

MacRubyプロジェクトがガンガン進んで、そのうちiPhoneアプリ開発も出来るようになるんじゃないかと期待してます。
※ちなみに、ネイティブアプリもRubyで開発出来るという噂に踊らされた私。Jailbreakしないと動かないらしいっす。ぬか喜び。