ブラウザスクリプト

社長:ブラウザでやってる一連の定型的な作業を自動化したいです。

開発:いわゆるワークフロー的なものですね。

社長:一般的に言えば、ブラウザに限らず、ユーザとしてやってるコンピュータ・ツールとの一連のインタラクションを全部、アルゴリズムを書いて走らせといて。人間として選択とか情報入力が必要な時だけ答えるというのが良いですね。

開発:でもとっかかりはやはり、ブラウザですかね。一番応用範囲が広そうですし。

基盤:ブラウザの自動テストプログラムとかはあるはずですよね。Monzilloのビルドをするときにも、テスト用の何かがありました。extensionにあるか、そもそもデフォでそういう機能があるかもです。

社長:構築したウェブサイトの自動テストという需要もあると思います。

開発:ウェブサイトの投稿フォームにSPAMを書き込んでるのって、実はそういう感じに実装されたロボットかも知れないですね。

社長:ブラウザがワークフローのスクリプトを解釈実行するというのがわかりやすいですが、そもそもブラウザに対して外部から通信メッセージで動作を制御できるようにすると、使い勝手というか作り勝手が良いですね。

開発:そうなると、ブラウザが提供すべきプリミティブのセットとは何か、ということになりますね。

社長:一番原始的には、マウス操作とキー入力情報を食わせる。これはもう万能で、ブラウザ以外にも適用できますが、意味をマッピングするのが難しくなる。一方で高水準なのは「指定したURLを新しいタブで開く」みたいなもの。

基盤:それも、いわゆるショートカットキーを使えば、キー入力として実装できますよね。

開発:でも、コマンドメッセージとして実現したほうがかっこいいですね。ショートカットの場合、ユーザやブラウザごとのカスタマイズに依存してしまうのが問題と思います。

社長:複数のマシンで複数の種類のブラウザを動かしているので、それらの動作を一律な方法で統括して管理できると良いですね。

開発:となると、最初の糸口はブラウザにコマンド受付用の通信ポートを持たせて、そこにコマンドを送るということですね。

社長:まずは「このURLを開け」だけで良いと思います。

基盤:MyChromiumのほうは性能的にまともに動かないので、とりあえずUbuntuでビルド済みのMonzilloですかね。

開発:ChromiumはMacMiniでビルドしたので、そのままiMacに引き継げるとは思うのですが…

社長:その前に食事にいきましょう。

開発:いや、ここで食って飲んで午睡してしまうと時間が…

社長:以前買ったとうもろこしをチンして済ませますか…

* * *

経理:今日も xso から .com が500円というSPAMが来てますね。

社長:この作業関係で何か思いついたら登録しますか。

基盤:えーと。この Ubuntu、以前 Monzillo をビルドした時に root とはパーティションを分けたらしいのですが、それが無くなってしまいました。

開発:マウントすれば出てくるのでは。スクリプトにしてあるとか。

基盤:ls -lt … ああ、ありました。日付は6月11日。単に mount /dev/sda /work ってしてるだけですね。sudo ... ディレクトリ出ました。で make ... あいかわらず時間が掛かりますが…

基盤:これも仮想ディスクがきつくなってるんで、QNAPにNFSするのが良いかなとは思いますが。

開発:さっきからなんか騒音がすると思ったら、Ubuntuの VMを動かしている Lenovo機のファンですね。以前は音無しだったような気がするのですが。

基盤:室温が高いからですかね。

社長:これはやはり、別の部屋に移しましょう。これに実物のモニタとかキーボードをつなぐことはもう無いでしょう。

基盤:いちおうUPSは付けて上げたいところですが…

開発:そういえばこの1万円UPS、消費電力計として結構面白いのは無いかと思います。

社長:電力計自体が1万円くらいするのもあるし、UPSのおまけについてくるってすごいおトクですね。

