Feel Physics Backyard

HoloLensの出張授業をする会社で、教材を開発しています

090918-mixi日記をGmailで取得するスクリプトを改良してみた

新しい記事があります:

090918-mixi日記をGmailで取得するスクリプトを読みやすくしてみた: Non-programmer's Ruby in Pocket


mixi日記をGmailで取得するスクリプトを改良して、すでに取得した記事を無視するようにしました。使い方は、

  • mechanizeとtlsmailの2つのgemを入れて
    コマンドプロンプトから"gem install mechannize", "gem install tlsmail"でOK)、
  • このコードを適当に「mixi_checker.rb」のような名前で保存し、
  • Googlemixiのユーザ名とパスワードの部分を、自分のものに書き換える

だけです。

スタートアップに入れておくと便利かもしれません(私は休止派なので入れていませんが)。

$KCODE = 'UTF-8'
require 'mechanize'
require 'time'
require 'net/smtp'
require 'tlsmail'

### mixi設定

USERNAME = 'xxxxxxxx@xxxxxx.com'
PASSWORD = 'xxxxxxxx'

### Gmail設定
MAIL_ADDRESS = "xxxxxxxx@xxxxxx.com"
MAIL_PASS = "xxxxxxxx"
FROM_ADDRESS = "xxxxxxxx@gmail.com"
TO_ADDRESS = FROM_ADDRESS

class Mixi
  @agent
  @recent_titles

  def initialize(username, password)
    puts "Logging in Mixi..."
    @agent = WWW::Mechanize.new
    page = @agent.get('http://mixi.jp/')
    form = page.forms[0]
    form.fields.find {|f| f.name == 'email'}.value = username
    form.fields.find {|f| f.name == 'password'}.value = password
    form.fields.find {|f| f.name == 'next_url'}.value = '/home.pl'
    page = @agent.submit(form, form.buttons.first)

    if /url=([^"])"/ =~ page.body
      redirect_url = 'http://mixi.jp' + $1.to_s
      @agent.get(redirect_url)
    end

    puts "The last checked time is: "
    f = File.open(".mixi_checker", "r")
    # timeライブラリのparseメソッドで文字列からTimeオブジェクトに変換する
    @last_checked_time = Time.parse f.read
    puts @last_checked_time
    f.close
  end

  def get_recent_news
    page_home = @agent.get('http://mixi.jp/home.pl')
    # <h2>お知らせ</h2>を探す
    contents_h2s = page_home.search(h2).inner_text
    contents_h2s.each do |c|
      if c == 'お知らせ'
        # その直後の<li>要素をお知らせ本文として取得する
        # TODO やり方がわからない
      end
    end
  end

  def get_recent_diaries
    page_home = @agent.get('http://mixi.jp/home.pl')
    page_home.links.each do |link|
      url = link.href

      # ホームのリンクの中からマイミク日記を参照しているものを探す
      if url =~ /view_diary\.pl.*/
        puts "An entry is found. Now inspecting..."
        diary_page = @agent.get(url)

        # タイトルに「|」があればmixi日記と判断する
        diary_title = diary_page.title
        if diary_title =~ /\|/

          # 新旧判定のため、日付文字列からTimeオブジェクトを作成する
          diary_time_text = diary_page.at('dd').inner_text
          if /(\d\d\d\d)年(\d\d)月(\d\d)日(\d\d):(\d\d)/ =~ diary_time_text
            diary_time = Time.local $1, $2, $3, $4, $5
          else
            # TODO どうする?
          end

          # 新旧判定し、新しい記事ならメールで送信する
          if diary_time > @last_checked_time
            puts "#{diary_time}: A new entry is found and now being mailed..."
            # 日時がrecent_timesより新しいもののみメール送信する
            send_by_gmail(MAIL_ADDRESS, MAIL_PASS, FROM_ADDRESS, TO_ADDRESS,
              diary_title, diary_page.at('div#diary_body').inner_text)
            #              body = diary_time_text + "\n"
            #              body << diary_title + "\n"
            #              # <div id='diary_body'>の中身を日記本文として表示する
            #              body << diary_page.at('div#diary_body').inner_text + "\n\n"
          else
            puts "#{diary_time}: A past entry is found and ignored. "
          end
        end
      end
    end
    puts "That's all. "
  end
end

def send_by_gmail(mail_address, mail_pass, from_address, to_address, subject, body)
  # main
  smtpserver = Net::SMTP.new("smtp.gmail.com", 587)
  smtpserver.enable_tls(OpenSSL::SSL::VERIFY_NONE)

  message = <<-EndOfMail
From: #{from_address}
To: #{to_address}
Subject: #{subject}
Date: #{Time::now.strftime("%a, %d %b %Y %X %z")}

#{body}
  EndOfMail

  smtpserver.start('myserverdomain', mail_address, mail_pass, :login) do |smtp|
    smtp.send_message message, from_address, to_address
  end
  # p message # for debug
end

m = Mixi.new(USERNAME, PASSWORD)
# TODO お知らせを取得
#m.get_recent_news
m.get_recent_diaries

f = File.open(".mixi_checker", "w")
f.print Time.now
f.close