ブログが続かないわけ

この日記のはてなブックマーク数
Webエンジニアが思うこと by junichiro on Facebook

[PHP]カレンダーの左上と右下の日付を取得する

このエントリーを含むはてなブックマーク hateb

カレンダーの左上と右下は、それぞれ前月と翌月の日付でうっすらと埋められているじゃないですか。あれ、表現しようと思うとなかなか面倒ですよね。というか、面倒でした。どこかにロジックが転がっているだろうと思いながらも、探す手間と書く手間を天秤にかけ、書くほうを選びました。

カレンダーの左上の日付を取得する。

function getCalendarStartDate($date = null, $format = 'Ymd') {
    if (!$date) $date = date('Ymd');
    return date(
        $format,
        strtotime(
            sprintf(
                "%d01 -%d days",
                date('Ym', strtotime($date)),
                date('w', strtotime(date('Ym', strtotime($date)).'01'))
            )
        )
    );
}

カレンダーの右下の日付を取得する。

function getCalendarEndDate($date = 
null, $format = 'Ymd') {
    if (!$date) $date = date('Ymd');
    return date(
        $format,
        strtotime(
            sprintf(
                "%d +%d days",
                date('Ymt', strtotime($date)),
                6 - date('w', strtotime(date('Ymt', strtotime($date))))
            )
        )
    );
}

strtotime とdate を使い過ぎなような気もしますが、パッと思いついたのはこの程度でしたし、とりあえず動いているので問題ないです。それにしても、strtotime の、'+2 days' とか '-3 days' とか '4 days ago' みたいな書式は便利ですよね。

[追記]コメントで教えて頂いたDateTime版

カレンダーの左上の日付を取得する。

public static function getCalendarStartDate($date = null, $format = 'Ymd') {
    if ($date instanceof DateTime === false) {
        $date = new DateTime($date);
    }

    $date->modify('first day of');
    if ($date->format('w')) {
        $date->modify('last sunday');
    }
    return $date->format($format);
}

カレンダーの右下の日付を取得する。

public static function getCalendarEndDate($date = null, $format = 'Ymd') {
    if ($date instanceof DateTime === false) {
        $date = new DateTime($date);
    }

    $date->modify('last day of');
    if ($date->format('w') != 6) {
        $date->modify('next saturday');
    }
    return $date->format($format);
}

こっちのほうが全然Cool じゃん!

PostgreSQL でCSV に出力する

このエントリーを含むはてなブックマーク hateb

ECCUBE でPostgreSQL とやりあう

久々にPostgreSQL と格闘しなければいけなくなりました。ECCUBE は管理画面でできることはとても限られていて、複雑なことをやろうとしたら、直接SQL を書いてしまうのが手っ取り早いということがよくあります。

結果をExcel などで使う

結果をただながめるだけでなく、Excel などでいろいろと加工したいこともあると思います。そういうときにはCSV で出力してしまうのが手軽でいいです。

psql [dbname] [username] -c '[SQL]' -A -F,

これでできます。(最後の「,」も誤植じゃないです)

オプションの説明

-c より手前は接続に必要な各種情報が必要になります。-c はcommand の略で、postgresql のコンソールに入らずに、その場で指定したSQL を実行します。

-A はpostgresql の出力のフォーマッティング(桁揃え?)を抑制します。

-F は続く指定で、区切り文字を指定できます。-A オプションだけですと、カラムの区切りは|(パイプ)ですが、-F, とすることでその区切りを「,」にすることができます。

これで出力が綺麗なCSV になりました。必要であれば適宜ファイルにリダイレクトして、Excel などで加工すると良いと思います。

以上、10月はなにも書いていなかったので、埋め草的なエントリでした。

Amazon EC2 のインスタンスを別のアカウントにうつすときのメモ

このエントリーを含むはてなブックマーク hateb

自社の環境で作ったインスタンスをお客様の環境にうつすなど

