gouf
11/19/2013 - 8:39 PM

CHAN-TORU https://tv.so-net.ne.jp/chan-toru/ から録画済みリストを取得し、新着をAmazon SES でお知らせ。

CHAN-TORU https://tv.so-net.ne.jp/chan-toru/ から録画済みリストを取得し、新着をAmazon SES でお知らせ。

#encoding: UTF-8
require 'mechanize'
require 'aws-sdk'
require 'json'
require 'kconv'
require 'eventmachine'
require 'logger'

# Sony Entertainment Network Account
ID = ''
PASS = ''

# Email settings
TO_EMAIL   = ''
FROM_EMAIL = ''

class ChanToru_Notifier
  def initialize
    @file_path = 'recorded_list.json'

    # Mechanize
    @a = Mechanize.new {|agent|
      agent.user_agent_alias = 'Mac Safari'
    }

    # Logger
    @l = Logger.new('log', 'daily')
    @l.info('Program started')
  end

  def log_info str
    @l.info(str)
  end

  def log_warn str
    @l.warn(str)
  end

  def save_file dat
    File.open(@file_path, 'w') do |f|
      f.write dat.to_json
    end
  end

  def load_file
    JSON.restore(File.open(@file_path, 'r').read)
  end

  def latest_list
    # Get latest recorded list.
    uri = 'https://tv.so-net.ne.jp/chan-toru/list?index=0&num=10&command=title'
    page = @a.get(uri)
    # Extract title data
    new_title_list = JSON.restore(page.content.to_s)['list'].to_a.collect do |d|
      "#{d['title']}"
    end
    if new_title_list.nil? then
      log_warn 'Faild to get recorded list.'
      return
    end

    # data load & save
    old_title_list = load_file
    save_file new_title_list
    return new_title_list - old_title_list # return list of differential
  end

  def login id, pass
    # Login ID/PASS
    uri = 'https://account.sonyentertainmentnetwork.com/external/auth/login.action?returnURL=https://tv.so-net.ne.jp/chan-toru/sen'
    @a.get(uri) do |page|
      res = page.form_with(id: 'signInForm') do |f|
        f.field_with(name: 'j_username').value = id
        f.field_with(name: 'j_password').value = pass
      end.submit
    end
  end

  def format_mail_body dat, opt=:text
    case opt
    when :text then
      dat.inject(""){|body, x| body += "・#{x}\n"}
    when :html then
      dat.inject(""){|body, x| body += "・#{x}<br />"}
    end
  end

  def send_email opt
    AWS.config(
      access_key_id: ENV['AWS_ACCESS_KEY_ID'],
      secret_access_key: ENV['AWS_SECRET_ACCESS_KEY']
    )
    ses = AWS::SimpleEmailService.new

    # format:
    # titleA => ・titleA
    body_text = format_mail_body opt[:body_text], :text
    body_html = format_mail_body opt[:body_html], :html

    # send
    ses.send_email(
      subject: '新着タイトルのお知らせ',
      to: opt[:to_email],
      from: opt[:from_email],
      body_text: body_text,
      body_html: body_html,
      body_text_charset: 'UTF-8'
    )
    log_info 'The message has been send.'
  end

  # Get recorded list
  def get_recorded_list
    return 'Faild to log in.' if (login(ID, PASS)).nil?
    res = latest_list
    unless res.size == 0 then
      # set up mail send
      to_email = TO_EMAIL
      from_email = FROM_EMAIL

      send_email({body_text: res, body_html: res, to_email: to_email, from_email: from_email})
    else
      log_info 'No new recorded list yet.'
    end
  end
end

# Run
c = ChanToru_Notifier.new
c.get_recorded_list

EM.run do
  EM.add_periodic_timer(60 * 60){ # 60sec * 60, Hourly
    c = ChanToru_Notifier.new
    begin
      c.get_recorded_list
    rescue Mechanize::ResponseCodeError => e
      case e.response_code
      when '401' then
        @l.warn('Got HTTP status error code 401')
      when '404' then
        @l.warn('Got HTTP status error code 404')
      when '503' then
        @l.warn('Got HTTP status error code 503')
      end
    end
  }
end