SSDに換装した&Ubuntu+Emobileリトライ

朝もくもく用のノートPCだが、やはりバッテリーのもちがあまりよくない。時間で約1時間50分ほどだろうか。電源が確保できればいいのだが、なかなかそうもいかない。
また、LLカンファレンスやPHPカンファレンスの準備MTGにそういった場合に、会議が終わるまで電池がもたないということにになる。

そこで、早いという評判もあるが、消費電力の少なさというのに目をつけて、HHDからSSDへの換装をしてみようと思った。

買いに行く

思い立ったらすぐに欲しいので、価格comで相場を調べておいて、渋谷のビックカメラに行ってみたが、ネットで25,000円ぐらいのものが、40,000近くで売っている。ちょっといくらすぐに手に入ると言っても無理な価格。
しかたがないので、家に帰って Amazonでぽちりました。お急ぎ便にして、到着を心待ちにする。

データ移行

初めは、ディスク容量が同じなのでそのまま ddコマンドなどで移行をしようと思い、USBでつないで ddコマンドで移してみる。
内蔵用なのでLEDがなく、さらにSSDなので、かりかりという頑張っている音もしない。なんだかできているのか不安になったが、ddコマンドも進捗が普通に見えるのですね。
進捗の状況を見ていると、どうやら 1G転送するのに、12〜15分ほどかかっている。120GBのディスクなので、もしかしたら単純計算する時間がかかるかもしれない。。
そこで、元の環境も作ったばかりで、それほど移行しなければならない情報もないので、新規でインストールすることにしてみた。

USBのブートディスク作成

USBのブートディスクは、つい先日作ったのだが、もう使わないだろうということで、フォーマットしてしまっていた。今回は、Ubuntu上に、syslinuxを落としてきてUSBに書き込みをしたが、Ubuntu自体のisoファイルが、Mac上にあったので、その後のコピーを MacOS10上で行ったが、それがよくないらしく、起動しない。
しかたがないので、MacのVMWare上のWindowsからまた作成。

Ubuntu8.10で行ったところ、以下の部分だけ違った

isolinux.cfgをsyslinux.cfgにリネーム
テキストエディタでsyslinux.cfgを開いて、/install、/casperを参照しているパスを変更
(ex. /casper/vmlinuz ⇒ /vmlinuz)

リネームは行ったが、syslinux.cfg 内に該当の記述がなく、そのままでいけた。

Emobile

自分の書いた記事を参考に入れようとしたら、ぜんぜんうまくいかない。
Ubuntu&Emobile(D12LC)で始める朝もくもく - maru.cc@はてな

なぜうまくいかないのかわからないが、とりあえず再インストールからやりなおしてみる。


以下、後で自分が参照するためにも詳細なログ付きで手順を残しておきます。

OS再インストール直後に Emobile D12LC を挿してみる
maru@maru:~$ lsusb
Bus 004 Device 004: ID 0483:2016 SGS Thomson Microelectronics Fingerprint Reader
Bus 004 Device 003: ID 0a5c:2110 Broadcom Corp. Bluetooth Controller
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
maru@maru:~$ lsusb
Bus 004 Device 004: ID 0483:2016 SGS Thomson Microelectronics Fingerprint Reader
Bus 004 Device 003: ID 0a5c:2110 Broadcom Corp. Bluetooth Controller
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 004: ID 1c9e:9101  
Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

9101の行で、USBメモリとして認識されているのがわかる。

libusb-devをインストールする

次に必要となるlibusb-devをインストールする。

が、普通にコマンドを打ってもインストールできない。

maru@maru:~$ sudo apt-get install libusb-dev
[sudo] password for maru: 
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
E: パッケージ libusb-dev が見つかりません


パッケージの一覧が古いのではないかとあたりを付けて以下を実行。

maru@maru:~$ sudo apt-get update


これで無事にパッケージが認識された。

maru@maru:~$ sudo apt-get install libusb-dev
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
以下のパッケージが新たにインストールされます:
  libusb-dev
アップグレード: 0 個、新規インストール: 1 個、削除: 0 個、保留: 261 個。
38.6kB のアーカイブを取得する必要があります。
この操作後に追加で 344kB のディスク容量が消費されます。
取得:1 http://jp.archive.ubuntu.com intrepid/main libusb-dev 2:0.1.12-12 [38.6kB]
38.6kB を 0s で取得しました (285kB/s)
未選択パッケージ libusb-dev を選択しています。
(データベースを読み込んでいます ... 現在 97880 個のファイルとディレクトリがインストールされています。)
(.../libusb-dev_2%3a0.1.12-12_i386.deb から) libusb-dev を展開しています...
Processing triggers for doc-base ...
Processing 22 changed, 1 added doc-base file(s)...
Registering documents with scrollkeeper...
Processing triggers for man-db ...
libusb-dev (2:0.1.12-12) を設定しています ...
usb_modeswitchのインストール

まずは、落としてきて解凍。

maru@maru:~$ cd /usr/local/src/
maru@maru:/usr/local/src$ sudo wget http://www.draisberghof.de/usb_modeswitch/usb_modeswitch-0.9.6.tar.bz2
maru@maru:/usr/local/src$ sudo tar jxvf usb_modeswitch-0.9.6.tar.bz2 
usb_modeswitch-0.9.6/
usb_modeswitch-0.9.6/README
usb_modeswitch-0.9.6/usb_modeswitch.conf
usb_modeswitch-0.9.6/usb_modeswitch.c
usb_modeswitch-0.9.6/usb_modeswitch.h
usb_modeswitch-0.9.6/Makefile
usb_modeswitch-0.9.6/usb_modeswitch
usb_modeswitch-0.9.6/COPYING


解凍したディレクトリに移動して、実行ファイルはあるが、念の為コンパイル。

maru@maru:/usr/local/src$  cd usb_modeswitch-0.9.6/
maru@maru:/usr/local/src/usb_modeswitch-0.9.6$ ls
COPYING  Makefile  README  usb_modeswitch  usb_modeswitch.c  usb_modeswitch.conf  usb_modeswitch.h
maru@maru:/usr/local/src/usb_modeswitch-0.9.6$ sudo gcc -l usb -o usb_modeswitch usb_modeswitch.c

インストール。これは手動でコピーしても同じ。

maru@maru:/usr/local/src/usb_modeswitch-0.9.6$ sudo make install
mkdir -p /usr/sbin
install ./usb_modeswitch /usr/sbin
mkdir -p /etc
install ./usb_modeswitch.conf /etc


設定をする

maru@maru:/usr/local/src/usb_modeswitch-0.9.6$ sudo vi /etc/usb_modeswitch.conf 


以下は、元ファイルとの差分。これは、D12LC用の設定なので、種類によって内容が違うかもしれない。

maru@maru:/usr/local/src/usb_modeswitch-0.9.6$ diff /etc/usb_modeswitch.conf ./usb_modeswitch.conf 
518,531d517
< #######################################################
< # Emobile D12LC
< #
< 
< DefaultVendor=  0x1c9e
< DefaultProduct= 0x9101
< 
< TargetVendor=   0x1c9e
< TargetProduct=  0x9104
< 
< MessageEndpoint=0x01
< MessageContent="55534243123456788000000080000606f50402527000000000000000000000"
< 
< 
切り替えをする

再度、現状の状態

