Kinopyo Blog

プログラマとしてRuby, Rails, iPhone, iPad,Macなどなどと向き合う日々のログポース

Archive for 00:45

TextMate:最後の編集した箇所に遷移するプラグインTMGoToLastEdit

2011年08月20日

課題

最後の編集した箇所に遷移する機能はTextMateデフォルトではないですが、多分みんなUndo/Redoで実現していたと思います。

でも⌘Z(Undo)、⇧⌘Z(Redo)はやはり手間がかかってしまいますので、一発でできるかをググッてみたところ、TMGoToLastEditを見つかりました。

インストール

ダウンロード、解凍、ダブルクリックでインストール完了です。

使い方

⌥⌘J ( Option + Command + J )

あるいは

Navigationのメニューからクリック

サーバの時刻確認と設定(NTPで時刻補正)

2011年08月19日
# stop it first if it's running,
# or you will get a warning like:
# the NTP socket is in use, exiting
$ /etc/init.d/ntpd stop

# ntp.nict.jp: 日本標準時プロジェクト 公開NTP
$ ntpdate ntp.nict.jp
19 Aug 15:30:18 ntpdate[27156]: step time server 133.243.238.243 offset -856.532277 sec

# start ntp again
$ /etc/init.d/ntpd start

# confirm
$ date
2011年 8月 19日 金曜日 15:32:15 JST

NPTについて

ここでは、ネットワーク上のサーバー及びクライアントマシンの時刻同期をとるためのプロトコルであるNTP(Network Time Protocol )について解説していきます。PCの時刻はマザーボード上のリアルタイムクロック(RTC)によって時間が表示されていますが、この時間はあまり正確ではなく、毎日少しづつ時間が狂っていきます(電池の消耗度にもよりますが、年間約10分程度)。NTPサーバーは、タイムサーバーに接続されたラジオ・クロックや原子時計から時刻を取得し、UTC (協定世界時)に同期させることができます。PCの時刻が狂っていると、メールの送受信時刻が狂ったり、こまめにとっているログの取得時間なども狂ってくることになります。Linuxでは標準でNTPサーバーが付属しているので是非、活用して時刻同期を行いましょう。

http://linux.kororo.jp/cont/server/ntp.php

TextMate ファイルパスが効くGoToFile Bundle

従来の⌘T(Command + T)Go to Fileの問題:パスが効かない

⌘TはTextMateで速やかにファイルを開ける機能ですが、例えばこんなファイルがあるとします。

  • blogs/index.html.erb
  • posts/index.html.erb
  • categories/index.html.erb
  • tags/index.html.erb
  • users/index.html.erb

で⌘Tで”blogs/index”を叩くと何も表示されない、つまりパスが効かないのが一番の問題です。それを解消するのがgotofile.tmbundle

インストール

cd ~/Library/Application\ Support/TextMate/Bundles/

git clone git://github.com/stevenchanin/gotofile.tmbundle.git GoToFile.tmbundle

で、textmateを再起動

使い方

⇧⌘K ( Command + Shift + K )で新しいGo To Fileダイアログを開いて”ar/in”を叩くことでarticles/index.htmlが選択されます!

他にもspaceキーでQuickLookモードでファイルを見たり、⌥(option)キーでデフォルトのアプリでファイルを開いたり、⇧(shift)キーでフォーカスに選択したファイルのパスを入力することができます。

参考

http://how-i-work.com/workbenches/2-keyboard-based-no-mouse-rails-development-with-textmate

RVMの更新、Ruby 1.9.2p290の更新

ruby 1.9.2p290へ更新しました。rvmもついでに。

# update rvm
$ rvm get head
# or older versions such as 1.0.0
$ rvm update --head
# you need to run reload to reflect the update
$ rvm reload
$ rvm -v
  rvm 1.7.2 by Wayne E. Seguin (wayneeseguin@gmail.com) [https://rvm.beginrescueend.com/]

# install ruby 1.9.2.p290
$ rvm install 1.9.2-p290
  ...
$ rvm list
  ruby-1.9.2-p0
  ruby-1.9.2-p180
# you need to replace the p0 based on your environment
$ rvm upgrade ruby-1.9.2-p0 ruby-1.9.2-p290
yes
yes
yes ...
Upgrade complete!
$ rvm list
  ruby-1.9.2-p290 [ x86_64 ]
$ rvm --default use 1.9.2
$ ruby -v
  ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-darwin10.8.0]

