Author Archive

{ 2010.11.9 }

SlideShare APIを使う

    はてなブックマーク - SlideShare APIを使う
    このエントリーをはてなブックマークに追加

    PHP Matsuri が一段落しましたので、ここでrubyの登場です。
    どうも、ヤマモトです。
    MA6も締切りが過ぎてしまいましたね。
    僕も何か応募したいと思いつつ、ありきたりのサービスしか思いつかなく結局なにも応募せず。。。

    MA6には当然入ってないんですが、スライド共有サービスの最大手であるSlideShareも、実はAPIを公開しています。
    今回はそのAPIの、APIキーの発行からキーワード検索までについて紹介したいと思います。

    SlideShare API
    www.slideshare.net/developers

    APIを利用するには、ユーザー登録が必要です。
    すでに登録している方でも、APIキー発行を行なってください。
    Apply for API Key
    から行ないます。
    発行処理を行うと、「APIキー」と「シークレットキー」がメールで届きます。
    これらを使って、APIを利用します。

    APIメソッドには様々な種類がありますが、基本的な「IDに紐づくデータの取得」をやってみます。
    そのメソッドは、「Get Slideshow Information」で、
    URLは、「http://www.slideshare.net/api/2/get_slideshow」
    必要なパラメータは、

    ・api_key
    ・ts
    ・hash
    ・id

    です。
    上3つは、どのメソッドにも必要な認証のためのパラメーターです。

    「api_key」はメールで送られたAPIキー。
    「ts」は「タイムスタンプ」のことで、現在の時刻をUNIXのTimestamp型に変換したものを付与します。
    最後の「hash」が若干手間で、「メールで送られたシークレットキー」+「現在の時刻のUNIX Timestamp」を、「SHA1でハッシュ値化したもの」です。
    「ts」に付与する現在の時刻と、「hash」に使用する現在の時刻は同一でないといけませんが、厳密に現在の時刻でなくてもいいようです。

    さらに、「id」を付与することで、そのIDに紐づくデータがxmlで返却されます。

    ruby(rails)で書いたソースを下に表示します。

    api_key = "API_KEY"
    secret_key = "SECRET_KEY"
    now_time = Time.now.to_i
    hash = Digest::SHA1.hexdigest("#{secret_key}#{now_time}")
    Net::HTTP.start('www.slideshare.net', 80) {|http|
      response = http.get("/api/2/get_slideshow?api_key=#{api_key}&ts=#{now_time}&hash=#{hash}&id=XXX")
      @xml_object = REXML::Document.new response.body
    }
    respond_to do |format|
      format.xml  { render :xml => @xml_object }
    end

    これで該当のIDに関するデータがXMLで表示されます。
    これを応用すれば、他のウェブサービスにも組み込んで、以下のようなキーワードにヒットするデータをサムネイル付きで表示する画面も作れます。

    MA6のAPIリストにSlideShareがもし入っていたら、何らかの面白いサービスができたのかもしれません。

      はてなブックマーク - USBメモリでブートして、CentOS5.5をネットワークインストール
      このエントリーをはてなブックマークに追加

      連発してどうもスミマセン、山本です。

      先日、CentOS5.5をネットワークインストールする際につまづいたので、その際のメモと注意を書かせてもらいます。

      CentOSをインストールするにあたっては、まずはブートしなければいけません。
      その方法としては、
      ・CDからブート
      ・USBメモリブート
      ・ネットワークブート(PXEBoot)

      敷居の高さは、上から順に高くなるかと思います。
      CDからブートは、単にブート用のisoイメージを取得し、CDに焼き、ブート時に選択するだけで簡単ですが、
      USBメモリからブートも、ネットワークからのブートも、ちょっとした設定がいるのでやや面倒です。
      しかし、USBメモリからブートに関しては、楽にできるツールもあるためやや敷居が下がる感じです。
      今回はUSBメモリからブートをすることにします。
      (どうせなら、全てネットワークにすればいいのでは?というツッコミはなしで。。。
      USBメモリならではの問題がありますので)

      USBメモリをブート用のデバイスにするためには、まずはネットワークインストール用のisoイメージを取得します。
      CentOS5.5の64bitであれば、
      CentOS-5.5-x86_64-netinstall.iso
      という名前で配布されてます。

      このisoイメージを基に、USBメモリからブートできるようにするには色々と設定が必要ですが、
      UNetbootinというソフトを使えば、簡単に作成できます。
      UNetbootin – Homepage and Downloads
      ソフトを起動し、USBメモリを挿し、isoイメージを選択してOKを押すだけで必要なファイルが作成されます。

      そして、このUSBメモリをサーバーに挿し、ブートを行ないます。
      ネットワークインストールを行うためには、”Installation Method”という画面で、”FTP” (もしくは”HTTP”)を選択します。
      そして、FTPのサイトの設定です。

      FTP site name : “任意のFTPサイト”
      CentOS directory : xxxxx/linux/centos/5.5/os/x86_64
      ※Directoryはサーバーによって異なりますが、バージョンの次のディレクトリは isos ではなくて、 os であることに注意

      後は、通常のインストールと同様に進めます。
      しかし、無事インストールも終わって、いざ起動と思ったらGRUBが見つからないとのことで起動しませんでした。
      なぜだろうと思い、試しにUSBメモリをもう一回挿して、そこから起動させると無事、ログイン画面が表示されました。
      どうやら、GRUBがUSBメモリへ書き込まれたようです。

      これを回避するためには、GRUBに関するファイルを本体へコピーすればいいでしょうが、インストール時において設定を変えることで回避できます。
      インストール時に「高度なブートローダーオプションの設定」にチェックを入れて設定をすればいいのですが、
      CentOS5.5からでしょうか、その項目が見当たりませんでした。
      試行錯誤の末、以下の順序でその項目に辿りつきました。


      まず、パーティションの設定画面で、「パーティションレイアウトの再確認と変更」にチェックを入れて次に行きます。


      次に表れる画面では、そのまま次に行きます。


      次の画面でようやく、「高度なブートローダーオプションの設定」が表れました。
      これにチェックを入れて次に行きます。


      ここで、ドライブの順序を編集します。
      初期ではUSBメモリが上にきているので、本体のディスクを最上部へ移動させます。

      これで、無事に本体から起動することができるようになります。

        はてなブックマーク - [Rails] TZInfoで、アクセス元のタイムゾーンに合わせる
        このエントリーをはてなブックマークに追加

        前略、ヤマモトです。

        みなさんはウェブサービスを立ち上げる際、タイムゾーンは意識されているでしょうか。
        日本国内のみのサービスであれば、時間帯は1つなので特に意識する必要はないと思いますが、
        これが全世界で利用して欲しいサービスであれば話が変わります。

        日本時間で「午後1時から午後2時まで限定公開」というプレミアコンテンツを予告し、全世界に公開したとしても、日本時間であると注釈しない限り、ユーザーはその地域の時間だと捉えるでしょう。
        「見てみたらまだ始まってなかった」ならまだいいでしょうが、日本は、全世界でも先の時間を行ってますから、ほとんどの地域の人からしたら「見てみたら終わってた」状態ですね。

        話は逸れますが、アメリカのような複数のタイムゾーンがある国では、ウェブサービスの時間の処理はどう行っているんでしょうか。
        いや、ウェブサービスに限らず、例えばテレビ番組は、ニューヨークでは午後7時から放送でも、サンフランシスコでは午後4時からとなるので、
        この場合の宣伝の仕方はどうしているんでしょうね。
        恐らく時間帯の注釈があるんでしょうが、アメリカに知り合いはいないのでちょっと謎です。
        YouTubeやFacebookといった全世界向けウェブサービスを見てみましたが、
        アメリカのプロキシ経由でアクセスしたり、言語設定を「英語」にしてアクセスしたりしても、とくに時間に変化はなさそうでした。

        かといって、タイムゾーンを考慮しない実装はできません。
        というのは、自社サービスであるZENPREの話ですが、これにはプレゼンテーションの開始時間と終了時間という概念があり、
        その間でしかリアルタイムな配信はされません。
        つまり、その地域に合った時間を表示しないと、世界中の人が見ることはできません。

        1番の解決策は、ユーザーにタイムゾーンを設定してもらうことでしょう。
        初めてアクセスがあった場合、必ずタイムゾーンの設定をしてもらう。
        あとはcookieにでも保存しておいて次回以降は、そのタイムゾーンを使う。
        ですが、その機構を作るための期間が取れず、また、果たしてそれが最適解だろうかというのもあったため、実装を見送りました。

        さて、かなり前置きが長くなってしまいましたが、
        ユーザーのタイムゾーンを取得するにあたって、自動で取得するため「TZInfo」というRubyのライブラリを使用することにしました。

        TZInfo – Ruby Timezone Library

        TZInfoは、国コードから該当するタイムゾーンを表示してくれます。
        例えば日本の場合、

        tz = TZInfo::Country.get("JP")
        tz.zone_identifiers # "Asia/Tokyo"

        となります。
        国コードの取得は

        Locale.get.country

        でできます。
        これを、application_controller.rbあたりで

        Time.zone = tz.zone_identifiers[0]

        とすれば、タイムゾーンが動的に設定できます。
        ※tz.zone_identifiersは配列

        ただし、これがタイムゾーンが複数ある地域になると問題です。

        tz = TZInfo::Country.get("US")
        tz.zone_identifiers
        ⇒America/New_York America/Detroit America/Kentucky/Louisville America/Kentucky/Monticello America/Indiana/Indianapolis ... America/AdakPacific/Honolulu

        となり、候補が複数取得できます。
        ここから、その地域を特定するのは不可能かと思います。
        現状では、「複数取得されたら、1番目のタイムゾーンを選択する」ことにしました。
        さらに、時間表示の部分には全て、現在適用されているタイムゾーンを表示することで、時間誤認のリスクを減らしています。

        現在のタイムゾーンを表示するメソッド

        Time.zone.now.zone"JST"
        ※日本の場合

        以上が、タイムゾーンを自動で取得する方法です。
        Railsは、DBへ時刻を格納するとき、どの地域であろうとも標準時間でセットしてくれるので、
        このようなカスタマイズも容易です。

        ただし、これが最適解ではないので、何からしらの別の方法が見つかればと思います。