ExpressとSocket.IOで作られたドラッグ&ドロップ対応ファイルアップローダ

dotHTML5から

ソースがGitHubで公開されているのでコードリーディング。Soket.IOの使い方が勉強になる。

あと、ヘッダのリソースをsession経由で渡せばいいのか。

  req.session.resources = [
    { type: 'javascript', uri: '/libraries/file-iterator/file-iterator.js' },
    { type: 'javascript', uri: '/socket.io/socket.io.js' },
    { type: 'css', uri: '/stylesheets/sender.css' },
    { type: 'javascript', uri: '/javascripts/sender.js' }
  ];
  req.session.variables = [
    { name: 'webSocketHost', value: "'" + config.client.webSocket.host + "'" },
    { name: 'webSocketPort', value: config.client.webSocket.port }
  ];
  res.render('sender');

こうしておくとテンプレートにハードコードしなくて良いからいいかもしれん。今度使おうっと。Flaskだったら辞書に突っ込んでレンダリングすればいいのかな。


8/21(Sun) @コミュニテイfで第二回Shizudevつくる会やります。

now.jsとcanvasでお絵描きリアルタイム共有

now.jsの練習。canvas操作ははじめての共同作業 Canvas編を流用させてもらった。

now.jsは単に呼び出せば非同期メッセージングができるようになるので便利ですね。あと実際に使ってみて楽だなぁと感じたのがjade、これはヤバイ。Pythonだと何が一番近いんだろうか?後で探してみよう。

expressコマンドでできたスキャフォールド

$ tree
.
├── app.js
├── package.json
├── public
│   ├── images
│   ├── javascripts
│   │   └── client.js
│   └── stylesheets
│       └── style.css
└── views
    ├── index.jade
    └── layout.jade

app.js

最後の二行追加したくらい。楽ちん

var express = require('express');

var app = module.exports = express.createServer();

// Configuration

app.configure(function(){
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(express.static(__dirname + '/public'));
});

app.configure('development', function(){
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); 
});

app.configure('production', function(){
  app.use(express.errorHandler()); 
});

// Routes

app.get('/', function(req, res){
  res.render('index', {
    title: 'Express'
  });
});

app.listen(3000);
var everyone = require("now").initialize(app);

everyone.now.distributeMessage = function(message){
  everyone.now.receiveMessage(message);
};
console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);

package.json

npm -d install

で依存モジュールがさくっとインストールされるので便利ですね。

{
    "name": "application-name"
  , "version": "0.0.1"
  , "private": true
  , "dependencies": {
      "express": "2.4.3"
    , "jade": ">= 0.0.1"
    , "now": ">= 0.0.1"
  }
}

client.jsのmove

now.distributeMessage(JSON.stringify(points));

だけで、他のクライアントに通知されます。

 Painter.prototype.move = function(event) {
   if (!this.isDrawing) {
     return;
   }

   var points = {
     bx: this.beforeX,
     by: this.beforeY,
     ax: event.clientX - 10,
     ay: event.clientY - 10,
     c: this.strokeStyle
   };

     now.distributeMessage(JSON.stringify(points));
     this.drawLine(points);

   this.beforeX = points.ax;
   this.beforeY = points.ay;
 };

layout.jade

!!! 5
html
  head
    meta(charset='UTF-8')
    title= title
    link(rel='stylesheet', href='/stylesheets/style.css')
  body!= body

index.jade

canvas(id='layer0', class='canvas', style='position: absolute; top: 0; left: 0; border: 10px solid #dddddd;', width='900px', height='600px')
script(src='http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js')
script(type='text/javascript', src='/javascripts/client.js')
script(src='/nowjs/now.js')
script
  $(document).ready(function(){
    var painter = new Painter('layer0');
    now.receiveMessage = function(message){
       var d = JSON.parse(message);
       painter.drawLine(d);
    }});

nowjsが使いやすそう

socket.ioを更に抽象化してnowっていうオブジェクトを操作するだけで非同期メッセージングをできるようにしたという理解でいいのかな。

Quick "Hello World" Exampleを触ってみる。サーバー側はたったの12行

var html = require('fs').readFileSync(__dirname+'/helloworld.html');
var server = require('http').createServer(function(req, res){
  res.end(html);
});
server.listen(8080);

