MeteorのPub/Subを理解するためにできるだけ最小構成で書いてみた

HTML

<head>
  <title>pub/sub test</title>
</head>

<body>
  {{> tweets}}
</body>

<template name="tweets">
  <div id="items-view">
    <div id="new-tweet-box">
      <input type="text" id="new-tweet" placeholder="New item" />
    </div>
    <ul id="item-list">
      {{#each tweets}}
        {{> tweet_item}} 
      {{/each}}
    </ul>
  </div>
</template>

<template name="tweet_item">
  <li class="tweet {{done_class}}">
    <div class="tweet-text">{{text}} : {{timestamp}}</div>
  </li>
</template>

Javascript

// Tweets -- {text: String,
//           timestamp: Number}
Tweets = new Meteor.Collection("tweets");

if (Meteor.isClient) {

	// Always be subscribed to the todos for the selected list.
	Meteor.autosubscribe(function () {
	    Meteor.subscribe('tweets');
	});
	
	Template.tweets.events = {
  		'keydown #new-tweet': function(e) {
   		 	if(e.keyCode == 13) {
      				console.log("Insert : " + text);
      				var text = String(e.target.value || "");
        			if (text){
					Tweets.insert({
						text: text,
						timestamp: (new Date()).getTime()
    					});
    				}
      				e.target.value = '';
    			}
  		}
	}
  	
  	Template.tweets.tweets = function () {
  		return Tweets.find({}, {sort: {timestamp: 1}});
	};

}

if (Meteor.isServer) {

	Meteor.publish('tweets', function () {
 		return Tweets.find({},  {sort: {timestamp: 1}});
	});
	
}

Google Drive API (Javascript)を使ってSpreadsheetの内容をCSVで取得する

Google Drive APIだけで行けるかと思ったら無理っぽくて、色々解らなかったのでメモ。

Google APIs ConsoleのServicesからDrive APIをOnにする。

API Access
"Client ID(for web applications)"と"Bowser Key"を作る。
"Client ID"の"JavaScript origins"はとりあえず"http://localhost"でいい感じ。

で、こんな感じのコードでできた。

<!DOCTYPE HTML>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Export Spreadsheet from Google Drive</title>
<script type="text/javascript">
var clientId = '<YOUR_CLIENT_ID>';
var apiKey  = '<YOUR_API_KEY>';
var scopes = 'https://www.googleapis.com/auth/drive';

function handleClientLoad() {
	gapi.client.setApiKey(apiKey);
	window.setTimeout(checkAuth,1);
}

function checkAuth() {
  gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: true}, handleAuthResult);
}

function handleAuthResult(authResult) {
  if (authResult && !authResult.error) {
        makeApiCall();
  } else {
	gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: false}, handleAuthResult);
  }
}

function makeApiCall() {
  
	var accessToken = gapi.auth.getToken().access_token;
	var xhr = new XMLHttpRequest();
	var url = "https://docs.google.com/feeds/download/spreadsheets/Export?key=<SPREADSHEET_KEY>&exportFormat=csv";
	xhr.open('GET', url);
	xhr.setRequestHeader('Authorization', 'Bearer ' + accessToken);
	xhr.onload = function() {
		console.log(xhr.responseText);
	};
	xhr.onerror = function() {
		console.log("error");
	};
	xhr.send();
	
}

</script>
<script src="https://apis.google.com/js/client.js?onload=handleClientLoad"></script>
</head>
<body>
</body>
</html>

「とよすすいぞくかん」リリースしました!

iPhoneをかざすと自分の周りが水族館になる、「とよすすいぞくかん」をリリースしました!


博報堂アイ・スタジオ崇城大学和泉研究室の共同開発です。
魚のモデル作成には崇城大学の学生も参加してくれました。
開発やモデル作成にはには本学の講義でも扱っているBlenderやUnityを使用しています。

デモバージョンでも水族館を楽しめますが、
豊洲の公園に行くと、もっと多くの魚に出会えたり写真を取ったりと楽しめます。
今後、水族館や魚の、共有機能などが追加される予定です。

無料ですので、是非ダウンロードして遊んで見られてください!!

http://itunes.apple.com/jp/app/toyosusuizokukan/id532183549

Unityの多言語化プラグインを作ってみた

アセットストアで$50で売っているようですが作ってみたので公開します。

言語化プラグインです。
パラメーターをTというクラスの変数にするためコンパイラによるチェックが行えます。

こちらからダウンロードできます
https://dl.dropbox.com/u/53790848/Unity/Packages/i18n/i18n.unitypackage