基盤:うーん、電力計によると現在の消費電力60ワット前後なんで、ほとんど平常負荷なんですけどね。やはりLenovoのファンが回っているのは気温のせいですかね。

経理:ファンの消費電力が気になります。

開発:ビルドを始めてもう15分を超えましたが… まさか1時間半かかっちゃうパターン?

社長:このUPSの管理ソフトの有償版なら電力消費の統計情報も見られるみたいなんですが、いくらなのかわからないですね。

基盤:おっと、Lenovoが静かになったと思ったらmake終わってますね。所要39分。では、mach run!

開発:めでたし。

基盤:確認のためもう一度 make… これ速攻で終わるはずと思うのですが…

開発:Firefoxのバイナリ自体は8秒で出来てるみたいですが。

基盤:この gkrust というのの build が差分ではないのか、やたら時間がかかるんですね。

社長:ところでこれって最新版開発版?

基盤:うちが6月のあたまにビルドしたのはこれ、77.0b7です。

開発:なんでリリース日付を表示しないんですかね?

基盤:現時点の安定版は78.0.2 みたいですね。

基盤:Firefoxの次期バージョンのページによると、ベータ版だと79.0beta、June 30, 2020 になってます。

基盤:開発版(Nightly)は 80.0a1 ですね。June 29。

開発:日付を出しましょう。どこで出しているのかな…

u18$ find browser -type f -exec grep -H You.are.currently.on '{}' ';'
browser/locales/en-US/browser/aboutDialog.ftl:channel-description = You are currently on the <label data-l10n-name="current-channel"></label> update channel

開発:じゃこれをちょっといじって make ...

基盤:さくっと変わりますね。

開発:でこの、.ftl とうファイル形式の中かなら、リリースの日付を取ってこれるかなのですが。

社長:というかさっきからずっと、手がとうもろこし臭いのが気になります。ちょっと休みましょう。

* * *

社長:そういえばこの3ヶ月以上、テレビはおろか、まともなスピーカーで音楽も聞いてないですね。これってどうやってiPhoneにつなぐんでしたっけ。USBに挿すだけでいいのかな…

基盤:てかこのONKYOのアンプ、やたら熱くなってますが… スタンバイとかしないんですかね?

経理:ずっと無駄に電気食って部屋を温めてたんですね。

経理:そういえば何年も見てなかったでんこレポートのサイトのパスワードを忘れてしまったので、てぷこさんに問い合わせ中です。こっちを特定する情報が確認できないと答えて来たので、お客様番号とか答えて再度回答待ちです。

開発:個人証明書で電子署名して送ってやりたいですね。

社長:あれー、音が出ないな… INPUTの選択ですかね… なんでこう沢山入力があるのかな。このしょぼいコントロールパネル… パソコンからリモートコントロールとかできないんですかね… ああ、USBのFってやつですね。あ、音が出た。

基盤:久しぶりに聴くまともな音。しみいりますね。

開発:そういえば昨日の朝、大谷くんはさんざんだったみたいですね。忘れてて見なくてよかった。

* * *

開発:FTLってなんですかねー。MDNで検索しても出てこないんですか。browser の下あたりに沢山あって、文字列定数を定義するような感じのものなんですが。簡単な HTML 的なマークアップもできるような。

開発:おや?そもそもこの、aboutDialog.ftl の中に例が書いてありますね。Nightlyなら日付が入っているはず…

社長:昔から思うんですが、ソースコードの先頭がお決まりのコピーライトの宣言で埋まってる割に、説明的なものがほとんど書かれてないのは悲しい風習ですね。

開発:どうやら変数が使えるようなので早速…

基盤:だめじゃんw

開発:どこに書いても代入してくれるわけではないようですね。ではその、aboutDialog-version というのに $isodate をねじ込みましょう。

基盤:そんな人はもうここには住んでません的なw

開発:別の名前になったとか?

u18$ find browser -type f -exec grep -H isodate '{}' ';'
browser/base/content/aboutDialog.js: versionAttributes.isodate = ${year}-${month}-${day};