単にインスタンスの複製を作るのは先日のエントリで書いた通りです。

[参考] Amazon EC2 で稼動しているサーバの複製を作るテンプレ | ブログが続かないわけ

「いろいろ時間がかかってしまったのでメモしておかなくては!」と思ったのですが、よくよく考えてみるとポイントはひとつだけでした。ブログにまとめるまでもないと思ったのですが、書きかけてしまったので最後まで行きます。

手順

前提

  1. 自社のAWS アカウントでEC2 が稼動している
  2. それをお客様のAWS アカウントで稼動するサーバにする

手順

  1. 自社のインスタンスでAMI をお客様向けに作成する
  2. AMI をお客様アカウントのS3 に転送する
  3. お客様アカウントでAWS コンソールにログインする
  4. さきほどのAMI を登録する
  5. そのAMI からインスタンスを立ち上げる

実践

こうして /mnt にサーバイメージを作成します。一見、前述のエントリとほとんど変わらないかもしれません。しかし重要なのはここです。この時点でお客様のAWS アカウントにひもづいている、private key や、cert それにuser id を使う必要があります。ここが、自分用のAMI 作成と違うところです。

そして、これをS3 に転送します。もちろんここでも、転送先のS3 はお客様のS3 でなければなりませんので、access key やsecret key はお客様のものを使います。bucket は予め作っておいたほうが良いと思います。

あとは、お客様のアカウントでAWS のコンソールにログインすれば、そこから先の手順は先日のエントリの通りです。

[参考] Amazon EC2 で稼動しているサーバの複製を作るテンプレ

とにかく大事なことは「イメージ作成の段階から、移転先のアカウント情報を使う」ということです。

使える本なので、もう一度紹介しておきます。

Amazon EC2 で稼動しているサーバの複製を作るテンプレ

このエントリーを含むはてなブックマーク hateb

Amazon EC2 東京上陸

Amazon EC2 がとうとう東京に上陸しましたね。これでレイテンシに悩まされることもなくなるかもしれませんね。

クラウドが日本に上陸 (The Cloud Expands to Japan)

サーバの複製

今日は、Amazon EC2 ですでにサービスが稼動している場合、その複製を用意するという行為のテンプレを紹介したいと思います。例えば、Amazon EC2 で本番のサービスが稼動しているとして、そこから複製して開発環境を作るなどのときに、重宝すると思います。US-East から東京へのregion 間の引越しはS3 へインスタンスを転送するところで、東京region のS3 に転送すれば良いと思うのですが、そこはまだ試していません。

手順

  1. AMI(Amazon Machine Image) を作成する
  2. AMI をS3 に転送する
  3. AMI を登録する
  4. そのAMI からインスタンスを立ち上げる
  5. apache などの必要なデーモンを起動する

実践

これで、/mnt 以下にサーバイメージが作成されます。事前に/mnt が空か確認しておいたほうがいいかもしれません。以前のイメージの残骸などが残っている場合はそれらは削除してしまっても構いません。

これで、S3 にイメージが転送されます。ここで東京region のS3 に転送すれば引っ越しもできると思いますが、そこはまだ調査中です。

次に、EC2 のConsole 画面に行きます。

左メニューにある、AMIs を選択し、上部のRegister New AMI から先程S3 に転送したイメージを登録します。

AMI

AMI

さきほど入力したbucket name を間違えないように入れてください。

これで、AMI の登録が終わりました。あとは、このAMI をベースにいくつでもインスタンスを起動できます。

次に、左メニューにある、Instances を選択し、上部のLaunch Instance からインスタンスを起動します。

INSTANCE

タブで、My AMIs を選択してから、先程登録したAMI があることを確認し、その右にあるSelect を実行します。

INSTANCE

あとは、ウィザード形式で迷うことなくインスタンス起動までいけると思います。

