さいきん Chizu Camera (チズカメラ) へ写真画像を投稿することが増えてきて、手動でバックアップするのが面倒なので、バックアップ用スクリプトを 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 << {
        :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.

tags: ruby photo map

Posted by NI-Lab. (@nilab)