Mongoose で MongoDB の Embedded Documents の扱いで嵌まったこと

node(.js)と相性が良いということで、MongoDB とそのJavaScript O/R マッパーライクなモデリングライブラリの Mongoose を使い始めました。 MongoDBと言えばドキュメント指向モデルでそれを特徴づける Embedded Documents が有名ですが、この機能を Mongoose から利用する上で躓いたので、メモしておきます。 Embbed Document の Array について var Users = new Schema({ name : String }); var Comments = new Schema({ title : String , body : String , date : Date }); var BlogPost = new Schema({ author : { type: ObjectId, ref: ‘User’ } , title : String , body : String , date : Date , comments : [Comments] , meta : { votes : Number , favs : Number } }); mongoose.model(‘User’, Users); mongoose.model(‘BlogPost’, BlogPost); ...

2011年10月30日 · Toshimitsu Takahashi

iOS デバイスで現在 iPod で再生中の曲情報を取得するには

iPhone, iPad, iPod touch で音楽などを再生したりするには、MediaPlayer.framework を使います。 MPMusicPlayerController が音楽を再生を制御するコントローラクラスでこのクラスメソッドの iPodMusicPlayer を使うと iPod のコントローラが取得できます。 さらに nowPlayingItem プロパティからその名の通り再生中(一時停止している場合も含む)のデータを MPMediaItem インスタンスで取得できます。 MPMediaItem からメタデータを各フィールドを表す定数を指定して取り出せます。アイテムの種別は MPMediaItemPropertyMediaType で NSInteger をカプセル化した NSNumber で取得できます。 以下は、曲を再生中の場合に曲名、アルバム名、アーティストそしてアートワークの80x80画像をそれぞれ取得しています。 #import <MediaPlayer/MediaPlayer.h> MPMusicPlayerController *pc = \[MPMusicPlayerController iPodMusicPlayer\]; MPMediaItem *playingItem = \[pc nowPlayingItem\]; if (playingItem) { NSInteger mediaType = \[\[playingItem valueForProperty:MPMediaItemPropertyMediaType\] integerValue\]; if (mediaType == MPMediaTypeMusic) { NSString *songTitle = \[playingItem valueForProperty:MPMediaItemPropertyTitle\]; NSString *albumTitle = \[playingItem valueForProperty:MPMediaItemPropertyAlbumTitle\]; NSString *artist = \[playingItem valueForProperty:MPMediaItemPropertyArtist\]; textView.text = \[NSString stringWithFormat:@"%@ - %@ / %@", artist, songTitle, albumTitle\]; MPMediaItemArtwork *artwork = \[playingItem valueForProperty:MPMediaItemPropertyArtwork\]; UIImage *artworkImage = \[artwork imageWithSize:CGSizeMake(80.0, 80.0)\]; UIImageView *artworkImageView = \[\[UIImageView alloc\] initWithImage:artworkImage\]; } }

2011年10月27日 · Toshimitsu Takahashi

svnadmin hotcopy で fsfs.conf が見つからないと言われたとき

Ubuntu のバージョンを上げたら、Subversion 1.6.12 になって、リポジトリのバックアップでエラーになってしまった。 svnadmin: Can’t open file ‘/var/svn/project/db/fsfs.conf’: No such file or directory リポジトリのバージョンアップすればいいかと思い、 $ svnadmin upgrade /var/svn/project Repository lock acquired. Please wait; upgrading the repository may take some time… Upgrade completed. とアップグレードしたものの、fsfs.conf は無いまま。 テキトウに fooproj などと新規リポジトリを作ったら、 $ svnadmin create /var/svn/fooproj fsfs.conf があったので、それを各リポジトリの db/fsfs.conf にコピーしたら動いた。 参考)#590790 - subversion - svnadmin hotcopy fails on older fsfs repos - Debian Bug report logs

2011年10月14日 · Toshimitsu Takahashi

G-CLOUD Magazine 2011 Autumn に寄稿しました

本日、2011年10月4日発売の G-CLOUD Magazine 2011 Autumn http://gihyo.jp/book/2011/978-4-7741-4832-8 に記事を寄稿させていただきました。 私が執筆したのは、「特集3 Windows Azure Toolkit for iOSを使ってクラウドストレージを利用した写真アプリを作ろう」になります。 iOS アプリから簡単に Windows Azure ストレージを利用できるライブラリ Windows Azure Toolkit for iOS を使って、写真共有アプリを実際に Xcode 4 で実装していきます。 ツールキットとともに提供されている Cloud Ready Packages を使って、Windows Azure ストレージのテーブルとブロブを利用しています。 GMO、AWS,Google App Engine など他にもクラウドの記事が盛りだくさんです。書店にお立ち寄りの際は、手に取って頂けると幸いです。 G-CLOUD Magazine 2011 Autumn 作者: 編集部編 出版社/メーカー: 技術評論社 発売日: 2011/10/04 メディア: 大型本 購入: 1人 クリック: 5回

2011年10月4日 · Toshimitsu Takahashi

Node.js に npm で express をインストールして試す

