iOS の容量表示が本当になぞ。
どこをどうみたらこの容量使ってるのか?
このような状況になると、初期化が一番手っ取り早いです。
初期化して、アカウントの設定だけ済ませればいい。
Safariのキャッシュやアプリ状態保存などのキャッシュが影響してるんだろうけど、削除する方法がないんだよね。
この状態で、容量不足と言われると、イラッと来る
markdown でスライド作れたら便利だよねと思っ試してみた。
$>gem install md2key
を実行してインストール$>brew install highlight
でハイライトパッケージを入れる$> md2key sample.md
で変換開始。バババッっと変換されていく様は、爽快感がありました。
フォーマットに沿ったものは綺麗になるし、良く出来てるん。
綺麗になるところは本当に綺麗になる。ハイライトも入る。
用途に合う人は多いんじゃないかな。ぱぱっとプレゼン作るなら便利だと思う。
個人的にコレジャナイ感。
私のマークダウン、画像が多かったり、BASE64でコンテンツ埋まってたりするからどうしても。。。
gfm で変換したり、CSS側で処理することにするよ。webkitFullscreen もあるし。
---
は不要じゃなねーんだよね。page-break after すれば印刷用PDFを経由してPDF資料にできるし。
git add -u .
これだけ。
簡単。
git mv 使うのよく忘れるので、この方法を覚えておくと捗るんだった。
画像のURLをクリックすると、WEBサーバから画像が送信される。当たり前のことですが、この当たり前の処理に、ハンドラを加えてプログラムを追加したいと思います。
http://example.com/img/top_banner.jpg
WEBサーバーは次の処理をする。
Apacheのモジュールや設定はそれぞれ段階で処理を挟みますよね。
画像を自動変換する、画像の直リンク(リファラ・セッション)をチェックなど。
これらを使ってApacheのハンドラを見なおしてみる。
次の流れで、JPGファイルを送信するのではなく、間にハンドラを挟むところ。
ポイントは jpg にハンドラ(関連付け)を行う。その実行する関連付けるプログラムを自分で書こうってはなし。
Apacheのハンドラは拡張子毎に登録します。ApacheがOSと変わらん動作をするのでチャント使うと便利ってことです。
Apache の設定側に ScriptAliasを設定。設定ディレクトリにCGI実行を許可する。
ScriptAlias "/cgi-bin/" "/var/www/example.com/cgi-bin/" <Directory /var/www/example.com/cgi-bin/> # AllowOverride None Addhandler application/x-httpd-php .php Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch Order allow,deny Allow from all </Directory>
許可したディレクトリに、独自のハンドラを追加。Apacheリロード。
$ cd /var/www/example.com/cgi-bin/ $ echo "<?php phpinfo();" > info.php
念のため、単体でphpが実行できることを確認
curl -v http://example.com/cgi-bin/info.php | grep _SERVER["SCRIPT_FILENAME"] /var/www/example.com/cgi-bin/info.php
これで準備終わり。はい簡単です。
拡張子JPGを、作成した info.php で処理移譲するハンドラ設定をします。
Action my_sample /cgi-bin/info.php AddHandler my_sample .jpg
Actionで my_sample という名前で/cgi-bin/info.php を登録する 拡張子JPGを処理するのを my_sample ハンドラに設定する。
この設定を好きな場所(htaccess / directory / conf ) に記述すればオッケ。
今回は.htaccessで /var/www/example.com/img/.htaccess に書いた。
完成したら、jpg にアクセスしてみる
curl -v http://example.com/img/sample.jpg | grep _SERVER["SCRIPT_FILENAME"]
出来た。これで指定の拡張子を任意のプログラムでApache実行できることがわかるね。
リクエストが来たファイル名はPATH_INFOでわかるね。
CGIの仕組みは、自分でプログラムを書いて、そのプログラムを指定拡張子に関連付け、またはディレクトリを関連付けが本来の姿だった。
そのプログラムをphp / ruby / clang で記述すればいいわけですよね。
画像やバイナリを関連付けで、処理するのにはいくつか便利な方法がある
http://example.com/img/sample.jpg?width=100
Apache側でファイルの存在確認と実行確認、パーミッションチェックまでヤってくれる。
http://example.com/show_img.php?path=sample.jpg&width=100
このような、ファイルの処理にまつわる処理を安全にできる。
パス変換やファイル存在チェックまではapahce側に依存できる。自分でプログラム書いたりフレームワークに頼らなくていい。ディレクトリ・トラバーサル脆弱性などに対応できうる。
ファイル処理くらい1枚のCGIで終わるものを、フレームワークかいてテストって意味なくね?
アップロード・ファイル処理する系はCGIが強いです。
gz が付いたphpから、content-type: image/jpeg
を設定すると transfer-encoding : chunked
になってしまい、GZipで転送されない・
<?php ob_start("ob_gzhandler"); header("content-type: image/jpeg");//この時点でgz_handler は無視される imagejpeg( $gd_image,); ob_end_flush();
テキストなら、圧縮されるが、画像は警告無しで無条件で無視された。なるほど。
text 系は本当に小さくなる。画像にはあまり効果がない。画像はHTTP的にGzipを掛けるべきではない。
原則として画像を小さくするには、画質を落とす、幅を小さくするなどして圧縮すべきである。とのこと。
画像をgzip 圧縮するより、画質を落とすことを考えろ
とのことでした。わかるんだけど・・・・・・・・・・・・・・・・・・・・
違うんだ、私は 画像をgzip圧縮したいんだ!
画質を劣化させることは本意ではない。gzip を最高圧縮9でやればJPEGでも10〜20%程度は容量を削減できるし。強引にヤってみた。
<?php header("content-type: image/jpeg; "); ob_start(); imagejpeg($img); $data = ob_get_contents(); ob_end_clean(); $gz_data = gzencode( $data , 9); header('Content-Encoding: gzip'); header("content-type: image/jpeg; "); header("Content-Length: ". strlen($gz_data) ); ob_start(); echo ($gz_data); ob_end_flush(); imagedestroy($img); return ; ?>
これで、ほんの少しだけ節約できるはず。
Content-Encoding: gzip Content-Length: 855241 Content-Type: image/jpeg;
Content-Encoding: gzip Content-Length: 749838 Content-Type: image/jpeg;
多少は、小さくなりました。でもやっぱり、幅を50%とかにしたほうが節約量圧倒的なので、できれば幅を変えたほうが良いよね。
<?php ob_start("ob_gzhander");
たったこれだけ。たったこれだけ。楽チンですね―
ブラウザが非対応ならどうするの?、IFぶんで条件分岐は?それが、いらないんです。私も実験して驚きました。
<?php ob_start('ob_gzhander'); phpinfo(); header("Content-Length: ".ob_get_length()); ob_end_flush();
単純に、ob_start を追記しただけです。
非対応なら、生のHTMLを返す(バッファリングは失敗するので、処理されない)
curl -v https://localhost/info.php > /dev/null < HTTP/1.1 200 OK < Date: Sat, 14 May 2016 10:46:45 GMT < Server: Apache/2.2.22 (Debian) Phusion_Passenger/5.0.23 PHP/5.4.45-0+deb7u2 mod_ssl/2.2.22 OpenSSL/1.0.1e < X-Powered-By: PHP/5.4.45-0+deb7u2 < Vary: Accept-Encoding < Transfer-Encoding: chunked < Content-Type: text/html
対応なら、HTMLのバッファリングが成功するので、圧縮されたコンテンツが飛んでくる
curl -v https://localhost/info.php -H 'Accept-Encoding: gzip, deflate, sdch' > /dev/null < HTTP/1.1 200 OK < Date: Sat, 14 May 2016 10:53:58 GMT < Server: Apache/2.2.22 (Debian) Phusion_Passenger/5.0.23 PHP/5.4.45-0+deb7u2 mod_ssl/2.2.22 OpenSSL/1.0.1e < X-Powered-By: PHP/5.4.45-0+deb7u2 < Vary: Accept-Encoding < Content-Encoding: gzip < Content-Length: 11219 < Content-Type: text/html <
ちゃんと圧縮されて飛んできます。
チャント調べたら安心できますね。
自動適用されるのは content-type : text/**
だけでした。 image は自分でやる必要がありますね。
https のURLを最近使うことが多い。ssh のほうが正直言って使いやすいんだけど。
ついついhttps のでコピペしちゃうので、HTTPS向けの設定をすることにした
パスワードを、ファイルに保存する設定。
git config --global credential.helper store
storeを設定した後に git clone/pushをすれば、ファイルに保存される。
通常パスワードはプレーンテキストでファイルに保存されるので、取扱には注意が必要。
global の保存先は $HOMEなので
~/.git-credentials
ここに保存される。繰返しになるけど、文字列そのまま入ってるので注意。
どうしてOSXは設定不要で動いていたのか考えていたら、設定の保存先が keychains だった。コレは便利すぎる。
credential.helper=osxkeychain
OSXだと安心して使えますね。
http://stackoverflow.com/questions/11403407/git-asks-for-username-everytime-i-push
$src = "my-sample.jpg" $dst = "out.png" $command = "convert $src $dst" ;
文字列の展開タイミングがあるので、これをクラスにすると面倒くさいんだよね。
文字列展開を後でやろうとすると出来無い。
<?php class MySample{ public $command = 'convert $src $dst'; //あとで文字列展開をしたい public function __construct(){ /*なにかしょり*/} public function convert (){ $src = escapeshellarg($this->source_file_name()); $dst = escapeshellarg($this->destination_file_name())); $command = "{$this->command}" // "convert $src $dst" ; を展開したいけど出来ない。。。 } }
こうなると、文字列展開を後でするには、コマンドをメソッド中で組み立てる必要があり、これがコマンド文字列をデバッグするのが面倒になる原因。
putenv で環境変数に直接php変数を渡してあげる。シェル呼び出し時に環境変数を利用することで、見通しがすっきるする
<?php class MySample{ public $command = 'convert $src $dst'; //あとで文字列展開をしたい public function __construct(){ /*なにかしょり*/} public function convert (){ $src = escapeshellarg($this->source_file_name()); $dst = escapeshellarg($this->destination_file_name())); putenv("src=$src"); putenv("dst=$dst"); ## シェル実行時に環境変数が使われる shell_exec($this->command); putenv("src=''"); putenv("dst=''"); } }
putenv で環境変数を渡すのが結構便利だった。
コマンドに記述ミスが有ると思ったら、$this->command
の中身をそのまま取り出せば、コピペで簡単に再現でき、シェルで実行がとても楽になる。
動作チェック、再実行したい時も簡単に、シェル起動してコピペで済む。
$ > src=my_jpg dst=out.jpg convert $src $dst
シェル呼び出しに使うコマンドを動的に組み立てないので、シェルスクリプトで使ってるコマンドをそのまま使うことが出来る。
追記:環境変数で突っ込む前に escapeshellargs されたら上手く動作しないよ。変数に無事突っ込めた時点でエスケープ不要だろうしね。。
関数sprintf
を使えば少しだけ、すっきりする。
<?php class MySample{ public $command = 'convert %s %s'; //あとで文字列展開をしたい public function __construct(){ /*なにかしょり*/} public function convert (){ $src = escapeshellarg($this->source_file_name()); $dst = escapeshellarg($this->destination_file_name())); $command = vsprintf( $this->command, [$src, $dst] );// sprinft で文字を埋め込み } }
文字列として展開される引数を後から決られるので、すっきりする。でも %s がたくさんあってワケガワカラナイヨ。
あとコマンド文字列が何を意味しているのか。%sでは変数の意図がでもわかりづらくなる。
eval すれば出来る。
<?php class MySample{ public $command = 'convert $src $dst'; //あとで文字列展開をしたい public function __construct(){ /*なにかしょり*/} public function convert () { $src = escapeshellarg($this->src); $dst = escapeshellarg($this->dst); eval("\$command =\"{$this->command}\";"); } }
eval を活用すれば、出来ることがわかる。でもエスケープが多い。eval の代わりに php://memory に書き出して include なども使えそう。
eval を変数展開に使うのは個人的には使いたくない。もしやるとしたら
<?php function expand_string( $string, $assoc_array ){ extract($assoc_array); eval("\$ret = \"$string\";"); return $ret; }
などと先に関数を定義しとかないとevalで何したいのか、一目でわかりづらくて困る。
これもeval とあんまり変わらないんだけど、関数をつくて、コールすれば用を満たせる。
<?php $command = 'convert $src $dst'; $f = create_function('$src,$dst', "return \"{$command}\" ;" ); shell_exec( $f( "src.jpg", "dst.jpg" )) ;
関数を作るとあとで中身が評価されるため、使い回し出来そう
シェルで作ったコマンドを、.bash_history から持ってきて貼り付けるだけだったので楽でした。
他にいい方法ないのかなぁ。
シェル経由のコマンド実行をバックグラウンド(プロセスの親 にする)には次のとおりに書く。
<?php shell_exec ( "sleep 100 > /dev/null 2>/dev/null & ");
STDOUT/STDERRをphp から切り離せば、プロセスをバックグラウンド・ジョブにすることが出来る。
コマンド1行に対して1つの &
が必要なので、複数行呼び出すときは複数回 &
をすると大変なことになる。
この場合、次々とコマンドを呼び出だすだけになる。
<?php shell_exec ( "sleep 100 > /dev/null 2>/dev/null & "); shell_exec ( "sleep 100 > /dev/null 2>/dev/null & "); shell_exec ( "sleep 100 > /dev/null 2>/dev/null & "); shell_exec ( "sleep 100 > /dev/null 2>/dev/null & ");
このコマンドが、一時ファイルを作って作業して一時ファイルを消すような処理をしていると、処理中の一時ファイルが先に消されちゃったりする。
コマンドを { $cmd }
のように 括弧で区切る方法が一番楽
<?php shell_exec ( "{sleep 100;sleep 100;sleep 100;sleep 100;} > /dev/null 2>/dev/null & ");
これは、気づくのに時間がかかった。シェル呼び出しは 括弧{}
でくくってあげると一括りのコマンドとして実行できるんですね
shell_exec で 2&1>/dev/null &
をつけると、が sh -c 経由になるので もしやと思ったらビンゴだった。
括弧をつけると、シェルスクリプトのエラーを探すのが面倒になる。エラーが出た時に追いかけるのが面倒です。
この場合は、エラーと標準出力の書き出し先を明示してあげれば楽ちんになった。
<?php shell_exec ( "sleep 100 > /tmp/stdout 2>/tmp/stderr & ");
phpの shell_exec 関数は 標準出入力がファイルに流されてて、&がついてたら apache プロセスから切り離すようになるみたいです。
バックグラウンドでroot は書きすぎなので削るなど
pdftk で null pointer が出るなんて、一瞬驚きました。 まさかJavaで出来てたなんて。
この条件下でエラーになるようです。
公式のバグレポートにバグレポでてました。 pdftk 2.0.1 で fix されているようです。
公式から最新版を落としてきて make します。
wget https://www.pdflabs.com/tools/pdftk-the-pdf-toolkit/pdftk-2.02-src.zip cd pdftk-2.02-dist/ cd pdftk cp Makefile.Debian Makefile make
sudo apt install gcj-jdk vim Makefile # gcj のバージョンを書換
これでnulllpointer が出なくなります。
HTTPリクエストで、時間のかかる処理を受け取った時どうするか。
すぐに思いつくのは websocket や ajax で pollingしたりpush 通知する方法でしょうが、面倒くさいんだよね。
ブラウザにリロードを命令する方法が無いのか、ヘッダを見なおしてみた。
この2つのヘッダが定義されていることがわかる。
retry-after はまさにバッチ処理の為に作られたようなHTTPヘッダなのだが、これを見てるのはGoogleBotくらいらしい。
もし使うとしたら、 202 Accepted
や 503 Service unavailable
などとともに使うことになるだろうがブラウザ側が実装してないので、使えない
実際にChrome/Safariで実験してみたが、全く相手にされなかった。ツライ
昔々の太古の時代からあるヘッダで、これは HTMLに記述して使われることが多かった。
<meta http-equiv="refresh:5 ; url=/page.html" /> <body> ページをリダイレクトします </body>
リダイレクトするページを入れるときは404ページのテンプレなどでよく使われた手段ですよね。邪魔だったから最近あまりみない。
http-equiv で refresh が動くとは、すなわちHEADERに埋め込んで利用可能である。
<?php header("refresh : 3 ; url= / ");
phpで例を記述しましたが、HTTPヘッダなので基本的にどこでも動作する。
URLには、相対パス・絶対パス・完全URLが使える。リダイレクトで使えるものならなんでも出来そう。
バッチ処理をうけて、処理結果を待つときに、Refreshが使えそう。
Javascriptで良いじゃん?と思うんだろうけど、動画・画像・音楽など、HTML中にコンテンツを埋め込むときに処理待ちをさせるのに便利。
ローディングアイコンでクルクルさせるのもいいんだけど、画像などで使ったら、ブラウザを待たせるのに、とっても楽チンだと思うんだよね。
ここまで書いていて何なんだけど、ブラウザは img 要素への refresh を全く無視してしまう。
惜しい、実に惜しい。画像生成を待たせるのに良いと思ったんだけどねー
画像のonerror を使うしか無いね。サーバー側で 404などエラーを返すと onerror が発動するのでそこでリロードするしか無い。面倒くさい。
<img src="" onerror="function(){}" />
pdftk target.pdf dump_data
pdftk でほとんどの問題は解決するんだけど。pdftk が gcj で null pointer 吐くことがあるので油断できない。
まぁコマンドじゃなく pdf のバイナリを読めって話なんだけど面倒だよね。
ページ数だけだと、pdftk は遅いのでpdfinfo の方が早い。
time pdftk out.pdf dump_data real 0m24.755s user 0m9.767s sys 0m13.269s
time pdfinfo out.pdf real 0m0.086s user 0m0.072s sys 0m0.012s
ページ数だけなら圧倒的にpdfinfo の勝ち
imagemagick convert コマンドでも処理できるが、convert だと 5分かかったので、話にならない
tar zxf sample.tar.gz tar Jxf sample.tar.xz tar jxf sample.tar.bz2
よく忘れるんだよね。
tar コマンドで gz がメジャーだったけど最近は xz や bz2 が増えてきたもんね。解凍するときにコマンドオプションを忘れそうになる。
j/ J / z
が bxz って覚えておくと展開するときに楽そう
複数カラムには設定できない。
create table my_test ( id int primary key auto_increment, path text not null default "" , locked tinyint not null default 0 , created_at timestamp not null default current_timestamp, modified_at timestamp not null default current_timestamp ) ;
ERROR 1293 (HY000): Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
非常に面倒くさいテクニックがアリまして。
timestamp not null のカラムに null を入れる。
not null に null を入れると current_timestap が導入される。なんともユーザーの期待を裏切る仕様
+----+----------------------------+--------+---------------------+---------------------+ | id | path | locked | created_at | modified_at | +----+----------------------------+--------+---------------------+---------------------+ | 17 | /home/takuya/test.1.jpeg | 1 | 2016-05-09 04:53:16 | 2016-05-09 04:53:54 | | 18 | /home/takuya/test.1.jpg | 0 | 2016-05-09 04:53:34 | 2016-05-09 04:53:34 | +----+----------------------------+--------+---------------------+---------------------+
created_at timestamp not null , modified_at timestamp not null on update current timestamp_default current_timestamp
insert into mytable ( path, created_at) values ( "/path/to/name", null );
not null テーブル・カラムに null 入れるなんて、コードレビューでRejectしてたんだが、まさかこんなことになってたとは
chrome 33-35 の周辺で警告が出続けます。
以前は、拡張子 sample.user.js を放り込んでいけばユーザーJSが使えて便利でしたが。ソレもできなくなりました。
自分で作った野良拡張機能をChromeに放り込めなくなっています。
強制的に disabled にされます。
警告が出続けます。
警告くらいべつにどってことないけど、起動時に毎回出るのはツライ。
chrome beta を使えたら出来たが、出来なくなった。
dev は常用するにはちょっとシンドい。Devが原因かサイトが原因か、拡張機能が原因か切り分けが面倒。というか、動いてないことに気づかずブラウジングしててはまることがある。
UserJS の ドラッグドロップが動くので vivaldi は良いんじゃないかと思う。「友人たちのためのブラウザ」を名乗るので、便利機能を消すような真似はしないだろうし。
その他、色々あるのでぐぐったら見つかると思う。
Windowsだとコレが確実かも。Mac OSXだと起動オプションをつけるのが面倒なのですが
--enable-easy-off-store-extension-install
open -a "Google Chrome.app" --args --enable-easy-off-store-extension-install
OSX の場合は、automatorでAPPにしないとSpotlightから起動が面倒になります。
今なら500円位だった。将来的にはどうなるかわからないけど。
公開ベレルが設定できるので、ソレで動く。
2番めの方法だとある程度プライベートな物が作れる。
またExtensionをWebStoreにアップするとプロファイルに保存されるんので、自動更新やChromeログインで拡張機能が自動ロードされるのが強い
ただし、これらはGoogleの審査がくるので、ある日突然停止されることもあるだろうし。公開数上限もありそうだし。怖い。
OSX Safariの拡張機能は AppleのDeveloper 登録が必要で年額100$は高い。
その点、5米ドル程度でしばらく使えるGoogle Webstore開発者アカウントは便利かもしれない。
ちょっとしたUserJS程度なら、拡張機能をインストールしなくても GreaseMonkey を使う tampermonkey を使うのも良いかもしれない。
個人的にはGreaseMonkeyで解決せずに拡張機能のノウハウを集めたいんだよなぁ。
強制的にdisabeされた、UserJSの拡張機能をオンにするには、Chrome Apps & Extensions Developer Toolで 強制ONにするボタンがクリックできますが、直ぐにオフにされます。
拡張機能は無くなって行くのかも。拡張機能をGoogleは消したい方向っぽいよね。セキュリティ対策
という正義で言われちゃどうしようもないし。IEのシェア抜いちゃった今では、1番保守的になる可能性が高いよね。
https://productforums.google.com/forum/#!topic/chrome-ja/7qSACiy8EtY