ルギア君の戯言

雑多な記事。

Wii に Twitter のボットをやらせる - その2

その1 にある注意事項をお読みください。

Wii Linux の準備

ルギア君「Wii 用の Linuxディストリビューションとしては Debian GNU/Linux (Whiite) と Arch Linux (Archii) がある。Arch Linux のほうが導入がやさし…そう…だから、そっちを入れることにするよ。」
キリルン「自分でビルドしてもいいの?」
ルギア君「ああ、不可能ではないが、相当面倒臭いぞ。」
キリルン「そうですね。」
ルギア君「話を戻すぞ。Archii の場合、基本的には」

https://wiki.archlinux.org/index.php/Wii_Tutorial

ルギア君「に書いてあることをそっくりそのままやればいいだけだ。」
キリルン「ふむふむ。」
ルギア君「まず、SDカードの下ごしらえからだ。この作業は USB メモリや USB ハードディスクに Linux を入れる場合には不要だ。逆に USB メモリや USB ハードディスクにインストールしたければカーネルを書き換えなくちゃいけないんだ。バイナリ編集が苦手なら、SD カードにインストールするしかないね。ほかにも NFS を使ったりするという選択肢もあるけど、これは他にもマシンを立ち上げておくことになるから今回の目的である Wii を使ったエコボットを作るという目的に対しては本末転倒になっちゃうね。」
キリルン「なるほど。」
ルギア君「まず、SDカードのパーティションを分ける。SDカードのパーティションを分けたものは Wii や Windows 機でフォーマットしないでね。(多分だけど) パーティションの設定が消えちゃうと思う。」
キリルン「なんで?」
ルギア君「SDカードはもともと FAT16 (SDHC は FAT32、SDXC は exFAT) 1 パーティションで使わなければいけない、って決まっているからね。ちなみに SDHC は使えるかもしれないけど、SDXC はほとんどダメだろうね (これも試したわけじゃないんだけどさ)。」
キリルン「はぁ。」
ルギア君「それじゃあ、始めよう。Linux マシンを使ってこうやってパーティションを分ける。CUI が苦手な人は gparted というソフトを使ってもできる。」

# fdisk -l /dev/sdf

Disk /dev/sdf: 4098 MB, 4098883584 bytes
128 heads, 63 sectors/track, 992 cylinders, total 8005632 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

   Device Boot      Start         End      Blocks   Id  System
/dev/sdf1   *         190     7999487     3999649    c  W95 FAT32 (LBA)

ルギア君「SD カードがどのデバイスファイルかは十分に注意してね。ここでは、/dev/sdf が SD カードだとするよ。」
キリルン「ふむふむ。」
ルギア君「まずは、中に入っているデータをどこかにバックアップしておいて。」
キリルン「そうね。」

# mount /dev/sdf1 /mnt -t vfat
# cp -rv /mnt /tmp                   # /tmp/mnt へバックアップ
# umount /mnt

ルギア君「それじゃ、作業を始めよう。まずは、パーティションテーブルの作成。」

# fdisk /dev/sdf
Command (m for help): o
Building a new DOS disklabel. Changes will remain in memory only,
until you decide to write them. After that, of course, the previous
content won't be recoverable.

ルギア君「次に、1つ目のパーティションを作る。これはあとで FAT でフォーマットする。ここでは容量が 256MB としておく。 のところは、Enter を押すだけね。」

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-990, default 1): <RETURN>
Using default value 1
Last cylinder or +size or +sizeM or +sizeK (1-990, default 990): +256M

Command (m for help): t
Selected partition 1
Hex code (type L to list codes): 6
Changed system type of partition 1 to 6 (FAT16)

ルギア君「もし FAT32 にしたければ、Hex code のところで L と叩いて FAT32 のコードを確認してね。」
キリルン「exFAT は?」
ルギア君「exFAT は今のところ Linux では対応していないから exFAT のフォーマットはできないよ。」
キリルン「なるほど。」
ルギア君「次に、2つ目のパーティションを作る。これをあとで ext2 で作る。ここでは容量 1.6GB としてある。」

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 2
First cylinder (136-990, default 136): <RETURN>
Using default value 136
Last cylinder or +size or +sizeM or +sizeK (126-990, default 990): +1600M

ルギア君「できたら、その設定を書き込む。」

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.

Syncing disks.

ルギア君「そしたら、フォーマットする。」

# mkfs.vfat /dev/sdf1 -n boot
# mkfs.ext2 /dev/sdf2 -L Archii

ルギア君「そしたら、最初に bootmii をインストールしたときに入っていた SD カードの bootmii 以下のディレクトリをコピーする。」