maru@maru:/usr/local/src/usb_modeswitch-0.9.6$ lsusb
Bus 004 Device 004: ID 0483:2016 SGS Thomson Microelectronics Fingerprint Reader
Bus 004 Device 003: ID 0a5c:2110 Broadcom Corp. Bluetooth Controller
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 004: ID 1c9e:9101  
Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

切り替えの前準備。

maru@maru:/usr/local/src/usb_modeswitch-0.9.6$ sudo modprobe usbserial vendor=0x1c9e product=0x9104

切り替えてみる

maru@maru:/usr/local/src/usb_modeswitch-0.9.6$ sudo usb_modeswitch 

 * usb_modeswitch: tool for controlling "flip flop" mode USB devices
 * Version 0.9.6 (C) Josua Dietze 2009
 * Works with libusb 0.1.12 and probably other versions

Looking for target devices
 No target device found
Looking for default devices
 Found default devices (1)
Prepare switching, accessing latest device
Looking for active default driver to detach it
 OK, driver found ("usb-storage")
 OK, Driver "usb-storage" successfully detached
Setting up communication with device
Trying to send the message
 OK, message successfully sent.
-> See /proc/bus/usb/devices (or call lsusb) for changes. Bye

切り替え後の状況

maru@maru:/usr/local/src/usb_modeswitch-0.9.6$ lsusb
Bus 004 Device 004: ID 0483:2016 SGS Thomson Microelectronics Fingerprint Reader
Bus 004 Device 003: ID 0a5c:2110 Broadcom Corp. Bluetooth Controller
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 005: ID 1c9e:9104  
Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub


ちゃんと認識されているか確認

maru@maru:/usr/local/src/usb_modeswitch-0.9.6$ ls /dev/ttyU*
/dev/ttyUSB0  /dev/ttyUSB1  /dev/ttyUSB2
都度打つコマンドを減らすための設定
vi /etc/rc.local

以下を exitより前に追記する

modprobe usbserial vendor=0x1c9e product=0x9104

これで、今後は、Emobileを挿した後に、以下のコマンドのみでOKになる。

sudo usb_modeswitch
接続用ソフトを入れる

今回は、参考元のサイトと同じ、GNOME PPP を使うことにした。


インストール

maru@maru:~$ sudo apt-get install gnome-ppp


あとは、個別にオプションの設定
設定内容は以下を参考に。

でも、今朝やったらつながらない

昨夜、家では動作確認ができたので、今朝、朝もくもくをするためにカフェに来てEmobileをつなごうと思ったら、エラーになってしまい、接続できない。
いろいろ調べたところ、以下が変な風に認識されているようだ。

maru@maru:~$ ls /dev/ttyUSB*
/dev/ttyUSB0  /dev/ttyUSB1  /dev/ttyUSB2  /dev/ttyUSB3

ttyUSB3 ってなんだ?


エラーのログはこんな感じ

GNOME PPP: Connecting...
GNOME PPP: STDERR: --> Ignoring malformed input line: ";Do NOT edit this file by hand!"
GNOME PPP: STDERR: --> WvDial: Internet dialer version 1.60
GNOME PPP: STDERR: --> Cannot get information for serial port.
GNOME PPP: STDERR: --> Initializing modem.
GNOME PPP: STDERR: --> Sending: ATZ
GNOME PPP: STDERR: --> Sending: ATQ0
GNOME PPP: STDERR: --> Re-Sending: ATZ
GNOME PPP: STDERR: --> Modem not responding.

/var/log/messages の内容

# usbを挿した
Mar 10 08:32:59 maru kernel: [ 1562.420069] usb 5-5: new high speed USB device using ehci_hcd and address 16
Mar 10 08:32:59 maru kernel: [ 1562.554943] usb 5-5: configuration #1 chosen from 1 choice
Mar 10 08:32:59 maru kernel: [ 1562.629143] scsi12 : SCSI emulation for USB Mass Storage devices
Mar 10 08:33:04 maru kernel: [ 1567.637539] scsi 12:0:0:0: Direct-Access     USBModem Disk             2.31 PQ: 0 ANSI: 2
Mar 10 08:33:04 maru kernel: [ 1567.641501] sd 12:0:0:0: [sdb] 65536 512-byte hardware sectors (34 MB)
Mar 10 08:33:04 maru kernel: [ 1567.643249] sd 12:0:0:0: [sdb] Write Protect is on
Mar 10 08:33:04 maru kernel: [ 1567.646871] sd 12:0:0:0: [sdb] 65536 512-byte hardware sectors (34 MB)
Mar 10 08:33:04 maru kernel: [ 1567.648496] sd 12:0:0:0: [sdb] Write Protect is on
Mar 10 08:33:04 maru kernel: [ 1567.651292]  sdb:
Mar 10 08:33:04 maru kernel: [ 1567.653507] sd 12:0:0:0: [sdb] Attached SCSI disk
Mar 10 08:33:04 maru kernel: [ 1567.654488] sd 12:0:0:0: Attached scsi generic sg1 type 0

#sudo usb_modeswitch
Mar 10 08:33:14 maru kernel: [ 1577.310935] usb 5-5: USB disconnect, address 16
Mar 10 08:33:14 maru kernel: [ 1577.556075] usb 5-5: new high speed USB device using ehci_hcd and address 17
Mar 10 08:33:14 maru kernel: [ 1577.694338] usb 5-5: configuration #1 chosen from 1 choice
Mar 10 08:33:14 maru kernel: [ 1577.705488] usbserial_generic 5-5:1.0: generic converter detected
Mar 10 08:33:14 maru kernel: [ 1577.707207] usb 5-5: generic converter now attached to ttyUSB0
Mar 10 08:33:14 maru kernel: [ 1577.707868] usbserial_generic 5-5:1.1: generic converter detected
Mar 10 08:33:14 maru kernel: [ 1577.709028] usb 5-5: generic converter now attached to ttyUSB1
Mar 10 08:33:14 maru kernel: [ 1577.710254] usbserial_generic 5-5:1.2: generic converter detected
Mar 10 08:33:14 maru kernel: [ 1577.711389] usb 5-5: generic converter now attached to ttyUSB2
Mar 10 08:33:14 maru kernel: [ 1577.712596] usbserial_generic 5-5:1.3: generic converter detected
Mar 10 08:33:14 maru kernel: [ 1577.713719] usb 5-5: generic converter now attached to ttyUSB3


昨日の正常時のログ

# usbを挿した
Mar 10 01:06:29 maru kernel: [  888.736055] usb 5-5: new high speed USB device using ehci_hcd and address 4
Mar 10 01:06:29 maru kernel: [  888.870921] usb 5-5: configuration #1 chosen from 1 choice
Mar 10 01:06:29 maru kernel: [  888.962637] usbcore: registered new interface driver libusual
Mar 10 01:06:29 maru kernel: [  888.977363] Initializing USB Mass Storage driver...
Mar 10 01:06:29 maru kernel: [  888.978862] scsi6 : SCSI emulation for USB Mass Storage devices
Mar 10 01:06:29 maru kernel: [  888.980381] usbcore: registered new interface driver usb-storage
Mar 10 01:06:29 maru kernel: [  888.980389] USB Mass Storage support registered.
Mar 10 01:06:34 maru kernel: [  894.000815] scsi 6:0:0:0: Direct-Access     USBModem Disk             2.31 PQ: 0 ANSI: 2
Mar 10 01:06:34 maru kernel: [  894.004603] sd 6:0:0:0: [sdb] 65536 512-byte hardware sectors (34 MB)
Mar 10 01:06:34 maru kernel: [  894.005747] sd 6:0:0:0: [sdb] Write Protect is on
Mar 10 01:06:34 maru kernel: [  894.008731] sd 6:0:0:0: [sdb] 65536 512-byte hardware sectors (34 MB)
Mar 10 01:06:34 maru kernel: [  894.010097] sd 6:0:0:0: [sdb] Write Protect is on
Mar 10 01:06:34 maru kernel: [  894.011397]  sdb:
Mar 10 01:06:34 maru kernel: [  894.021386] sd 6:0:0:0: [sdb] Attached SCSI disk

