Avatar

storj試してみた

本当はEthereumをマイニングしてみる(2017夏) - MOLのようなかっこいい mining rig が欲しいけど、とりあえずmacbookでやってみたら熱くなって電池が痛みそうなのでやめてOSXですぐ動くstorjを試してみました。

storjは計算するわけでなくストレージを貸すだけでGPUもCPUもいらなくてマシンが熱くなったりもしません。アーキテクチャはブロックチェーンを利用したストレージサービス「Storj」に詳しく紹介されています。

Storj - Pricingを見るとamazon S3の2/3くらいの価格。安定したlatencyで確実にread/writeできるならおもしろいかもねというわけで試してみました。

farming

storjはストレージの貸し出しのことをfarmingと呼んでいます。 OSXで動くGUIのクライアントがあってすぐに始められますが、これはElectronのラッパーになっていてウインドウを閉じるとdaemon自体も止まるので真面目にやるならCLIのStorj/storjshare-daemonにしましょう。

READMEに書いてある通りにやったら動いた気がします。

write

Storj/core: Implementation of the Storj protocol for Node.js にあるexampleで認証/アップロード/ダウンロードとひととおりのことができます。

bucketはwebで予め作ったほうが楽です。APIで使うのはbucket名でなくbucketIdなのでメモりましょう。同様にuploadしたファイルもファイル名でなくidでアクセスします。(なので不便です)

1.1Gのファイルを書き込んでみたところ、書き終わるまで4分。S3の場合2分でした。

もうひとつ880Mのファイルを書き込んでみたら3分だったのでだいたい 300M/min くらいのスループットです。

read

読みます。

アップロード時に鍵を生成して暗号化したものをアップロードするので、ダウンロード時にも同じ鍵が必要です。アップロードした1.1Gのファイルをダウンロードしてみようとしたら、すぐに Missing shard と出てきてダウンロードできませんでした。

壊れてるのかなと思って60バイトのファイルをアップロードしてみたら今度は正しくダウンロードできました。

880Mのファイルは15分で90Mくらいがダウンロードされたので400M/1hくらいです。

まとめ

  • 書き込みは 300M/min くらい。そこまで遅くない。
  • 読み込みは 400M/h くらい。書き込みの1/50くらいの速度です。
  • アップロード/ダウンロードする環境で共通の暗号化用の鍵が必要。
  • ファイルが読めないこともありそう

適用できるアプリケーションを選ぶストレージです。ちなみにはじめの1年は25Gまで無料です。

farming儲かるの?

STORJ.IO — How much will I make from DriveShare? のはじめに投げやりな感じで we don't know と書いてあります。

そのあとちょっとまじめな試算があって、13Tのスペースを貸し出してアメリカの電気代を払ってハードウェアを3年で減価償却したとして$67/monthの利益が出る、と書かれています。

自分のところでは昨日から1日動かして9Gしか貸し出されないので、今のペースで行くと13Tのスペースを貸し出せるようになるには4年後になります。

Avatar

Google Sheetsでi18n文字列を管理してi18n-jsで使う

Google Sheetsで作ったシートをtsvでpublishする機能はデフォルトでついているので、そのtsvをi18n-jsで読み込める形式に変換するパッケージ tsv-i18njs を作りました。

なんでGoogle Sheetsでi18n文字列を管理するの?

Railsだと config/locales の下にロケールごとに *.locale.yaml のファイルを作って管理するけどこの方法は以下の点で好ましくありません。

  • 文言の変更をエンジニアが対応しないといけない(お互い面倒でやりたくなくなる)
  • 特定ロケールで文言が欠けていても気がつかない

その点sheetsで管理するといいことばかりです。

  • だれでも変更できる
  • conditional formatting で特定ロケールで欠けていてもすぐ分かる
  • sheetをそのまま外部に翻訳依頼できる
  • =GOOGLETRANSLATE() も使える(いいかんじにはならないけど)

そこでこういうsheetでi18n文字列を管理しています。

各セルは [Format] → [Conditional formatting...] で Custom formula is

=AND(AND(ISBLANK(B1), NOT(ISBLANK($A1) )), ISERROR(find("#", $A1)))

にしてあるので文字列が欠けていると色が変わってすぐに分かります。

使い方

Expoで React Native のプロジェクトで使うのでビルド時に実行するようにしています。

node_modules/.bin/tsv-i18njs.js \ 'https://docs.google.com/spreadsheets/d/e/2PACX-1vSUUk1_F-VxePs-exsB6R2F3fVIcAdxRRVLxgxz0uV4_Y0xPFDfMrLjvMAHQeYO4EXelqaJ2fgiNmF2/pub?gid=0&single=true&output=tsv' \ ./translations

これで translations/ 以下にこういう構造の

// THIS FILE IS GENERATED BY tsv-i18njs // DO NOT MODIFY DIRECTLY. module.exports = { "screen": { "welcome": { "hello": "Hello" } }, "currency_sign": "$", "ok": "OK", "cancel": "Cancel" }

ファイルが生成されるので、適当なコンポーネントで初期化して使います。

import I18n = require("i18n-js") import en from './translations/en' import ja from './translations/ja' import zh from './translations/zh' async componentWillMount() { I18n.translations = { en, ja, zh } await I18n.locale = Expo.Util.getCurrentLocaleAsync() }