# mkdir -p /mnt/sdf1
# mount /dev/sdf1 /mnt/sdf1
# cp -rv /tmp/mnt/bootmii /mnt/sdf1

ルギア君「次に、Linux カーネルを取ってくる。自分のテレビの仕様を間違えないように。日本の場合は、NTSC/60Hz で、コンポジット接続の場合はインターレース 480i で、コンポーネント接続・D端子接続の場合は、プログレッシブ 480p を選ぶ。」

# cd /mnt/sdf1
# wget 'http://downloads.sourceforge.net/gc-linux/mikep5-zImage-2.6.32.mini.480i(NTSC).elf'    # NTSC インターレース
# wget 'http://downloads.sourceforge.net/gc-linux/mikep5-zImage-2.6.32.mini.480p(NTSC).elf'    # NTSC プログレッシブ

ルギア君「ダウンロードしたファイルは短い名前にリネームしておこう。」

# mv mikep5-zImage-2.6.32.mini.480i\(NTSC\).elf mikep5-480i.elf
# mv mikep5-zImage-2.6.32.mini.480p\(NTSC\).elf mikep5-480p.elf

ルギア君「その他のカーネルはここから。」

http://www.gc-linux.org/wiki/MINI:KernelPreviewFive

ルギア君「ちなみに ここ に Arch Linux のプロジェクトの方で少しカスタマイズされたカーネルがおいてあるけど、これは NTSC の 480i 専用みたい。」
キリルン「ふむふむ。」
ルギア君「同じところから archii.tar.xz をダウンロードしてくる。そして、ext2 の領域に展開する。このとき、」

# mkdir -p /mnt/sdf2
# mount /dev/sdf2 /mnt/sdf2 -t ext2
# cd /mnt/sdf2
# tar Jxvf /path/to/where/you/download/archii.tar.xz --exclude=./swapfile

ルギア君「のように、あとで簡単に作れる swapfile は除いてください*1。SD カードの読み書きが遅くなければいいんだけどね。ちなみに、tar の J オプションがダメって言われたときは、」

# xz -dc /path/to/where/you/download/archii.tar.xz | tar xvf - --exclude=./swapfile

ルギア君「てやれば OK だよ。」
キリルン「なるほど。」
ルギア君「そしたら swap をつくろう。まあ、必須ではないが、メモリが足りなくなるのは目に見えているので、な。」

# dd if=/dev/zero of=swapfile bs=4M count=16
# mkswap -L archii.swap swapfile
# chmod 600 swapfile

ルギア君「サイズは bs × count な。この場合は 64M。最適値は本体のメモリと同じ量で、72M …かな。できたら、次は設定の変更だ。」
キリルン「おー、大変ですね。」
ルギア君「うむ。」

# vim etc/fstab                 # 頭に / はないよ! あと、エディタはお好きなものをどうぞ。
#
# /etc/fstab: static file system information
#
# <file system>        <dir>         <type>    <options>          <dump> <pass>
none                   /dev/pts      devpts    defaults            0      0
none                   /dev/shm      tmpfs     defaults            0      0

/dev/mmcblk0p2         /           auto    rw,defaults,noatime     0      1
/dev/mmcblk0p1         /boot       auto    rw,defaults,noatime     0      0
/swapfile              swap        swap    defaults                0      0    # この行を追加

/dev/cdrom             /media/cd   auto    ro,user,noauto,unhide   0      0
/dev/dvd               /media/dvd  auto    ro,user,noauto,unhide   0      0
/dev/fd0               /media/fl   auto    user,noauto             0      0

ルギア君「もうひとつ。まずは基本的な設定から。」

# vim etc/rc.conf
#
# /etc/rc.conf - Main Configuration for Arch Linux
#

# -----------------------------------------------------------------------
# LOCALIZATION
# -----------------------------------------------------------------------
#
# LOCALE: available languages can be listed with the 'locale -a' command
# HARDWARECLOCK: set to "UTC" or "localtime"
# USEDIRECTISA: use direct I/O requests instead of /dev/rtc for hwclock
# TIMEZONE: timezones are found in /usr/share/zoneinfo
# KEYMAP: keymaps are found in /usr/share/kbd/keymaps
# CONSOLEFONT: found in /usr/share/kbd/consolefonts (only needed for non-US)
# CONSOLEMAP: found in /usr/share/kbd/consoletrans
# USECOLOR: use ANSI color sequences in startup messages
#
LOCALE="en_US.utf8"            # 端末は日本語が表示できないので英語のままにしておきます
HARDWARECLOCK="localtime"      # Wii は日本時間で設定していると思うので、localtime に変えます
USEDIRECTISA="no"
TIMEZONE="Asia/Tokyo"          # 日本時間。Asia/Tokyo または Japan。他は上に書いてある場所を参照
KEYMAP="jp106"                 # 直接挿して使うキーボードの配列。英語の場合は us。他は上に書いてある場所を参照
CONSOLEFONT=
CONSOLEMAP=
USECOLOR="yes"