個人的にはこのあと、Elastic IP を取得して、開発環境であろうとも、IP を割り当てることをオススメします。IP を割り当てたら、別途DNS などでこの開発サーバにドメインを割り当ててもいいですね!あとはこのサーバにログインしていろいろやるだけです。

EC2/S3 に関しては、次の1冊があれば通常運用では困ることはないと思います。

本当にお勧めです。

関連記事

Amazon S3 に自動で定期的にDB のバックアップをとるようにしました

Emacs で連番を挿入する方法のまとめ

このエントリーを含むはてなブックマーク hateb

たまに、Emacs で連番を挿入したい場面に出くわします。いままで数が少ないときは、普通にタイプして、数が大きくなるときは、最悪Excel などを起動して、連番を作ってコピーなどという作業をしていました。これだけ便利なEmacs なんだからそのくらいの機能はあるだろうということで、少し調べてみましたら、るびきちさんがまとめてくださっていました。

便利ですし、いろいろなやり方があることがわかります。また、途中で出てくる技が、連番挿入以外にも使えそうなものばかりで、とても参考になりました。

僕は一番原始的でてっとりばやい、「Ruby のワンライナーを使う」というのを参考にさせて頂きまして、「Perl のワンライナー」で実践しています。

これの良いところは、手軽にフォーマットをいじれることです。例えば、(1)(2)...(100)のように括弧をつけたければこうなります。

さらに、0で桁埋めしたい場合なども簡単です。

便利!

って、でもこれ完全にPerl の話でしたね。失礼しました。Emacs シェルを立ち上げて、これらのワンライナーを実行してから、その結果をコピーしてもとのバッファにペーストするという手順で使います。Perl でしたらLinux でもMac OSX でもだいたい最初から入っているので、Perl を知らなくてもこれはこのまま使えると思います。

Emacs の各種便利技は、るびきちさんの下記の著書がめちゃくちゃ参考になりました。ほんとうに作業効率がカイゼンされていくのが実感できます。

SEO対策の本質。重要なのはコンテンツそのもの

このエントリーを含むはてなブックマーク hateb

SEO対策って

SEO対策という言葉があります。検索エンジンでなるべく上位に表示されるように施す各種対策のことです。しかし、サイト制作者の都合で簡単に上位表示させることができてしまっていいものなのでしょうか。それがWeb の使いやすい形なのでしょうか。

検索エンジンを運営する側の立場で考えてみました。例えば、Google やYahoo! はできるだけ数多くの人に使ってもらいたいわけですから、検索性能が高くなければいけません。検索性能が高いというのは、レスポンスが早いとか、インタフェイスがわかりやすいとか評価基準がいろいろあると思います。そういった評価基準のなかに、重要なものとして「検索した人が望む結果が出てくること」というのがあると思います。

検索エンジンはこう考える

そう考えたときに、検索エンジン側としては下記の2つのどちらを検索結果として表示してあげたいと考えるでしょうか。

  1. みんな(制作者)が見せたいもの
  2. みんな(検索者)が見たいもの

じっくり考えるまでもありません。検索する人が望むものを見せる、後者のほうを表示したいと思うはずです。一方、SEO 対策というのは、なんとなくですが制作者視点の「見せたい、見せたい」オーラが出ている気がしてなりません。検索エンジン側には「制作者の見せたい想いが強いもの」を見せるつもりはないと思います。いまは、Google やYahoo!(もはや同じですが)の検索性能が完全ではなく、SEO対策が一部有効なこともあるかもしれません。しかし、当然できる限り「検索者が見たいものを上位表示する」ように仕様を変更、いや、改良して行くはずです。

Googleが検索アルゴリズムを変更 1割以上の検索クエリーに影響 - ITmedia News

同社は今回の変更の目的について、質の低いサイトの検索順位を下げるためのものと説明している。質の低いサイトには、ユーザーへの付加価値が低いもの、ほかのサイトのコンテンツのコピー、あまり役に立たないサイトなどが含まれる。