refs

Avatar

faradayで無条件にずっとキャッシュさせる

faraday-http-cacheでふつうにキャッシュするとレスペンスヘッダの指定に従ってキャッシュがexpireする。が、Faraday::HttpCacheにレスポンスが渡される前にヘッダを加工すればexpireしなくなる。

class NeverExpire < Faraday::Middleware def initialize(app, *args) super(app) end def call(env) dup.call!(env) end def call!(env) response = @app.call(env) response.headers['max-age'] = 86400 * 365 * 10 response.headers["Expires"] = "Thu, 14 Nov 2024 01:44:36 GMT" response end end

client = Faraday.new do |builder| builder.use :http_cache, store: Rails.cache builder.use NeverExpire builder.adapter Faraday.default_adapter end

Avatar

mitmproxyを使ってSSL通信の中身を確認する

MacでiPhone上で行われている通信の内容を調べたい。HTTPのときはWiresharkで見られるけれどSSLのときはCharlesでもできるらしいけど、ちょっとだけ使うには少し高めなのでmitmproxyを使います。mitmproxy - SSL interceptionに書いてあるSSLでの使い方をそのままやるだけでできます。

インストール

wget http://mitmproxy.org/download/mitmproxy-0.6.tar.gz | tar xf cd mitmproxy-0.6 sudo python setup.py install curl http://excess.org/urwid/urwid-1.0.1.tar.gz | tar xf - sudo python setup.py install

OSX 10.7だと問題なくインストールできたけど10.6の場合urwidのインストールで

lipo: can't open input file: /var/tmp//cc5eveXg.out (No such file or directory)

と言われて失敗するので[Urwid] Build problem with urwid-0.9.9.2.tar.gz on Mac OS X 10.6.8に従って

sudo env ARCHFLAGS="-arch i386" python setup.py install

とします。

iPhone側設定

次にmitmproxyを信用してもらうためにiPhoneに証明書をインストールします。

証明書の転送

Img 1186
ALT
Img 1182
ALT

一度/usr/local/bin/mitmproxyを実行して起動して生成された証明書をiPhone実機に転送します。mitmproxyを起動すると~/.mitmproxyディレクトリにmitmproxy-ca.pemという名前の証明書ができているので、これをメールに添付してiPhoneに送ります。 メールアプリで添付ファイルを開くとprovisioning profileのインストールと同じ画面が出てきます。 このときロックスクリーンにパスワードをかけているとそのパスワードを聞かれます。はじめ何のパスワードなのかわからなくて困りました。

WiFiのproxy設定

Img 1184
ALT

[設定]→[WiFi]→OSXで共有設定したネットワークの詳細ボタンでproxyの設定をします。mitmproxyのデフォルトは8080ですが、ここでは1080に変えています。

起動

iPhone側の設定が終わったらOSXでmitmproxyを起動します。ポートを変えたので-pオプションでポートを指定しています。

sudo mitmproxy -p 1080

このときsudoで起動しないとドメインごとの動的な証明書の生成ができないようでEvent log(mitmproxy起動時にvを押すと出る画面)に

SSL routines:SSL_CTX_use_certificate_chain_file:PEM lib

と出てきてブラウザが繋がりませんでした的なエラーを出して表示してくれません。mitmproxyがSSLの証明書を生成できないのでSSLコネクションが確立できないけれどTCPレベルでは繋がっている状態です。

つないでみる

proxyの設定を反映させるためにMobileSafariを一度終了させます。再度起動してテストとしてhttp://www.google.com/につなぎました。 そうすると送っているリクエストのリストが出てきて ↑↓でリクエストを選んでReturnで詳細が表示されます。 Tabを押すとレスポンスが表示されます。 前の画面に戻るにはqです。 pythonでスクリプトを書いてサーバから受け取ったレスポンスを書き換えてクライアントに渡したりもできて、それによってiOS上で動いているアプリのUIWebViewにweinreを流しこんでインタラクティブにハックすることができるようになります。時間なくなったので帰ったら書く。

Avatar

javascript vs PHP 速度比較

はじめに

WebKit, Chrome, Firefox, Operaでjavascriptのスピードアップ合戦を繰り広げている結果そのへんのLightweight programing languageより速くなっているのではないか、という予測におおまかな数字を与えるために測ったものです。本当にどちらが速いのかはHTTPサーバ・データベース・アプリケーションによるので、これはあくまでどの程度なのかを知るためのものです。

ユースケース

友だちが100人ずついるAさんとBさんの共通の友だちを探します。データベースから持ってきたレコードを手動でjoinする処理です。今回は言語の実行速度のみを知りたいのでデータベースから持ってくる部分は測る時間に含めていません。 速度を意識した実装はしないで、普段書いているような記述にしています。評価環境はmacBookPro"15 2.4GHz Core i5 です。

javascript

node.js 0.4.11を使いました。だいたい2.9秒。

function virtual_friends() { var friends = []; while (friends.length < 100) { var n = Math.floor(Math.random()*10000); if (!friends.some(function (v) {return v === n})) { friends.push({user_id:n}); } } return friends; } var a = virtual_friends(); var b = virtual_friends(); var starts = Date.now(); for (var i = 0; i < 100 * 1000; i++) { var user_id_key_table_a = {}; a.forEach(function (u) { user_id_key_table_a[u.user_id] = true; }); var friends_in_common = []; b.forEach(function (u) { if (u.user_id in user_id_key_table_a) { friends_in_common.push(u); } }); } var ends = Date.now(); console.log((ends - starts) / 1000);