var nowjs = require("now");
var everyone = nowjs.initialize(server);

everyone.now.distributeMessage = function(message){
  everyone.now.receiveMessage(this.now.name, message);
};

ポイントはこの3行か。

everyone.now.distributeMessage = function(message){
  everyone.now.receiveMessage(this.now.name, message);
};

Expressとの連携も簡単だそうです

var app = express.createServer();
app.listen(3000);
var everyone = require("now").initialize(app);

あとで何か作ってみる

FilePadはNode.js製のオンラインエディタ

Node.jsとcoffee-scriptの勉強のために読んでみた。coffee-scriptは(javascriptよりも)読みやすくていいですね。

サーバーにあるファイルを読み書きできます。

filepad

複数のクライアントで同時に開いても変更がリアルタイムで反映されているので面白い。

でも使い道がよくわからない。

Node.jsで簡単なブログを作ってみる

Blog rolling with mongoDB, express and Node.jsの写経だが、このエントリはわかりやすいですね。

node_blog

MongoDBって使いやすそうなので、SQLiteから乗り換えようかなと思ってちょっと調べたところMongoKitはSQLAlchemyっぽいような気がしたんだけどどうなんだろうかねぇ。結局javascriptだとクラス関係ないしJSON(BSON)だからMongoとの相性がいいんだろうか?あとでもう少し調べてみよう。

さて、上のエントリのブログのサンプルで使われていたHTMLとCSSのテンプレートエンジンが面白かったので調べてみた。

Jade

zen-codingみたいなノリでサクサク書いていけるっぽい。

Jade - robust, elegant, feature rich template engine for nodejs

Hamlっぽいとか書いてあったんだけどHaml知らんからなぁ(普段はFlask+Jinja2使ってます)。

EmacsのJade-modeはないみたい

stylus

CSSをシンプルに書ける独自のスタイル指定言語らしい。構造化してすっきりと記述できるみたい。

Expressive, robust, feature-rich CSS language built for nodejs

スクリーンキャストもありますね。

CSSなんてすぐにぐちゃぐちゃになって可読性が落ちるので、CSSなんてバイナリと一緒で人が読むもんじゃないんだぜみたいな立場にたてば、DRYを保てるようなこういった仕組みは良いんだろうなと思う、っていうか良い。

モジュールをインストールするとstylusっていうコマンドがついてきて、別にNode.jsじゃなくても使えるのでFlaskで使おうかなと思っている。

こんなstylがあるとして

body
  font-family "Helvetica Neue", "Lucida Grande", "Arial"
  font-size 13px
  text-align center
  text-stroke 1px rgba(255, 255, 255, 0.1)
  color #555
h1, h2
  margin 0
  font-size 22px
  color #343434
h1
  text-shadow 1px 2px 2px #ddd
  font-size 60px

コマンドラインからコンパイル

$ ../../node_modules/stylus/bin/stylus style.styl
  compiled style.css

できた。

body {
  font-family: "Helvetica Neue", "Lucida Grande", "Arial";
  font-size: 13px;
  text-align: center;
  text-stroke: 1px rgba(255,255,255,0.1);
  color: #555;
}
h1,
h2 {
  margin: 0;
  font-size: 22px;
  color: #343434;
}
h1 {
  text-shadow: 1px 2px 2px #ddd;
  font-size: 60px;
}

Node.jsでtwitterのストリームをgrowlで通知する

普通にスクリプトとして使えるので、覚えてくるとなかなか楽しいですね。Node.jsのモジュール一覧を眺めながら面白そうなのをいじっています。

今日はgrowlで遊んでみてますが、通知はgrowlnotify経由なのであらかじめインストールしておく必要があります(入ってなくてもエラーを吐かないので一瞬悩む)。

#!/usr/bin/env node

require.paths.push('/usr/local/lib/node_modules')

var TwitterNode = require('twitter-node').TwitterNode
, growl = require('growl');

var twit = new TwitterNode({
  user: '####', 
  password: '####',
  track: ['perl','python','haskell','javascript']
});

twit.addListener('error', function(error) {
  console.log(error.message);
});

twit.addListener('tweet', function(tweet) {
    growl.notify("@" + tweet.user.screen_name + ": " + tweet.text);
}).stream();