#sudo usb_modeswitch
Mar 10 01:07:42 maru kernel: [  961.684803] usb 5-5: USB disconnect, address 4
Mar 10 01:07:42 maru kernel: [  961.956071] usb 5-5: new high speed USB device using ehci_hcd and address 5
Mar 10 01:07:42 maru kernel: [  962.090315] usb 5-5: configuration #1 chosen from 1 choice
Mar 10 01:07:42 maru kernel: [  962.103354] usbserial_generic 5-5:1.0: generic converter detected
Mar 10 01:07:42 maru kernel: [  962.104663] usb 5-5: generic converter now attached to ttyUSB0
Mar 10 01:07:42 maru kernel: [  962.105813] usbserial_generic 5-5:1.1: generic converter detected
Mar 10 01:07:42 maru kernel: [  962.106867] usb 5-5: generic converter now attached to ttyUSB1
Mar 10 01:07:42 maru kernel: [  962.110130] scsi7 : SCSI emulation for USB Mass Storage devices
Mar 10 01:07:42 maru kernel: [  962.111853] usbserial_generic 5-5:1.3: generic converter detected
Mar 10 01:07:42 maru kernel: [  962.114528] usb 5-5: generic converter now attached to ttyUSB2

意味がわかりません。。

もしかしたら、昨日インストール後にパッケージをいろいろアップデートしたので、なにかドライバ等が上書きされてしまい、それで認識が出来なくなってしまったのではないかと思ったが、調べる方法も特定ドライバを戻す方法もわからない。何より、もくもくのためにカフェに来ているので、他のPCで調べ物等が出来ない。。
何度も再起動等していたのだが、最後の悪あがきで、再度再起動をしてみたら、なぜか認識しました。


今回は、挿したまま再起動しましたので、最初からモデムとして認識されていました。差し直すとダメなのでしょうか?
たしかに、挿したまま再起動でないとうまく認識しないという話はありましたが、途中さしでも出来ていたと思うのですが。。

maru@maru:~$ lsusb
Bus 005 Device 002: ID 1c9e:9104  
Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 003: ID 0483:2016 SGS Thomson Microelectronics Fingerprint Reader
Bus 004 Device 002: ID 0a5c:2110 Broadcom Corp. Bluetooth Controller
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
maru@maru:~$ ls /dev/ttyUSB*
/dev/ttyUSB0  /dev/ttyUSB1  /dev/ttyUSB2


以下、接続時のログ

maru@maru:~$ sudo gnome-ppp
[sudo] password for maru: 
Launching a SCIM daemon with Socket FrontEnd...
Loading simple Config module ...
Creating backend ...
Loading socket FrontEnd module ...
Starting SCIM as daemon ...
GTK Panel of SCIM 1.4.7


(gnome-ppp:5917): Gtk-WARNING **: GtkSpinButton: setting an adjustment with non-zero page size is deprecated

(gnome-ppp:5917): Gtk-WARNING **: GtkSpinButton: setting an adjustment with non-zero page size is deprecated
WVCONF: /root/.wvdial.conf
GNOME PPP: Connecting...
GNOME PPP: STDERR: --> Ignoring malformed input line: ";Do NOT edit this file by hand!"
GNOME PPP: STDERR: --> WvDial: Internet dialer version 1.60
GNOME PPP: STDERR: --> Cannot get information for serial port.
GNOME PPP: STDERR: --> Initializing modem.
GNOME PPP: STDERR: --> Sending: ATZ
GNOME PPP: STDERR: ATZ
GNOME PPP: STDERR: OK
GNOME PPP: STDERR: --> Sending: ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
GNOME PPP: STDERR: ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
GNOME PPP: STDERR: OK
GNOME PPP: STDERR: --> Modem initialized.
GNOME PPP: STDERR: --> Sending: ATM0L0DT*99***1#
GNOME PPP: STDERR: --> Waiting for carrier.
GNOME PPP: STDERR: ATM0L0DT*99***1#
GNOME PPP: STDERR: CONNECT
GNOME PPP: STDERR: --> Carrier detected.  Starting PPP immediately.
GNOME PPP: STDERR: --> Starting pppd at Tue Mar 10 08:42:08 2009
GNOME PPP: STDERR: --> Pid of pppd: 5927
GNOME PPP: STDERR: --> Using interface ppp0
GNOME PPP: STDERR: --> local  IP address xxx.xxx.xxx.xxx
GNOME PPP: STDERR: --> remote IP address xxx.xxx.xxx.xxx
GNOME PPP: STDERR: --> primary   DNS address xxx.xxx.xxx.xxx
GNOME PPP: STDERR: --> secondary DNS address xxx.xxx.xxx.xxx

(IPだけ伏せ字にしてあります)

とりあえず

原因は不明ですが認識できました。詳しい調査は別途することにします。

mod_access_tokenをPHPから使ってみる

mod_access_tokenとは

ウェブサイト上の画像やファイルに有効期限を指定して、ユーザーに一時的なダウンロードを許可する、ライブドアで独自開発したApacheモジュールです。このモジュールをApache Webサーバに組み込むことにより、画像やファイルをウェブ上で公開するときに有効期限をつけることができるようになり、Webアプリケーションと組み合わせる事で公開範囲の制御を行なう事が可能になります。


ソースコードはこちらから入手できます。
modaccesstoken - Secure downloading module for Apache2 - Google Project Hosting


livedoor ラボ「EDGE」 開発日誌 : 「mod_access_token」の配布開始と「EDGE src」公開のお知らせ - livedoor Blog(ブログ)


ファイルのアクセス制限をApacheのモジュールに任せてしまおうというものだ。
使いどころなどは、ファイルのアクセス制限にいちいちプログラムによる制御を入れられない大規模サイトなどが考えられる。
例えば、会員制サイトのログインユーザのみに見せるプロフィール画像など。


もしくは、コンテンツ自体に課金させるなどのサイトの場合にも使えそうだ。
モバイルサイトの場合、コンテンツに有料課金や、会員onlyの制限をしているものも多くあるので、使いどころがあるかもしれない。

mod_access_tokenのインストール

まずは、入れてみないと話にならないので、入れてみる。

$ wget http://modaccesstoken.googlecode.com/files/mod_access_token-0.10.tar.gz
$ tar xzvf mod_access_token-0.10.tar.gz
$ cd mod_access_token/
$ ls
Makefile.in  README  configure  configure.in  eg  mod_access_token.c
$ ls eg/
httpd.conf-example  sign.pl
$ ./configure
$ sudo make install


