Google App Engine
以前から、Google App Engine のことを聞いていて、無料アカウント先着10000名という
脅迫観念にさいなまれながら、なかなかユーザー登録できなかったのですが、夏休み中
にいろいろ話を聞いたところパイソニアン(数年前からチュートリアルを脱したあたりでとまっているのだが)
であれば、こんな恵まれた環境は無いよ(無料だし)。ということで、やっと、(出遅れまくりなのだが)
ユーザー登録を行い、月並みながら hello world を表示するアプリケーションを登録しました。(間に合ってよかった。。)
少し前までは、ウェイトリストに登録とかあったらしいのですが、今だと、携帯電話経由で、
即アプリケーションを追加できるようになっています、なんとも便利になっています。
登録できるアプリケーションも10個になったらしく、いろいろ使えそうです。
django や Cherry-Pie が使用できるそうなので、そちらのフレームワークを使用するようにしたいと思います。
erlang チュートリアル中
先日、CMSCOM主催の erlang 勉強会に行ってきました。みなさん、お疲れ様でした。。
erlang 勉強会、いろいろ聞けて参考になりました。
まだ、チュートリアルを抜け出してないのですが、下記には最初戸惑いました。
@ 変数の代入は1回かぎり
一度初期化をしてしまうと変更することができないことが驚きでした。チュートリアル中に「変数じゃないじゃん」と叫んでしまいました。。 変数の再代入をしなくてよい仕組みに、再帰呼び出しをおこなっているからとのことでしたが、無限ループのような場合だとスタックはどうなるの? ということがすごく心配でした。末尾再帰しているとスタックオーバーフローにはならないとのことで安心しました(末尾再帰は、関数の一番最後で自分自身を呼び出すこと)たしかに、関数の最後で再帰をおこなっても戻り値を返すだけなので、コールスタックをつむ必要はないといえばないのですが、そこは言語の仕様なのでしょうね。うまくできてます。
A 行末の記号が ";" だったり "." だったり "," だったり、なにもなかったり、、
勉強会でも、 この仕様は慣れるしかないとのことでした。 が、最近、こういう変な仕様もありかと思い始めました。自分的にも、文法で毛嫌いすることが多かったのですが、なぜかすんなり入ってきたような感じです。多分関数型言語ということで、特異な文法がすくないので、これくらいでちょうどいいといった感じなのかもしれません。。
ということで erlang をすこしづつやっていこうと思います。
開発合宿(2nd)
CMSCom 主催の開発合宿に参加しました。今回で2回目となります。
今回は、Silverlight をメインに考えていたのですが、結局2時間くらいしか触れませんでした。
ホームページをまともに作成したことがないので、まず、HTML と CSS のリファレンスを見ながら
すすめていきました。
■ 概要
○ サイト名
俳句LOG (仮)
○ 目的
俳句と旅をテーマとしたコミュニティサイトの構築。。。
○ 対象
・中高年
・小中学生
※ 中高年を対象としていたが、この間テレビで、小中学生も
結構やってることが判明。俳句だけじゃなく、川柳や短歌
なんかも同じようにできたらいいかと思ってます。。
○ 概要
・ 俳句と、背景画像や、文字列の位置などを web上で
簡単に設定&投稿&コメント&ランキングなどを
できる仕組みを提供。
⇒ ここらへんで Flash か Silverlight を使用したいが、、
・ 写真とりこみまたは、フォト蔵からのイメージ選択
・ コミュニティサイトっぽく 新着、俳号別、季語別、タグ別
ランキング、検索画面なんかほしい。
・ 旅行先で詠んだ句とマップを関連ずけを行う。(こちらは跡付けで、、)
このとき、近くの宿の情報のマッシュアップやコメントを
入力できるようにする。
俳句の詠める宿ランキングなんかできるとよいかも。。
・ ユーザー登録などは行わず、敷居を低くしたいが、、
○ セキュリティ
考えてません。
○ システム構成
クライアント : XHTML , AJAX , Silverlight
WEBサーバー : Zope2
webapi関連 : Text2Voice
DB : SQLite
■ 成果物
俳句LOG : http://kei-fc3s.ath.cx/MashupAward/HaikuLog/Home
■ 開発中にはまったこと
○ ZPT(Zope Page Template) ではまったこと
・tal:attributes でマルチバイト文字を設定できない?
<span tal:define="x: string:あいう; y: string:えお"
tal:attributes="name python:x + y">
・ページ本体を複数のコンテンツに分割して、ページの共通部分を
獲得により画面を構築しようと思い、メニュー部分を固有とした
ところ、メニューアイテム毎に固有部分ができてしまい、
メニューを直すのがすごく面倒になってしまった。
⇒ パラメータでカレントの画面を
○ 基本的なところではまったこと
・サイトのルートとなるフォルダを、適当な場所につくって
しまったため、リンクを張るのが面倒だった。
・シルバーライトで 日本語が使えなかったこと
・SQLite が複数スレッドでの書き込みでロックされてしまうこと
■ 今後
メニューや、URL設計をリファクタリングしつつ、基本構想分を
作成したいと思います。
■ 最後に一句
http://kei-fc3s.ath.cx/MashupAward/HaikuLog/Miru?kid=73
web api 覚え書き。。。
覚え書き。。
とりあえず経過段階
http://kei-fc3s.ath.cx/MashupAward/Text2Voice/index3.html
1. ウェブAPIで JSONP が使用できないものをJSONPであつかう
サーバーサイドでURLをオープンして読み込んだ内容を返します。
他ドメインと自ドメインで2回通信が発生してしまいますが。。。
XML -> JSON 変換サービスなんかもこんな感じでやってるんじゃないかな。。
@ Zope ExternalFile で下記のような関数を作成
url :対象のURL
type : 'xml' or 'json' or 'string ' (xml形式はまだ対応していない)
callback : コールバック関数名となります。
JsonpWrapper.py
-----------------------------------------------------------------------------
import urllib
def JsonpWrapper(url, callback, type = "xml"):
handle = urllib.urlopen(url)
# set callback function name.
strJsonpData = callback + "("
if type == "string":
strJsonpData += "'"
# data body
strData = handle.read()
strJsonpData += strData.strip()
if type == "string":
strJsonpData += "'"
strJsonpData += ");"
return strJsonpData
-----------------------------------------------------------------------------
A JavaScript 側は、、、
下記ファンクションは、動的に Script タグを作成するところです。追加し続けると
増殖してしまうので、最初にScriptタグを削除します。
URLの引数を cntArgument でわざわざ設定しているのは、escape 関数を通して
引数に不正な文字が入らないようにするためです。
-----------------------------------------------------------------------------
require = function(strUrl, cntArgument)
{
var strUrlEx = strUrl;
var strSeparator = "?";
// ワークスペース中のスクリプトタグを削除
var cWorkSpace = document.getElementById('work_space');
var nChildMaxCount = cWorkSpace.childNodes.length;
for (var nChildIndex = 0; nChildIndex < nChildMaxCount; ++nChildIndex) {
cWorkSpace.removeChild(cWorkSpace.childNodes.item(0));
}
// 引数のエスケープ
for (var cArgument in cntArgument) {
strUrlEx += strSeparator;
strUrlEx += cArgument + "=" + escape(cntArgument[cArgument]);
strSeparator = "&";
}
var cScript = document.createElement('script');
cScript.type = 'text/javascript';
cScript.src = strUrlEx;
// ワークスペースへ追加
cWorkSpace.appendChild(cScript);
}
-----------------------------------------------------------------------------
B 使用する方法は、、
-----------------------------------------------------------------------------
// コールバック関数。。http://api.satoru.net/text2voice/ のサイトは MP3 のURLを返す。
var strFileName = ""
GetMp3FileName = function(cJsonData)
{
strFileName = cJsonData;
LoadMp3();
}
ExpandMp3 = function()
{
var cText = document.getElementById("mp3_input_text");
require("http://kei-fc3s.ath.cx/MashupAward/Text2Voice/JsonpWrapper",
{
"url":"http://api.satoru.net/text2voice/?text=" + cText.value,
"callback":"GetMp3FileName",
"type":"string"
});
}
LoadMp3 = function()
{
// playmp3.loadNo(strFileName , 1);
// playmp3.playNo(1);
playmp3.playFile(strFileName);
}
-----------------------------------------------------------------------------