PHP

PHP 5.3.4を使いました。だいたい3.25秒。

<?php function virtual_friends() { $friends = array(); while (count($friends) < 100) { $n = rand(1, 10000); $m = array_search($n, $friends); if ($m === false) { $friends[] = array( 'user_id' => $n ); } } return $friends; } $a = virtual_friends(); $b = virtual_friends(); $starts = microtime(true); for ($i = 0; $i < 100 * 1000; $i++) { $user_id_key_table_a = array(); foreach ($a as $u) { $user_id_key_table_a[$u['user_id']] = true; } $friends_in_common = array(); foreach ($b as $u) { if (isset($user_id_key_table_a[$u['user_id']])) { $friends_in_common[] = $u; } } } $ends = microtime(true); print $ends - $starts;

考察

というわけで、これだけではなんとも言えませんが、この例ではjavascript(node.js/V8)のほうが速かったです。この例はV8のJITが効きまくるのが明らかなのでV8に有利すぎる設定なのかもしれません。 この共通の友だちを探すのは一般的なウェブアプリケーションのロジックの中では例外的にCPU intensiveな処理で、実際のアプリケーションでコードを見てみたところ大半はDBから持ってきた変数をテンプレートエンジンにセットするだとか、JITの効かなそうな処理が多かったです。それでもnode.jsインスタンスがずっと動いているなら二度目のリクエストからはJITの恩恵に預かれるのかもとか、そんなことを考え始めるときりがないのでこのへんで。

Avatar

Androidで画像がぼやけるのはなんで

画像の1ピクセルが実際のデバイス上で何ピクセルとしてレンダリングされるかを示す-webkit-device-pixel-ratioという値があります(この値はwebkit系であればwindow.devicePixelRatioに入っています)。 iPhone4ではこの値が2になっていて、今まで通りに画像を表示させると自動的に拡大されてなんかぼんやりしたかんじになってしまいます。 これを避けるには、実際に表示させたいサイズの2倍のピクセルサイズのものを用意して、でも縦横を1/2にして表示させると画像の1ピクセルとデバイスの1ピクセルが1:1対応になって拡大されることなく表示されるようになります。 で、日本のキャリアが販売している多くのandroid端末でこのdevicePixelRatioが1.5になっています。意味わかんない。 画面を写真に撮ったものなのでわかりにくいですが、上が45x100ピクセルの画像をそのまま45x100ピクセルで表示したもの。下は90x200ピクセルの画像を45x100ピクセルで表示したものです。上はなんか滲んでますが下はきれいに表示されています(ぼんやりしてるのは写真だから)。 身近にあった端末でdevicePixelRatioを調べたところ以下のとおり。

端末 devicePixelRatio IS02 1.5 IS03 2 xperia 1.5(たぶん) SH-03C(LYNX 3D) 1.5 005SH 1.5 001HT(Disire HD) 1.5 001DL 1 004HW 1

というわけで表示させたいピクセル数の1.5/2倍のサイズで画像を用意して表示すればぼんやりしないです。

追記

Philosophical Games: Customize Android Browser Scaling with target-densityDpi WebView | Android Developers <meta name="viewport" content="width=device-width; target-densitydpi=device-dpi" />でデバイスの1ピクセルに画像の1ピクセルが表示されるようになります(そのぶんページ全てがちっちゃく表示されます)。 via Twitter / shogo: @ku これかな http://darkforge. ...

Avatar

Flashのことを笑っている場合じゃない

Web開発の現状を25のトゥウィートで斬るとこうなる–iPhoneを見捨てたFacebookデベロッパの告白のはなし。 Apple vs Adobeで大揉めしてみんなに楽しい娯楽を提供してくれているけれど、我々ウェブ開発者(というのは大雑把すぎるくくりだけれど)にとってはFlashなんてはなから選択肢に入っていないのだから単なるゴシップでしかない。 でもJoe Hewittの話はひとごとではない。 彼は10年前の2001年にcanvasを実装し[canvas]、Firebugを作り[firebug]、facebookのiPhone向けWeb版を作り、facebookのiPhoneアプリを作りセットでいろんなiPhoneアプリで使われてるthree20を作り、Appleの身勝手にうんざりしてiPhoneアプリはもうやらないと宣言してた。 彼のいまのウェブに対する見方はこのふたつのtweetに集約されてる。

I've always preferred the web, but native platforms have been kicking its ass. I go where the power is. Twitter / Joe Hewitt: @sprynmr I've always prefe ...
Hopefully we'll look back on today as the day the mobile web began to eclipse proprietary mobile platforms. Still a ways to go, though. Twitter / Joe Hewitt: Hopefully we'll look back ...

いつだってウェブのほうが好きだけど、今はネイティブアプリがきてる。自分はパワーのあるところに行く。 いつか今日が独占的モバイルプラットフォームをモバイルウェブが侵食し始めた日だったって振り返れたらいいね。まだまだ先そうだけど。

the web sucks

