gist

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

2012年5月19日土曜日

node-progressで進捗をコンソール出力してみた

node-progressは、ファイルダウンロードなどの進捗状況をコンソールに出力するためのパッケージです。

$ npm install progress

ProgressBar = require 'progress'

progress = new ProgressBar 'downloading [:bar] :percent :etas', {
 total: 20
 width:20
}

timer = setInterval ()->
 progress.tick()
 if progress.complete
  console.log 'Complete!\n'
  clearInterval timer
, 1000

new ProgressBar の第1引数にコンソール出力の書式を指定します。書式には以下を指定できます。

  • :bar・・・プログレスバー
  • :current・・・進捗の値
  • :total・・・進捗の合計
  • :percent・・・進捗の割合
  • :elapsed・・・経過した時間
  • :eta・・・残り時間

第2引数には、オプションを指定できます。

  • :total・・・進捗の合計
  • :width・・・プログレスバーの長さ
  • :complete・・・プログレスバーの完了時の文字列
  • :imcomplete・・・プログレスバーの未完了の文字列

2012年5月17日木曜日

コンソール出力を整形するcliffを使ってみた

cliffは、コンソール出力を整形して色もつけられるパッケージです。


$ npm install cliff
cliff@0.1.7 ../../../node_modules/cliff 
├── colors@0.6.0-1
├── eyes@0.1.7
└── winston@0.5.11

CoffeeScriptで書いてみます。

cliff = require 'cliff'

rows = [
    ['Name',  'Flavor',    'Dessert'],
    ['Alice', 'cherry',    'yogurt'],
    ['Bob',   'carmel',    'apples'],
    ['Joe',   'chocolate', 'cake'],
    ['Nick',  'vanilla',   'ice cream']
]

cliff.putRows 'data', rows, ['red', 'blue', 'green']

実行結果

日本語ですと上手く整形されないようです。

2012年5月16日水曜日

finditを試してみた

finditは、ディレクトリを再帰的に探索できるパッケージです。

$ npm install findit

CoffeeScriptで書いてみます。

findit = require 'findit'

finder = findit.find('..')

finder.on 'directory', (dir, stat)->
 console.log dir + '/'

finder.on 'file', (file, stat)->
 console.log 'File: ' + file

finder.on 'link', (link, stat)->
 console.log 'Link: ' + link

findメソッドで、対象ディレクトリを指定します。EventEmitterのonメソッドでdirectory, file, link毎に処理を書けます。

実行してみます。expressでファイルを増やしています。

$ express .
$ coffee sample.coffee
File: ./app.js
File: ./package.json
./public/
./public/images/
./public/javascripts/
./public/stylesheets/
File: ./public/stylesheets/style.css
./routes/
File: ./routes/index.js
File: ./sample.coffee
./views/
File: ./views/index.jade
File: ./views/layout.jade

あまりにファイル数が多いディレクトリを指定すると、コールスタックがサイズオーバーして落ちる場合があります。

/Users/inouetomoyuki/node_modules/findit/node_modules/seq/index.js:76
        f.apply(cb, context.stack);
          ^
RangeError: Maximum call stack size exceeded
    at Function.APPLY_OVERFLOW (native)
    at action (/Users/inouetomoyuki/node_modules/findit/node_modules/seq/index.js:76:11)
    at next (/Users/inouetomoyuki/node_modules/findit/node_modules/seq/index.js:208:17)
    at /Users/inouetomoyuki/node_modules/findit/node_modules/seq/index.js:213:30
    at /Users/inouetomoyuki/node_modules/findit/node_modules/seq/index.js:55:24
    at Function.<anonymous> (/Users/inouetomoyuki/node_modules/findit/index.js:75:25)
    at Function.<anonymous> (/Users/inouetomoyuki/node_modules/findit/node_modules/seq/index.js:210:38)
    at action (/Users/inouetomoyuki/node_modules/findit/node_modules/seq/index.js:76:11)
    at next (/Users/inouetomoyuki/node_modules/findit/node_modules/seq/index.js:208:17)
    at /Users/inouetomoyuki/node_modules/findit/node_modules/seq/index.js:213:30

依存モジュールのseqから発火されています。未解決のようです。node 0.7.8(Win版)ではhack方法が紹介されています。