gist

2012年5月29日火曜日

[Node.js] sprintfが意外と使える件



sprintfは、その名の通り書式を指定して文字列を生成するパッケージです。

sprintfは、JavaScriptのsprintfライブラリと同じ動作をします。オブジェクトや配列を出力できます。

$ npm install sprintf

CoffeeScript

sprintf = require('sprintf').sprintf
vsprintf = require('sprintf').vsprintf

# %2$s で2番目の文字を出力します。
console.log sprintf '%2$sは%3$sが%1$sです!', '大好き', 'ニャル子', '真尋さん'

# vsprintfでは配列を出力します
console.log vsprintf '登場人物: %s, %s, %s, %s', ['真尋', 'ニャル子', 'フー子', 'ハス太']

# オブジェクトを出力します。%(プロパティ名)s で指定します。
user = {name:'ニャルラトホテプ', nickname:'ニャル子'}
console.log sprintf '%(name)sのニックネームは、%(nickname)sです', user 

# オブジェクトの配列も出力可能
users = [
    {name: '真尋'}
    {name: 'ニャル子'}
    {name: 'フー子'}
]
console.log sprintf '%(users[0].name)s, %(users[1].name)s %(users[2].name)s', {users: users}

結果

$ coffee sample.coffee 
ニャル子は真尋さんが大好きです!
登場人物: 真尋, ニャル子, フー子, ハス太
ニャルラトホテプのニックネームは、ニャル子です
真尋, ニャル子 フー子

地味ですが強力なパッケージです。もちろん%d, %f, %xなども使えます。

2012年5月28日月曜日

hook.ioで「 (」・ω・)」うー!(/・ω・)/にゃー!」してみた




hook.ioは、ソケット通信を利用してデータ通信を可能にするパッケージです。イベント名をドメインで管理することができます。
$ npm install -g hook.io
 

uh.coffeeとnya.coffeeを用意します。

uh.coffee
hookio = require 'hook.io'

hookA = hookio.createHook {name: "a"}
hookA.on "*::uh", (data)->
 console.log data
 setTimeout ()->
  hookA.emit 'nya', '(/・ω・)/にゃー!'
 , 1000

hookA.start()

createHookメソッドでフックの名前を指定しています。hookA.on の第1引数にイベント名を指定します。これは::で区切ったドメイン風に指定できます。*::uh であれば、最後のイベント名が uh であれば補足して、第2引数に指定した関数を実行します。第2引数のメソッドの引数dataには、飛んできたdataが入ってきます。console.logでdataの内容を出力して、1秒したら nyaイベントを発火(emit)します。

続いてnya.coffee。

nya.coffee
hookio = require 'hook.io'

hookB = hookio.createHook {name: "b"}
hookB.on 'hook::ready', ()->
  hookB.emit 'uh', '(」・ω・)」うー!'

hookB.on '*::nya', (data)->
 console.log data
 setTimeout ()->
  hookB.emit 'uh', '(」・ω・)」うー!'
 , 1000

hookB.start();

hook::redayで1回 uhイベントを発火します。hook::readyは hookが用意できた時にhook.ioから発火されるイベントです。もし nyaイベントが飛んできたら データを出力して1秒後に uhイベントを発火します。

イベントをドメインでフィルタできるのがいいところ、かと。

実行結果



レッツ\(・ω・)/にゃー!

2012年5月27日日曜日

mimeを使ってみた

mimeは、MIME-TYPEをマッピングしているパッケージです。

$ npm install mime

CoffeeScript

mime = require 'mime'

console.log '--- lookup ---'
console.log mime.lookup '.txt'
console.log mime.lookup '.mp3'
console.log mime.lookup 'a.htm'
console.log mime.lookup '.flv'

console.log '--- extension ---'
console.log mime.extension 'text/html'
console.log mime.extension 'application/vnd.ms-excel'
console.log mime.extension 'video/x-m4v'
console.log mime.extension 'application/json'

mimeには、ファイルの拡張子からMIME-TYPEを取得する lookup メソッドと、その逆でMIME-TYPEから拡張子を取得する extensionメソッドがあります。

実行してみます。

$ coffee sample.coffee 
--- lookup ---
text/plain
audio/mpeg
text/html
video/x-flv
--- extension ---
html
xls
m4v
json

また、mimeでは、独自のMIME-TYPEを追加することができます。

mime = require 'mime'

console.log '--- custom ---'

mime.define {
 'text/coffee': ['coffee', 'cf']
 'text/ruby': ['rb', 'ruby']
}

console.log mime.lookup 'sample.coffee'
console.log mime.lookup 'sample.cf'
console.log mime.extension 'text/coffee'
console.log mime.lookup 'sample.rb'
console.log mime.extension 'text/ruby'