MySQL, OracleのGroup by date, 日付別で集計

2011年08月17日

これが既存データで、同じ日に複数のデータがある。

期望結果はこれ、つまり日付別で集計したい場合

MySQLではDATE関数を使う


mysql> SELECT DATE(create_datetime), COUNT(*) FROM user_m GROUP BY DATE(create_datetime);

Oracleではto_char関数を使う


SELECT to_char(create_datetime, 'YYYY-MM-DD'), COUNT(*) FROM user_m GROUP BY to_char(create_datetime, 'YYYY-MM-DD');

参考

http://blog.asial.co.jp/209

http://d.hatena.ne.jp/bingo_nakanishi_perl/20090530/1243649406

TextMateをLionのフルスクリーンに

2011年08月16日
git clone https://github.com/enormego/EGOTextMateFullScreen.git /tmp/EGOTextMateFullScreen

xcodebuild -project /tmp/EGOTextMateFullScreen/EGOTextMateFullScreen.xcodeproj -target EGOTextMateFullScreen

cp -R /tmp/EGOTextMateFullScreen/build/Release/EGOTextMateFullScreen.tmplugin ~/Library/Application\ Support/TextMate/PlugIns

# after installed
rm -rf /tmp/EGOTextMateFullScreen/

これが完成図!

FirefoxのTab BarとNavigation Barを一行にしてくれるAddon:OneLiner

表題の通りFirefoxのTab BarとNavigation Barを一行にしてくれるアドオンです。by Mozilla Labsのアドオンでhttp://www.lifehacker.jp/2011/08/110807_oneliner.htmlでも紹介しています。早速入れてみました、結構ツールバーのスペースが増えたように感じますね。

oneLinerでインストール!

アドレスバーにフォーカスするときは自動で横幅を拡大してくれます。

Mixiモバイルアプリ:フォームPost時のOAuth Signature検証失敗について

2011年08月10日

現象

MixiモバイルアプリのフォームからPOSTするとOAuth Signatureが不一致で検証が通らない。

デバッグ

フォームをPOSTするときはフォーム内のデータがOAuthのBase StringのNormalize Request Parametersに含まれます。

