カスタムfindコマンド

alias f="find"


でも、そこそこ便利だけれど
.gitディレクトリを、検索対象外にしたいときに

f . -name .git -prune -print


となり、長いし忘れやすいので

#!/bin/bash
case $# in
1)
  path='.'
  name=$1
  ;;
2)
  path=$1
  name=$2
  ;;
esac

#echo "find \"$path\" -name .git -prune -o -name \"$name\" -print"
find "$path" -name .git -prune -o -name "$name" -print


デフォルトで、.gitディレクトリを抜いてfindさせるシェルスクリプトを作成。
引数が1つの場合は、カレントディレクトリから引数で与えられたnameを検索。
引数が2つの場合は、第一引数のディレクトリから、第二引数のnameを検索。

node.jsを使ってWebページからテキストを取得

jsdomモジュール使うと、http周りの記述しなくて良いから楽だね。
レスポンスヘッダもしくは、メタ要素で指定された文字コード見てUTF-8に変換すれば
もうちょっとましになりそう。

ソース

// getText.js
var jsdom = require('jsdom');

function removeElements(list) {
  for (var i = 0, l = list.length; i < l; i++) {
    var elem = list[i];
    elem.parentNode.removeChild(elem);
  }
}

jsdom.env(process.argv[2], function(errors, window) {
  var body = window.document.body;
  removeElements(body.getElementsByTagName('script'));
  removeElements(body.getElementsByTagName('style'));

  console.log(body.textContent);
});

使い方

% node getText.js http://d.hatena.ne.jp/TakiTake/

JSON形式の設定ファイルに対する変更をリアルタイムに反映する方法

JSON形式の設定ファイルに変更があったら動的に変更を読み込みたいな
ということで、

var fs   = require('fs');
var conf = null;
var filepath = '/path/to/file';

// 設定ファイルを再読み込みする関数
// 第二引数で、同期か非同期かを選べる
function reload(filepath, sync) {
  if (sync) {
    conf = JSON.parse(fs.readFileSync(filepath, 'utf8'));
  } else {
    fs.readFile(filepath, 'utf8', function(err, data) {
      if (err) {
        throw err;
      }

      conf = JSON.parse(data);
    })
  }
}

// 設定ファイルを監視するロジック
// watchFileして、更新日時が新しかったら再読み込みする
fs.watchFile(filepath, function(curr, prev) {
  if (curr.mtime > prev.mtime) {
    reload(filepath);
  }   
}); 


デバッグレベルを切り替えてみたり、上限や下限値を変更したりと
アプリを再起動するまでも無い変更には便利かと

annotatable-http-proxyを作ろうと思う

大学の頃

任意のサイト(主に授業の教材)のHTMLコンテンツに対してメモを書けるようにし
それをユーザ間で共有することで、学習支援しようという研究してた。

実装方法

  1. WebサーバにGET/POSTリクエストでメモを書き込みたいサイトのURLを送る
  2. WebサーバがURLを基にオリジナルのサイトからコンテンツを取得
  3. Webサーバ上で先ほど取得したコンテンツにメモを付加
  4. ユーザに対して、メモが付加されたコンテンツを返す

というものだった。
PHPフレームワークとしてsymfonyを導入したり、JavaScriptを大幅に書き直したりと
好き勝手やらせてもらって、それはそれで楽しかったけれど知識不足で果たせなかったこともあった。


proxyサーバ化するというもの


いちいちURLを送るのはスマートでは無いとは感じていたけれど
proxyサーバって難しそう、と避けていた。

そこでnode.jsですよ

node.jsの勉強がてら、全部JSで実装してみよう!

Apacheにmod_proxy入れれば

(∩゚д゚)アーアーきこえなーい

node.jsでproxyサーバ

node.jsのインストール

https://github.com/ry/node/wiki/Installation


0.5.0-preになってる!

% node -v
v0.5.0-pre

httpサーバを立てる

リクエストは、GETの当て決め
サーバから受け取ったレスポンスをそのままブラウザに返す。

var sys     = require('sys'),
    url     = require('url'),
    http    = require('http');
var port = 8000;

http.createServer(function(req, res) {
  http.get({
    host: req.headers.host,
    port: url.parse(req.url).port || 80,
    method: 'GET',
    path: req.url,
    headers: req.headers
  },
  function(response) {
    res.writeHead(response.statusCode, response.headers);
    response.on('data', function(chunk){ res.write(chunk); });
    response.on('end', function(){ res.end(); });
  });
}).listen(port);

sys.puts('Server listening on port ' + port);

ブラウザ側の設定

環境設定 > ネットワーク
辺りでプロキシを設定する。


簡単だな。

XMLの差分取得2

textNodeの中身消去して、XMLの構造だけを比較するバージョン

#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use LWP::UserAgent;
use XML::Simple;
use XML::DOM::XPath;
use Text::Diff;

binmode(STDOUT, ':utf8');

my $content1  = get('http://search.hatena.ne.jp/keyword?word=ABC&mode=rss&ie=utf8&page=1');
my $content2  = get('http://search.hatena.ne.jp/keyword?word=ABC&mode=rss&ie=utf8&page=2');

print diff \$content1, \$content2;

sub get {
  my $ua = LWP::UserAgent->new;
  my $xs = XML::Simple->new(ForceArray => 1, RootName => 'root');
  my $r  = $ua->get(shift);
  die $r->status_line unless $r->is_success;
  my $content = parse($r->content);

  return $xs->XMLout($xs->XMLin($content));
}

sub parse {
  my $parser   = XML::DOM::Parser->new();
  my $doc      = $parser->parse(shift);
  my @nodelist = $doc->findnodes('//text()');

  foreach my $node (@nodelist) {
    $node->setNodeValue('');
  }

  return $doc->toString();
}

XMLの差分取得

今日は、Windows XP環境で実施。
cpanが使えるということで、"Strawberry Perl"をインストールしてみた。
http://strawberryperl.com/


んで、はてなのサーチAPI叩いてみたよ。

#!C:\strawberry\perl\bin
use strict;
use warnings;
use utf8;
use LWP::UserAgent;
use XML::Simple;
use Text::Diff;

# コマンドプロンプトで文字化けしないように
binmode(STDOUT, 'encoding(cp932)');

# レスポンスのXMLを取得
my $content1  = request('http://search.hatena.ne.jp/keyword?word=ABC&mode=rss&ie=utf8&page=1');
my $content2  = request('http://search.hatena.ne.jp/keyword?word=ABC&mode=rss&ie=utf8&page=2');

# 差分表示
print diff \$content1, \$content2;

sub request {
  my $ua = LWP::UserAgent->new;
  my $r  = $ua->get(shift);

  # XMLを整形
  return XMLout(XMLin($r->content));
}