参考にしたサイトでは、エラーが起きたという話もあったが、得にエラーもなくインストールできた。
まめ畑


ちなみにインストールした環境はソースインストールしたApache2.0.59だ。

$ /usr/local/apache2/bin/httpd -v
Server version: Apache/2.0.59
Server built:   May 29 2008 14:44:08


httpd.confに以下のようなモジュールロードが書き込まれていた。

LoadModule access_token_module modules/mod_access_token.so


さっそく、適当な ディレクティブ に、サンプルの ディレクティブ を記述してテストをしてみる。

<VirtualHost xxx.xxx.xxx.xxx>
   #略
   <Location /dl>
       AccessTokenCheck On
       AccessTokenSecret 15cfb576a8bdc1551219fdeb3117ed85
       AccessTokenAccessKey 7864ffcb01fb5cde1f1c2f37b619fbcd
   </Location>
</VirtualHost>


これで、この指定した VirtualHostのdlディレクトリ内に直接アクセスすると 403のエラーが発生するようになる。

制限ファイルに、phpスクリプト経由でアクセスしてみる

まず、サンプルのファイルを作成しておく。

$ cd /path/to/document_root/
$ echo 'hoge' > dl/hoge.html

dlディレクトリ内にアクセス制限をした hoge.htmlというファイルがあるという想定だ。
もちろん、画像や動画であっても同じです。



次にphpファイルのソース。

<?php
$uri = '/dl/hoge.html';
$accesskey = '7864ffcb01fb5cde1f1c2f37b619fbcd';
$secret = '15cfb576a8bdc1551219fdeb3117ed85';
$expires = time() + 10; //制限は10秒
$plaintext = 'GET'.$uri.$expires.$accesskey;
$signature = base64_encode(hash_hmac('sha1', $plaintext, $secret, true));
$signature = str_replace('=', '', $signature);
$token_param = sprintf('AccessKey=%s&Expires=%s&Signature=%s'
   , $accesskey
   , $expires
   , urlencode($signature))
?>
<html>
<head>
<title>mod_access_token test</title>
</head>
<body>
mod_access_token test<hr>
plaintext:<?php echo $plaintext ?><br>
signature:<?php echo $signature ?><br>
<a href="<?php echo $uri ?>?<?php echo $token_param ?>">hoge.html</a>
</body>
</html>


それぞれ軽く説明。

  • $uri は、アクセスする対象のファイル /から始まる絶対パスである必要があります
  • $accesskey は、httpd.confで設定した AccessTokenAccessKeyと同じ値
  • $secret は、httpd.confで設定した AccessTokenSecretと同じ値
  • $example には、現在の Unix タイムスタンプ + 秒数を指定
  • $plaintext の、'GET' は、HTTPリクエスト時のメソッドです、今回は普通にaタグからのアクセスなのでGETとします
  • Signatureは、urlencodeしても、しなくても正常に動きましたが、base64_encodeした値に、スラッシュやプラス記号があったので、urlencodeしてみました


軽くつまづいた点

  • hash_hmacの第4引数に true を指定する必要がある。デフォルトで false でした。
  • base64_encode 後の文字列で、末尾の = が不要
    • 今回は無理やりstr_replaceしていますが、もっといい方法があるのかな?

mod_access_token導入時の確認方法

動いているか

直でアクセスして 403 Forbidden になるか、また、Apacheのエラーログにログが残っているか。

パラメータが正しいかどうか

アクセスしたパラメータが正しいはずなのにアクセス出来ないという場合には、エラーログを調べることで確認することができます。

エラーログには、$plaintext と、アクセスされたSignature と、想定する正しいSignatureが記録されています。

Invalid signature: <$plaintext> => <正しいSignature>:<アクセスされたSignature>

以下のような感じのログ

[Mon Mar 02 21:47:35 2009] [error] [client xxx.xxx.xxx.xxx] Invalid signature: GET/dl/hoge.html12359980617864ffcb01fb5cde1f1c2f37b619fbcd => 3s5CSeQ4gCJ+eu9AOf8KB+sB6hA:3s5CSeQ4gCJ+eu9AOf8KB+sB6hA=, referer:http://example.com/

このログでは、base64_encode後の末尾の = が付いているためエラーになっています。

.htaccessでの記述

LoadModule出きるぐらいであれば、httpd.confに記述することも可能かと思いますが、軽い案件で、.htaccessに記述したい場合に可能かどうか試してみました。


結論は、記述可能。ただし、httpd.confでの設定の上書きは出来ない。というものでした。


確実に保護したいものは、httpd.confで記述した方がよく、.htaccessで、以下のような記述をしても制限が外れることはありませんでした。

AccessTokenCheck Off


また、AccessTokenSecret、AccessTokenAccessKeyを別の値に上書きも、もちろん出来ませんでした。


逆に、サーバ管理チームと、アプリ作成チームがはっきり分かれていて、アプリの都合でのhttpd.confへの記入するより.htaccessの方が運用に合っている場合や、アプリのバージョン管理でSVNなどで制限情報も管理したい場合には、.htaccessというのもありではないでしょうか?

$ cat .htaccess
AccessTokenCheck On
AccessTokenSecret 15cfb576a8bdc1551219fdeb3117ed85
AccessTokenAccessKey 7864ffcb01fb5cde1f1c2f37b619fbcd

使いどころを考えてみる

軽く思いついたのは、以下のようなケースとか。


ダウンロードサーバが別。または、ASPっぽいサービスとか。

  • サーバ間通信で、コンテンツダウンロードタグを発行する
  • Webアプリのダウンロードページで、そのダウンロードタグを表示し、ユーザにコンテンツをダウンロードしてもらう
  • 有効期限が切れたり、直アクセスは禁止

なんか、こんなASPサービスもありましたが、比較的簡単に、しかもダウンロードサーバは軽くできそう。


あとは、モバイルサイトのコンテンツ周りでしょうか。現状モバイルサイトを作成し、特定ユーザのみにDLしてもらうコンテンツの場合には、コンテンツファイル自体をPHPで吐き出すようなことをしています。
PHPでコンテンツを吐き出すため、オーバーヘッドがありますし、ダウンロードページ表示時の会員認証と、そこからのコンテンツダウンロード時の会員認証など、二重にチェックになっている部分があるので、そこは軽くできるかもしれません。


あとは、携帯の場合、ダウンロードページを画面メモをしていて、そこからのダウンロードを阻止したい場合にも有効かもしれません。


期間限定の例えば○月○日までDL可能なコンテンツという場合には、EXPIRESが固定になりますので、静的なダウンロードページに静的なリンクにしてしまうという方法もありますね。

要検証な点

  • 403時にhtmlが表示できるか
    • ErrorDocument 403 とか効くのかな?
  • docomoのiモーションダウンロード時の挙動
    • Rangeヘッダによる分割アクセス時
    • 403になった場合の端末挙動
  • auのobjectダウンロード時の挙動
    • Rangeヘッダによる分割アクセス時
    • 403になった場合の端末挙動
  • auのダウンロードCGIの挙動
  • SoftBank
    • 公式サイトのほげほげしたダウンロードの場合の挙動


ほかに何かあるかなぁ?

ついでに

Expires: 有効期限 UNIX エポックからの秒数

Unixタイムスタンプのことを、UNIX エポックと呼ぶのを始めて知った

