2010-06-01 [長年日記]
_ OfficeファイルもRepository & Ticketベースで
ファイルがたくさんある
以前から思っていたのですが、ファイルベースの情報の管理というのは難しいです。ファイルという単位で扱えるものはしょせん1アプリケーションが表現可能なものに制限され、人間の脳内の活動をアウトプットするには非力すぎるからです。
なんて小難しいことが言いたいわけではなく、例えば Web を考えてみれば分かりますが、HTML をテキストファイルで、画像はそれぞれ画像フォーマットで表現します。画像が2つある文書を作ったらその時点でファイルは3つになってしまいます。
さらに画像は今のところ基本的にラスタ画像(PNG, GIF, JPEG)として表現する必要があり、「元画像」や「素材」と呼び分けたベクタ画像(AI, SVG などの XML形式)を別に保存しておく必要があったりします。同じラスタ画像でもより高解像度の画像を素材として残しておく場合もあります。
日付付きファイル名管理の限界
上のような特徴は HTML の場合に特に顕著ですが、Office 系の情報でも似たような状況にはなり得ます。
- Word の提案文書
- Excel の添付資料(比較資料や見積もりなど)
- 製品のマニュアル PDF や関連情報の Web サイトのスクリーンショット
こういった構成の「資料」をやりとりすることは非常にありふれた話だと思います。そしてこれらの情報にはいわゆる「先方」の要望の変化や思い違い、あるいは単純なミスなどから細かく修正、訂正が入ります。つまり、Office 系のファイルでも
- 意外に素材がある
- 意外に変更が多い
- 最終的には1ファイルではなく、セットが管理できないといけない
わけです。
私は以前からファイル名の頭にはほぼ必ず日付を入れて
20100601-hogehoge.xls
のようなファイルを作るようにしているのですが、複数のファイルを扱う場合、素材や、修正を加えた別バージョンと日付がずれていってしまい、頼りの日付の部分が返ってややこしいという問題が起きます。
もっとも、それだけであれば作業の開始日、あるいは締め切りの日付をフォルダ名に加えて、その中でファイルを管理することで回避することも可能です。素材が使い回しだったら単純にコピーでフォルダの中に持ってきても構いません。
共同管理が事態をややこしくする
いわゆる会社というところでこれらのファイルを扱っている場合、
共同編集はしなくても複数人で扱うことが多く、共有コストもバカにならない
という別の問題も発生します。例えば
| 窓口 | 制作担当 |
| 上司 | 部下 |
| 営業 | エンジニア、デザイナ |
といった組み合わせで同じファイルに複数の人間が絡むことはよくあります。そしてファイルの共有方法が
- 共有フォルダ
- メールの添付ファイル
などになっており、
オリジナルの管理が難しい
といった事態を生むわけです。一人の作業としてもファイルがバラついて面倒なのにこれを共同管理するなんて考えただけでうんざりです。
共同管理なら Google Docs はどうなの?
- 素材を含めての管理となると決して使いやすくはない
- 最終的にはきれいな「印刷物」も大事
- 印刷関連機能の充実したローカルアプリの重要性は減らない
- ファイル管理の話にアカウント管理の話が加わってしまう
個人的には OOo を使うよりは Google Docs の方がひょっとして軽くていいかも、という気もするのですが、関わる人みんなを Google Docs に連れてくるのが大変だったり、アカウント管理どうするのよ、という別な問題が出てきます。組織の規模やカタさにもよりますが、解決したい問題に対して解決策が重すぎる場合はやはり不採用でしょう。
Officeファイルを中央集権的バージョン管理で
ということで前振りが長くなりましたが、今はこの方法で管理しようかと思い始めています。まだ安定して継続しているわけではありませんが。
- 「仕事の単位」でフォルダを作り、全部突っ込む
- ついでに ITS の milestone などに設定する
- commit はとりあえず分かってる人だけでやる
関わっている全員が commit できるのは理想かもしれませんが、そこまでの必要性は感じていません。どうせファイルを実際に編集して作業する人間はほとんど決まっています。
それよりもファイルの管理と同時に、雑多なファイルを取りまとめてやりとりする際のゴールを ITS の milestone で、残りの課題を ticket で見える化できることの方が効果としては大きいと思っています。
中央集権的と書きましたが、別に分散バージョン管理でも構いません。ただ、これを考えた段階で自分の環境では
- どうせ作業者はある程度絞られる
- 基本的にはシーケンシャルな使い方しかせず、複雑なマージなどは考える必要がない
- ファイルの数もせいぜい多くて十数個までで、深い階層も必要ない
- 出先作業は考慮しない
ので、別に何を使ってもいいです。基本的には
自分の使っている Trac がデフォルトで svn 対応だから
です。
まぁ、あえて言うなら「オリジナルの管理が難しい」という最初の課題に対する回答としては分散ではなく中央集権的なバージョン管理の方が分かりやすいのではないかと思います。
逆にほぼ自分一人が作業を行い、かつ出先など repository にアクセスできない環境でも変更を加えたいということなら当然分散バージョン管理の方がいいんですが、もうそうなるとそもそもの前提が違います*1。
実は開発の流れと同じ
こうやって道具を持ち替えてみると、意外なことに気づきます。
- 複数の人間が絡んでいろんなファイルのバージョンを管理しなきゃいけない状況は単純なルーチンワークとは違う
- ITSでワークフローや進捗を含めて見える化されると作業の漏れを減らせる
- 要望が上がって作成 or 変更ののちリリース、のセットを回していく
これって何かに似てませんか?
そうです。開発の行程と同じです。いや、逆ですね。同じになるように道具を入れてるんです、ごめんなさい。
いやしかし、同じように回せることが分かればこっちのもの。開発で養ったノウハウが活きます。
- 内容はともかくワークフローはある程度固めることができる
- 定型タスクに落とし込んでどんどん自動化するとよい
- 例えば相手の名前、例えば日付、こうしたチェックは自動化を考えよう
- アーカイブなどのパッケージングも自動化すればメールで送る際も楽
- テンプレート(パターンと呼び変えても可)を充実させるとよい
- 道具の使い回しを考えてテキストから変換して生成するのは良いアイディア
ただし、
- 残念ながらタイムボックスを取り入れた iteration とは相性の悪いケースもありがち
なのは現状致し方ないかなと思っています。一つ言えるのは
それでも手帳&メール添付ベースの進捗&バージョン管理よりはずいぶんマシ
ということです。
多少ツールが増えた分のコスト増はありますが、課題の見落としやどれが最新バージョンか分からない、regression などの問題は起きにくくなりますし、ゴールを明確化しやすくなるのでいわゆるビジネスパーソンの好きな PDCA の話にも落としこみやすくなります。
特に最後の効果は新しい道具の導入にあまり積極的でない人にもメリットを伝えやすくて、とてもいいんじゃないかなぁ。何より自分のやろうとしている方法では管理する側の手間は増えないし。とりあえずなんでもバージョン管理、なんでも Trac、を今後はもっと積極的に進めていこうと思っています。
名付けて Ticket Driven Documentation つまり TDD です :-)
*1 Office 系の文書もバージョン管理 & ITS 管理するというアイディア自体は別に複数人で関わらなくてもメリットありますけど。
2010-06-05 [長年日記]
_ PYTHON-FIT 2回目
北陸でネットワーク越しに Python を勉強しようの会の2回目が行われた。内容はチュートリアルなんだけど、
- 石川の社会人組が KIT から卒業し、金沢駅西APAの中のシアトルズベストコーヒーへ
- 同時にいつものインフラ支援を受けられない状態
- 実は自分の機械で複数人の参加する Skype の音声チャットにそれなりに長い時間参加したのは初めて
- ヘッドセット使うのも初めて
ということで今回も Python ネタ以外にいろいろ勉強になった。
ヘッドセット
Skype で使う場合は本体の環境設定の音声入出力とは別に Skype の方でも音声入出力に使うデバイスを指定する必要があった。なんか得意になって身構えていたのに本体から音が出ててまぬけなことに。
やはりテキスト以外の情報には信頼できるネットワークが必要
今回利用した石川の会場で拾える Wifi 3つのうち、2つは IP アドレスが取得できず、1つはセッション数の関係か急に詰まって使いものにならなくなった。スピードテスト的には 1.3M 出て申し分なかったんだけど、長時間音声およびテキストでチャットし続けるので、瞬発力ではなく持続力が必要。
e-mobile + PocketWifi は調子にもよるけど Skype 音声2人分を問題なく捌ける
前回の KIT 会場ではヘロヘロだった 3G 回線だったけど、今回の金沢駅周辺では文句なしに使えた。この辺、ビーンズとかにしておかなくてよかった。ビーンズのタリーズは e-mobile の電波弱すぎるのでこんな芸当はまず無理。
場所重要
今回はたまたま隣のテーブルがうるさかったが、比較的静かでかつ電波状況もよく、かつ電源*1にも駐車場にも困らない場所ということで、このシアトルズベストコーヒーはかなり侮れない。
問題はちょっと周辺の駐車場が高い(1時間300円が相場)ことかなと思ったけど、ちゃんと探すと1時間100円や2時間100円の駐車場がある*2ので、そういうところを使えばもっとずっと気軽に利用できる場所だと思った。まぁ、人数的にはせいぜい 1〜3人程度かなとは思うけど。
今日はなんだかんだで1700円くらい使ってる*3けど、次回以降はもっと安くできそう。
※ あとで分かったが、建物の作り上、どうしても音が反響してしまい、雰囲気に反して騒がしくなってしまうようだ。これが Skype の向こうの人には多くのノイズとして伝わってしまうので、一人で黙々作業するには良い場所だが Skype する場所としては向いてないという結論になってしまった。
Python は?
- トリプルクォートを複数行コメント代わりに使うみたい
- 標準で虚数とか複素数とか扱えるんだね
- 数字のリテラルと数値のオブジェクトの違い
- 3.real はダメで (3).real はイケるんだけど、この () は誰だろう?
- interactive shell でだけ _ が使える
- Perl, Ruby のように無制限で使えるわけじゃないのはいいと思う。
- 文字列の repeat は意外にあるよ
- Perl は x
- Ruby, Python は *
- 文字列は連結以外に連接もできる
- ヒアドキュメント == トリプルクォートという理解でいいの?
- 文字列の中の変数展開はどうなるんだろう? ないのかな?
- スライスの記法は便利だけど、実際どう使うんだろう? 固定長フォーマットかな?
- リストって配列じゃないの?
- なんか勝手に単方向リストのことかと思ってスルーしたけど、よく分からないっちゃ分からないな
- どんな種類のデータも突っ込めるのは非 LL 組からすると気持ち悪いらしい
- リストのリテラルは [] しかないのかと思ったら list() ってのがあるらしい。tuple からリストを作るのに使える
- Unicodeオブジェクトが少し謎
Unicode オブジェクトについては u記法がとても目につくので、Perl の utf プラグマのように utf フラグをユーザーが意識する必要があるのかと思ったけどそうではなくて、むしろ Python 3 の時点では Ruby の扱いに近くて、内部的には Unicode で統一されている、と考えると自分的にしっくりきそう。
逆に u記法のない Py3 時代には euc-jp で書かれたコード資産を活用するのは難しいのかなぁとか思った。Perl は昔のコードにはほぼ手を入れずに動くというメリットがある代わりにおまじないが増えた。Python, Ruby は積極的に非互換を作っている感じだろうか。個人的には Ruby の方がなんとなく古いコードを活かしやすそうに見えるんだけど、実際どうなんかなぁ。
地味にエスケープ地獄にならない ur 記法が評価されていたが、分かったような分からないような。Java 書いてないからかもしんない。elisp ではエスケープ地獄うざいと思うが、あまり他の言語で気になったことがない。
2010-06-06 [長年日記]
_ 今さらSelenium CoreでWebアプリテストの自動化
愚痴
最近は比較的自分の中では TDD のサイクルは安定して回っているんだけど、TDD でやりにくい部分についてはそれほど必死にやらないようにしている。TDD が絶対だとも思っていないし、「技法」を編み出すための時間を用意するのも正直難しい。
それでもやはりやりにくいなりに自動化したい部分はあって、その一つが各ブラウザでの検証作業。いちいちフロントエンドを直すたびにいろんなブラウザで手作業で検証するのは面倒なのでやりたくない。
以前はあまりフロントには時間を掛けていなかったというかあまりフロントで問題が出ないようにモノを作っていたんだけど、最近は JavaScript フレームワークやそれを利用したいわゆる "Good Parts" が増えてきていて、ちょっとした味付けに利用したりすることが増えてきている。
そのまま使っている場合はいいんだけど、ちょっとしたカスタマイズを加えてほしいというケースはやはり多く、そうなると途端に IE 6 などで動きが怪しくなる。まぁ
IE 6 は別料金だよね
とは思うものの、できることを放棄するのはまたちょっと違うとも思う。
要件
そこでこんなツールが欲しいと思った。
- Webアプリの TDD で漏れがちなのはフロントエンド
- できるだけ大げさな道具は使わず、誰でもテストを書いて実行できるのが理想
- 完璧なテストを望む気はさらさらないが、regression はできるだけ避けたい
で、そう言えば自分は Selenium IDE を使ってるけど、Firefox 以外でテストしたいなら Selenium Core でいんじゃね?と思った次第。テストケースがちゃんと記述できていれば最悪テストは自分でやらなくていいし :-P *1
※ というか以前 Selenium Core は試しているんだけど、なんで使わなくなっちゃったんだろう? 厳密なテストにこだわりすぎていたからかな?
Selenium Core の制限
- テストしたいアプリと同じサーバに Selenium Core が deploy されている必要がある
- Test Suite, Test Case を HTML で記述する必要がある
1 については http://selenium.googlecode.com/svn/tags/selenium-core/ 以下を svn:externals にしちゃえばいい気がする。そうすれば svn co すれば自動的にインストールされる*2。
ディレクトリツリーはこんな感じでいいんじゃないか。
project/
app/
selenium/ svn:externals
tests/
selenium以外のテスト/
selenium/
2 については Selenium IDE を使う :-)
Selenium IDE 利用時の注意点

