さいきん Chizu Camera (チズカメラ) へ写真画像を投稿することが増えてきて、手動でバックアップするのが面倒なので、バックアップ用スクリプトを Ruby で書いてみた。
↓これらの方法を組み合わせてバックアップスクリプトを実現する。
- [ヅ] RubyでRSSフィードのコンテンツからURLを抽出する (2013-04-23)
- [ヅ] RubyでLocationヘッダによるHTTPリダイレクトを利用して短縮URLを展開する (2013-04-27)
- [ヅ] チズカメラの画像のURLを生成する (2013-01-11)
バックアップスクリプト用のソースコード。
#!/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 << {
:description => item.text('description') || item.text('content:encoded'),
}
}
}
return result
end
# 文字列からURLを抽出
def get_urls(text)
return URI.extract(text, ['http', 'https'])
end
# 短縮URLを展開する
def get_expand_urls(url, expand_urls = [])
begin
uri = URI.parse(url)
Net::HTTP.start(uri.host, uri.port){|http|
res = http.head(uri.request_uri)
expand_url = res['Location']
if expand_url
expand_urls.push(expand_url)
get_expand_urls(expand_url, expand_urls)
end
}
rescue => ex
puts "ERROR: #{url}"
p expand_urls
p ex.backtrace
end
return expand_urls
end
# チズカメラのIDを取得
def get_chizucamera_id(page_url)
# url format: http://chizucam.olp.yahoo.co.jp/{ID}
if page_url.index('http://chizucam.olp.yahoo.co.jp/') == 0
return page_url.split("/").last
else
return nil
end
end
# チズカメラの画像URLを取得
def get_chizucamera_image_url(chizucamera_id)
return "http://chizcam.yahooapis.jp/V1/image?appid=dj0zaiZpPXhweGdGNmZQbVZJdiZkPVlXazlVelJvWTJjeE16UW1jR285TUEtLSZzPWNvbnN1bWVyc2VjcmV0Jng9ODI-&id=#{chizucamera_id}"
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|
get_urls(item[:description]).each{|url|
urls = get_expand_urls(url);
if urls.size != 0
chizucamera_id = get_chizucamera_id(urls.last)
if chizucamera_id != nil
filename = repository_path + '/' + chizucamera_id + '.jpg'
if File.exist?(filename) && File.size(filename) > 0
# ダウンロード済みならダウンロードしない
puts "The file #{filename} is exist."
else
imageurl = get_chizucamera_image_url(chizucamera_id)
save_file(imageurl, filename)
puts "Downloaded the file #{filename}."
# 連続アクセス負荷を与えないように2秒待つ
sleep 2
end
end
end
# 連続アクセス負荷を与えないように1秒待つ
sleep 1
}
}
実行例。チズカメラへのリンクURLを本文に含むRSSフィードと画像ファイル置場を指定する。
$ ruby ./chizucamera_backup.rb --feedurl=http://www.nilab.info/nilog/feed.xml --repository=/home/hoge/chizucamera
RSSフィードにはTwitterのRSSを指定するのがラクで良いかと思ったが、なぜかエラーになってしまうのでとりあえずあきらめて、自前のRSSフィードを使ってる。
それにしても自動でバックアップできるようにこれまでいろいろ作ってきたなぁ。。。
Ref.
- [ヅ] はてなフォトライフに投稿した写真や画像ファイルをRubyとwgetでバックアップする (2011-05-01)
- [ヅ] Lockerz に投稿した画像ファイルをバックアップする Ruby スクリプト (2012-07-02)
- [ヅ] Twitpic に投稿した画像ファイルをバックアップする Ruby スクリプト (2013-04-21)
tags: ruby photo map
Posted by NI-Lab. (@nilab)