このような仕様変更に一喜一憂するようなSEO対策は、やはり小手先のテクニックに過ぎないと思います。本質的に検索エンジンに好かれたいのであれば、簡単な話ですが、「みんなが見たいもの」を作ればいいのです。

例えばSEOのテクニックに、「title タグにキーワードを入れる」とか「本文でキーワードが出てくるところではstrong タグを使う」とかあると思いますが、これは正しいと思います。いままで話してきたことと矛盾しているように思われるかもしれませんが、これらをSEO対策としてではなく、見る人の利便性を上げると考えれば当然なのです。単純にそのページの質として、そういうことをしてくれているほうが良いからです。そちらの方が読む人に対してより親切だからです。

いわゆるSEO対策の中には上記のようなものもたくさんあります。ただ、それらをSEO のためにやるというのがナンセンスで不毛だと思うのです。どのテクニックが有効で、どれはもう有効じゃないとか、今回の検索エンジンの仕様変更で、どこをどう変えたほうがいいとか、そういうのはもう時間の無駄だと思います。「そのコンテンツを見るひとのために最大限できることをやる」というのが、間違いなく本質的かつ恒久的に検索エンジンに好かれる方法だと思います。

SEO に対して特別詳しいわけではないので、実際にSEO対策がどれだけ有効なのかはわかりませんし、検索エンジン側の気持ち、Web全体を良くしようと思う気持ちを考えればこうなるだろうと思っただけですので、上記が正しいかどうかはわかりません。しかし、自分のブログで恐縮ですが、実例なら少しだけあります。

実例

このブログではSEO対策はほとんど意識していません。上記にあるように、純粋に「見る人にとってこうだったらいいだろうな」、と思うことはできるだけやっているだけです。その結果、下記のページはそれなりの検索順位を得ることができています。

■「LEGO 国旗」で検索
LEGO(レゴ) 拡充記念に国旗を作ってみた | ブログが続かないわけ
そういう人がいるかどうか知りませんが、レゴで国旗を作ろうと思ったらだいたい僕のところにたどりつくと思います。こういう小さなキーワードはそこそこ上にくるのは確かに難しくはないです。

■「Web::Scraper」で検索
Web::Scraper 使い方(超入門) | ブログが続かないわけ
これは4位ですね。ただ、この1位のページはやっぱり、見る側を意識しているいいページです。

[参考:1位] use Web::Scraper; - 今日のCPANモジュール

余談中の余談ですが、この「今日のCPANモジュール」というのは連載中から評判が良く、なんとなく終わってしまっていたのを悲しむ読者がたくさんいたそうです。それを受けてか、この内容を刷新して、ボリュームも加えた書籍がそろそろ出るとのことですので、要チェックです

■「佐倉市 スポーツ鬼ごっこ」で検索
第1回スポーツ鬼ごっこ大会 in 千葉県佐倉市 | ブログが続かないわけ
これも1位ですが、こういう小キーワードばかりでは実証にならないかもしれません。

最後になりますが、いままでのにくらべてビッグなキーワードでの事例です。

■「リボ払い」で検索
リボ払いは悪魔 | ブログが続かないわけ
Wikipedia についで2位です。聞いた話では、金融系はアフィリエイトの料率も良かったりするため、金融系のキーワードはSEO対策の主戦場らしいです。そこで、まったく対策していないこのページが、しかも「リボ払い」を否定するページが上位にくるというのは、ある程度いままで話してきたことのの実証にもなっているのではないでしょうか。

今度、僕の大好きなサッカースパイク、「パラメヒコ」について書いて、ランキング調査してみる予定です。

まとめ

いわゆるSEO対策は有効かもしれないが、時間的なコストパフォーマンスが良いとは思えない。

ページそのものの価値が上がるように考えて、文章を考え、マークアップを考えることこそが、検索エンジンに好かれる王道である。