場当たり的に Selenium IDE を使っているときには問題にならないんだけど、ちゃんと Test Suite, Test Case を保存するために使うとすると気をつけなきゃいけないのが、Test Suite, Test Case の存在が分かるように使うこと。
なんでわざわざこんなこと書くかと言うと、自分が気づかなかったからなんだけど :-)

画像を見てもらうと早いんだけど、Selenium IDE は複数のテストケースを扱うインターフェイスがデフォルトでは隠れちゃってるのね。これ。これだけ気をつければ ok. あとは必要なテストケースを作り、作り終わったらテストスイートを保存すればいい。
保存先はもちろん上の
project/tests/selenium/
内になる。
ちょっと面倒なのは Test Suite, Test Case は一つずつ保存しなきゃいけないことかな。Test Suite の保存をしようとするとこの Test Case を保存しろ、この Test Case も保存しろと言われる。
イマドキ の Web アプリは遅延ロードしまくり
Selenium IDE で「記録」される操作は基本的に遅延ロードを考慮していない。普通に生成された HTML を対象にするのと同じで、人間が「待っていた」部分は記録されていない。そこで
記録されたテストケースに waitFor をいろいろ書き足してやる必要が出てくる。
逆に言うとそこを気をつけてあげれば十分使えるテストケースになる。
例えば RTM でタスク登録のテストをする場合、ログイン後、実際にタスクを入力できる状態になるまで最初の DOM 構築*3後の遅延生成を待つ必要があるが、これは以下のように書いてやると実現できる。
<tr> <td>waitForTextPresent</td> <td>タスク</td> <td></td> </tr>
こんな記述を随所に書き足しやる必要が恐らく出てくると思う。
open する URL
わざわざディレクトリレイアウトを示した理由は、open する URL は相対でいいから。これはたぶん Selenium IDE 上じゃなくて repository に突っ込んだ状態で手作業で修正することになるんだけど、例えば
project/tests/selenium/case1.html
のテストケースでは open する URL は
../../app/PATH/TO/RESOURCE
と書くことができる。こうしておけば他の人の環境で svn up してすぐにテストしてもらえる。はず。
2010-06-07 [長年日記]
_ RubyとGrowlでシンプルなネットワーク監視
問題
- あるホストがときどきネットワークからちょっと切断され、すぐに元に戻るなど変な動きをする
原因の仮説
現象の発生は席替え後、らしいのでソフトウェア的な何かではなくハードウェアだろう。
- LAN ケーブル
- HUB の port
- HUB そのもの
- PC の NIC
辺りか。
対処
まずはいちばん簡単な HUB の port 差し替えを行ったが現象はあまり変わらない様子。ずっと切断されるわけではなく気づくとツールチップで切断されたことが通知されている程度なのでユーザーはそれほど神経質になていないが、Sysadmin としては気持ち悪いことこのうえなし。
とりあえず監視を始めることにした。そこででっちあげたのが以下のコード。ハードコードの部分が残っているのでそのままでは使えないけど :-P (普段から使ってるわけではないので設定ファイルなどに分離する必要がなかった。)
やってることは
- ping を打って
- 返事がなかったらログに残すとともに Growl で通知
する。これを Ruby の Thread を使って複数ホストに対して*1一斉に行う。監視と通知そのものは Growl の入っていない機械でも行えるようにしてある。
結果としては HUB そのものが原因だった。理由は最後まで詰めなかったが、あるタイミングで通信が不安定になるという症状で、後からよくよく聞くと他にも印刷やスキャンなどが不安定だったらしい。そういうことは早く言ってよねー。
コード
*1 具体的に実際に行ったのは同一の HUB にぶら下がっている全ホスト
2010-06-09 [長年日記]
_ 今度こそgit status, commitをsvnに近づける
結論から言うと
$ git status -uno
$ git commit -uno -a
です!
なんでこんなに苦しんだかっていうと、
git help status
で情報が得られないからでした。
git status -x
とか、適当にエラー起こしたら出たよ。どうなってんの!*1しかもこれは help を得るためのコマンドの使い方じゃないから、実際に git リポジトリの中にいないと help を見ることができない。
不便すぎる。いちばん大事なはずのコマンドなのに超不便すぎる。で、分かったことは
-u, --untracked-files[=<mode>]
show untracked files, optional modes: all, normal, no.
(Default: all)
というオプション。これを使って
git status -uno
としたら tracking してないファイルのリストが出てこなくて見やすくなったよ! ということで alias を
[alias]
stat = status -uno
こうしておいた。これで
git stat
って打ったら svn stat 相当の表示になる。よしよし。やっと快適になったよ! 長かったー。
あとこのオプション、status だけのものではないので、
git commit -a -uno
ってやると commit 時のファイルのリストも svn 相当になる。うむうむ。
*1 実は git help commit の方にまとめて出てるからです。
2010-06-10 [長年日記]
_ Thunderbird 3 サポート業務で最近知ったこと
※ 別にあたしゃサポセンの人ではありません。単に何でも屋なだけです。
- Thunderbird 2 -> 3 アップグレードで「なぜか」マスターパスワードを要求されて、どうにもならなくてパスワードリセットしなきゃいけないケースがあるらしい。
- Contacts Sidebar - Thunderbird extension は 0.8 pre 現在、メニューの [ 表示 ] -> [ レイアウト ] -> [ Contacs Sidebar ] からしか表示できない。Tb 2 時代にはボタンがあったのに
- Tb 3.1 になったら動かなくなった。早く正式リリースしないのかなぁ
- メールボックスのサイズがある節目*1に達すると、それ以降そのフォルダに操作を加えることができない
- MozillaZine.jp :: トピックを表示 - [解決済み] 最適化してもINBOXの容量が変わらない
- いくらメールを削除して最適化してもメールのフォルダの実態であるファイルのサイズは変わらないので、ずっとこのまま
- Inbox がこの制限に引っかかると一切受信できなくなる
- 上のリンク先の MozillaZine のフォーラムに書いてある「エディタでメールを保存し直す」方法は、サイズは元に戻ったが Tb で認識できなくなる可能性があるのでやっちゃダメ(確認済み)
- 回復方法は以下の通り
- Thunderbird 終了
- Inbox ファイルを適当に rename
- Thunderbird 起動
- rename 先のフォルダから Inbox へメールを移動
でかい添付ファイルを日常的にやりとりする人はマメに添付ファイルを分離しないとダメだね。
*1 2GB とか 4GB
2010-06-12 [長年日記]
_ あるMacの通信だけが遅いのに無線AP再起動で回復することがある
これイマイチよく分からないんだけど、現象を列挙すると、
- AirMac Express 2台で WDS を組んでいる
- WDS の下流の有線LANからの通信は正常
- WDS の途中に割り込んでいる MacBook だけ通信がやたら遅い
で、これは MacBook 側の問題だろうと思ったんだけど、これがなんともなくて、AirMac ユーティリティから AirMac Express を再起動したら回復した。(速度差で 7 〜 8倍)
あんまりネットワークとか無線 AP 端末の特徴とか知らないんだけど、こういうもんなのかなぁ。とりあえずメモを残しておく。
2010-06-14 [長年日記]
_ SkypeのHTML形式のログにgrepを掛ける
最近 Skype のログの活用を真面目に考えていたのでこんなものを書いてみました。要は Skype のログからまとめを作りやすいんじゃないかな、という思惑です。
最悪、検索が満足いく結果にならなくても
time : name : massage
フォーマットのテキストになるので、HTML に比べると編集容易性はぐっと上がります。
できること
- 任意の日付のログに対して*1
- time, name, message のいずれかに対して正規表現で検索
たぶん。実際にこの日記を書いているのは2ヶ月後なので、よく覚えていません。ただ、目的として日付の指定と「人」の指定は外せなかったはずなので、その機能は実装されているはずです。
実行環境
- Ruby
- Nokogiri
- HighLine
に依存しています。Ruby 1.9 では確認していません。
使い方
仮に名前を shlg ( Sky HTML Log Grep ) として、実行権限を与えてあるとすると、
$ shlg [-d yyyy-mm-dd] -r regexp filename $ cat filename | shlg -r regexp -d yyyy-mm-dd
こんな感じで使えるはずです。
コード
*1 コマンドラインオプションで与えなかった場合は interactive に指定する必要があります。
2010-06-16 [長年日記]
_ rest-clientがイロイロ変わってた
まず maintainer が変わって、official repository が変わってた。もう半年前の話だった。
archiloque's fork is now official
そんでもって 0.9 からの違いで言うと
- jeweler で gem を作るようになった
- rspec でテストを書くようになった
- mimetype の取り回しは mime-types に依存するようになった
- cookie 周りで CGI を呼び出すようになった
こんな感じ*1。
一度 1.4 で response が String でなくなって、あれ、既存のスクリプト書き直しか?と思ったら 1.5 でまた String に戻った*2。ということで 1.4 を華麗にスルーしていた自分は慌ててスクリプトを書き直す必要はなかった。
rest-client を使って cache 付きの downloader のようなものを書いて動かしてるんだけど、最近は
crohr's rest-client-components at master - GitHub
Rack Middleware を透過的に使おうとしているものもあるらしい。実はここら辺からもうよく分からなくなってきてるんだけど、Rack ってサーバサイドの話じゃないんだっけ? Rack Middleware を client サイドで使うこともできるのね。まぁ rest-client の投げる request を受け取って処理するんだから Rack でいいのか。
で、Rack::Cache は Rack とは別 gem なので注意。中身は軽く見たところ
- Marshal を使ったファイルベースの cache
- memcached
- GAE
に対応しているらしい。なるほどなぁ。
2010-06-17 [長年日記]
_ テキストのn行目以降を取得する
ふと、ある出力の6行目以降が欲しくなった。はて?
- 先頭から6行なら head -n 6
- 末尾6行なら tail -n 6
おや?
ここでふと「find の引数で -mtime 1 はちょうど 1時間だけど -mtime -1 なら 1時間以内になる」ということを思い出したので、
なんか + とか - 付けたらいい感じに動くんじゃね?
と思ったらこれが Bingo. 一応 *BSD でも Linux でも同様に動くことを確認したが、どのバージョンからそうなのかまでは追ってない。まぁ tail なんてコマンドはそうそう変化はないと思うので、ほぼすべての環境で使えると思っていいんじゃなかろうか。
というわけで、冒頭の課題は
tail -n +6
で解決。
なーるほどなぁ。
ということはアレか。いわゆる MacBinary カッターって tail だけでいいのか。(良い子はもう MacBinary カッターなんて知りません。)
2010-06-20 [長年日記]
_ 標準状態のWindowsで再生可能なMPEG4ムービーを作る
自分は Mac 使いで、mp4 の吐き出しを iMovie がやってくれるので、
ffmpeg で mp4 -> MS MPEG4
ってやるだけ。
MS MPEG4 対応の WMV のバージョンがいくつからとかまで知りません。普通にバージョン上げてください。Codec の追加が必要ないだけマシってことで。
2010-06-22 [長年日記]
_ FreeNAS News野良feedの配信をやめました
たぶん誰も購読してないので影響ゼロなのですが、一応公開していたものをやめるのでエントリとして起こしておきます。
Yapra で FreeNAS News の野良 feed を作った - あーありがち(2008-08-24)
Yapra デビューにもなった記念すべき野良 feed でしたが、
- 本家サイトがリニューアルして全面的に DocuWiki に
- 当然ながら scrape して feed を起こす処理は作り直す必要がある
ここで、今度こそ Pipes で作ろうかと思ったのですが、
- ちらっと見たら News のページがあるんだかないんだか?
- Wiki の feed は有象無象混ざるので面白くないけど blog を発見
なんかもう、blog の feed でいいんじゃないの?
ということで、FreeNAS については Yapra も Pipes も捨てて本家 blog を追うことにしました。
2010-06-23 [長年日記]
_ PHPアプリの依存packageをpearで管理する
いつもちゃんと pear で管理しろよと言っている wtnabe です。おはようございます。
以前 pfm を使って pear package を作れるようになってからずいぶん経つんですが、実はこれまで依存 package を管理していませんでした。自分の作っているものはスタート時点では依存 package がややこしくならないようにするためのライブラリだったのですが、だんだんとできることが増えくるにしたがって依存 package も増えてきました。
package.xml を書くのは面倒
そこで pear package で依存 package をどう記述するのかを調べたのですが、当然ながら XML という非人間的なフォーマットで定義されているので、とてもサッと書ける気がしません。どうしよう、YAML で書いて package.xml に merge するツールでも書こうか、とか思ったりもしていたのですが、面倒です。だいたいあんまり生産的な感じがしない。
しかし先日、ついに気がつきました。
pfm に依存 package を定義するインターフェイスがあるじゃん。
使ってなかったから見落としてただけでした。
じゃあ話は簡単、とっとと定義してしまおう。add と delete しかできない豪快仕様だけど、XML 手打ちよりは多少マシ。
で、依存 package を解決できるようになってハタと思いつきました。
これでアプリ(サイト)単位で利用してる package を管理できるじゃん。
複数サイトのメンテナンスは面倒
複数のアプリ(サイト)をメンテしていると環境の準備がだんだん煩雑になってきます。こっちはこれとこれに依存していて、こっちはあれとそれに依存していて、えーとじゃあこの機械には結局何と何が入っていればいいんだっけ?という状態になるわけです。作っているときは気にならないけど、久しぶりにいじらなきゃいけなくなったときにこれではかなり困ります。ドキュメントがあればまだマシですが、手作業で準備しなきゃいけないのは面倒です。常にオリジナルから全 copy というスタイルもあるようですが、portable じゃないのであまり好きになれません。
そこで思いついたのが
依存 package だけを定義した package があればいんじゃね?
という方法だったのですが、結論から言うとこれは無理でした。
ダミーファイルを用意して package を作る
だったら話は簡単、内容のないダミーのファイルを用意すればいいんです。具体的にはアプリ(サイト)を識別する名前で空のファイルを作ります。
<contents>
<dir baseinstalldir="." name="/">
<file baseinstalldir="."
md5sum="d41d8cd98f00b204e9800998ecf8427e"
name="APP_NAME"
role="data" />
</dir>
</contents>
最低一つはこうした形で中身が必要になります。
名前とインストール先
名前はライブラリをインストールしたいアプリケーションの名前でいいんじゃないかと思います。この際、拡張子なしでファイルを作ると pear directory の中の data/ というディレクトリに入ります。
以下のような感じ。
|-- data `-- app_name アプリ名 `-- APP_NAME ファイル
具体的な pfm での作業の様子
まずは空のファイルを作る
作業のディレクトリを掘って、空のファイルを用意します。
$ mkdir app_name $ cd app_name $ touch APP_NAME
pfm で package の基本情報を入力
具体的にどのように作業するのか、ログを晒していきます。
$ rlwrap pfm .
rlwrap は必須じゃないですが、あるとないとで作業効率が全然違います。ぜひ入れておきましょう。
PEAR Package File Manager Command Line Tool
Please enter the location of your package [.]*: .
Creating a new package file ...
Enter the base install directory*: .
Enter the name of the package [app_name]*:
Channel or URI based package? [c] (c,u)*: u
Enter the package URI*: http://example.com
Enter a 1 line summary*: meta package
Enter a description* (2 blank lines to finish):
meta package for dependency packages
Enter the release version*: 0.1.0
Enter the API version [0.1.0]*:
Choose a release stability [alpha] (alpha,beta,stable)*: beta
Choose an API stability [beta] (alpha,beta,stable)*:
Enter any release notes* (2 blank lines to finish):
initial release
Enter the minimum PHP version [5]*:
Enter the minimum PEAR Installer version [1.4.0]*:
Please choose a license from one of the following options
1) Apache
2) BSD Style
3) LGPL
4) MIT
5) PHP
Please choose an option: 2
How many maintainers?*: 1
What type of maintainer is #1? [lead] (lead,developer,contributor,helper)*:
Enter maintainer #1's name*: name
Enter maintainer #1's username*: name
Enter maintainer #1's email [name@php.net]*: name@example.com
ここまでで以下のような package の元データができます。
PEAR Package File Manager Command Line Tool
1. Package name [app_name]
2. Channel/URI [URI: http://example.com]
3. Summary [meta package]
4. Description [meta package for dependency packages]
5. Maintainers
6. Version [Release: 0.1.0 API: 0.1.0]
7. Stability [Release: beta API: beta]
8. License [BSD Style]
9. Notes [initial release]
10. Dependencies
11. Tasks
12. Regenerate contents
13. Echo package file to stdout
14. Save & Quit
15. Quit without saving (ctrl-c)
Please choose an option from the menu:
ここで 10 を選んで依存 package を定義していきます。
依存 package の定義
すると dependencies 用の menu が現れます。今回は試しに Pear にある Net_URL_Mapper を定義します。
Edit Dependencies
1. Return to main menu
2. Add new dependency
3. Clear all dependencies
4. Change PHP >= 5
5. Change PEAR Installer >= 1.4.0
Dependencies:
Please choose an option from the menu: 2
Dependency type [pkg] (pkg,ext,php,prog,os,sapi,zend)*:
Dependency name*: Net_URL_Mapper
Is the dependency (o)ptional or (r)equired [r] (o,r)*: r
Package type (c)hannel or (u)ri [c] (c,u)*: c
Dependency channel [pear.php.net]*:
Minimum version:
Maximum version:
Edit Dependencies
1. Return to main menu
2. Add new dependency
3. Clear all dependencies
4. Change PHP >= 5
5. Change PEAR Installer >= 1.4.0
Dependencies:
Required Package dependency "Net_URL_Mapper" - pear.php.net
こんな感じで依存 package が定義できました。あとはメインメニューに戻って
14. Save & Quit
を選びます。できあがった package.xml のうち dependencies の部分だけ抜き出すと以下のようになっています。
<dependencies> <required> <php> <min>5</min> </php> <pearinstaller> <min>1.4.0</min> </pearinstaller> <package> <name>Net_URL_Mapper</name> <channel>pear.php.net</channel> </package> </required> </dependencies>
まぁ慣れれば手でも書けそうですけどね…。一度定義すればそんなに変更することはないですからね。慣れによる精度向上を望めない作業は直接の手書きよりも pfm のようなインターフェイスで制限を設けて作業した方がいいように思います。
URI package は拡張子抜きで
[2010-07-13 追記]
Manual :: package.xml 2.0 における依存性の指定
に書いてある通りなんですが、
<package> <name>Foo<name> <uri>http://www.example.com/Foo-1.3.0</uri> </package>
こんな感じですね。恐らくほぼ間違いなく .tgz を省略することになると思います。
beta package の依存性を解決する
pear パッケージマネージャはデフォルトでは beta バージョンについては依存関係を解決できません。一つ一つ手で入れる必要があります。しかしちゃんと検証して使えることが分かっていれば beta でも自動で入ってくれた方が嬉しいです。これは
pear config-show | grep preferred_state
が stable ではなく beta になっていると beta も自動解決できるようになります。
package.xml の中で特定の依存性に関しては beta でも解決するとか、install コマンドのオプションとか、そういう方法がないのが痛いですねぇ、pear は。channel package だけは beta でもインストールを継続するための記法があるんですが、依存 package についても beta でもインストールできるようにするオプションというものがありません。この辺は正直気が効いてない印象ですね。
まぁ、pear は cpan などと違って自由がないのが特徴なんですけど。
2010-06-27 [長年日記]
_ モバイルデバイス再整理
完全自分向けメモ。
iPad をはじめ、この春から初夏にかけてモバイルがますます熱いわけですが、この辺の所有について自分なりにもういちど考え直してみました。
- 現在持っているのは ガラケー*1 + iPod touch 2G + PocketWifi ( e-mobile )
- iOS 4 の恩恵をほとんど受けられない
- iPad はまぁ買うつもり
ここで一度なんかみんなが iPad, iPad 言い始めたので天の邪鬼を発揮して Android にしちゃおうかな、なんて思ったのですが、コンシューマ向けのコンテンツ、アプリは iPhone/iPad の方が強いだろう、と思い直して帰ってきました。急いでないのでいつ買うかは分かりませんが。基本的にはダイニング/キッチン端末、みたいな感じなのかなぁという印象。天気予報とテレビ番組表とちょっとレシピと地図と電話番号、郵便番号くらいが調べられれば十分なんじゃね?という感じです。Androidタブレットもあるにはあるんですが、なんかどれも微妙で。特に 7" タイプにはまったく引かれないですね。大きさが中途半端すぎます。持って読み書きするというよりはフォトフレームのサイズなので、使う楽しみがあまりない感じ。
アプリやコンテンツについては、Android の方は技術的に面白いもの、iPhone/iPad の方はエデュテイメント方面が充実するんじゃないかという読みです。個人的には今は仕事向けのアプリが滞りなく動けば何も文句はないのですが、Android の方がまだ PC っぽさが残っててイヤな感じです。PC がイヤなのかって? 管理しなきゃいけない機械が増えるのはイヤです。
もう一つは持ち運び用の iPod touch ですが、先日、待ち時間に iPod touch + Evernote だけで小一時間ほど何かを書く、ということをやってみたのですが、これが実につらい。iPhone は確かに革命的な体験を我々に与えてくれたかもしれないけど、やはりこのサイズのソフトキーボードには自ずと限界が出てきます。かと言っていつもノートパソコンを持ち運ぶような仕事はしてないし、そんな気合いももうありません。しかしつらいのはつらい。
そこで bluetooth キーボード対応した iOS4. しかし手持ちの機械はアップデートしても bluetooth には非対応です。かと言って iPod touch 3G をまた3万出して買い直すのもバカバカしい。
はてなぁ。
ものは試しで Android 端末を調べてみたけど、このサイズになると白ROMの電話になってしまって軒並み高いです。いやぁ、考えたら iPhone の値段は驚異的だなぁ。2年縛りがあってもそれ以上の何かを得られるのであれば十分許せるかもしれないなどとちょっとよぎりましたが、ティザリングできてちゃんと定額のプランが適用されないとあまり面白くないので、グッと堪えました。*2
結論から言うと、とりあえず秋に iPhone 4 世代の touch を、その前後に iPad を買う感じかなぁ。電話も実は謎の再起動とかあって変えたい気もするんですが、iPhone にすべてを預けるのはちょっと怖い&SoftBank回線もなんかイヤ、かと言って Android(特に HTC デザイン)も今はなんかもうひとつ魅力に欠ける、という感じでスマートフォンへの移行は完全に二の足を踏んでいる状態です。
2010-06-29 [長年日記]
_ Emacsで改行を含む置換とxml-modeのindent-region
実際には6月30日のネタだけど長くなるのでずらして書くなり。
minibuffer では \n ではなく C-q C-j
Emacs で改行コードを含む置換をやったことがなかったか避けてきたらしく、今まで知らなかった。
調べると以下のように書かれている。
8.2 Editing in the Minibuffer
The minibuffer is an Emacs buffer, albeit a peculiar one, and ""the usual Emacs commands are available for editing the argument ""text. (The prompt, however, is read-only, and cannot be changed.)
Since <RET> in the minibuffer is defined to exit the minibuffer, ""you can't use it to insert a newline in the minibuffer. To do ""that, type C-o or C-q C-j. (The newline character is really the ""ASCII character control-J.)
Minibuffer Edit - GNU Emacs Manual
てっきり \n や \\n で改行を表現するのかと思っていたけど、ハードタブを入力するのと同じく C-q に続けてコードそのものを入力するらしい。
ちなみに普段編集している際には Enter も C-j も C-m も同じように改行してくれるけど、
| C-m | CR |
| C-j | LF |
は厳密に区別されるので注意。また自分の環境では C-q RET は CR が入力された。これはもしかしたら設定で変更できるかもしれないけど、C-q C-j で覚えてしまう方が楽な気がする。
ところで、上記以外のコントロールコードも何がどれに割り当てられてるか知らないな…。と思ったらここにあった。
Control character - Wikipedia, the free encyclopedia
これだけ分かればとりあえず足りる、のかな?
xml-mode の indent には改行が必要
なんで改行コードを含む置換をしたくなったかと言うと、OOo の template の XML ファイルを編集する際に indent がなくて見にくかったから。Emacs の xml-mode で indent できるよって教えてもらったけどできなかったので、改行コードが要るのかと思って試してみたらこれが bingo.
具体的には
replace-string で > を >C-qC-j に置換
した。
2010-06-30 [長年日記]
_ rst2odt.py 用の stylesheet を作る準備
rst2odt.py の変換結果がイロイロまずい
先日、docutils を使った OOo Writer (.odt ) 形式への変換 を試してからサクっと一ヶ月が経ったわけだけど、あれは実はあのままでは面白くない。というのも
フォントなどのスタイル情報が自分の好みに合わない。
結果として手作業で一つ一つスタイルを合わせ直さないといけないんだとすると、全然省力化になっていない。そもそもこの「マウスを握ってポチポチやらなきゃいけない感」がきらいだからこそ Office がきらいだと言っても過言ではないのに、そこが改善されないままではいくらスタートが reST であってもダメダメである。
スタイルシートを与えて変換する
ではどうしたらいいのかというと、ちゃんと方法がある。help を見ると
$ rst2odt.py --help
Usage
=====
rst2odt.py [options] [<source> [<destination>]]
Generates OpenDocument/OpenOffice/ODF documents from standalone
reStructuredText sources. Reads from <source> (default is stdin) and writes
to <destination> (default is stdout). See
<http://docutils.sf.net/docs/user/config.html> for the full reference.
Options
=======
(snip)
ODF-Specific Options
--------------------
--stylesheet=STYLESHEET
Specify a stylesheet. Default: "/opt/local/Library/Fr
ameworks/Python.framework/Versions/2.6/lib/python2.6
/site-packages/docutils-0.6-py2.6.egg/docutils/writers
/odf_odt/styles.odt"
と書かれているので、
--stylesheet=STYLESHEET
を与えればよいことが分かる。また、このときデフォルトで与えられる stylesheet のファイルが分かる*1ので、次にこれを cp して中身を確認してみる。
ODTWriter の stylesheet の中身を見る
最初に引っかかったのが
stylesheet として与えるものが .odt であるということは、これは Writer のファイルそのものであって、テンプレート ( .ott ) ではない
ということだった。というのも、GUI で文書を作るときにはテンプレートを作ってそれが見た目の基準になるのが基本的な流れだから。どうも docutils の ODTWriter の考え方は違うらしい。
話がそれたが、OOo のファイルフォーマットである ODF ( Open Document Format ) は XML でかつ ZIP アーカイブだということは知っていたので、まずは styles.odt を展開してみる。
$ unzip styles.odt -d styles Archive: styles.odt extracting: styles/mimetype inflating: styles/content.xml inflating: styles/styles.xml <- コレ extracting: styles/meta.xml inflating: styles/Thumbnails/thumbnail.png inflating: styles/Configurations2/accelerator/current.xml creating: styles/Configurations2/progressbar/ creating: styles/Configurations2/floater/ creating: styles/Configurations2/popupmenu/ creating: styles/Configurations2/menubar/ creating: styles/Configurations2/toolbar/ creating: styles/Configurations2/images/Bitmaps/ creating: styles/Configurations2/statusbar/ inflating: styles/settings.xml inflating: styles/META-INF/manifest.xml
もう正解は書いちゃったけど、それっぽい名前のファイルが見つかった。まずは font の設定を変更したいので font 関連の記述のあるファイルを探そう。
$ grep -rl font * content.xml settings.xml styles.xml
※ ここで役に立つのが(実際には同日の作業なんだけど)昨日のエントリとして書いたxml-modeのindentとそれを活かすための改行の挿入である。
content.xml は内容っぽいのであやしいのは settings.xml と styles.xml かな。このうち settings.xml は font の設定はないっぽい。となると styles.xml か。
ということで styles.xml をいじっていけばよいらしいことが分かった。
該当スタイルを見ておく
最初何も考えずに styles.xml をいじり始めて「反映されない!」と騒いでいたんだけど、よくよく見れば当たり前。変換後の文書を注意深く見てみると分かるんだけど、rst2odt.py で生成した文書は通常の「見出し」などの書式ではなく
"rststyle-heading1" のような書式が割り当てられている。
そうか、これをいじるのか。ということは 'rststyle-*' を対象にスタイルを考えていけばいいのか。
とりあえず今日はここまで。
参考
ざっと手順を追ってみたけど、後で調べたらちゃんと資料があった。まぁ当たり前か。
関連エントリ
*1 上の場所は MacPorts で入れた Python 2.6 の docutils 0.6 の場合