ルギア君「更に下の方を見ていく。ここは変更する必要はなし。」

# -----------------------------------------------------------------------
# HARDWARE
# -----------------------------------------------------------------------
#
# MOD_AUTOLOAD: Allow autoloading of modules at boot and when needed
# MOD_BLACKLIST: Prevent udev from loading these modules
# MODULES: Modules to load at boot-up. Prefix with a ! to blacklist.
#
# NOTE: Use of 'MOD_BLACKLIST' is deprecated. Please use ! in the MODULES array.
#
MOD_AUTOLOAD="yes"
#MOD_BLACKLIST=() #deprecated
MODULES=()

# Scan for LVM volume groups at startup, required if you use LVM
USELVM="no"

ルギア君「更に下を見ると、ネットの設定がある。比較的新しい Arch Linux では netcfg というものを使うことになっていて、有線、無線にかかわらず、これを使う。ちなみに無線の場合は古い設定では (多分だが) WPA が使えない。とりあえず、ここでは無線を使う場合を考えることにする。さっきも言ったように、古い設定では無線が使えないので、」

# -----------------------------------------------------------------------
# NETWORKING
# -----------------------------------------------------------------------
#
# HOSTNAME: Hostname of machine. Should also be put in /etc/hosts
#
HOSTNAME="Wii"

# Use 'ifconfig -a' or 'ls /sys/class/net/' to see all available interfaces.
#
# Interfaces to start at boot-up (in this order)
# Declare each interface then list in INTERFACES
#   - prefix an entry in INTERFACES with a ! to disable it
#   - no hyphens in your interface names - Bash doesn't like it
#
# DHCP:     Set your interface to "dhcp" (eth0="dhcp")
# Wireless: See network profiles below
#
#eth0="dhcp"           # コメントアウト
INTERFACES=(!wlan0)    # !wlan0 に変える

# Routes to start at boot-up (in this order)
# Declare each route then list in ROUTES
#   - prefix an entry in ROUTES with a ! to disable it
#
gateway="default gw 192.168.0.1"
ROUTES=(!gateway)

# Enable these network profiles at boot-up.  These are only useful
# if you happen to need multiple network configurations (ie, laptop users)
#   - set to 'menu' to present a menu during boot-up (dialog package required)
#   - prefix an entry with a ! to disable it
#
# Network profiles are found in /etc/network.d
#
# This now requires the netcfg package
#
NETWORKS=(ArpaCastle) # コメントアウトを外し、好きな名前に変える

ルギア君「あ、そうそう、IOS 版のカーネル*2 だと Wii 内蔵の無線は使えないから気をつけてね。最後、デーモンの設定をする。」

# -----------------------------------------------------------------------
# DAEMONS
# -----------------------------------------------------------------------
#
# Daemons to start at boot-up (in this order)
#   - prefix a daemon with a ! to disable it
#   - prefix a daemon with a @ to start it up in the background
#
DAEMONS=(syslog-ng net-profiles netfs crond sshd alsa hal bluetooth)
# network の代わりに net-profiles に変える。

ルギア君「そしたら、ネットの詳しい設定をする。etc/network.d に入って、examples の中から使いたいものを選んで、先程 rc.conf で設定した名前でコピーします。」

# cd etc/network.d
# ls examples
complete.example         ethernet.example  ppp.example         wep.example
ethernet-static.example  loopback.example  wep-static.example  wpa.example
# cp examples/wpa.example ArpaCastle
# vim ArpaCastle
CONNECTION="wireless"
INTERFACE=wlan0
SCAN="yes"
SECURITY="wpa"
ESSID="mynetwork"    # ESSID
KEY="SomePasskey"    # WPA key
IP="dhcp"
TIMEOUT=20

ルギア君「ちなみに SturmHome というのがもとから入っていて、おそらくパッケージした人の環境。多分何かのミス。」
キリルンは笑った。
ルギア君「あと、これも作った人のミス (だと思う) で、root のパスワードがどこにも書かれてないのでここで変更する。ちなみに期限切れにする方法はダメだった。ので、/etc/shadow からコピーするなどして凌いでくれ。」

# vim etc/shadow
root:[暗号化されたパスワード]:14437::::::
# (以下略)

ルギア君「ちなみに archie のパスワードは root でログインしたあとで変更してね。」
キリルン「ああ。」
ルギア君「設定はこれで終わりで、起動する。」
キリルン「おお。」