TechCrunchには載ってなかったけどHewittがtwitterで紹介していた The web sucks. Browsers need to innovate - Sachin's Posterous この記事は秀逸だ。いかにブラウザを基盤としたウェブアプリがだめで、ネイティブプラットホーム上のアプリが優れているかについて細かく例を挙げて教えてくれる。(日本語でも読めるよ PosterousのCEO「Webはクソ。ブラウザはマジなんとかしろ」 - 床のトルストイ、ゲイとするとのこと) そして現実にiPhoneユーザの多くは普段ネイティブのアプリを利用していて、ウェブアプリを使っていることは稀だ。twitterやgmailはiPhone向けに最適化されたウェブページを持っているが一体誰がそれを使っているだろうか? ネイティブアプリは文字通りなんでもできる(Appleがダメだということを除いて)。ウェブアプリにはブラウザでできることしかできない。 いままでウェブ開発者はブラウザでできないことはできないのだと無意識に思い込んでいたけれど、iPhoneアプリがコンピュータにはなんだってできるんだということを思い出させてくれたはずだ。アプリで写真をとって位置情報つきでサーバにアップロードするみたいな今となっては当たり前のようにやっていることができないし、後で読むためのフィードデータをバックグラウンドでデータをダウンロードして保存しておくことはウェブアプリでもできるけどネイティブアプリと比較するとパフォーマンスが悪すぎる。 これからの主戦場である(既にそうだ)モバイルプラットホームでウェブ/ウェブアプリはユーザに選ばれなくなって、代わりにネイティブのアプリケーションに時間が費やされている。 スティーブジョブズはiPhoneにFlashを載せない理由としてThoughts on Flashで"中間層がイノベーションを阻害するから"だと言った。それは"Flashを載せないため"の理由でしかないだろう。Flashのことは我々には関係ない。でもHTMLだってプラットホーム上にある中間層であり、イノベーションについていけてない(=阻害している)のはFlashと同じだ。 この一連の話が気になったのは、まえに似たようなことを思ったからだ。 2008年の12月にiPhoneのアプリを書いてたときにこう書いてた。

なるほど、ウェブの時代は終わって再びソフトウェアの時代が帰ってきたのだ。 not enough memory

余談

ウェブアプリケーションだけがウェブじゃないみたいな話は Understand The Web · Ben Ward に書かれてました。 The web sucks. Browsers need to innovate - Sachin's Posterous

People are using apps more because the experience is much better. We will see a decline in web traffic and search in the coming years

というくだりがあってはっとさせられるもののそんなでもないんじゃないかと思うけど、でも既にGoogleはちゃんとAndroid+AdMobを持っている。

参考

  1. Twitter / Joe Hewitt: While waxing nostalgic, I ... Bug 102285 – create xul canvas tag for custom painting control
  2. Firebug :: Add-ons for Firefox
Avatar

GoogleChromeの拡張を作る上でFirefoxアドオン作者が知っておくべきやればできること

GoogleChromeの拡張を作る上でFirefoxアドオン作者が知っておくべき10の違い【GoogleChromeでニコ動拡張を作ってみた感想】 - love_firefoxportableの日記についてMySpaceのMP3ファイルにID3tagを埋め込みつつダウンロードするJSActionsスクリプトを作ったあたりからFirefoxアドオンの柔軟さに魅了されていろいろ作ってきたけどChromeのUIのブロックしなさが快適でChromeにスイッチしようとしている人間が書きます。 将来にわたってChromeのextensionでFirefox addonのような自由度が実現されるようなことはないと思いますが、それでも今の段階でやればできることもちょっとあります。大半はできないけど。

右クリックはいじれない

いじれません。このへんまだ実装自体がやっつけな感じなので将来的にはいじれるようになるんじゃないかと思ってます。 API Wish List (The Chromium Projects)にも載っています。

補足 2009.12.16

Context menu is potentially on the M5 list. Exposing Chrome Extensions APIs to DOM UI. - Chromium-dev | Google Groups

だそうなので来年前半には実装されそうです。

データのダウンロード保存はできない

chromeのダウンローダでダウンロードすることはできませんが、どうしてもダウンロードしたければNPAPI pluginを作ればできます。

クリップボードの操作はできない

補足 2010.1.7

NPAPI pluginを作ればできます。(ex. chromeでMake LinkみたいにページのHTMLリンクをコピるCreateLink « ku) 通常NPAPI pluginを使うと通常のウェブページからもpluginの昨日にアクセスできてしまいますが、chromeのNPAPI pluginはextensionのオリジンからだけ有効にすることができるオプションがあります。これによってobjectタグを通じて通常のウェブページからは利用できないけれどextensionからは使える関数を用意することができます。 ただ現状プラットフォームごとにべつべつのバイナリを用意することができなくて、ぜんぶおんなじバイナリを読み込むのでターゲットのプラットホーム以外で読み込むとクラッシュしたりします(公式リリースではextensionはwindowsでしか動かないことになっているので問題ないといえば問題ないんでしょうけど...)。これは中の人もちょう怒ってました。Extensions and the Mac - Chromium-dev | Google Groups

ブラウザの通信に対してフックをかけることはできない

できません。 が、Extensions API proposal: access to the HTTP request - Chromium-extensions | Google Groupsで作りたいっていってdesign docを書いてる人がいたのでできるようになるかもしれません。書かれたのは3ヶ月前でその後音沙汰ないですが...