使い方:
・メニューのi18nからi18n Windowを選択
・最上部のセルに使いたいローケールを設定
・キー(左端のセル)と値を設定。キーに使える文字は[a-zA-z0-9_]のみ(先頭文字は数字以外)。
・UpdateをクリックするとMessages.xmlとT.csが作成される
・言語の指定はi18n.locale = i18nLocale.ja_JP.ToString();の感じで
スクリプト中で T.helloのような形で使う(または、T.t("hello"))
・文字列、画像、サウンドに対応

サンプルシーンが入っているので、ご参考ください

Meteor入門 [4] 取り敢えず本家のDocumentを読みながら要約

途中だけど取り敢えず掲載。あとで追記の予定。

Data

Meteorクライアントはインメモリのデータベースキャッシュを持つ
クライアントキャッシュはサーバ側のマスターデータベースの部分的な複製を持つ

チャットシステムの例
サーバは例えば全てのルームとすべてのメッセージの2種類のセットを公開する
クライアントはルームのマスターセットと選択したルームのメッセージのセットに登録する
登録したら、クライアントはキャッシュを早いローカルデータベースとして使う
これでクライアントモデルのコードがとてもシンプルになる

Meteorの分散ドキュメント更新プロトコルはデータベース非依存。
デフォルトではMongoDB APIを使う。
サーバはMongoDBコレクションにドキュメントを格納する
クライアントはクエリと更新がMongoAPIで実装されたキャッシュをつかってキャッシュする

Meteor.publish("chatrooms");
Meteor.publish("messages", function (room_id) {
  return Messages.find({room] room_id});
});

Meteor.subscribe("chatrooms");
Meteor.subscribe("messages", Chatrooms.find()[0]._id);

ドキュメントの変更は自動的に拡散される。
insert, remove, updateなどはクライアントキャッシュデータで即座に実行される。
同時に、クライアントはサーバーに命令を送り、マスターデータベースも変更される。

通常クライアントとサーバは同意するが、異なるときもある?
(パーミッションのチェックや他のクライアントとのオーバーラップなど)
サーバの結果はクライアントに再公開される
同じ登録をしている全てのクライアントは更新されたドキュメントを受け取る

Messages.insert({room : 2413, text: "hello!"});

これによって、遅延の埋め合わせが実現される。
latency compensation = 遅延の埋め合わせ?
クライアントは必要なデータのフレッシュなコピーを保持し、サーバへのラウンドトリップ時間を待つ必要がない
クライアントがデータを変更した時はローカルで実行されるので、サーバを待たなくて良い

Reactivity

MeteorはReactive Programmingを用いている。
コードをシンプルに素早くかける
コード中で使っているデータが変更されたらそれを利用した結果も自動的に再計算される

Meteor.autosubscribe(function(){
  Meteor.subscribe("messages", Session.get("currentRoomId"));
}):

Meteor入門 [3] ファイルやディレクトリ構成について

Javascriptでクライアントサイドからサーバサイドまでやれちゃう、IsomorphicでReactive Programmingな新技術Meteorを勉強してみる。の記録。
http://www.meteor.com/main

今回は、ファイルやディレクトリ構成について

ディレクトリについて

Meteorは1つのファイルにサーバとクライアントの両方のコードを書けるわけだけど、分けて書くことも出来るらしい。
あと、サーバが使うファイルとクライアントが使うファイルはディレクトリで分ける。

それ以外は両方にコピーされる。

クライアントに送りたくないコード(例えば、パスワードや認証機構が入っているもの)はserverディレクトリに入れておかなければならない!!

JavascriptCSSファイル

serverとpublicサブディレクトリ以外のCSSファイル(JSファイルもかな?)は自動的にまとめてクライアントに送られる。
(開発モードではデバッグしやすくするため、Javascript, CSSともに個別のファイルとしてクライアントに送られる)

HTMLファイル

ディレクトリ中の全てのHTMLファイルからhead, body, templateタグのセクションに分けてスキャン。

headとbodyセクションは単一のheadとbodyにまとめて、ページの初回ロード時にクライアントに送信される。
templateセクションは、Javascriptの関数に変換されて、Template名前空間の下に置かれる。

Meteor入門 リンク集

個人的にMeteorを勉強する過程で読んだリンク集です。

Meteor.js : naoyaのはてなダイアリー
http://d.hatena.ne.jp/naoya/20120422/1335109615

Trigger と Stream ベースの Reactive スタイルについて考える : Block Rockin’ Codes
http://d.hatena.ne.jp/Jxck/20120509/1336566474

Meteor について発表してきました : Block Rockin’ Codes
http://d.hatena.ne.jp/Jxck/20120501/1335895469

やさしいFunctional reactive programming(概要編): maoeのブログ
http://d.hatena.ne.jp/maoe/20100109/1263059731