はてなブックマーク - PostgreSQLで数え年計算
    このエントリーをはてなブックマークに追加

    まさかまさかの4回目。いま宝くじを買えば3億当確の安元です。
    最近肩こりがひどいので、昨日からピップマグネループつけてます。
    そちらのレビューはまた今度。ビバ!プラシーボ!!

    さて本題。
    最近めっきり聞くことも少なくなった「数え年」。皆さんご存じでしょうか?
    ウィキペディアさんに聞いてみました

    数え年(かぞえどし)とは年齢や年数の数え方の一つである。生まれた時点、基点となる最初の年を「1歳」、「1年」とし、以降元日(1月1日)を迎えるごとにそれぞれ1歳、1年ずつ加える(例:12月31日に出生した場合、出生時に1歳で翌日(1月1日)に2歳となる。また1月1日に出生した場合は、2歳になるのは翌年の1月1日になる)。数え歳とも、単に数えともいう。
    これに対し、誕生日前日午後12時に加齢、加年する数え方を満年齢、満という。本稿においては主に年齢に関する事柄について記述する。

    これ日本独自のものかと思ってましたが、アジア圏ではそれなりに使われているそうです。
    私が必要となった数え年は、「1月1日」での年齢加算ではなく
    「4月1日」での年齢加算でした。いかにも日本の企業で必要になりそうですね!

    年齢を計算してみましょう

    誕生日から一般的な年齢計算を行いましょう

    ここで一番大切なのは「1979-09-02」ですね!私の誕生日です!

    SELECT句の2行目
    age関数が返してくる値は経過年月日ですね。
    SELECT句の3行目
    age関数の結果から「年」だけを切り出したものこれが「満年齢」になります。

    1月1日で年齢を加算する

    数え年ということは、「1月1日」で年齢が加算されるということです。
    ということは、何月に生まれようとも誕生日を「1月1日」生まれにしてしまえば
    みんな一緒に歳をとれますね!

    SELECT句2行目が示すように、
    誕生日から年だけ切り出し「-01-01」を付け足すことで無理矢理「1月1日」に強制しています
    やや乱暴ですが、これで数え年はでました。

    4月1日で年齢を加算する

    では日本ではよく使う「4月1日」を基準に考える「年度」で歳を取りましょう。

    ここで問題になるのは1月〜3月生まれの人々です。
    先ほどのように全員「4月1日」生まれに強制してしまいたいのですが、単純に年を切り出すと
    1月〜3月生まれは1歳進んでしまいます。
    この3ヶ月が邪魔なので、みんな誕生日を3ヶ月巻き戻して考えてしまいましょう。
    3月生まれは前年の12月生まれに、4月生まれは同年1月生まれになりますね。
    これで年をそろえることができます。

    1920年8月生まれは90歳 3月生まれは91歳と差が出ているのがわかります。

    PostgreSQLでは、日付計算が「 + ’1months’」のように月単位や年単位での計算ができます。

    長々とSQLを書いてきましたが、システム内で頻繁に年度計算を利用する場合は
    関数化してSQLに組み込むと使い勝手がよくなるのでご検討ください。

    それでは肩がこってきたのでこの辺で。

      はてなブックマーク - CakePHP 静的コンテンツのURLについて
      このエントリーをはてなブックマークに追加

      こんにちは、一年前に買ったデニムのサイズが合わなくなってきた島田です。

      皆さん食べ過ぎには注意しましょう。。。
      (俺が悪いんじゃない、会社周辺に美味しいお店が多いからいけないんだ!!)

      では、早速本題。

      CakePHP環境下で静的コンテンツは、通常『インストールフォルダ/app/webroot』の配下に設置しますよね。

      /app/webroot/test/index.html

      にファイルを設置すれば、

      example.com/test/index.html
      example.com/test/

      といった感じのURLでアクセスできます。

      ではこの状態で、 example.com/test (『/』なし)にアクセスするとどうでしょう?

      どん!

      example.com/app/webroot/test/

      そうなんです。

      『/app/webroot/』 が付いた状態にリダイレクトされちゃうんです。
      mod_rewite をとおさず直接アクセスしてますねぇ。

      画像やCSSファイルへのパスは、相対的位置関係が変わらないので、表示が崩れるということはありませんが、なんだか気持ち悪い。。。
      同じ情報のページに2URLからアクセス出来るのはSEO的に良くないし、
      Google Analytics などでアクセスログを取得しているときは、同一コンテンツなのに集計結果がわかれてしまう。。。

      ということで、こいつを解決しちゃいます。

      まずは Apache のログを見てみよう

      問題の解決に移る前にまず Apache のログを見てみましょう。

      192.168.0.1 - - [19/Dec/2010:23:08:06 +0900] "GET /test HTTP/1.1" 301 354 "-" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; ja-jp) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4"
      192.168.0.1 - - [19/Dec/2010:23:08:07 +0900] "GET /app/webroot/test/ HTTP/1.1" 200 928 "-" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; ja-jp) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4"

      301エラーを返したあとで、『/app/webroot/test/』にリダイレクトしています。

      簡単にいうとこんな感じです。

      1. スラッシュなしでアクセスしたため、Apache がファイルとして『test』を検索
      2. ファイルは見当たらなかったがディレクトリは見つかったので、クライアントに301エラーとリダイレクトメッセージ(『/』つきのURL)を返す
      3. リダイレクトメッセージにあるURLに再度リクエストを投げる
      4. コンテンツを表示

      2. で返ってくる『リダイレクトメッセージ』を直してリダイレクト先を変えてやればいいのか思いきや、
      それだと直接『example.com/app/webroot/test/』にアクセスされてしまう。。。

      というわけで、今回は

      example.com/app/webroot/test/

      に飛んできたURLを

      example.com/test/

      にリダイレクトさせるという方法で問題を解決しちゃいます。

      .htaccess を改変しよう

      CakePHP ではデフォルトで 3つの .htaccess が設置されていますが、今回は『インストールフォルダ/app/webroot/.htaccess』を改変します。

      <IfModule mod_rewrite.c>
      RewriteEngine On
      RewriteCond %{REQUEST_FILENAME} !-d
      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
      </IfModule>

      インストール時のままだとこんな感じです。
      これをこんな感じに改変します。

      <IfModule mod_rewrite.c>
      RewriteEngine On
      RewriteCond %{REQUEST_FILENAME} !-d
      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
      RewriteCond %{THE_REQUEST} "^(.+?) (.*?)/app/webroot/(.*?) (.+?)$"
      RewriteRule ^(.*?)$ %2/%3 [R=301,L]

      </IfModule>

      THE_REQUEST とは 先程のログの 『”GET /app/webroot/test/ HTTP/1.1″』 の部分を返します。
      要するにホストネーム以下のURLに /app/webroot/ が含まれていたら、それを省いたものへリダイレクトすると書かれています。

      Apache のログはこんな感じ

      192.168.0.1 - - [19/Dec/2010:23:18:06 +0900] "GET /test HTTP/1.1" 301 354 "-" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; ja-jp) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4"
      192.168.0.1 - - [19/Dec/2010:23:18:06 +0900] "GET /app/webroot/test/ HTTP/1.1" 301 342 "-" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; ja-jp) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4"
      192.168.0.1 - - [19/Dec/2010:23:18:07 +0900] "GET /test/ HTTP/1.1" 200 928 "-" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; ja-jp) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4"

      二回リダイレクトして目的のURLにたどりついているのがわかります。

      最後に

      今回の解法は、Rewriteの条件を追加していますので、どうしてもその部分にコストが追加でかかってしまいます。
      レスポンススピードをシビアに求められるコンテンツには向かない場合もありますので、注意してください。

      それでは、また次回お会いしましょう。
      さようなら。

      追記

      RewriteRule でURLを書き換えた時、自動的に URLエンコード が行われてしまいます。
      クエリ文字列に特殊文字を含む場合、意図しないURLに書き変わってしまいますので、 NEフラグを指定してエンコードを行わないようにした方がよいでしょう。

      <IfModule mod_rewrite.c>
      RewriteEngine On
      RewriteCond %{REQUEST_FILENAME} !-d
      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
      RewriteCond %{THE_REQUEST} "^(.+?) (.*?)/app/webroot/(.*?) (.+?)$"
      RewriteRule ^(.*?)$ %2/%3 [R=301,L,NE]

      </IfModule>

        はてなブックマーク - Ustream Data APIの使い方
        このエントリーをはてなブックマークに追加

        ダーツの、Dartsliveのレーティングは9、PHOENIXのレーティングは12、の山本です。
        親にはゴルフをしろと言われてますが、休日は打ちっぱなしより投げっぱなしです。
        お父さん、すんません。

        さて、タイトルが、前の杉本によるエントリーと似ていてすみません。
        が、似て非なるもののご紹介です。

        Ustream Data APIは、Flash Client APIとは異なり、動画に関する情報やユーザーに関する情報がXML形式やJSONなど、計4種類の形式で受け取れますので、どんな言語にも組み込むことができます。PHP形式もありますので、PHPで組み込む場合はすごく親和性が高いのではないのでしょうか。

        API key の発行

        developer.ustream.tvから、開発者用のアカウントを作成する必要があります。
        登録するとAPI Keyが発行されます。

        ユーザー情報を取ってみる

        基本中の基本といえば、ユーザーの情報を取ってくることでしょうか。
        そのアドレスは以下のようになります。

        http://api.ustream.tv/xml/user/ya_ma23/getInfo?key=APIKEY

        ROOTのURL直下にある「xml」は、xml形式で返して表示することを示します。ここを、「json」「php」「html」のいずれかに変えることができます。

        「ya_ma23」に当たるところがユーザー名を指定します。
        そして、APIKEYの部分に、取得したAPIキーを入力します。

        これは私個人の情報になりますが、XML形式だとこんなふうに返ります。

        <xml>
          <results>
          <id>1134298</id>
          <userName>ya_ma23</userName>
          <registeredAt>2009-04-07</registeredAt>
          <url>http://www.ustream.tv/user/ya_ma23</url>
          <gender>male</gender>
          <website></website>
          <about></about>
          <imageUrl></imageUrl>
          <rating>0.000</rating>
          <numberOf>
            <comments>0</comments>
            <friends>1</friends>
          </numberOf>
          </results>
          <msg></msg>
          <error></error>
          <processTime>TRUE</processTime>
          <version>mashery-r10</version>
        </xml>

        テスト用アカウントのため、何とも寂しい情報しかありませんが、プロフィール情報等が取得できます。

        番組に関する情報を取得する

        番組に関する情報も取得できます。チャンネル自体の情報や、そのチャンネルの埋め込みタグや、投稿されたコメントなどを取得できます。
        ごく基本的な情報の取得のために「getInfo」メソッドがあります。

        http://api.ustream.tv/xml/channel/ya_ma/getInfo?key=APIKEY

        「ya_ma」の部分にチャンネル名を指定します。
        これで取得できる情報をここに書くとすんごく長くなってしまうので割愛しますが、
        このチャンネルを作ったユーザーや、ブラウザで見るためのURL、いつ作られたか、いつ配信されたか、視聴者数、埋め込みタグ、といった様々な情報が得られます。

        録画された全てのチャンネルを取得する

        Ustreamはライブ配信した映像を録画することができます。
        で、その録画したチャンネルのリストというものも、APIで取得できます。
        そのメソッドが「listAllVideos」です。

        http://api.ustream.tv/xml/channel/ya_ma/listAllVideos?key=APIKEY

        ZENPREでは、一度配信したプレゼンをあとでいつでも見れるようにする、同期録画機能を備えてますが、
        その設定画面にて、このAPIを使用しています。
        録画番組の一覧をAPIから取得し、ユーザーはただ選択するだけで済むように負担を軽減しています。

        おわり

        Ustreamは、Flash Client APIと合わせても、結構豊富にAPIを提供しています。
        ただ、そこまで普及していないのかな、という印象です。
        OAuthに対応して、Ustreamサイト以外からでも気軽に視聴や配信ができればなと思います。

        イベント、勉強会、セミナー、討論会、個人的に行なっている活動、など、多くの人に見てもらいたい活動を行うときに、
        テレビやラジオ、新聞等で宣伝するだけでなく、こういったネットでの配信も活用してほしいなあと、いち技術者は思う次第です。