# cd
# umount /mnt/sdf1
# umount /mnt/sdf2
# eject /dev/sdf

起動

ルギア君「電源を入れたらリモコンで Homebrew Channel を選んで起動する。起動したら、リモコンのホームボタンかGCコントローラの START ボタンを押してメニューを表示し、Bootmii を起動する。」
キリルン「ふむふむ。」
ルギア君「ゲームキューブコントローラの矢印キーとAボタンで SD カードのアイコンを選択し、SD カードに入れた mikep5-480i.elf か mikep5-480p.elf を起動すれば Linux が立ち上がってくるはずだ。ちなみに、ゲームキューブのコントローラがない場合は、Wii の電源ボタンとリセットボタンを使うんだよ。」

ボットを作るためのソフトウェアの下ごしらえ

ルギア君「ボットを作るためには、いくつかの方法があるんだけど、ここでは twbot2.rb というフレームワークを使ったボットを作ることにしよう。」

フレームワーク/ライブラリ名 言語
twbot2.rb Ruby
Twitter (Rubygem) Ruby
python-twitter Python
twitteroauth PHP
Net::Twitter Perl
liboauth C/C++
Twitter4J Java

ルギア君「これらの言語では当然こんなフレームワークを使わずに…というかここにあるのもいくつかは認証のサポートだけだけど、自分で API を叩いて bot を作ることも出来るよ。gcc/g++ の環境はあるから liboauth を使う場合もあとで説明しておこう。」


ルギア君「まず、ruby は入っていないので、インストールするん…だけど、しばらく前から Arch Linuxレポジトリの依存関係が不十分となっていて、ruby-1.9.3p0 に必要な libyaml がないので、ここ からまず libyaml をダウンロードしてビルドする。多分、これはそのうち直るから、直っていたら、pacman -Sy ruby でインストールしてね。」

#  wget http://pyyaml.org/download/libyaml/yaml-0.1.4.tar.gz
#  tar zxvf yaml-0.1.4.tar.gz
#  cd yaml-0.1.4
#  ./configure --prefix=/usr
#  make
#  make install
#  ldconfig

ルギア君「他必要なものをインストールないしは更新する。pacman を更新して良いか聞かれるが、その必要はない。というか面倒くさい。」

#  pacman -Sy openssl

ルギア君「次に ruby をインストールする。ruby-1.9.3-20110919.tar.xz 直(ルギア君の自前ビルド)*3 をダウンロードして展開し、」

#  tar Jxvf ruby-1.9.3-20110919.tar.xz
#  cd ruby-1.9.3-20110919
#  make install

ルギア君「をやればいいんだけど、そのままやると 2GB の SD カードではたぶん容量が足らなくなるので USB メモリを用意するか 200M 以上開けてからやってほしい。ちなみに 3, 4 時間あればビルドもできるよ。」
キリルン「…。」
ルギア君「あ、そうそう、ビルドオプションは」

# ./configure --prefix=/usr

ルギア君「な。あ、あと、このファイルは多分そのうち消す。そして oauth の gem をインストールする。」

#  gem install oauth

ルギア君「そしたら、twbot2.rb を取ってくる。」

# wget http://maraigue.hhiro.net/twbot/twbot2-0.20.zip
# unzip twbot2-0.20.zip
# cd twbot2
# ruby simplebot.rb init
============================================================
Here I help you register your bot account to the setting file.
Please prepare a browser to retrieve OAuth tokens.

Input the screen name of your bot account.
============================================================
User name >lugia_kun
============================================================
To retrieve OAuth token of user "lugia_kun":
(1) Log in Twitter with a browser for user "lugia_kun".
(2) Access the URL below with same browser:
    https://api.twitter.com/oauth/authorize?oauth_token=[トークン]
(3) Check the application name is "twbot2.rb" and
    click "Allow" link in the browser.
(4) Input the shown number (PIN number).
    To cancel, input nothing and press enter key.
============================================================
PIN number >

ルギア君「あとは、twbot2 の説明を読んで楽しい bot を創り上げてね! じゃあ、またな。」

*1:1.6G だと swapfile を入れちゃうと容量が足りない気がした。Arch Linux の wiki では 2GB の SD カードを使っているようであり、他にも幾つか外部サイトとの整合性があっていないところがある。wiki にもは、そこの内容が out-of-date とかかれているが、まさにそのようである。

*2:Homebrew Channel から直接起動するタイプ

*3:SHA256SUM: d59f040771b3880f7fd94680e688bb7c57c49c2a488fd2f110f6a0f24823876f, 22MB