The Unix epoch is the time 00:00:00 UTC on January 1, 1970.

http://en.wikipedia.org/wiki/Unix_time

Ubuntu&Emobile(D12LC)で始める朝もくもく

最近、一部で朝もくもくというのが流行っています(流行っているように見えます)。


もくもく(もくもく会)とは。

もくもく会とは喫茶店やカフェなどに集まって各自もくもくと勉強したり仕事したりする会です。家ではどうも仕事や勉強に集中できない、さぼってしまいがち…というフリーランスの人や学生の人におすすめです。

http://moku2.g.hatena.ne.jp/

とはいえ、こちらに参加しているわけではないのですが。。


さらに、朝もくもくとは、朝早起きして、出勤前にカフェなどでもくもくしようというものなのです。
早起きに定評のあるm-takagiさんや、lllnorikolllさんが行ってたりします。
前々から作業する時間を確保するのに、早起きをしたいと思っていましたが、なかなかできなかったのですが、出来ない原因の外堀を埋めれば出きるのではないかと思ったりしました。

  • 持ち運ぶノートPCが無い
    • MacBookはあるが、重すぎて持ち運ぶ気にならないし
  • カフェに入る習慣が無い
    • コーヒー飲まないし、周りに知らない人がいる状態で集中できないし
  • 早起きできない
    • 帰るのも寝るのも遅いし

そんな時に

IRCチャンネルに張られた id:yandodさんのエントリを見て、これだ!と思ったのでした。

この試みを始めるにあたって用意したのは下記の4つ。

  • Eee PC s101
  • E-Monster
  • ノイズキャンセリングイヤホン
  • iPod
  • 早朝から開いている会社のそばの喫茶店

EeePCで始める早起きオープンソース生活 - yandodの日記

とりあえず、見た瞬間にノイズキャンセリングイヤホンをぽちりました。
iPodは、会社の先輩からもらった、shuffleがありますし、最悪PCから音を出してもいい。EMobileは、勉強会参加時に使えるようにとすでに持ってます。
会社の近くの喫茶店。喫茶店は会社の始業時間がそれほど早くないし、渋谷なのでいろいろありそうです。


残るはPC。

EeePCをぽちりたいところでしたが、そこはぐっとこらえて、まずは、家に帰って、最近使っていなかったLenovoのマシンを体重計にのっけてみました。約1.5kg。なんか、いけそうです。
ただ、WindowsXP上で作業するには、VMWareなどで、Linuxの環境が必要になり、マシンパワー的にかなり厳しいので(こいつを持ち運び用にしなくなった理由)、Linux系のOSを入れて持ち運び用にすることにしました。

入れるOSは、Linuxの最近のディストリビューションに詳しくないし、仕事やプライベートでもLinuxCUI Onlyでしか入れたことがなかったので、何人かに聞いてみたところ、ほぼ全員がUbuntuという答えが帰ってきたので、入れるOSは Ubuntuにしました。

Ubuntuのインストール

まずは、何も考えずに UbuntuのインストールCDをMacで作成。MacOSXには、ディスクユーティリティというものがあり、思ったよりも簡単にisoファイルからCDを作れました。で、さぁインストールという時点で、ノートPCにCDドライブがないことに気づきましたw


外付けのCDドライブを探したが、どうやら実家にあるらしく、手元にありません。


次に、ネットワークインストールの方法を探したが、なんかいろいろ必要そうで、面倒くさいので却下。
外付けの空のHDDがあったのでそいつを使おうかと思ったのだが、おでかけ帰りに新宿のヨドバシに行ったら、USBメモリが思ったよりも安かったので 8Gのを買ってきて、インストールディスクにすることにしました。


参考にしたのは、こちらのサイト


syslinuxというのがわからなく、そんなコマンドねーよとか思っていたのだが、落としてくればいいだけでした。
Macからのコマンドがわからなかったのだが、とりあえずMac上のVMWareに入れていたWindowsXPからコマンドを実行しました。


実際のインストールでは、インストール後になぜかディレクトリビューアが起動しないとか謎な現象が発生しましたが、再度インストールしなおすことで解決しました。

次にEMobile

かなり苦戦しました。


最初にぐぐっていた情報では、USBに指してから起動すればOKというものだったのですが、どうやら、D12LCは、それだけではダメなようです。
D12LCは、USBメモリとしての機能と、USBモデムの機能の2つがあり、普通に挿しただけでは、USBメモリとして認識されるため、切り替えが必要みたいでした。


最終的には、こちらのすばらしいエントリを参考にさせていただきました。このエントリにたどり着くまでの試行錯誤で数時間が。。。
UbuntuでEmobileのD21LCを利用する | Blog.37to.net


作業手順

  1. libusbをインストール
  2. usb_modeswitchをダウンロードして、コンパイル&インストール
  3. D12LC用の設定を追加してusb_modeswitchを実行
  4. GNOME pppをインストール
  5. GNOME pppを起動して設定
1.libusb

usb_modeswitchを入れるために必要なライブラリで、libusb-develが必要です

sudo apt-get install libusb-dev libusb-0.1-4
2.usb_modeswitch

以下から落としてきてインストール
Draisberghof - Software - USB_ModeSwitch

gcc -l usb -o usb_modeswitch usb_modeswitch.c
make install
3.D12LC用の設定

以下の設定を追記

#######################################################
# Emobile D12LC
#

DefaultVendor= 0x1c9e
DefaultProduct= 0x9101

TargetVendor= 0x1c9e
TargetProduct= 0x9104

MessageEndpoint=0x01
MessageContent="55534243123456788000000080000606f50402527000000000000000000000"

Ubuntu日本語フォーラム / EMOBILE D12LCでネット接続するには?


usb_modeswitchの実行

sudo modprobe usbserial vendor=0x1c9e product=0x9404
sudo usb_modeswitch

最初参考にしていた、こちらのサイトでは、sudoをつけていない例が載っていて、一般ユーザ権限で実行してしまっていてはまりました。
ページが見つかりません:@nifty

4.GNOME pppインストール

こちらは、apt-getで入れてしまいます。

sudo apt-get install gnome-ppp
5.GNOME ppp起動

root権限で動かさなければならないというのがわからずに、またまたはまりました。(実行権限等を見直せば解決するのかもですが。。)
なので、プロンプトから以下のコマンドで実行しています。

sudo gnome-ppp


とりあえず、これで接続出来るようになりましたが、実はここでもはまりまくったことがありました。
Firefoxのブラウザリロードなどで、つながっているかを見てしまっていたのですが、なぜか、オフライン作業モードになってしまっていて、何回リロードしてもFirefoxがネットに接続していると認識してくれませんでした。
しかも、設定を変更して開き直してもオフラインモードに戻ってしまっています。


Emobileを後から挿した場合には、以下のコマンドを実行することで、USBモデムとして正しく認識されました。

sudo usb_modeswitch

今後

とりあえず、ネット環境が整ったので、朝もくもく出来るようになりました。


まだまだ設定変更したい箇所がいくつかあって、少しずついじっていこうと思います。

  • EMobileを挿した後のコマンドをワンクリックにしたい
  • もうちょっと時間がもつように何か対策をする
    • 電源確保等 今日どのくらい電源が持ったか見てみたら1時間半だった
  • Lenovo X60で、センターボタン+トラックポインタでスクロール出来るように
  • 左Alt+Spaceで半角/全角の切り替えをしたい
  • EMobile範囲外のためにdocomoの携帯でネット接続出来るようにしたい