node.js と npm を Ubuntu にセットアップ - Tosshi Note の続きです。 npm で Express - node.js web application framework を入れて動かす。 express は node.js をさらに使いやすくするフレームワーク。使ったことがないが Ruby の Sinatra ライクだそうです。 express をインストール g はグローバルオプション。これを付けないとコマンド実行パスの node_modules にインストールされる。 $ sudo npm install -g express expressのヘルプ確認 セッション機能やテンプレート、CSSエンジンの指定ができることがわかる。 $ express -h Usage: express [options] [path] Options: -s, –sessions add session support -t, –template add template support (jade|ejs). default=jade -c, –css add stylesheet support (less|sass|stylus). default=plain css -v, –version output framework version -h, –help output help information ...

2011年9月26日 · Toshimitsu Takahashi

Node.js と npm を Ubuntu にセットアップ

Ubuntu を 11.04 に上げたが、apt-get で入る node.js が 0.2.x だったので、ソースからコンパイルしてインストールすることにした。 当初 github からチェックアウトして 0.5.x で試していたが、最終的に express が未対応だったので、安定板をダウンロードして入れることにした。 さらに node.js のパッケージ管理ツール npm もインストールする。 node.js インストール node.js をインストール。 必要パッケージの準備 コンパイル、ビルド、依存ライブラリのインストール $ sudo apt-get update $ sudo apt-get install gcc $ sudo apt-get install libssl-dev $ sudo apt-get install build-essential opensslをコンパイル時に参照できるようにパッケージを設定 $ sudo pkg-config openssl –cflags –libs -lssl -lcrypto 最近のバージョンでは $ sudo apt-get install libcurl4-openssl-dev を行うとよいようだ(2012/3/30 追記)。 ダウンロードからビルド・インストール http://nodejs.org/#download から安定板の 0.4.12 を落としてビルドインストール。 $ wget http://nodejs.org/dist/node-v0.4.12.tar.gz $ tar zxvf node-v0.4.12.tar.gz $ cd node-v0.4.12 $ ./configure $ make $ sudo make install ...

2011年9月23日 · Toshimitsu Takahashi

Ubuntu 11.04 で DHCP から 静的 IP アドレスに切り替えるには

普通にインストールしたら、DHCPなってしまった。固定 IP アドレスに変更する方法をメモしておく。 ネットワークインターフェイス設定 interfaces ファイルを開く。 $ sudo vi /etc/network/interfaces /etc/network/interfaces # The primary network interface iface eth0 inet dhcp 上記部分を下記のとおり書き換える。 # The primary network interface auto eth0 iface eth0 inet static address 192.168.1.100 netmask 255.255.255.0 gateway 192.168.1.1 dns-nameserver 192.168.1.1 ネットワークサービスを再起動 再起動してNICに適用する。 $ sudo /etc/init.d/networking restart

2011年9月22日 · Toshimitsu Takahashi

Xcode 4 のユニバーサルプロジェクト構成を考える

Xcode 3 から Xcode 4 になってウィザードから生成されるプロジェクトの構成も変わっている。 iPhone, iPadで共通化するユニバーサルで、ユニットテストありにした Windows Base プロジェクトを生成すると下記のようになる。 ファイルシステム上は、プロジェクト名のフォルダにxcodeprojectフォルダさらに同名のプロジェクトフォルダとTestsがサフックスに付いたテストフォルダが並ぶ。 プロジェクトフォルダにはiPhone, iPadが並ぶ。 WindowExample - WindowExample.xcodeproj - WindowExample - iPhone - iPad - WindowExampleTests Xcode 3 のようにClasses, Resourcesがない。自分も経験的に、XIBファイルと対になるViewControllerクラスは並んでいた方が扱いやすい。テンプレートでクラスを追加したときに同時に生成されるのでまとまっていた方が良いだろう。 ユニーバサルであればビューのベース部分やそもそも共通クラスがある(Common)。さらにイメージファイルもグループ化すると良いだろう(Images)。ほかにもユーティリティ群などが並ぶだろう(Utilities)。 ファイルシステム上もiPhone, iPad, Common, Images, Utilitiesはフォルダにする。クラス数が多ければ各グループ内もさらにグループ化した方がいいだろう。 ただこれらのグループは、画面数の増加などアプリの修正・機能追加に伴って柔軟に変えられる方が良いと考える。よって、ファイルシステム上はフラットに管理することにする。 WindowExample - WindowExample.xcodeproj - WindowExample - iPhone - iPad - Common - Utilities - Images - WindowExampleTests Xcode は Visual Studio, Eclipse のようにプロジェクトのファイル構成がファイルシステムと同一ではない。Java をやってきた人には気持ち悪いかもしれない。パッケージや名前空間という概念は Objective-C にはない。グループはあくまでも人間から見た管理のしやすさだ。 Xcode はファイル追加後にファイルシステム上の移動をするのが非常に面倒である。このため、ファイルの上の場所は追加するときに確定させた方が良い。ただグループもフラットだと管理上破綻するだろう。これが前述のような構成にした理由だ。 まとめると、 プロジェクトフォルダ、テストフォルダを分ける。 プロジェクトフォルダの直下は、iPhone, iPad, iPhone・iPad共通でグループをわける。 これらのグループはそのままファイルシステム上フォルダ化にする。 第2階層以降のグループは Xcode プロジェクトのみで管理し、ファイルシステムには適用しない。 となる。