基盤:問題は、その aboutDialog.js ですね。

開発:これかな?

基盤:なるほどw

開発:なんにしてもビルドの日付を入れてくれるだけみたいね。やってみますけど…

基盤:おおっと、意外な展開。

開発:いずれにしても、リリースの日付を表す属性を加える必要があると思いますね。それをどこから持ってくるかは別として、$released とか追加してみる。

let versionId = "aboutDialog-version";
let versionAttributes = {
version: AppConstants.MOZ_APP_VERSION_DISPLAY,
bits: Services.appinfo.is64Bit ? 64 : 32,
released: "2020-07-28" //@@2020-0728 ITS more
};

開発:で ftl で参照する。

aboutDialog-version = { $version } ({ $isodate }) ({ $bits }-bit) <b>(^-^)/ITS more 4</b> ---- released @ { $released } ----

開発:でどうなるか。

基盤:そいういうことですね。

社長:その77.0b7てどこに書いてあるんですかね?

開発:検索。

u18$ find browser -type f -exec grep -H 77\\.0b7 '{}' ';'
browser/config/version_display.txt:77.0b7
u18$ more browser/config/version_display.txt
77.0b7

開発:browser/config には、この 77.0b7 と命名した日時の情報が無いですね。ただファイルの日付が暗示している。

開発:grep 2020… おっと、トップディレクトリにあるこれかな?

u18$ cat sourcestamp.txt
20200518172851
https://hg.mozilla.org/releases/comm-beta/rev/68012bf3f92a15aa5f8e2019fd90faed491659e9
https://hg.mozilla.org/releases/mozilla-beta/rev/83a8484759305eb1c93029065c4566e007325649

u18$ ls -l sourcestamp.txt
-rw-r--r-- 1 ysato ysato 192 May 19 04:25 sourcestamp.txt
u18$ TZ='GMT' ls -l sourcestamp.txt
-rw-r--r-- 1 ysato ysato 192 May 18 19:25 sourcestamp.txt

基盤:2時間ずれてますが、そんな感じですね。

開発:sourcestamp.txt の日付を参考にすれば良いみたいですね。ただちょっとわからないのは、アップロードされているtarballのタイムスタンプがそれより古いことですが。

開発:なんにしても、.js で定義して、.ftl で参照して表示する、という流儀のようですね。

社長:少し前進しましたし、お昼もとうもろこしだけだったし、飲みに行きましょうか。といいますか、いくら洗っても手がもろこし臭くて… じっと手を見る。

* * *

社長:帰りました。

経理:あまり酒臭くないですね。

社長:中瓶1本で堪えましたからね。今日は休肝日だったと日記に書いても良心の呵責が無いくらいです。

社長:で郵便受けを見たら例のこれが入ってました。

経理:再発行の印がある以外は普通の請求書の内容ですね。これって、トータルで100円くらいコストかかってませんかね?

開発:例外処理のために作業をした人の人件費を計上すれば、とんでもないことになりそうです。

基盤:それはそうとこの「料金後納郵便」というのに興味があります。料金体系も違ったりするんでしょうか?

社長:それでこの「月刊協会けんぽいばらき」というのをちらっと見たんですが「限度額適用認定証をご存知ですか」というのが非常に重要な情報と思いました。

開発:限度額という仕組みがあるのは聞いてましたが、こういう申請をする必要があったんですね。

経理:このページですね。制度の説明はこれ「高額療養費・70歳以上の外来療養にかかる年間の高額療養費・高額介護合算療養費」。「70歳未満の方であっても、平成24年4月より…」とあります。