node.jsとNginxが相性がいいって見かけたので、さくらVPSのApacheをNginxに置き換えようかなぁと思いNginxの本を注文してみた。

ProductName ハイパフォーマンスHTTPサーバ Nginx入門
Clement Nedelcu
アスキー・メディアワークス / 3150円 ( 2011-04-21 )


javascript-script

Calipsoのコード読んでたらnode.jsはスクリプトとして動かせることに気づいたのでスクリプトにしてみた。

といっても一行足すだけだけどね。

モジュールのパスがおかしかったのでrequire.pathで足してみたけど、なんでおかしいのかわからん。どこかに余計な環境変数を入れてあるのかなぁ。

#!/usr/bin/env node

require.paths.push('/usr/local/lib/node_modules')

var TwitterNode = require('twitter-node').TwitterNode
, sys = require('sys');

var twit = new TwitterNode({
  user: '######', 
  password: '######',
  track: ['perl','python','haskell','javascript']
});

twit.addListener('error', function(error) {
  console.log(error.message);
});

twit
  .addListener('tweet', function(tweet) {
    sys.puts("@" + tweet.user.screen_name + ": " + tweet.text);
  })
  .stream();

Node.jsでtwitterのストリームをだらだらと流してみる。

twitter-nodeを使う。

var TwitterNode = require('twitter-node').TwitterNode
, sys = require('sys');

var twit = new TwitterNode({
  user: '######', 
  password: '#########',
  track: ['perl','python','haskell','javascript']
});

twit.addListener('error', function(error) {
  console.log(error.message);
});

twit
  .addListener('tweet', function(tweet) {
    sys.puts("@" + tweet.user.screen_name + ": " + tweet.text);
  })
  .stream();

実行結果

$ node tw.js 
@halfstepper: @seocosenza Ah, mi spiace, non ne so niente, io mi occupo di php-html-javascript, per il resto mi barcameno, ma non sono ferrato :-(
@rapella: RT @deliprao: Why MIT switch from Scheme to Python? (via @gappy3000) http://ow.ly/5N6hO
@piotrlukanko: RT @6Wunderkinder: We really need talented #JavaScript and #PHP (#CodeIgniter) developers @6Wunderkinder in #Berlin jobs@6wunderkinder.c ...
@js_gallery: Javascript motion gallery Forum | Yo! Venice! Forum. This forum requires Javascript to be enabled for posting ... http://tinyurl.com/4azlt77
@stackfeed: line aligning, HTML, CSS JAVASCRIPT: I am making an application for an android phone using eclipse, I want to be... http://bit.ly/oe79tO
@perlism: RT !natsutan: Pythonの文字列処理苦手。perlの s// が気楽で良い
@perlism: RT !reanisz: 「Perl好き」とは常日頃言っているが「Perlが得意」な訳ではない・・・(´・ω・`)
@glidepro: RT @creativeapps: New #Javascript feature on CAN: DrippingPaint.Js by @twholman | http://ca-n.in/nWFbWr
@_yueyue350179: RT @perlism: RT !natsutan: Pythonの文字列処理苦手。perlの s// が気楽で良い
@Nikole_2: "I know you like with the lights on, even if they off you can still feel the python" #SWAG
@jcvfeed2: Rugby - Top 14 - Manas : "Une ébauche du projet de jeu" (Rugbyrama.fr) javascript:void(0);

なかなか楽しい。

Node.jsで作るechoサーバー

Node.jsとは何かの写経

このエントリはわかりやすかった。

var net = require('net');
var sockets = [];

var server = net.Server(function(socket) {
   sockets.push(socket);

   socket.on('data', function(d) {
       for (var i=0;i < sockets.length; i++) {
           sockets[i].write(d);
       }
   });

   socket.on('end', function() {
       var i = sockets.indexOf(socket);
       sockets.splice(i,1);
   });
});

そしてFelix's Node.js Style Guide(和訳)も参考になった。

javasciptの新刊二冊

グラフィックスとNode.js

両方気になるなぁ。

ProductName Supercharged Javascript Graphics
Raffaele Cecco
Oreilly & Associates Inc / 3957円 ( 2011-07-29 )


ProductName Node: Up and Running: Scalable Server-Side Code With Javascript
Tom Hughes-croucher
Oreilly & Associates Inc / 2877円 ( 2011-09-22 )