2011年8月29日 · Toshimitsu Takahashi

Twitter Streaming APIを使って関連TLをテレビにオーバーレイ表示するAIRアプリを作ってみた

一昨年の記事、テレビにTwitterの関連TLをオーバーレイ表示するAIRアプリを作ってみた - Tosshi Note で紹介したアプリを Twitter Streaming API に対応してみました。 AIRアプリ自体の公開は反応をみることにして、Twitter Streaming API を ActionScript で実装する例があまり見つからなかったので、とりあえず載せときます。 ちなみに URLStream を使って実装していますが、URLStream の Progress イベントは HTTP chunk レスポンスの受信とは別に起こります。そのため、流れの速いTLでないと TweetReceived イベントにタイムラグが発生するかもしれません。 URLStreamから取得できるデータ本体は、[ツイートJSON][CRLF][ツイートJSON][CRLF][ツイートJSON][CRLF] となります。 ツイートがないときに、Keep-Aliveのためのパケットも[CRLF]となるため、バッファに文字列をためつつ、[CRLF]を探しては切り出して、文字列長0でなければJSONをパースしてツイート受信イベント発生という流れです。 以下、ソースをべた貼りしておきます。 TwitterStreamLoader.as コンストラクタ引数にBASIC認証のTwitterスクリーン名とパスワードを指定します。 package com.tilfin.tvtwlayer.twitter { import com.adobe.serialization.json.JSON; import flash.events.EventDispatcher; import flash.events.HTTPStatusEvent; import flash.events.IOErrorEvent; import flash.events.ProgressEvent; import flash.net.URLRequest; import flash.net.URLRequestHeader; import flash.net.URLRequestMethod; import flash.net.URLStream; import flash.net.URLVariables; import mx.utils.Base64Encoder; /** * Tweet Received イベント / [Event(name=“tweetReceived”, type=“com.tilfin.tvtwlayer.twitter.TwitterStreamEvent”)] /* * Twitter Stream API Loader / public class TwitterStreamLoader extends EventDispatcher { private static const ROOT_URL:String = “http://stream.twitter.com/1/statuses/"; private var _authHeader:URLRequestHeader; private var _stream:URLStream; private var _streamBuffer:String = “”; /* * コンストラクタ * * @param screenName スクリーン名 * @param password パスワード / public function TwitterStreamLoader(screenName:String , password:String) { super(); var encoder:Base64Encoder = new Base64Encoder(); encoder.encode(screenName + “:” + password); _authHeader = new URLRequestHeader(“Authorization”, “Basic " + encoder.flush()); } /* * 各種フィルタをかけたストリームの受信を開始します。 * * @param params クエリパラメータ / public function loadFilterStream(params:Object):void { var variables:URLVariables = new URLVariables(); for (var key:String in params) { variables[key] = params[key]; } var request:URLRequest = new URLRequest(ROOT_URL + “filter.json”); request.method = URLRequestMethod.POST; request.requestHeaders = [ _authHeader ]; request.data = variables; _stream = new URLStream(); _stream.addEventListener(IOErrorEvent.IO_ERROR, onIoError); _stream.addEventListener(HTTPStatusEvent.HTTP_RESPONSE_STATUS, onHttpResponseStatus); _stream.addEventListener(ProgressEvent.PROGRESS, onProgress); _stream.load(request); } /* * ストリームを閉じます。 */ public function close():void { _stream.removeEventListener(IOErrorEvent.IO_ERROR, onIoError); _stream.removeEventListener(ProgressEvent.PROGRESS, onProgress); _stream.close(); _stream = null; } private function onProgress(event:ProgressEvent):void { var buffer:String = _stream.readUTFBytes(_stream.bytesAvailable); _streamBuffer += buffer; var twstr:String; var splitpos:int = _streamBuffer.indexOf(”\r\n”); while (splitpos > -1) { twstr = _streamBuffer.substr(0, splitpos); if (twstr.length > 0) { receivedTweet(twstr); } _streamBuffer = _streamBuffer.substr(splitpos + 2); splitpos = _streamBuffer.indexOf("\r\n"); } } private function receivedTweet(str:String):void { var tweet:Object = JSON.decode(str); dispatchEvent(new TwitterStreamEvent(TwitterStreamEvent.TWEET_RECEIVED, tweet)); } private function onIoError(event:IOErrorEvent):void { trace(“IO Error.”); } } } ...

2011年8月27日 · Toshimitsu Takahashi

iPhoneとiPadで処理を替えるには

直ぐ忘れるのでメモ。iOS 3.2以降で使用可能。 float fs; if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) { fs = 11.0; } else { // if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) fs = 13.0; } return [UIFont fontWithName:@“Helvetica” size:fs];

2011年8月22日 · Toshimitsu Takahashi