ぐらいでしょうか。とりあえずblog書いて、ローカルでいろいろいじくるぐらいであれば支障なさそうです。


今回は渋谷のPRONTOに入ってみたのですが、周りの音がけっこう気になります。今日届くであろうノイズキャンセリングイヤホンに期待で、明日も早起き出来るように早めに寝ようと思います。

「Re:デザイナーとの協業での工夫 Smartyプリフィルタの活用法」実際に行なってみたソースなど その1

昨年の11月のエントリで、デザイナーとの協業での工夫というエントリを書きました。
デザイナーとの協業での工夫 Smartyプリフィルタの活用法 - maru.cc@はてな
この案件が実際にリリースを向かえ、一通りの作業がひと段落がついたので、感想と今後行なっていこうと思っていることをまとめてみます。


また、実際に行なった仕組みのソースを公開したいと思いましたが、案件のソースは公開できません(あたりまですが)。
そこで、他のサイトを実際に作成しながら、許せる範囲で使ったものか、同等の機能を別途実装して公開したと思います。


どんなサイトにしようか迷ったのですが、長らく放置してしまっていた Ethna-users.jp がちょうどありましたので、そちらを題材に実装しようと思います。
github で公開中なので、ぜひ参考にしてください。もちろん forkしてコードにつっこみも大歓迎です。
http://github.com/marucc/ethna-users.jp/

仕組みとして作ったもの

こちらを、何回かにわけて実際の実装方法をソースをまじえて説明をしたいと思います。

  • 1. .htmlファイルをエントリポイントにする
  • 2. Smartyのデリミタを変える
  • 3. Smartyのデリミタの種類増やす
  • 4. http<->https絶対パスで書かなくても動くようにする
  • 5. 部品のincludeを出来るようにする

1. .htmlファイルをエントリポイントにする

これは、かなり成功しました。

実は、モバイルサイトを作る場合などで実績のある仕組みなので、予想通りという感じです。サイトを作るデザイナーさんには、PHPプログラムで動くということをまったく意識せずに、aタグやimgタグの画像などに関しても、通常のhtml同士のリンクと同様に相対パスで記述できるため、マージ時に作業が発生しません。

これが、例えば、PathInfoなどを使う形式や、テンプレートファイルが .tpl などの場合に、実際に作成しているものと設置時で差異が出てしまうため、余計な手間が発生します。
テンプレートファイルを .htmlに無理やりしたとしても、画像やCSSと、テンプレートファイルを別の場所にアップする必要が出てきてしまうため、やはり余計な手間や判断が必要になってきてしまいます。


また、ほぼ静的だが、一部だけ、DBから取得したデータなどを動的に表示させたい場合に、actionは必要ないが、phpの処理が書きたいという場合にも対応をしました。

まずは、.htaccessの設定

http://github.com/marucc/ethna-users.jp/blob/e210e107e0b3a880d2aea5b33339b1b9cc8da37c/www/.htaccess
以下の部分が肝心の箇所です。

AddType application/x-httpd-php .html
AddType application/x-httpd-php .htm
 
<FilesMatch "\.html?">
php_value auto_prepend_file "./_page.php"
AcceptPathInfo Off
</FilesMatch>

auto_prepend_file という設定はご存知でしょうか?
PHP: コア php.ini ディレクティブに関する説明 - Manual: auto_prepend_file


PHP勉強会の懇親会などで話していて感じたたことですが、この auto_prepend_file の設定ですが、相対パスで書けるというのは意外に知られていないようです。
もちろん、相対パスで書いた弊害として、下層ディレクトリで動かなくなってしまうので、階層が違う場合にはいずれかの対応が必要になります。

  • a.auto_prepend_file をフルパスで書く<今回はこれを採用しました
  • b.全ての下層ディレクトリに _page.php を作る
  • c.全ての下層ディレクトリに .htaccess を作り、auto_prepend_fileの相対パスを調整する

ま、常識的に考えて、フルパスでしょう。
なぜ、このような相対パスの形式の書き方をしているかというと、やはり、開発時のサーバ、ステージングサーバ、本番サーバと順に反映していく上で、フルパスが書かれてしまっているというのは、環境依存になりリリース作業の弊害になります。
.htaccessには、別の設定も記述することになるので、反映ファイルから除外しておくと、本番環境での設定漏れ等が発生してしまう可能性があります。


特に、モバイルサイトでIP制限をしている場合、.htaccessで行なうことが多いのですが、そのIP帯域追加時などに問題になったりします。
それよりは、ファイル数が少ないのであれば、全てフラットにし、多くなるとしてもディレクトリの分け方を少なくし、b,cのどちらかの対策を取る方が得策な場合もあるでしょう。

次に、auto_prepend_file で呼ばれる _page.php

http://github.com/marucc/ethna-users.jp/blob/e210e107e0b3a880d2aea5b33339b1b9cc8da37c/www/_page.php

<?php
require_once dirname(__FILE__) . '/../app/Ether_Controller.php';
 
Ether_Controller::main('Ether_Controller', array('page'), 'notfound');
exit;
?>

Ethna特有になってしまいますが、Ether_Controller::main の第二引数を array指定にし、pageアクションのみが動くようにしているところも注意すべき点です。また、exit; も必須になります。
Ethna エントリポイント毎に実行可能なアクションを制限する


もちろん、他のフレームワークを使用している場合には、そのフレームワークを呼ぶエントリポイントになればいいかと思います。


viewを判断する actionの処理

呼ばれる htmlごとに特殊な処理をしないのであれば、こちらは必要ありません。
例えば、トップページのみ最新のニュースの一覧を表示したい、といったページを作るのに、使えるかと思います。
もちろん、ニュースの一覧表示ぐらいだったら、Smartyのカスタムプラグインとして実装するのもありですけどね。ひとつの方法として参考にしてみてください。

http://github.com/marucc/ethna-users.jp/blob/e210e107e0b3a880d2aea5b33339b1b9cc8da37c/app/action/Page.php

<?php //色づけ

    /**
     * page action implementation.
     *
     * @access public
     * @return string forward name.
     */
    function perform()
    {
        $base_view_name = 'page';
 
        $action = preg_replace('!^' . $this->backend->ctl->getDirectory('www') . '/(.+)\.html?$!i', '\1', $_SERVER['SCRIPT_FILENAME']);
        $action = preg_replace('![^a-z0-9/]!', '', $action);
        $action = str_replace(array('/'),array('_'),$action);
        $view_name = "{$base_view_name}_{$action}";
        $view_dir = $this->backend->ctl->getViewdir();
        $view_path = $this->backend->ctl->getDefaultViewPath($view_name, false);
        if (file_exists("$view_dir$view_path")) {
            return $view_name;
        }
        return $base_view_name;
    }

コードを解説すると

  1. $_SERVER['SCRIPT_FILENAME'] からアクセスされたページを判別し、$this->backend->ctl->getDirectory('www') の部分のパスを取り除くことで、ファイルへのパスを判別します
  2. 英数字とスラッシュ以外は取り除きます これは、サイトのファイル命名規則によっては、かぶってしまい問題がでるかもしれません
  3. スラッシュを Ethnaのディレクトリ区切りのアンダーバーに置換します
  4. アクセスされたファイル専用のViewファイルが存在するか判別します もしあれば、その Viewを使用します
  5. 専用のViewが無い場合には、共通のpage Viewを使用します