付録

正しくマークアップするのも、読み手のことを考えればこそだと思います。

Amazon S3 に自動で定期的にDB のバックアップをとるようにしました

このエントリーを含むはてなブックマーク hateb

Amazon S3 は利用量の上限がないですし、費用も割と安いので、バックアップ用のオンラインストレージとしては結構便利だと思います。SCP などの今まで使い慣れていたデータ転送の仕組みを使えないのが少し面倒に感じるかもしれませんが、それもシェルスクリプトなどで一度自動化してしまえば問題ありません。S3 へのデータ転送にはRuby 製のs3sync を使っていますが、これに関しては他に詳しい記事がございますのでそちらを参照してください。

S3sync について

S3Sync.net - S3Sync Wiki Amazon EC2/S3を使ってみた - 8.EC2とS3のデータを同期させる(S3Syncを使う)

バックアップを自動化

基本的に直近2ヶ月間は毎時バックアップを残し、それ以前は月初のデータだけ永続的に残すというポリシーで運用しようと思いますので、今回は以下の作業を自動化しました。

  1. 1時間に1回DBのバックアップをとる
  2. ユーザーがアップロードする領域のバックアップをとる
  3. それらをS3に転送する
  4. 2ヶ月前のバックアップを削除する
  5. ただし2ヶ月前のついたちの午前1時のバックアップは永続的に残す

以下、ソース。今回はシェルスクリプトで作りました。

#!/bin/bash

# AWS のアカウント設定
AWS_ACCESS_KEY_ID='YOUR_ACCECC_KEY_ID'
AWS_SECRET_ACCESS_KEY='YOUR_SECRET_ACCESS_KEY'
export AWS_ACCESS_KEY_ID
export AWS_SECRET_ACCESS_KEY

# バックアップ用のファイルを一時的に置く場所
backupDir=/home/test/backup/tmp

# バックアップファイル名と削除対象のファイル名を作成する
year=`date +%Y`
oyear=$year
month=`date +%m`
omonth=$(($month-2))
if [ $omonth -le 0 ]
then
  omonth=$(($omonth+12))
  oyear=$(($oyear-1))
fi
dayhour=`date +%d%H`
suf=`printf "%s%02d%s" $year $month $dayhour`
osuf=`printf "%s%02d%s" $oyear $omonth $dayhour`

# バックアップを実行
mkdir -p $backupDir
/usr/bin/mysqldump -u root -F -l db_name > $backupDir/dump.$suf.sql
cp -a /home/test/html/user_data $backupDir/
cd $backupDir
/bin/tar cfz backup.$suf.tar.gz user_data dump.$suf.sql
rm -rf user_data dump.$suf.sql
/bin/mv ./backup.$suf.tar.gz ../
cd ../
rmdir $backupDir
/home/test/bin/s3sync/s3sync.rb -r ./ footing:backup

# 2ヶ月前のバックアップデータを削除(ただしついたちの午前1時は対象外)
if [ $dayhour != '0101' ]
then
  /home/test/bin/s3sync/s3cmd.rb delete footing:backup/backup.$osuf.tar.gz
fi