DOM構築前のデータを弄ることはできない

できません。これってFirefoxだとどうやったら実現できるのか知りたいです!

ブラウザの下部に新しくツリーボックスを作る等、ブラウザの構造を変えることはできない

できません。ここはFirefoxの奇跡だと思っています。 昔Netscape社でNavigator6を作り、今はChromeの開発をしているBen Goodgerさんのmillennium | Google Chrome Extensionsを読むと、もともとFirefoxのextensionでブラウザ自体のUIをいじれるようになっているのは意図して設計されたわけではなかったと書かれています。Navigatorの内部で使うためのAPIをハックしてUIをカスタマイズできることが発見されて、それが人気があったので長い年月を経て生き残り、現在のようなextensionにまで成熟したと書かれています。

If this “back door” into browser customization hadn’t existed by virtue of Netscape’s componentized install, it’s not necessarily a given that Firefox would _ever_ have had extensions. Think about that. It’s awesome that it did, because it’s a feature users love.

Firefox extensionの自由さは偶然から生まれて今に至るのです。

外部exeを実行することはできない

NPAPI pluginでできます。

XMLHttpRequestはクロスドメイン制限を受ける(content_scriptsの場合)

これはいちおうbackground pageからきるけどreferrerがつけられないことが大きな制約として残るだろうとConstellationさんが言っていました。が、NPAPI pluginでやればなんでもできます。

content_scripts内のjsからlocalStorageにアクセス出来ない

バグな気もします。Greasemonkeyとは名前空間の分離の仕方が違うことに起因してます。Chromeでどうやって分離しているかはAaronのブログに図解があります。 aaronboodman.com - Aaron Boodman's work blog

javascript1.6とか1.7とか1.8は無い

1.6の範囲はchromeでもサポートされています。個人的にはE4Xがサポートされてないのが辛いです。でもこのへんはFirefoxでしか使えないのでFirefoxが勝手(?)に色々つけくわえてるという印象が...

拡張を大量にぶちこんでも重くならない

FirefoxのUIがブロックする=重たい印象になってると思われるのでFirefoxでもelectrolysisでかなり改善されるんじゃないかと思っています。 たしかにChromeは拡張の量が増えてもUIは重くなりませんが、絶対的に重くならないなんてことは当然なくて、たくさんインストールするとレンダリング終了までにかかる時間は長くなるという結果がパフォーマンステストから示されています。 Extensions performance data - Chromium-dev | Google Groups

結論

  • Chromeでサポートされていないけど欲しいものはNPAPI pluginを使って自分で作ればいろいろできるようになります。NPAPI pluginを作るのは面倒ですがnixysaを使うと少しは楽に開発できるらしいです。いまのところnixysaを利用してWindowsで動くバイナリを作るにはハックしてモノにする必要があります。そのハックはネイティブのアプリケーション開発に詳しくないと難しかんじです(CreateLinkはふつうに手で書いて作りましたが、その時バージョンストリングなどが入ったリソースファイルをリンクしないとchromeがpluginとして認識してくれないという謎現象に遭遇しました)。
  • Firefoxアドオンの自由度は奇跡的です。millennium | Google Chrome Extensionsを読んでその奇跡を噛み締めましょう。

所感

自分も「GoogleChromeマジ神wwwwwwwwFirefox(笑)」な人を見るとアホかと思いますが、実際のところ大半の人は現在のChromeの貧弱なAPIでできる範囲の拡張でほとんど困らないんだと思います。 それはたまたまなわけでもなくてAaron Broodmanが書いているように

Here's an interesting factoid about browser extensions: lots of them are not about extending the browser at all. By my count, about 75% of the this week's top 20 Firefox extensions are more about extending the web content rendered by the browser than extending the browser itself. aaronboodman.com - Aaron Boodman's work blog

AMO上位20拡張のうち75%はGreasemonkeyでできることしかやっていない現実を反映しているだけなんでしょう。たしかに自分も職場のWindowsマシンのChromeにはAutoPatchWorkしか入っていません。そしてこのExtensionはGreasemonkeyでできる範囲のことしかやっていません。実際AutoPatchWorkの祖先であるAutoPagerizeはGreasemonkeyのスクリプトです。 ただ予め意図されているようなextensionしか作れないChromeに押され、極めて柔軟で大半のことは実現できるFirefox extensionの開発者が減っていけば、ブラウザの使い方が均質化して行き、ひいてはウェブ上でのサービスの進化が鈍ってしまうのではないかという恐れを感じます。

Avatar

pearのHTTPプロキシ設定

借りてるサーバでpearが全然動かない。

% sudo pear install HTTP_Client No releases available for package "pear.php.net/HTTP_Client" Cannot initialize 'channel://pear.php.net/HTTP_Client', invalid or missing package file Package "channel://pear.php.net/HTTP_Client" is not valid install failed

よくわからないままchannel-updateしても動かない。