共通の page View

実際に、アクセスされたファイルをテンプレートとしてどのように使っているかですが、以下のような指定の仕方をしています。
http://github.com/marucc/ethna-users.jp/blob/e210e107e0b3a880d2aea5b33339b1b9cc8da37c/app/view/Page.php

<?php //色づけ
    /**
     * 遷移名に対応する画面を出力する
     *
     * 特殊な画面を表示する場合を除いて特にオーバーライドする必要は無い
     * (preforward()のみオーバーライドすれば良い)
     *
     * @access public
     */
    function forward()
    {
        $this->forward_path = $_SERVER['SCRIPT_FILENAME'];
 
        parent::forward();
    }

forward() メソッドは、通常継承して上書きする必要はありませんが、今回は、テンプレートの forward_pathを変更するために使用します。
Ethnaでは、Viewクラスのforward_pathプロパティに入っているファイル名が、そのままSmartyに渡されるため、こちらを変更することで無理やりですがテンプレートを変更することが出来ます。
また、フルパスで指定することにより、templateディレクトリ以外のファイルを使うことも出来ます。

特定のページ用のView

特定のページ用のViewは、app/view/Page/ 以下に作成します。
例として、もし、/sample/index.html用の Viewを作成したければ、次のように作成することが出来ます。

ethna add-view page_sample_index


これらのpage以下に作成した Viewは、元となる page Viewクラスを継承する必要があります。
ページ先頭で page Viewを require_once して読み込みます。この場合に、BASEからのパスを記述している理由は、下階層のviewを作成しても、全て同一の記述をするためにこのような書き方をしています。

<?php //色づけ
require_once BASE . '/app/view/Page.php';

次に、classの継承をします。

<?php //色づけ
/**
* page_index view implementation.
*
* @author {$author}
* @access public
* @package Ether
*/
class Ether_View_PageIndex extends Ether_View_Page
{
()
}


今回は、直下の index.html なので、page_index がView名になります。
http://github.com/marucc/ethna-users.jp/blob/e210e107e0b3a880d2aea5b33339b1b9cc8da37c/app/view/Page/Index.php

<?php //色づけ
    /**
     * preprocess before forwarding.
     *
     * @access public
     */
    function preforward()
    {
        // 処理いろいろ
    }

あとは、Ethnaの通常の流儀なので、View の preforwardメソッドには自由に処理を記述し、テンプレートとなる htmlファイルに、「ここだけはいじらないでね(はーと)」とデザイナーさんと意識あわせをして タグを書いてしまえばOKです。


もし、このpage以下全ての Viewクラスで特定の処理を行ないたい場合には、page Viewクラスの setDefaultメソッドを使用するといいでしょう。
Ethna 遷移時のデフォルトマクロを指定する。


とりあえず

この Ethna-users.jp程度ならば、ここまでの仕組みはまったく必要ないと思います。ただ、座組みやファイルを触る人が分かれる場合には、有用な場合もあるのではないでしょうか?


続きは、また書きます。

LLカンファレンス&PHPカンファレンスの実行委員やります

昨年、koyhogeさんにお誘いいただいて、LL Futureの当日スタッフをしたのですが、今年はもっと前から関われたらと思い、昨日のLLカンファレンス2009(名称未決定)の準備委員会(?)のMTGに参加してきました。
404 Not Found
LL Futureのお手伝いすることになりました - maru.cc@はてな
LL Futureにスタッフとして参加してきました - maru.cc@はてな

今年のLLカンファレンスは、また面白くなりそうです。コンセプト・企画についての話をいろいろして(ってか聞いて)きました。
どう形にしていくのか、という部分はありますが、その課程も含めて勉強になるだろうし楽しくなりそうです。

すでに、2009年の開催日が決定しています。予定を押さえておくといいと思います!


あと、PHPカンファレンス
2008年は何も出来なかったのですが、2009年は実行委員として、第一回のMTGに先日参加してきました。
こちらも、水面下で動き出しつつあります。今回は、php-users MLでもスタッフ募集をしようという話も出ていますので、参加するだけではなく中から関わってみるのも面白いと思います。
場所、日時ともにまだ未定ですが、追々情報が出てくると思うので楽しみにしていてください。


PHPカンファレンスには、思い入れがあったりもします。2007年のPHPカンファレンスに、同僚に誘われて参加したのが、最近のこのblogや勉強会、オープンソースへの参加などのきっかけになったのでした。
その頃、社内のことや自分の勉強にしか目がいっておらず、外をまったく見ていませんでした。
PHPカンファレンスで、何百人の前でおもしろい深い話をしている発表者の人たちを見て、自分も話す側になりたい と思ったのが、勉強会で発表するきっかけになりました。
また、その頃社内のフレームワークとしてEthnaを使用していて、それなりに使い込んでいる方だと思ったりしていました(いま考えればまだまだですが)。GREEの藤本さんの発表で「Ethnaにも新しいコミッターを迎え… 会場に来てると思いますよ mumumuさんが」みたいなことをおっしゃっていて、コミッターか〜、いま出来ていることをそうやってフィードバックしたいなぁ とも思うようになりました。


ついでなので、今年もやもやとやりたいと思っていること

  • 自転車レースのJCRCで表彰台に乗りたい(いきなりで、上記とまったく無関係ですがw)
  • LLカンファレンス、PHPカンファレンスPHP勉強会、PHPユーザ会 etc.. などに中から関わる
  • 他のフレームワーク、他の言語、もっと深いレイヤーなどいろいろ手を出したい
  • いま使っているライブラリをオープンソースにしたい(openpearとかcodereposとかgithubとか)
  • なんかサービスを作る(構想はあったりします。形にしたい)

SJISファイルをutf8に変換するコマンド

とあるメッセージにレスをするために、コマンドを書いてみて、それをさすがにテストせずに発言するのには無責任すぎると思い、手元のMacでテストしてから発言しようと思った。


まずは、find関数。
普段、よく使うが、いざMac上で動かしてみたら動かない。

$ find ./ -name *.php
find: hoge.php: unknown option


あー、評価式は文字列か。ということで。

$ find ./ -name '*.php'
.//fuga.php
.//hoge.php

なんか変だ。


CentOS上で実行すると

$ find ./ -name '*.php'
./hoge.php
./fuga.php


そこで、./ ではなく、 . のみにすれば、うまくいくことがわかった。CentOSだけ使っていたら気にしなかった。

$ find . -name '*.php'
./fuga.php
./hoge.php

つぎに、nkf
案の定、Mac上には入っていなかった。
以前、MacPortsを入れていたので、yum感覚で、portsで入れてみた。

$ sudo port list | grep nkf
p5-nkf                         @2.08           perl/p5-nkf
nkf                            @2.0.8b         textproc/nkf
$ sudo port install nkf
--->  Fetching nkf
--->  Attempting to fetch nkf-2.0.8b.tar.gz from http://keihanna.dl.sourceforge.jp/nkf/26243/
--->  Verifying checksum(s) for nkf
--->  Extracting nkf
--->  Configuring nkf
--->  Building nkf
--->  Staging nkf into destroot
--->  Installing nkf 2.0.8b_0
--->  Activating nkf 2.0.8b_0
--->  Cleaning nkf
$ which nkf
/opt/local/bin/nkf


