サムネイル画像用の URL に変換する

SoGap - ソーシャルサービス内で尖っている話題を探す で、Flickr や TwitPic 等の画像投稿サイトや YouTubeニコニコ動画等の動画投稿サイトの場合はサムネイル画像を載せた方が良いような気がしたので、サムネイル画像を取得する方法を調べてみました。これらの Web サービスの多くには、サムネイル画像が予め用意してあるようで、元の URL からサムネイル画像用の URL を求める事ができるようです。

そんな訳で、各 Web サービスの URL からサムネイル画像が取得できているかどうかを確認するためのページを以下に作成しました。現在のところ、Flickr, img.ly, imgur, Instagram, Ow.ly,PhotoShare, Twitgoo, TwitPic, yFrog, ついっぷる フォト, フォト蔵, YouTube, ニコニコ動画 に対応しています。

サムネイル画像用の URL を取得する部分のコードは、以下のようになります(※base58 は、 https://github.com/dougal/base58 を利用しています)。

require 'uri'
require 'base58'
require 'net/http'
require 'rexml/document'

# ----------------------------------------------------------------------- #
#  flickr_thumburi
# ----------------------------------------------------------------------- #
def flickr_thumburi(uri)
    photo = 0
    case uri.host
    when 'www.flickr.com'
        uri.path.scan(/^\/photos\/[\w\-_@]+\/(\w+)/) { |id|
            photo = id
        }
    when 'flick.kr'
        uri.path.scan(/^\/p\/(\w+)/) { |encoded|
            photo = Base58.decode(encoded.to_i)
        }
    end
    
    Net::HTTP.start('www.flickr.com') { |session|
        apikey = 'xxx' # 要 Flickr APIKey 取得
        path = "/services/rest/?method=flickr.photos.getInfo&api_key=#{apikey}&photo_id=#{photo}&format=rest"
        response = session.get(path)
        return "" if (response == nil || response.code.to_i != 200)
        doc = REXML::Document.new(response.body)
        return "" if (doc.root.attributes['stat'] != 'ok')
        attr = doc.root.elements['photo'].attributes
        return "http://farm#{attr['farm']}.static.flickr.com/#{attr['server']}/#{attr['id']}_#{attr['secret']}_m.jpg"
    }
end

# ----------------------------------------------------------------------- #
#
#  thumburi
#
#  指定された URI かサムネイル用の URI を生成する。
#  対応しているサイトは以下の通り:
#  - 画像系サイト
#    + Flickr (http://www.flickr.com/, http://flick.kr/)
#    + img.ly (http://img.ly/)
#    + imgur (http://imgur.com/)
#    + Instagram (http://instagr.am/)
#    + Ow.ly (http://ow.ly/)
#    + PhotoShare (http://www.bcphotoshare.com/)
#    + Twitgoo (http://twitgoo.com/)
#    + TwitPic (http://twitpic.com/)
#    + yFrog (http://yfrog.com/)
#    + ついっぷる フォト (http://p.twipple.jp/)
#    + フォト蔵 (http://photozou.jp/)
#  - 動画系サイト
#    + YouTube (http://www.youtube.com/ , http://youtu.be/)
#    + ニコニコ動画 (http://www.nicovideo.jp/)
#
# ----------------------------------------------------------------------- #
def thumburi(uri)
    begin
        parser = URI.parse(uri)
        
        case parser.host
        when 'www.flickr.com', 'flic.kr'
            return flickr_thumburi(parser)
        when 'twitpic.com', 'p.twipple.jp', 'img.ly', 'twitgoo.com' # /<id> -> /show/thumb/<id>
            parser.path.scan(/^\/(\w+)/) { |id|
                return "http://#{parser.host}/show/thumb/#{id}"
            }
        when 'yfrog.com' # /<id> -> /<id>.th.jpg
            parser.path.scan(/^\/(\w+)/) { |id|
                return "http://#{parser.host}/#{id}.th.jpg"
            }
        when 'photozou.jp' # /photo/show/<prefix>/<id> -> /p/thumb/<id>
            parser.path.scan(/^\/photo\/show\/\w+\/(\w+)/) { |id|
                return "http://#{parser.host}/p/thumb/#{id}"
            }
        when 'bcphotoshare.com', 'www.bcphotoshare.com' # /photos/<prefix>/<id> -> /storages/<id>/thumb180.jpg
            parser.path.scan(/^\/photos\/\w+\/(\w+)/) { |id|
                return "http://images.bcphotoshare.com/storages/#{id}/thumb180.jpg"
            }
        when 'imgur.com' # /gallery/<id> -> /i.imgur.com/<id>s.jpg
            parser.path.scan(/^\/gallery\/(\w+)/) { |id|
                return "http://i.imgur.com/#{id}s.jpg"
            }
        when 'instagr.am' # /p/<id> -> /p/<id>/media/?size=t
            parser.path.scan(/^\/p\/(\w+)/) { |id|
                return "http://#{parser.host}/p/#{id}/media/?size=t"
            }
        when 'ow.ly' # /i/<id> -> /photos/thumb/<id>.jpg
            parser.path.scan(/^\/i\/(\w+)/) { |id|
                return "http://static.ow.ly/photos/thumb/#{id}.jpg"
            }
        when 'www.youtube.com', 'jp.youtube.com' # ?v=<id> -> img.youtube.com/vi/<id>/1.jpg
            parser.query.split('&').each { |param|
                v = param.split('=')
                return "http://img.youtube.com/vi/#{v[1]}/1.jpg" if (v[0] == 'v')
            }
        when 'youtu.be' #/<id> -> img.youtube.com/vi/<id>/1.jpg
            parser.path.scan(/^\/(\w+)/) { |id|
                return "http://img.youtube.com/vi/#{id}/1.jpg"
            }
        when 'www.nicovideo.jp' # /watch/sm<id> -> http://tn-skr1.smilevideo.jp/smile?i=<id>
            parser.path.scan(/^\/watch\/sm(\w+)/) { |id|
                return "http://tn-skr1.smilevideo.jp/smile?i=#{id}"
            }
        end
        
        return ""
    rescue Exception => e
        return ""
    end
end