% sudo pear channel-update pear.php.net audit_log_user_command(): Connection refused Updating channel "pear.php.net" Cannot retrieve channel.xml for channel "pear.php.net" (Connection to `172.20.25.95:18080' failed: Connection timed out)

困ってソースを見ているうちにpearにPEAR/Config.phpという設定ファイルっぽいものがあるのを知った。 それならばその設定を見るオプションがあると考え探すとpear config-showで見られることが分かった。

% pear config-show Configuration (channel pear.php.net): ===================================== Auto-discover new Channels auto_discover <not set> Default Channel default_channel pear.php.net HTTP Proxy Server Address http_proxy http://172.20.25.95:18080/ PEAR server [DEPRECATED] master_server pear.php.net Default Channel Mirror preferred_mirror pear.php.net

無効なproxyが設定されていた。

% sudo pear config-set http_proxy "" config-set succeeded

これで解決。pearが使えるようになった。

Avatar

chromeでMake LinkみたいにページのHTMLリンクをコピるCreateLink

Twitterにページのリンクを貼るときや、ブログを書くときにFirefoxではMake Linkというアドオンを使うと右クリックのメニューから選ぶだけでテキスト+URLや

chromeでMakeLinkみたいにページのHTMLリンクをコピるCreateLink « ku http://ido.nu/kuma/2009/12/10/create-html-link-with-createlink-for-chrome-like-makelink/

HTMLのリンクをクリップボードに作ってくれます。

<a href="http://ido.nu/kuma/2009/12/10/create-html-link-with-createlink-for-chrome-like-makelink/">chromeでMakeLinkみたいにページのHTMLリンクをコピるCreateLink « ku</a>

そのchrome版を作りました。NPAPIを使っているのでwindowsでしか動きません。

インストール

コード

余談

クリップボードにデータを転送する部分はちぎってほかのextensionから使うことができるので、クリップボードを使いたいときにはご利用ください(ただデータをセットできることしか必要なかったのでそれしか実装してません)。

予定

  • NPAPIはChrome Galleryのレビューを通過できるのか試してみます
  • ほんもののMakeLinkのようにフォーマットをカスタマイズできるようにしたいです
Avatar

ManualPatchWorkを使って手動でAutoPatchWorkにページをロードさせる

補足

Chrome Keyconfigでも手動でロードできます。

日経ビジネスオンラインの記事のようにフッタが異常に長くて本文の最後まで読んでもAutoPatchWorkが次のページを読み込んでくれないようなサイトでJを押したら手動で次のページを読み込むことができるchrome extensionをつくりました。

インストール

manualpatchwork.crx こんなかんじで本文よりもフッタのほうが長いページでもJを押したら次のページがロードされます。 はじめREMAIN_HEIGHTで判断するのをやめてnextLinkとpageElementの位置関係とスクロール状態から次のページをロードするかどうか決めれば自動でできないかと思ったけど本文の下にリンクが有るとは限らないのとnextLinkがpageElementの中に入ってたりすることもあるので無理そうでした。

Avatar

HTTP::Request::Commonでsjisをエスケープしたパラメータにゴミが入る

解決

name => "北海道";

'name' => "北海道";

とクオートしたら期待通りに動きました。 ありがとうございます。

use strict; use warnings; use utf8; use Encode; use HTTP::Request::Common; my $name = "北海道"; $name = encode('shift_jis', $name); my $req = POST 'http://ido.nu/kuma/pref', [ name => $name ]; print $req->as_string;

こういうコードでクエリで送る文字列をsjisでエスケープされたものにしたかったんだけどうまく行かないので表示させてみたら

POST http://ido.nu/kuma/pref Content-Length: 31 Content-Type: application/x-www-form-urlencoded name=%C2%96k%C2%8AC%C2%93%C2%B9

%96k%8AC%93%B9になるべきところに%C2がやたら混じっていて文字が壊れている。 use bytesで囲めば直る。

{ use bytes; my $req = POST 'http://ido.nu/kuma/pref', [ name => $name ]; print $req->as_string; }

でももとのコードでなんでうまくいかないのか分からない。

Avatar

chrome + NPAPI / nixysa

Google Japan Blog: Google Chrome 拡張(Extensions) を作ってみませんか?に参加しました。事前のアイディアソンでSCRAPBOOK :: Firefox Extensionみたいにページの中身をダウンロードしてローカルに保存してあとで見られるようにするextensionを(HTML5チーム6人で)作る、ということになったのはいいものの、ちょっと調べてみるとファイルをローカルにダウンロードするいい方法がありません。 chrome extensionのAPIにはファイルをダウンロードさせるAPIがありません。gearsのlocal serverを使うと新しいドメインで使用するたびにgearsを使っていいかのダイアログが出るのに加えて同じドメインにある画像しか保存できません(画像はamazonS3だったりするサービスも多くなってきているのでページと同じドメインしかキャッシュできないのは困る)。

nixysa

そういえばextensionでNPAPIのpluginを読み込ませられるからそれで解決できるのでは、と思って何も知らないところから調べ始めたらFirefoxやChromeのPlugin開発に便利なnixysa // CIOを目指しつつの8makiのアレnixysaというので簡単にNPAPI pluginが書けるというのを発見しました。じゃあこれでやってみるかということではじめにHelloWorldWalkThru - nixysa - Hello World Walk-Thruをやりました。環境はWindowsXP SP2+VisualStudio2008です。

scons

どうもこのチュートリアルはLinuxを対象にしているようでWindowsで動かしたい時は書いてありません。でもchromium本体をビルドする時にBuild Instructions (Windows)に従って作ったcygwin環境を使ったらビルドすることができました。ただはじめにsconsがpythonのモジュールplyとgflagsがないと言ってこけます。これはnixysaをsvnからcheckoutしてきたときにthird_party/の中に入っているのでそれを

./setup.py install

でインストールすれば動くようになります(入っているのに気がつかなくて自分でダウンロードしてきました...)。

std::wstring

sconsが動いてコンパイルが始まると今度はnixysa/static_glue/npapi/common.hでgccがstd::wstringというクラスはないと言い出してこけます。これはcygwinのgccがそういうものだそうでgcc(cygwin)でのstd::wstringの利用方法 -OKWaveに素っ気なく書いてある

typedef basic_string<wchar_t> wstring; としてみる

という回答以上に詳しいことが書かれているものを見つけられなかったのでcommon.hにそう書いたらコンパイルできるようになりました。なんでcygwinのgccはwstringが使えないんでしょう?

about:plugins

これでsconsを実行するとめでたくhelloworld.dllができあがりました。manifest.jsonにpluginsを追加してhelloworld.dllを指定するとchromeでabout:pluginsを開くと、プラグインのリストにhelloworldが入ってるはずなのですが出てきません。なんとかしたいけどそもそもNPAPIがどういう仕組みになっているのかがわかってない状態でnixysaがなんで動かないのかがわかるはずがないのでnixysaはあきらめました。たぶんLinuxだとちゃんと動くんだと思います。

npsimple.dll

ふつうにNPAPIで検索するとFirefox用のコードばかり出てくるので、原理的にはそれでも問題ないはずだけど問題が出た時に何も知らない素人には解決できないからchromeで動くことが分かっているNPAPI pluginのコードを手に入れてそれをいじるという方針に変えて探していたらIssue 13564 - chromium - NPAPI Chrome crash - STRINGZ_TO_NPVARIANT - Project Hosting on Google CodeにNPAPI pluginのひな形のようなものがあるのを見つけました。テスト用についているnpsimple.dllをmanifest.jsonで読み込むように指定するとちゃんとabout:pluginsに出てきます(これでnixysaで作ったDLLがちゃんと機能していないのに確信を持ちました)。 コード自体はnixysaで書くのに比べるとたしかに面倒なのですが、nixysaで簡単になる部分はNPAPIからブラウザにオブジェクトを返すとき、読み込む時のメモリ管理だけで、けっきょくC++でjsのオブジェクトを操作するというめんどくささは変わらないので全体の作業量からすればそんなに便利にはならないと感じました。でもnixysaだと公開するメソッドのインターフェイスをIDLで記述できるので圧倒的に見通しがよくなるし、ミスで引数が違っていて落ちる、というようなこともなくなります。NPAPIの仕組み自体はGecko Plugin API Reference - MDCにしっかり書いてあるので読むとよくわかります。ただ、できることは非常に限られていて、ブラウザに特定のURLをリクエストさせてそのbodyをストリームとして読み取ること、与えられたウインドウ矩形を描画すること、OSネイティブのイベントをハンドリングすることぐらいしかできません。デスクトップアプリケーション開発者ならなんでもできて楽しいかんじですが、ウェブ開発者からしたら"ダウンロードしかできない"かんじです。 で、指定したファイルをダウンロードしてきてローカルファイルに保存する、というNPAPI pluginを作ったけど時間がなくてパラレルにリクエストしたりしてもちゃんと動くのかとか実用に堪えるのかのテストは全くできていなかったのであとで泣きを見たりしそうだったのと手動で環境変数を設定しないと動かないインチキ実装なのとで怖いからハッカソンでは使いませんでした。

コード

Avatar

OSXでRFC2822をフォーマットする

HTTPの日付文字列はあまり使われていないRFC2822になっている。探すとNSDateFormatterを使ったコードがけっこう出てくるけどこのクラスはちゃんと設定されているロケールに応じた日付文字列を返すのでシステムが日本語に設定してあると曜日が日本語で出力されてRFC2822にならない。書いた方が早い。

NSString* rfc2822StringFromDate(const NSDate* date) { time_t t; struct tm tm; time_t epoch = (time_t)[[NSDate date] timeIntervalSince1970]; time(&epoch); gmtime_r(&epoch, &tm); static const char* month_names[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; static const char* day_names[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; return [NSString stringWithFormat:@"%s, %02d %s %4d %02d:%02d:%02d GMT", day_names[tm.tm_wday], tm.tm_mday, month_names[tm.tm_mon], tm.tm_year + 1900, tm.tm_hour, tm.tm_min, tm.tm_sec ]; }

Avatar

chromium for tableauでタグをつけたりできるようになりました

前に作ったやつTomblooのないChromeで自分をちょっとGoogle化する chromium for tableauにフォームをつけました。Windowsでもビルドしてみたんですがメニューは出るけど反応しない状態だったので相変わらずOSX版だけしかありません。 右クリックでメニューが出てくるので タグをつけたりしたい時はShare...のほうを選ぶとフォームが出てきて投稿先のサービスを選ぶことができます。 上の方の矢印ボタンを押せば(ここ壊れてるみたいで矢印出てきませんすみません...) タグやコメントをつけたりもできます。 いまのところTumblr, delicious, google bookmarks, twitter, はてなブックマークを利用できます。 写真以外のところを右クリックすればふつうにブックマークするのにも使えます。 ブックマークするのに使うだけならふつうのchromeでもbookmarkletから使うことができます。ブックマークしたいページでブックマークットを押すと上のフォームが表示されるので、タグやコメントを書いてボタンを押せばブックマークすることができます。

インストール

chromium for tableau本体

tableau(chromium extension)

使い方

ダウンロードしたchromium.appを起動してtableau-0.3.0.crxにアクセスして拡張機能をインストールしてください。

Avatar

Freebaseをサーバサイドjavascript実行プラットホームとして使う

たぶん前(ちょうどappjetが潰れることになった後くらい)に焼き肉に行った時にid:koyachiucnvswdyhyoupyか誰かにFreebaseでappjetと同じようにjavasriptのコードをサーバで実行できる、というのを教えてもらいました。 今日いじってみたらだいたいappjetみたいなかんじでjavascriptでコードを書いたら実行してくれます。必要な範囲でしかいじってないけどappjetより完成度は高い印象。はじめ使い方が全然わからなかったのでメモ。

Getting Started

はじめにFreebaseのアカウントを作ってログインしたらFreebase App Editorにアクセス。 こういう画面が出てくるのでてきとうに名前をつける。 そうするとコードが書けるようになるので(Greasemonkeyと相性が良くないみたいなので、この画面が出なかったらGreasemonkeyをoffにしてみてください) デフォルトではPHPみたいなテンプレートエンジンモードになっていて、scriptで囲まないとjsのコードとして認識されないのでFileからAcre typeScriptに変えましょう。そうするとベタにjsが書けます。 設定を変えたら

acre.write("hello")

と書いて右上のView with Consoleを押せばhelloとだけ書かれたページが表示されます。 あとはHelpにAPI Referenceがあるのでそれを参考にコードを書きましょう。

secrets

Freebaseはning, appjetの影響でconle this appボタンがついていて、ボタンを押すだけでほかのアプリを自分のところにコピーしてきて編集できるようになっています。でもそういう時に困るのが秘密にしておかないといけないAPI keyで、ningもappjetもそれぞれ秘密のAPI keyまでもがコピーされないようにする仕組みがありました。Freebaseではacre.keystoreというのを使って秘密のコピーされないデータにアクセスできるようになっています。 秘密のデータを設定するのはGUIからしかできません。 左上のアプリケーション名が書かれているボタンを押してWeb Servicesのタブを押すと設定できます。

雑感

  • appjetよりも自由度の高いHTTP requestが出せるので便利
  • cronはないっぽい
  • Content-Typeを設定しても反映されない text/plain固定なのかも

ちなみにこのacre本来はウェブ上のデータを持ってきて編集してfreebaseに格納するのに使うためのものみたいです。 まじめにつくればちゃんとしたウェブアプリも作れます。

Avatar

chromeのねんどろいどテーマ

joinだけしてあるのを思い出してtiarraから#chromiumのログを見てみたら

2009.10.01.txt:11:21:40 <#chromium@freenode:aboodman> w00t: http://dl.getdropbox.com/u/124107/success.png 2009.10.01.txt:11:22:03 <#chromium@freenode:aboodman> (first successful render of browser action badges)

Image

というのを発見。 Greasemonkeyのはじめの開発者で今はchromeのextensionまわりの開発を担当しているAaronがiPhoneのアイコンみたいに数字がお手軽に表示できるAPIができたぜー、といってるんだけど このテーマはなんだAaron! Aaronはねんどろいど(わからなかったのでid:HolyGrailに聞いたら速攻で教えてもらえて解決した)のテーマを作ってchromiumに使ったりするキャラだったのか、そうかそうかいいひとそうなオーラを出しているうえにオタク?だなんてほんとうにいいやつじゃないかとおもいました。実際には自作じゃなくてGoogle Chrome テーマ ギャラリー: Good Smile Companyみたいだけどaaronさんいいひとそうです。先々週に結婚されてました。おめでとうございます。youngpup.net - Aaron Boodman's personal blog そんなAaronのextension API仕様に関する後悔。

2009.10.03.txt:05:56:35 <#chromium@freenode:aboodman> you need to pass a null for the first argument 2009.10.03.txt:05:56:37 <#chromium@freenode:aboodman> (our implementation of 'optional' is bad) 2009.10.03.txt:05:56:45 <#chromium@freenode:aboodman> you should have at least gotten an error

僕もそう思います。optionalなのは省略できるんだと思ってました。 もうひとつ。こっちはvideoタグがらみでx264とTheoraのコーデック品質比較画像。

2009.08.13.txt:2435:09:36:26 <#chromium@freenode:Dopefish> Simetrical: http://imk.cx/temppics/extra_x264.png -- http://imk.cx/temppics/extra_theora.png -- the theora one was about 1400 - 1500 kbps higher in bitrate

X264

theora

theoraのほうがぼんやりしてるのにビットレートは高い、のはいいけどそのサンプルがなぜ東方永夜抄なのか!? よくしらないけどいったいどうやって手に入れたんでしょう。 日本はすごいんだということを知った#chromiumでした。

You are using an unsupported browser and things might not work as intended. Please make sure you're using the latest version of Chrome, Firefox, Safari, or Edge.