2010年12月31日

2010年12月31日時点のPC環境

今年は1年の間に結構色々とPC環境に手を入れた気がするのでちょっとまとめようと思う。

Clip to Evernote

2010年12月29日

ServersMan@VPS から さくらのVPS へ乗り換え

ServersMan@VPS はユーザに root 権限を与えているのに事あるごとに触られて怖いので無料期間内にさくらのVPSへ乗り換えることにした。ServersMan@VPS の時は当時 CentOS と Debian しか選べなかったので Debian にしたが、さくらは色々選べるので Ubuntu の 64bit 版を入れることにした。

Clip to Evernote

2010年12月26日

ギガプリン

昨日 Twitter のタイムラインを眺めている時にギガプリンの曲に遭遇して、前からこうなんというか気になるというかイラッとするというか思うところがあったので、なんかよくわからん伴奏を被せてみた。


などという文章とともに、twaud.io の埋め込み機能と YouTube の iframe 埋め込み機能を実験する記事を作ってみた。
Blogger では mp3 ファイルのアップロードに結構困ってたけど、twaud.io の埋め込み機能があれば心配なさそうだ。

※twaud.io の埋め込み機能は再生成功率が低いなぞのトラブルがあるので一旦取り除いた
Clip to Evernote

2010年12月23日

SSL のページに非 SSL の iframe が挿入された時の動き

SSL で保護されたページにブックマークレットで iframe を挿入して、ブラウザがどれだけアクションを起こしてくれるのか調べてみました。

Clip to Evernote

2010年12月17日

ルイカ細めセットを買った

Windows は Linux や iOS と比べるとフォントレンダラに癖があるのかフォントが汚く見えることがよくある。
プログラミングなどの用途で使えるフォントなどを探しているとき、1Il| O0 '` ,. などの区別が付きやすく、かつ日本語が使える見やすいフォントとなるとなかなか思ったようなフォントが見つからずに困っている。
ソース内のコメントを日本語で書いたり、普通のテキストファイルや HTML ファイルを編集するときなどのことを考えると漢字の数も十分にないと困るし、その時点で選択肢がほとんどなくなってしまう。
メイリオを加工するような手法も検索すると散見されるがライセンス的にどうなのかわからないし、少なくとも Ubuntu を併用してる自分が同じフォントを両方の環境で使うのはアウトのように思える。同じような理由でフォントリンクを使うような手法も面倒なので微妙だ。

そんなこともあり今まではVLゴシックをメインに使っていたのだが、タイプラボのルイカ等幅がプログラミング用に使えるように配慮されていることを偶然知った。まずは教育漢字までが使える無料版を試用してみたのだが、PuTTY の画面が個人的にはなかなか読みやすかった。

VL Gothic
ルイカ等幅-02
ルイカ等幅-03

VLゴシックは丁度良い感じに行間が確保されていて嫌いではないのだが、t や f の横棒のように滲んでしまう文字がいくつかあったりして微妙に濃さが安定しない。
ルイカ等幅-02やルイカ等幅-03は行間が狭く、102、103行目の p と b が非常に近く若干読みにくかったり、そもそも p の縦棒が少し短めで視認性が低いなどいくつか問題はあるものの少なくとも滲む場所はなかった。

ルイカは全9ウェイトで、ダウンロード版は1ウェイト税込2730円で可変幅と固定幅のフォントが1つずつ付いている。可変幅の方は英数字もスタンダードな書体になっていて使い勝手がよく、とてもコストパフォーマンスがいい。
ダウンロード購入ページの下の方にはお得なセット販売の案内まであり、5ウェイトが4ウェイト分の価格で購入できる。Webサイトを作るときにも使えるし、思わずルイカ細めセットを買ってしまった。

商売上手である。

次の給料が入ったらルイカ太めセットも買おう。買った。いいフォントは長く使える。
でもできれば自己解凍書庫だけでなく zip 形式とかでもダウンロード販売して欲しい。
Clip to Evernote

2010年12月9日

「『作曲できる奴ちょっとこい』のデータで遊ぶ」の3日間

「作曲できる奴ちょっとこい」のデータで遊ぶ
http://sdc.oov.ch/

「埋もれた歌詞の救済」というテーマを元にこんなサイトを作ってみた。
実際の作業自体は大体3日ぐらいで終わった。実作業時間は半日とちょっとぐらい。