console.log '--- load sample.types ---'
mime.load 'sample.types'
console.log mime.lookup 'a.mid'
console.log mime.extension 'audio/x-midi'

defineメソッドでコードからMIME-TYPEを追加できます。loadメソッドでは、ファイルを指定して追加することもできます。このときのファイルフォーマットは、Apacheのtypes形式となります。

sample.types

audio/x-midi mid

実行

$ coffee sample.coffee 
--- custom ---
text/coffee
text/coffee
coffee
text/ruby
rb
--- load sample.types ---
audio/x-midi
mid

mimeは、地味ですが、expressなどのWebフレームワークで使われている重要なパッケージの一つです。

2012年5月24日木曜日

ディレクトリ丸ごと操作できるwrenchを使ってみた

wrenchは、ディレクトリに対して、mkdir、chmod、chown、rmdir などができるパッケージです。

$ npm install wrench

CoffeeScript


wrench = require 'wrench'


files = [];
wrench.readdirRecursive '.', (error, curFiles)->
    console.log curFiles

wrench.chmodSyncRecursive '.', '0755'

結果

他にも、mkdirSyncRecursive、rmdirSyncRecursive、readdirSyncRecursive、chownSyncRecursive、copyDirSyncRecursive などのメソッドが用意されています。

ディレクトリに対して操作できるパッケージとして使われており、npmでも上位に位置しています。

2012年5月22日火曜日

フォームデータを解析する formidable を使ってみた

formidable は、受信したフォームデータを解析し、オブジェクトに変換するパッケージです。connectパッケージで使われています。

$ npm install formidable

CoffeeScript

formidable = require 'formidable'
http = require 'http'
util = require 'util'

http.createServer (req, res)->
 if req.url is '/upload' and req.method.toLowerCase() is 'post'
  form = new formidable.IncomingForm()
  form.parse req, (err, fields, files)->
   res.writeHead 200, {'content-type':'text/plain; charset=UTF-8'}
   res.write 'received uploaded\n\n'
   res.end util.inspect {fields: fields, files: files}
  return

 res.writeHead 200, {'content-type': 'text/html'}
 res.end """
 <html><head><meta charset="utf-8"></head>
 <body>
 <form action="/upload" enctype="multipart/form-data" method="post">
 <input type="text" name="title"><br>
 <input type="file" name="upload" multiple="multiple"><br>
 <input type="submit" name="Upload">
 </form>
 </body>
 """
.listen 3000

new formidable.IncomingForm() でインスタンス化し、parse 関数で解析を開始します。コールバックの第2引数 fieldsには、フォームデータのキー(inputタグのname属性)と値(value値)のオブジェクトが配列で入ってきます。第3引数 files には、アップロードされたデータの情報が入ってきます。

実行します。

$ coffee sample.coffee

ブラウザで http://localhost:3000 にアクセスします。

テキストフィールドに適当な文字列を入力し、適当なファイルを選択して、送信します。

特にファイル情報を簡単に、しかも高速に取得できる点で、とても便利なパッケージです。1万以上のパッケージの中で57のパッケージに使われています。

2012年5月21日月曜日

ディレクトリを簡単に作成できる mkdirp を試してみた

mkdirpは、ディレクトリを作成するだけのパッケージです。ちょうど mkdir -p を実行したのと同じ動作になります。


$ npm install mkdirp

CoffeeScript

mkdirp = require 'mkdirp'

mkdirp 'sample/sample2/sample3', (err)->
 if err 
  console.log err
 else 
  console.log 'created!'


実行結果

$ coffee sample.coffee 
created!
$ tree
.
├── sample
│   └── sample2
│       └── sample3
└── sample.coffee

3 directories, 1 file

ちょっとしたパッケージですが、148ものパッケージに使われています。こういうアイデアも大事ですね。

2012年5月20日日曜日

クエリ文字列をオブジェクトに変換する qs を使ってみた

qsは、クエリ文字列をオブジェクトへ、オブジェクトからクエリ文字列に変換できるパッケージです。expressやconnectで使われています。

$ npm install qs

qsには、parseとstringifyの2つのメソッドがあります。

qs = require 'qs'

obj = qs.parse 'user[name][first]=Miku&user[name][last]=Hatsune&user[email]=miku@vocaloid.com'

console.log obj

obj = 
 user: 'Hatsune Miku'
 mail: 'miku@vocaloid.com'

str = qs.stringify obj

console.log str

実行結果

$ coffee sample.coffee 
{ user: 
   { name: { first: 'Miku', last: 'Hatsune' },
     email: 'miku@vocaloid.com' } }
user=Hatsune%20Miku&mail=miku%40vocaloid.com