# clean up
rm ./*

ファイル名とかディレクトリ名とかが2重化しまくっているので、これを参考にされる方は、そのあたりを上の方でまとめて定義しておいたほうが良いと思います。

サーバ間通信のデータ詐称回避

このエントリーを含むはてなブックマーク hateb

サーバ間で通信をする場合、その引数の内容が詐称されていないかを判定するためにひと工夫凝らさないといけません。良くある方法としては、サーバ同士お互いに秘密鍵を持ち、通信の引数とその秘密鍵を種にして同じロジックでハッシュを生成しそれを比較するというものがあります。

例えばユーザーIDが712904684のユーザーの残高を200円上げるという処理をサーバ間通信で依頼することを考えると、こんなAPI(URI) を考えるかもしれません。

http://www.example.com/api?uid=712904684&money=200

ところがこれがこのまま通って残高が200円あがるとなると、200の部分を9000に詐称するのも簡単な気がしてきます。

http://www.example.com/api?uid=712904684&money=9000

サーバ間通信を行うアプリケーション以外からでも、例えばこんなURLをブラウザのアドレス欄に入力して実行するだけで簡単にこのユーザーの残高を9000円もあげることができてしまいます。サーバ間通信の内容は普通はユーザーには見えにくいので、こういう問題を気にせず実装されているソーシャルアプリもたくさんあり、巷のソーシャルゲームでチートが横行している一因にもなっています。さて、話を戻して、このような詐称をさせないために、最初にお話したハッシュを比較するという方法をどのように適用するのかみてみましょう。

  1. サーバ間通信を行う2者で事前にsecret_key となる文字列を決めておく
  2. 引数のkeyをアルファベット順に並び替える
  3. その順番でkey=valueという文字列を連結させる
  4. その文字列の最後にsecret_key を連結する
  5. できた文字列をmd5 でハッシュにする
  6. 通信の最後の引数にこのハッシュを付加する

secret_key をa1b23c とします。 PHPで書くとこんな感じでしょうか。

function generate_hash($params_array) {
    $secret='a1b23c';
    ksort($params_array);
    foreach ($params_array as $k=>$v) {
        $str .= "$k=$v";
    }
    $str .= $secret;
    return md5($str);
}
これで生成されたhashをx43q98tgaji45asoiとすると、次のようなURI でユーザーの残高をあげるようにリクエストを投げます。

http://www.example.com/api?uid=712904684&money=200&hash=x43q98tgaji45asoi

こうしておいて、リクエストを受け付けたサーバ側でも同じsecret_key を用いて同じロジックでハッシュを計算して、それがhashという引数で渡ってきたもの(x43q98tgaji45asoi)と一致しているかをチェックしてデータが詐称されていないかを調べることができます。

この場合に最初に見たような詐称をするとどうなるでしょう。

http://www.example.com/api?uid=712904684&money=9000&hash=x43q98tgaji45asoi

money=9000の部分の文字列がmoney=200の文字列と異なるため、同じロジックでハッシュを生成しても、できあがるhash がx43q98tgaji45asoiという文字列になりません。そのためリクエストを受け付けたサーバ側ではhash の不一致が発生し、エラーとして処理されます。一方、詐称したいと考える第三者がこのハッシュもちゃんと書き換えたURI を作成しようと考えたとしましょう。しかし、その第三者はあいにくsecret_key を知らないのでそれも不可能です。ここはmd5 が一方通行の変換であるために、正しい通信からsecret_key が逆算されないことを利用しています。詳細は割愛しますが、「正しい通信の内容からもsecret_key は推測できない」というのは大事な部分です。

以上が、サーバ間通信における詐称回避のひとつの解であり、Facebook でもほとんど似た方法が取られています。

自前でセキュアなサーバ間通信を行う場合はデータの詐称というのがなかなか厄介な悩みとなります。第三者に公開しないようなシステムであればアクセス元IP をチェックするというような簡単な方法でも対応できるかもしれませんが、第三者に広く公開する場合はこういう方法を検討するのもいいと思います。その場合、API 利用者をしっかりと管理し、その利用者ごとに別のsecret_key を割り当てるのがまたもう一つ難しいところなのですが。

[Emacs]折り返しまとめ(自分メモ)

このエントリーを含むはてなブックマーク hateb

画面分割してもデフォルトで折り返す

(setq truncate-partial-width-windows nil)

via Emacsで、C-x 3とかした時にも行の折り返しをする設定 - subpop - subtech

折り返しする/しないをトグルで切り替える

(defun toggle-truncate-lines ()
    "折り返し表示をトグル"
    (interactive)
    (if truncate-lines
        (setq truncate-lines nil)
        (setq truncate-lines t))
    (recenter))

(global-set-key "¥C-c¥C-l" 'toggle-truncate-lines)

via ubulog: Emacsで行の折り返し表示をON/OFFする

この両方の組み合わせで折り返しに関しては最強。

[ツール]画面キャプチャの共有にTinyGrab をおすすめしたい

このエントリーを含むはてなブックマーク hateb
TinyGrab

最近、TinyGrab という画面キャプチャ共有ツールを知りました。それの紹介の前に、まず、似たようなアプリケーションのGyazo を紹介したいと思います。画面キャプチャを他の人に見せたいとき、僕は今までGyazo を使っていました。

Gyazoへようこそ | スクリーンショットの瞬間共有

Gyazo の素晴らしいところは、このアプリをインストールするだけですぐに画面キャプチャの共有が実現できるところです。サイトへの登録など一切不要です。インストールして、実行するとすぐにマウスカーソルが、領域選択のようなカーソルに変わるので、それで選択するだけ。そうすると選択範囲の画面がキャプチャーされ、自動的にサーバにアップされ、さらにそのキャプチャー画像を表示するためのパーマネントなURI が生成され、親切にもそれが自動的にデフォルトブラウザで開かれます。

これはホントに便利です。まだ使ってない人は試してみるといいと思います。画面キャプチャをブログにアップする方などは、わざわざブログの管理画面で画像アップロードなどしなくても、このGyazo にあがってる画像に対してリンクを貼れば十分なんじゃないかと思うくらいです。

Gyazo の良いところ

1. 登録不要
2. 自動的にサーバにアップロード
3. 自動的にパーマネントリンクの生成

Gyazo の微妙にかゆいところに手が届かないところ

1. キャプチャするたびにアプリを起動しなければならない
(Spotlight などのランチャ経由でキーストロークだけでGyazo を呼び出せばそれほど気にはなりません。)
2. ローカルには保存されない
(自動で開くブラウザに表示されてる画像をD&D で持ってくれば解決する話ではあります。)
3. 過去にアップした画像を探せない

次に本題のTinyGrab についてです。最近macheist 経由で知ったのですが、これはなかなか良いアプリ/サービスです。事前にサイトへの登録が必要なのが唯一Gyazo に劣るところではありますが、それさえ一度済ませてしまえば、Gyazo で実現できなかったことがすべて実現できます。
TinyGrab
TinyGrab の良いところ

1. 自動的にサーバにアップロード
2. 自動的にパーマネントリンクの生成
3. 一度アプリを起動しておけば常駐してくれる
4. Mac の場合、従来のキーストロークでキャプチャするだけ
(Command + Shif + 4)
5. ローカルにも保存するかしないか選べる(保存しない場合はゴミ箱へ)
6. Control Panel から過去に撮ったキャプチャにアクセスできる
7. 自分のサーバに自動でFTP アップロードすることもできる
(プレミアムのみ)

7. はまだ試していないのですが、自分の好きなサーバにアップできるのであれば、ちょっとしたスクリプトやAPI と組み合わせていろいろできるかもしれません。いまなら(2009/11/12まで?)MacHeist 経由であれば自動でPremium アカウントになります。Premium じゃないと少しGyazo には劣ると思いますので、MacHeist 経由がおすすめです!

Simple. Screenshot. Sharing. - TinyGrab
MacHeist nanoBundle

TinyGrab を使っていると、共有するしないということも意識せず、普通にキャプチャを撮るだけで、それがサーバに蓄積されるというのもとても魅力的です。
まあ、「管理しなくてもいい」というのがGyazo の最大の魅力なので、管理できるのが強みというTinyGrab とではコンセプトが違うかもしれませんので、どちらを好きになるかは人それぞれだと思います。僕はしばらくTinyGrab を使ってみようと思います。

なんとなくまたEvernote と棲み分けの難しいツールのような気もしてきていますが...