1日目 ----

ネタ元はもちろん少し前に話題になったJ-POP ジェネレータ
それを見た友人が「作曲スレのデータでできないかな」と言っていて、作業しようと思い立ったのがこの日。

まず最初に歌詞のデータを集めてくる必要があった。
いくつか抜けている部分もあるもののIDは既に19000を越えているようなので、1秒ずつ HTTP アクセスを掛けたとしても19000秒。
図書館事件も記憶に新しい今日この頃なので、サーバのレスポンス速度も確認してデータ収集中はほぼ常時対象サーバもクライアントも監視していた。

収集で使用したのは概ね以下のようなコード。golang で書いた。
package main
import (
    "http"
    "io"
    "os"
    "log"
    "fmt"
    "time"
)
func main(){
    for i:=0; ; i++ {
        time.Sleep(1e9)
        r, _, err := http.Get(fmt.Sprintf("http://www9.atpages.jp/stewmusic/akadb/songlist.php?key=No:%d", i))
        if err != nil {
            log.Printf("http.Get error: %s", err.String())
            i-- //リトライ
            continue
        }
        dir := fmt.Sprintf("akadb/%02x", i & 0xff)
        filename := fmt.Sprintf("%s/%04x.html", dir, i)
        err = os.MkdirAll(dir, 0755)
        if err != nil {
            log.Printf("os.MkdirAll error: %s", err.String())
            r.Body.Close()
            continue
        }
        file, err := os.Open(filename, os.O_WRONLY | os.O_CREAT, 0644)
        if err != nil {
            log.Printf("os.Open error: %s", err.String())
            r.Body.Close()
            continue
        }
        written, err := io.Copy(file, r.Body)
        if err != nil {
            log.Printf("cannot write to file: %s", err.String())
            r.Body.Close()
            file.Close()
            continue
        }
        file.Close()
        r.Body.Close()
        log.Printf("%04d written %d bytes.", i, written)
    }
}
これを自宅のマシンで動かした。
恐らくインデックスが張られているであろうID基準での検索なのでレスポンスも速く順調に進んでデータの収集は難なく終了した。

2日目 ----

次にローカルに落としたファイルから歌詞の部分を抜き出す処理を書こうと思ったのだが、Go言語のパッケージにある html 解析周辺は絶賛開発中で上手く動かなかった(使っているのがreleaseブランチではなかったせいだと思う)のでここの解析処理は Python で BeautifulSoup を使った。
# -*- coding: utf-8 -*-
import sys, string, sqlite3
from BeautifulSoup import BeautifulSoup

def main(begin, end):
    db = sqlite3.connect("akadb.sqlite3")
    dbc = db.cursor()
    for i in xrange(begin, end):
        filename = "akadb/%02x/%04x.html" % (i & 0xff, i)
        soup = BeautifulSoup(open(filename, "rb").read())
        outline = soup.find('div', id="contents_outline")
        if outline == None:
            continue
        inlines = outline.findAll('div', id="contents_inline")

        #最後の contents_inline は歌詞ではない可能性が高いので
        #調べて必要ないなら消す
        last = inlines[len(inlines)-1].renderContents()
        if last.find("<!--//") != -1 or last.find("<a href") != -1:
            inlines.pop()

        for inline in inlines:
            body = inline.renderContents()
            #brタグのみを改行としてその他の改行は取り除く
            body = body.replace("\r", "").replace("\n", "")
            body = body.replace("<br />", "\n").rstrip() #末尾の改行は消す
            body = body.replace("&quot;", "\"").replace("&lt;", "<").replace("&gt;", ">").replace("&amp;", "&")
            dbc.execute("insert into lyric (parent_id, body) values (?,?)", (i, body))
            print "%d processed." % i
    db.commit()

if __name__ == "__main__":
    main(int(sys.argv[1], 10), int(sys.argv[2], 10))
ひとつの記事に対して複数の歌詞が存在するケースがしばしばあるので、そこも考慮して SQLite3 に突っ込んでいく。
入門段階で終わっていた Python を久々に触ると色々忘れててやばい感じだったが無事に収集できた。

テキストの処理がやっつけ仕事なので若干漏れたデータがあるかも知れない。
まあでも取りあえず次進んじゃいましょうということでこのステップもさくっと終了。

3日目 ----