で、肝心のコマンドを、テストファイルを作って実行してみる。
vimで、SJISのファイルを作る場合には、空ファイルを作成後に、 :++enc=sjis コマンドを使い、その後に日本語を入力すれば、作ることが出来る。


後は、テストを実行してみる。

$ find . -name '*.php' | xargs nkf -Sw --overwrite


後処理としては、nkfにかけただけだと、ファイルの更新時間が変更されない。
svnなどでバージョン管理している場合には、touch を実行してあげる必要がある。
参考:変更したのに svn status に出てこない場合の対処 - maru.cc@はてな


まぁ、結局はネタでレスしようと思っただけなんですけどね。

Shift_JISでかかれたソースコードをどうしてくれようか考え中。
by 個々一番 at 2009-02-03(Tue) 00:15:55

http://wassr.jp/user/cocoiti/statuses/5d2LlFzWGS

つ find . -name '*.php' | xargs nkf -Sw --overwrite
by marucc at 2009-02-03 00:35:12

http://wassr.jp/user/marucc/statuses/6qv8WUfPIE


さて、寝よ。

追記

ELFさんのレスもあった

find -name \*.php | xargs php -r '$argv = $_SERVER['argv']; array_pop($argv); foreach($argv as $name) { var_dump($name); file_put_contents($name, mb_convert_encoding(file_get_contents($name), "UTF-8", "SJIS-WIN"));}'
by Tadashi "ELF" Jokagi at 2009-02-03(Tue) 00:41:55

http://wassr.jp/user/elf2000/statuses/w1OoZoUZ3v


CentOSで実行すると

$ find -name \*.php | xargs php -r '$argv = $_SERVER['argv']; array_pop($argv); foreach($argv as $name) { var_dump($name); file_put_contents($name, mb_convert_encoding(file_get_contents($name), "UTF-8", "SJIS-WIN"));}'
string(1) "-"
string(10) "./hoge.php"


Mac上で動かすと

$ find -name \*.php | xargs php -r '$argv = $_SERVER['argv']; array_pop($argv); foreach($argv as $name) { var_dump($name); file_put_contents($name, mb_convert_encoding(file_get_contents($name), "UTF-8", "SJIS-WIN"));}'
find: illegal option -- n
find: illegal option -- a
find: illegal option -- m
find: illegal option -- e
find: *.php: No such file or directory


んー おもしろい

第39回PHP勉強会@関東に参加してきました

2009年第一回目のPHP勉強会い参加してきました。
第39回PHP勉強会@関東 - events.php.gr.jp

今年の1月から半年すぱんぐらいで、勉強会番長的な持ち回りをしたらどうかという話がでていて、gusagiさんが名乗りをあげてくださり、今回から勉強会主催&懇親会の幹事までやってくれました。
あと、場所を提供してくださった、株式会社ディノさん、会場提供ありがとうございました。


まずは恒例の自己紹介タイム
やっぱ、CakePHPSynfonysymfonyを使っている人が多いなぁという感じ。(追記2009-02-03:はずかしい。。>それは気が早い - よくきたはてダ)


以下、発表で個人的に面白かった・興味のある話

CakePHP1.2最新情報

発表者:id:yandodさん

  • Pagination
    • コード書かなくてもページング出来る。内部でどんな方式か気になる。やっぱりクエリをいっぱい投げるのだろうか?
  • AuthComponent
    • 認証処理 出てすぐにバグがあったけど
  • I18n
  • Behavor
    • ビギナーがすぐに使うような物ではないが便利
    • DBにレコードを登録したらその後に必ず行う処理などが出来る
  • Set
    • blogにSetちょー便利って記事がいろいろあがるだろうとのこと
    • 誰かエントリ書いてくださいとのこと
  • Downloads -> Debugkit.zip
    • pluginの下に置いて、app_controllerに設定値を1行書くだけ
    • debugkit自体ではなくて、そこまで内部に関われるのが未来を感じる


今後のバージョン
1.3 (PHP4-PHP5) 2.0 (PHP5)
いつPHP4を捨てるのか気になる。ちょっと追っかけてないけど、2.0っていつごろ出るのかなー?


http://thechaw.com/
CAkePHPで作られたTracライクなサービス
githubのようなforkしてどうこうというのが出来るというものらしいです。

この考え方の説明の図がとてもわかりやすく、gitってよくわからないなーと思っていたのがすっと理解できたと思います。
github thechawの開発方式

管理者(メインのコミッタ?)は、forkしたものからマージ等をしてどうこうできるという感じだそうだが、マージって大変だよなぁとか思ったりしなくもない。


日本PostgreSQLユーザ会との共同で 福岡でCakePHPの勉強会(カンファレンス?)があるそうです。
2009-03-13 18:30-21:30
あすみん(福岡市中央区大名)
(間違えているかもしれないので情報は調べてみてね)


余談
スライドの最終ページのキャラは忍者タウンでぐぐるとわかるらしいw
http://www.ninjatown.com/

symfony 1.2 を支えるサブフレームワーク

発表者:id:Fivestar

  • Form Framework
    • symfony1.1から追加されたもの
    • CSRFとかやってくれる
  • アクションが簡潔になる
    • handleErrorとお別れ
    • Formクラスにひとつにまとまるので見やすくなる
  • Filter Framework
    • 検索用のsfForm
  • RESTfulなルーティング
    • Methodによってアクションをわけられる
    • これは面白いかもしれない
  • sfRoute
  • sfRequetRoute
  • sfObjectRoute


などなど。。
正直そんなにsymfonyのことを知らないので、へ〜とか、そうなんだぁという感じだったりしました。。


ただ、symfonyに実装されている面白い考え方は勉強していきたい。

SENSIO(SYMFONY)訪問レポート

発表者:akkyさん

発表スタート時にすでに発表資料がWebに公開されているというのはすばらしいと思いました。
Ust越しでもきれいなものが見ながら話が聞ける。
ネタとかはばれちゃうけどね。

話が興味深くてメモはとくにとって無いので、記憶に残っていること。

  • フランスでは、symfonyZend Framework が2大派閥らしい
    • 大規模な企業系のシステムは symfony 、お金がない(?)規模が小さな案件は ZFとゆるやかな区分けがあるとのこと
  • symfonyオープンソースにしたまでの話
  • 日本で2冊の symfony本が出てるのは世界的に見ても多いらしい
    • 買おうとしたけど、amazonからのメールが日本語で意味がわからず断念したらしいw
  • 世界中からメール等がくるが、日本と中国からはさっぱりらしい
    • どんどんメールとか連絡とかして日本でも使っているというのをコンタクトしてほしい、日本語でもgoogle翻訳とかするからいいよ とは言っていたらしいが、正直つらいと思う。。

懇親会

近くの焼肉屋っぽいお店で、焼肉以外のコース料理でおいしかった。

感想

ちょうど、PHP勉強会直前に Ethna 2.5.0 Preview3 が出たこともあり、今後Ethnaがどうなっていくのかなぁと思っているところでの参加で、やっぱ、symfonyCakePHPもコミュニティや使っている人の層がすごいなぁと感じた。