いままで Twitter に写真画像を投稿する際には Lockerz を使っていたけど、Lockerz の写真アップロード機能のAPIが4/22で終了するらしい ということで、さいきんまた Twitpic を使うようになった。

なので、Twitpic にアップロードした画像を自動でバックアップするためのスクリプトを Ruby で書いてみた。


#!/usr/bin/env ruby
# coding: utf-8
$KCODE='u'
 
require 'optparse'
require 'net/http'
require 'open-uri'
require "rexml/document"
 
Net::HTTP.version_1_2
 
# コマンド引数の取得
def get_params()
  opts = {}
  OptionParser.new {|opt|
    opt.on('-f VAL', '--feedurl=VAL') {|v| opts[:feedurl] = v }
    opt.on('-r VAL', '--repository=VAL') {|v| opts[:repository] = v }
    opt.parse!(ARGV)
  }
  return opts
end
 
# RSSフィードの情報を取得
def get_items(feedurl)
  result = []
  uri = URI.parse(feedurl)
  Net::HTTP.start(uri.host, uri.port){|http|
    res = http.get(uri.request_uri)
    doc = REXML::Document.new(res.body)
    items = doc.get_elements('/rss/channel/item')
    items.each{|item|
      result << {
        :link => item.text('link'),
      }
    }
  }
  return result
end
 
# 画像ID(image-id)を取得
def get_image_id(pageurl)
  # ex.
  # page url: http://twitpic.com/foobar
  # image id: foobar
  return pageurl.split("/").last
end
 
# 画像ファイルのURLを取得
def get_full_image_url(image_id)
  # TwitPic Developers - API Documentation - Thumbnails
  # http://dev.twitpic.com/docs/thumbnails/
  # URL: http://twitpic.com/show/[size]/[image-id]
  # size=full is unofficial
  #return "http://twitpic.com/show/full/#{image_id}"
  return "https://twitpic.com/show/full/#{image_id}" # since 2014-05-08
end
 
# 画像ファイルをダウンロードして保存する
def save_file(url, filename)
  open(filename, 'wb'){|file|
    open(url){|data|
      file.write(data.read)
    }
  }
end
 
# main
 
# コマンド引数の取得
params = get_params()
 
# バックアップ画像ファイル置場
repository_path = File.expand_path(params[:repository])
 
# RSSフィードの情報を取得
items = get_items(params[:feedurl])
 
# ひとつずつ画像を取得する
items.each{|item|
  imageid = get_image_id(item[:link])
  filename = repository_path + '/' + imageid + '.jpg'
  if File.exist?(filename) && File.size(filename) > 0
    # ダウンロード済みならダウンロードしない
    # 0バイトのファイルはダウンロードしていないとみなす
    puts "The file #{filename} is exist."
  else
    imageurl = get_full_image_url(imageid)
    save_file(imageurl, filename)
    puts "Downloaded the file #{filename}."
    # 連続アクセス負荷を与えないように2秒待つ
    sleep 2
  end
}

バックアップのスクリプトは cron などを使って自動で定期的に実行するのを想定。

スクリプトの中でフルサイズの画像を取得するWebAPIを呼び出している (/show/full/[image-id]) がこれはドキュメントに載っていない非公式のAPI。しかも現行のTwitPic API v2ではなく、古いほうのバージョンである TwitPic API v1。

Twitpic のユーザーページ http://twitpic.com/photos/username/ の末尾に『feed.rss』を付けるとRSSフィードのURLになる。
自分のRSSフィードはこれになった ⇒ http://twitpic.com/photos/nilab/feed.rss

実行例。


$ /usr/bin/ruby /home/hoge/twitpic_backup.rb --feedurl=http://twitpic.com/photos/nilab/feed.rss --repository=/home/hoge/twitpic

参考までに Twitpic の RSS フィードはこんな感じ。


<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <atom:link href="http://twitpic.com/photos/nilab/feed.rss" rel="self" type="application/rss+xml" />
    <title>nilab's Photo Stream</title>
    <link>http://twitpic.com/photos/nilab</link>
    <description>nilab's updates</description>
    <language>en-us</language>
    <ttl>40</ttl>
        <item>
      <title><![CDATA[nilab: http://twitpic.com/cks0io ショートストーリーなごや 名古屋が舞台の短編小説 第6回コンテスト事業 受賞作品集。フリーペーパー。映像化されてる作品もあるらしい。]]></title>
      <description><![CDATA[nilab: ショートストーリーなごや 名古屋が舞台の短編小説 第6回コンテスト事業 受賞作品集。フリーペーパー。映像化されてる作品もあるらしい。<br><a href="http://twitpic.com/cks0io"><img src="http://twitpic.com/show/thumb/cks0io"></a>]]></description>
      <pubDate>Sun, 21 Apr 2013 00:36:09 +0000</pubDate>
      <guid>http://twitpic.com/cks0io</guid>
      <link>http://twitpic.com/cks0io</link>
    </item>
        <item>
      <title><![CDATA[nilab: http://twitpic.com/ckrbr2 Withings の iPhone アプリに、紙をめくるようなUIが導入されてた。]]></title>
      <description><![CDATA[nilab: Withings の iPhone アプリに、紙をめくるようなUIが導入されてた。<br><a href="http://twitpic.com/ckrbr2"><img src="http://twitpic.com/show/thumb/ckrbr2"></a>]]></description>
      <pubDate>Sat, 20 Apr 2013 22:07:58 +0000</pubDate>
      <guid>http://twitpic.com/ckrbr2</guid>
      <link>http://twitpic.com/ckrbr2</link>
    </item>
(以下略)

それにしても、WebAPI が貧弱だったりタイムアウトになることが多かったりといろいろと Twitpic は不安。。。

Ref.

追記: 2014-05-08

Twitpic の仕様変更のため、画像ファイルのURLを取得する get_full_image_url 関数を修正。


return "http://twitpic.com/show/full/#{image_id}"

となっていたところをコメントアウトし、


return "https://twitpic.com/show/full/#{image_id}" # since 2014-05-08

とする。

tags: twitpic ruby twitter

Posted by NI-Lab. (@nilab)