これはOAuthに仕様に準じてます(http://oauth.net/core/1.0a/#anchor13)が、

なぜかMixiだと通れないです。

<form action="?guid=ON&url=http%3A%2F%2Fexample.com%2Ffoo%2F" method="post">
  <input name="field1" type="text" value="value1" />
  <input type="submit" value="送信" />
</form>

こんなフォームがあるとして、中のfield1がNormalize Request Parametersに存在するとダメだってことが検証でわかりました。

回避方法

フォームPOSTする箇所を特定して、その場合はOAuth Signatureを検証しないようにしました。

参考リンク

同じ現象にあった方がいました: Mixi OAuth POST時のシグネチャ検証 – phantasmistの日記

OAuth Signatureの検証方法について << mixi Developer Center (ミクシィ デベロッパーセンター)

ページ遷移とAPIアクセス << mixi Developer Center (ミクシィ デベロッパーセンター)

OAuth Core 1.0

OAuth Core 1.0a

PHP プロセス数を指定して実行するマルチスレッド処理(curl_multi)

2011年08月09日

curl_multi系を使って、プロセス数を指定して実行するマルチスレッド処理です。

urlは配列で受け取って、もし指定したプロセス数より多い場合は分割して実行するようになってます。

このサンプルコードではこのブログの幾つかのurlに対してtitleを取得しました。

<?php
/**
* 指定したプロセス数で並列処理を実行する
*
* @param array $url_list URLの配列
* @param boolean $url_as_key 結果配列を返すときに、urlをキーにする
* @param int $timeout タイムアウト秒数 0だと無制限
* @return array 結果配列
*/
function execute($url_list, $url_as_key = false, $timeout=0) {
    // set your process number
    $process = 5;

    $is_over_process = false;
    if ($process < count($url_list)) {
        // chunk url list / process number*
        $url_chunk = array_chunk($url_list, $process);
        $is_over_process = true;
    }

    $ret = array();
        
    if ($is_over_process && !empty($url_chunk)) {

        foreach ($url_chunk as $key => $url_list) {
            echo "chunk start:{$key}\n";
            
            $res = fetch_multi_url($url_list, $url_as_key, $timeout);
            if (!empty($res)) {
                $ret = array_merge($ret, $res);
            } else {
                continue;
            }

        }
    } else if (!$is_over_process && !empty($url_list)){
        $ret = fetch_multi_url($url_list, $url_as_key, $timeout);
    } else {
        echo "url invalid::";
    }
    
    return $ret;
    
}

/**
* curl_multi_execの並列処理
* ほぼboilerplate
*
* @param array $url_list URLの配列
* @param boolean $url_as_key 結果配列を返すときに、urlをキーにする
* @param int $timeout タイムアウト秒数 0だと無制限
* @return array 結果配列
*/
function fetch_multi_url($url_list, $url_as_key, $timeout) {
    $mh = curl_multi_init();
    foreach ($url_list as $i => $url) {
        $ch[$i] = curl_init($url);
        curl_setopt($ch[$i],CURLOPT_RETURNTRANSFER,1);

        //タイムアウト
        if ($timeout){
            curl_setopt($ch[$i],CURLOPT_TIMEOUT,$timeout);
        }

        curl_multi_add_handle($mh,$ch[$i]);
    }

    //URLを取得
    //すべて取得するまでループ
    $active = null;
    do {
        $mrc = curl_multi_exec($mh,$active);
    } while ($mrc == CURLM_CALL_MULTI_PERFORM);

    while ($active and $mrc == CURLM_OK) {
        if (curl_multi_select($mh) != -1) {
            do {
                $mrc = curl_multi_exec($mh,$active);
            } while ($mrc == CURLM_CALL_MULTI_PERFORM);
        }
    }

    if ($mrc != CURLM_OK) {
        echo '読み込みエラーが発生しました:'.$mrc;
    }

    //ソースコードを取得
    $res = array();
    foreach ($url_list as $i => $url) {
        if (($err = curl_error($ch[$i])) == '') {
            // url_as_keyがtrueの場合、urlをキーとして格納
            if ($url_as_key) {
                $res[$url] = curl_multi_getcontent($ch[$i]);
            // そうでない場合は、ただ配列に入れる
            } else {
                $res[$i] = curl_multi_getcontent($ch[$i]);
            }
        } else {
            echo '取得に失敗しました:'.$url_list[$i].'<br />';
        }
        curl_multi_remove_handle($mh,$ch[$i]);
        curl_close($ch[$i]);
    }
    curl_multi_close($mh);

    return $res;
}


// 並列実行したいurl list
$url_list = array(
    "http://www.kinopyo.com/blog/ipad-2-not-charging-when-connected-to-pc-usb",
    "http://www.kinopyo.com/blog/the-first-app-i-installed-to-ipad2",
    "http://www.kinopyo.com/blog/chrome-warn-before-quitting-with-command-q-in-mac",
    "http://www.kinopyo.com/blog/reply-to-all-always-in-gmail",
    "http://www.kinopyo.com/blog/lion-fullscreen-shortcut-key-conflict-with-evernote-client",
    "http://www.kinopyo.com/blog/how-to-set-gesture-for-chrome-to-swipe-back-and-forth-in-lion",
    "http://www.kinopyo.com/blog/3-free-ebooks-for-study-coffeescript"
);

// start time
$start_time = microtime(true);

// execute
$res = execute($url_list, true);

// execute time
$time = microtime(true) - $start_time;

// play with the result
// here I just get the page title
$titles = array();
foreach ($res as $url => $html) {
    preg_match('{<title>(.*)</title>}',$html, $match_title);
    $titles[$url] = $match_title[1];
}

echo "Result:\n";
echo "time:{$time} sec\n";
print_r($titles);

参考:PHPでマルチスレッド(バックグラウンド処理)を実現する方法

iPad2をPCのUSBに接続する時「充電していません」(Not Charging)と表示する問題

2011年08月08日

iPad2をPCのUSBに繋ぐと「充電していません」(Not Charging)のメッセージが右上に出ます。Macbook Proは問題なかったです。

どうやらPC(あるいは結構古いMac)のUSBは十分の電力を提供できないらしいです。すクルーンをオフにしてNot Chargingのままでも一応チャージはできるんですが、4倍くらい遅いと言われてます。

ASUS Ai Chargerという面白いツールも見つかりました。なんとPCでiPod, iPhone, iPadの充電を50%くらいスピードアップできるそうです。全部のマザーボードをサポートしているようですが、自分は試していません。。

参考:https://discussions.apple.com/thread/2789455?start=0&tstart=0