高額療養費の現物給付化(健康保険限度額適用認定証)
70歳未満の方であっても、平成24年4月より、従来の「入院される方」及び「外来で在宅時医学総合管理料、特定施設入居時等医学総合管理料及び在宅末期医療総合診療料を算定される方」に加え、「外来で療養を受ける方」の高額療養費を現物給付化し、一医療機関ごとの窓口での支払を自己負担限度額までにとどめることができるようになりました。この制度を利用するには、事前に全国健康保険協会の各都道府県支部に「健康保険限度額適用認定申請書」を提出、「健康保険限度額適用認定証」の交付を受け、医療機関の窓口に認定証と被保険者証を提出してください。

社長:ありがたい制度ですね。でもこの「所得区分」にちょっとカチンと来るものが。

経理:月給の3割程度以上は免除してくれるって感じでしょうかね。

開発:しかしこれ、有効期限が1年。申請から発行まで1週間ですから、突然の事故とかでなければ、必要になった時にオンデマンドでも良いと言えなくもないかもですね。

基盤:それよりもなによりも、この入力用のファイルがWordでもExcelでもなくPDFだというのが面白いですね。

社長:会社の設立から幾つもの入力用ファイルを見ましたが、PDFで入力をサポートしてるのは初めて見ました。WordとかExcelの素人が練習用に作りましたみたいな感じのものばかりでしたが。

開発:まあ、フォーム入力してPDFを生成するとか、そもそも電子申請できればいいんじゃないかとは思いますけどね。この保険証って実は電子証明書入りのICカードで、署名にも使えるとかだったりしないんですかね。

基盤:マイナンバーがどうとか書いてますが、要は保険証番号持ってればそれを書いて協会けんぽに送るだけでオッケーってことですね。

社長:じゃ印刷したのにサインしてと。

経理:明日投函しておきます。

開発:郵便配達したついでに収集もしてってくれると良いのにね。

* * *

社長:ああ、それで飲んでる時にこの「明るく高コントラストの「空中ディスプレイ」、マクセルが開発 感染症予防にという記事を見たのですが、冗句かと思いましたよ。

開発:感染症予防とか個別の話じゃなくて、世の中を変えるくらいのインパクトがありそうですけどね。

社長:でこの記事をiPhoneのメモというかAppleのNotesに入れたのですが、その時、あー、よろずブックマークって全部Notesでいいかなと思ったんです。

社長:どんなコンテクストでも、ワンタッチとかワンクリックでノートに追加できるようになっているといいかなって。

開発:NotesとMailの密接な連携というか基盤の共有が期待されますね。

* * *

開発:それで grep するとその、指定された URLをウィンドウで表示するというのは openLinkIn という関数のように見えます。なので、JavaScriptで定義してあるらしきそれを無効にして何が起こるか見たのですが、効果がありません。

開発:そもそもどこにmainループらしきものがあるのか… どうもこの、toolkit/xre/nsAppRunner.cppの先らしいですが… これって browser/app/nsBrowserApp.cpp より後にコンパイルされるんですね。それでビルド途中で打ち切ったら反映されなかったと。browser/base/contentの下のjsもそうなのかな…

開発:ところでこのnsAppRunner.cppの中にある command-lineというのがやたら気になりますね… あれ?

/*
* XRE_mainRun - Command line startup, profile migration, and
* the calling of appStartup->Run().
*/

開発:そうですか。toolkit/components/startup/nsAppStartup.cpp臭いですね。ああ、コンソールにメッセージ出したいんですが。printfできればいいのに。

社長:C++なんで、できるんじゃないですか?

開発:あ、できたw。でその mAppShellというのはどこから来ているのか… いいかげん追いかけるの飽きてきた。

基盤:gdbで止めてスタックを見ればよいのでは。

開発:でもこの mach run とかいうのが何をやっているのかわからないので… でもひょっとして直接 firefoxのバイナリを起動したら動いたりして obj*/dist/bin/firefox… なんだ、普通に立ち上がるんですか。では gdb obj*/dist/bin/firefox… なんかマルチタスクでマルチスレッドでよくわからないというか途中でとまるというか… ^C! あ、なんか動き出した。^C!。コマンドモードになしました。bt。