準備は整ったのであとは実際に歌詞を解体して組立て直すだけでいい。ここは再び golang で。
SQLite3 の DB に突っ込んだデータを gosqlite でランダムに30件程度抜き出してきて、その中のテキストを行単位とブロック単位で切り分け。
サビっぽい箇所にブロックの1行目を持ってきたりとか、歌詞っぽくするために適宜改行入れたりとか、そういうわりと単純な処理をいくつかやって完成。

この辺は自分で考えるのが楽しいところで晒すのは色々アレなので端折るが、それでも230行程度。
その中で http サーバを立てて JSON 形式でデータを返すような処理も行っている。

ここまで出来上がったらあとは実際に Web サイトとして仕上げるための作業。
ドメインを当てたり HTML とか JavaScript とか CSS を書いたりとか。
さり気なくこの前衝動的に買った紙・布・テクスチャー素材集も使ってみた。いい感じ。だと思う。

一応 JavaScript が動いてない環境でも最低限の挙動は出来るようサーバサイドでも PHP を使って多少処理をした。
Web サーバの nginx とランダム歌詞を返す golang 製サーバは HAProxy を経由して両方ともポート80番でアクセスできるようにした。

そして公開。埋もれた歌詞が発掘されるきっかけになればいいなあと思う。
Clip to Evernote

2010年12月4日

Flash-Socket-Policy への応答を xinetd で行う

https://github.com/gimite/web-socket-js
Flash のソケット通信機能を経由すれば IE や現行の正式版の Firefox や Opera でも WebSocket と同じレベルの通信ができるということで、最近 gimite さんの web-socket-js を使ってみている。

Flash の場合アクセスを許可するためのポリシーファイルを配信しなければならないようなのだが、ServersMan@VPS の Debian には最初から xinetd が入っているようなのでこれを使って許可するようにしてみようと思う。
(もちろん WebSocket サーバ側で準備するのもいいけどポート843番は特権ポートなのでサーバをユーザ権限で動かしたい場合直接は listen できない模様)
まず /etc/services にポート843番に関する情報を追加する必要がある。
vim /etc/services
flsockpolicy tcp/843
次に登録したポートに対応した応答用の定義を追加する。
vim /etc/xinetd.d/flsockpolicy
service flsockpolicy
{
        disable         = no
        wait            = no
        socket_type     = stream
        flags           = IPv6
        user            = www-data
        group           = www-data
        server          = /usr/local/flsockpolicy/flsockpolicy
}
で、この server に書いた場所に実際に実行されるスクリプトファイルを設置する。
cd /usr/local/
mkdir flsockpolicy
cd flsockpolicy
vim flash-socket-policy.xml
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
    <allow-access-from domain="flashが設置されているドメイン名" to-ports="アクセスを許可するポート番号"/>
</cross-domain-policy>
vim flsockpolicy
#!/bin/sh
read -n 23 INPUT
if [ $INPUT = '<policy-file-request/>' ]; then
  cat /usr/local/flsockpolicy/flash-socket-policy.xml
fi
chmod 700 flsockpolicy
chgrp www-data *
chown www-data *
準備が終わったら xinetd をリロード。
invoke-rc.d xinetd reload
テストする。
telnet 127.0.0.1 843
応答が返ってくるのが確認出来れば成功。


要求の内容もロクに確認しない適当スクリプトだけど Flash 経由で使えるようになったのでこれで問題ないようだ。


---- 2010-12-17 追記
ちゃんと受信してから返答しないと成功しないケースが多かったのでちゃんと内容を見るように修正。
Clip to Evernote

2010年12月3日

Avast! の Web シールドを一時停止しても WebSocket で接続できない

最近 WebSocket サーバをGo言語の勉強を兼ねて作っているのだが、友人の環境で接続に失敗してしまう問題が起こり、それの解決策がわからず微妙に悩んでいたが、タイトルに書いてあるとおり Avast! が原因だということがわかった。
WebSocket の情報がまだ少ないと思って検索してなかったが、avast websocket で検索すると思いっきりそれに関する情報が出てくるではないか。

この一件で個人的にはもう無料で対策したいなら Microsoft Security Essentials、最新のウィルスからも迅速に保護されたいなら有料の有名どころを使えばいいじゃないと内心思ってしまった。

カスペルスキー系はここに書いてあるトラブルシューティングで回避方法が書かれているので手動設定しないとダメかも。
Clip to Evernote