社長:大変おなじみの画面になりましたね(^-^)

開発:ということで、敵の本丸は widget/gtk/nsAppShell.cpp:PollWrapper() にありました。さっそく printf を突っ込んでコンパイル。

社長:ちょっと休みますか。なんか、さっきからストラビンスキーがかかってて妙にハマるんですがw

基盤:しかしこの、コンパイルに8分待つのはつらいというか、なんかおかしいですね。たぶん、ビルドのオプションが変。

* * *

開発:では起動…

開発:しまった、pid も出すべきだった。

社長:でも、 pollしているfdは4つ程度ですね。

開発:まあ、マウスとキーボードとtty?いや、Xからのメッセージ?てこれ、X Windowなんですかね?

基盤:psするとx11 というプロセスがありますし、DISPLAYという環境変数も。

社長:なんにしても、あとはうちのコマンド受信用のソケットなりttyなりをpollに入れてもらえば参入可能ですね。

開発:それって、pollをタイムスリッパ式に差し替える手で、既存のバイナリにも適用できますね。

基盤:キー入力のX11のパケットを作っちゃうとか?

開発:とりあえず標準入力をpollして入力があったらエコーするようにしてみます… ああ、できますね。ただ、これいじるごとに8分待ちでは話にならないので、コードはbrowser/app/nsBrowserApp.cppに追加することにしましょう。widget/gtk/nsAppShell.cppのpollにフックをかけてこっちにコールバックさせると。

社長:といいますか、うちの拡張部分はshared libraryにして、Firefoxのリビルド無しで済ませたいですね。

* * *

基盤:それにしてもあの台所の換気扇うるさいですね。すごく昔のだし、無駄に電気も食ってそう。

経理:大変です。我社初の誤発注発生。Thunderbolt - Ethernetアダプタを購入したのですが、Thunderbolt のコネクタの形状が…

開発:なにこれ?ミニディスプレイポートみたいな。

社長:Appleの妙ちくりんインターフェイスには昔から泣かされてきましたねw

* * *

開発:うーん、ツールキットとmainとの間でコールバック用の関数を渡す方法というかリンカーで解決してもらう方法がわかりません。ツールキット側でも参照が閉じている必要があるらしく… 面倒くさいから環境変数でアドレス渡しちゃいますかw

社長:なんでも良いです。とりあえず先導坑を開けましょう。あれ?先進導坑っていうのかな?

開発:まあ何で渡すにしても、仕様と作成者の署名をして突き合わせればいいっちゃいいんでしょうけどね。

開発:ではこんな感じで。

開発:コードの変更後、ブラウザのリビルドに9秒未満。起動すると変更が反映されています。

社長:生産性50倍向上ですね。

開発:でもってpollしてエコーさせたのがこれ。

基盤:複数のプロセスで取り合っちゃってますね。

開発:まあこれは、一文字毎にselectしてますからね。でも、もしFirefoxの各プロセスが同じファイルディスクリプタを継承していたら、起こらない話ではありません。ていうか、この3つのプロセスって何なんですかね。表示されているのは一つのタブだけなんですが。

基盤:-prefsLen という引数が違うだけみたいですね。

開発:X WIndow のインベントだとすると、現在アクティブなウィンドウに行きますよね。まあ、あれは同じファイルディスクリプタを共有してたりはしないんじゃないかなぁ… まあ、ファイルディスクリプタの挿してる先の素性を調べてみればわかることですが。

社長:全ウィンドウにブロードキャストというかマルチキャストしたい事もあるでしょうね。なんかもう、VIABUSを思い出しちゃいます。

開発:別種のブラウザ間を接続して仲良くさせるバスにもなると良いですね。

社長:今日はビルドの仕方も思い出したり、手の突っ込み方も結構見えて来ましたし、このくらいにしましょうか。

-- 2020-0729 SatoxITS