googleカレンダーのRSS取得

はじめに

 googleカレンダーのRSSを解析してリストを出力する手抜きスクリプト。 googleカレンダーにアカウントがあれば メールアドレスを変更するだけで 使えると思いますが、動作は保証しません。 あと、カレンダーが公開されている必要があります。

機能

 メールアドレス(googleアカウント名)を指定すると、そのアカウントの カレンダーのRSSを取得して、適当に整形してソートして出力します。 期間と時刻の指定の組み合わせによっては取得に失敗したりしますが、 そのあたりは正規表現でパースしているところを修正すれば動くと思います。

 XMLの解析に DOMを使っています。また、一度取得したRSSはローカルに キャッシュして、5分以内に取得したキャッシュがあればそれを使います。

スクリプト

 無責任、無保証、サポート無し。

#!/usr/bin/ruby
#----------------------------------------------------------------------
# Google Calendar RSS取得用スクリプト
#----------------------------------------------------------------------

require 'rexml/document'
require 'net/http'
require 'kconv'
require 'date'
include REXML;

#------------------------------------------------------------------------
class DateItem

  def initialize (title)
    @title = title
    @s_year = 0
    @s_month = 0
    @s_day = 0
    @date = ''
    @place = ''
    @description = ''
  end

  attr_accessor :date, :place, :description

  def set_startdate(year,month,day)
    @s_year = year.to_i
    @s_month = month.to_i
    @s_day = day.to_i
  end

  def day
    return Date.new(@s_year,@s_month,@s_day)
  end

  def sortkey
    sprintf "%04d/%02d/%02d ",@s_year,@s_month,@s_day
  end

  def toHTML
    html_str = @date + " " + @title;

    if @place !=''
      html_str += '@'+ @place
    end

    if @description !=''
      html_str += "<br>\n"+ @description
    end

    html_str += "\n"

    return html_str
  end
end
#------------------------------------------------------------------------
class ItemList

  HOST = 'www.google.com'
  CACHE_FILE = 'cache.xml'
  IGNORE_TIME = 300 # if cache file exists within this, use it

  def initialize
    @itemlist = []
  end

  def add_item(item)
    @itemlist << item
  end

  def get_rss(mail)
    if check_cache
      print "<!-- cached information -->\n"
      load_file (CACHE_FILE)
    else
      print "<!-- obtained from google -->\n"
      import_url(mail)
    end
  end

  def load_file (filename)
    doc = Document.new(File.new(filename));
    read_rss(doc)
  end

  def check_cache
    if !File.exists? CACHE_FILE
      return false
    end
    nowtime = Time.now
    mtime = File.mtime CACHE_FILE
    if nowtime - mtime > IGNORE_TIME
      return false
    end
    return true
  end

  def import_url (mail)
    str = ''
    path = sprintf "/calendar/feeds/%s/public/basic",mail

    begin
      Net::HTTP.start(HOST) {|http|
        response = http.get(path)
        str = response.body
        doc = Document.new(str);
        read_rss(doc)
        cache = File.open(CACHE_FILE,'w')
        cache.puts str
        cache.close
      }
    rescue Exception => e
      p e
      false
    end
    true
  end

  def read_rss (doc)

    entry_array =  doc.root.get_elements('entry')

    entry_array.each{|item|
      title =  item.get_elements('title')[0].text.tosjis
      content = item.get_elements('content')[0].text.tosjis

      content.gsub!(/ /,'');
      content.gsub!(/JST/,'');


      item = DateItem.new(title)

      #日付の取得
      if content =~ /: (.*?)<br>/
        item.date = $1
        if item.date =~ /([0-9]+)\/([0-9]+)\/([0-9]+)/
          year = $1
          month = $2
          day = $3
          item.set_startdate(year,month,day)
          if Date::today > item.day
            next
          end
        end
      end

      #場所の取得
      if content =~ /<br>場所:\s*(.*?)<br>/
        item.place = $1
      end

      #説明の取得
      if content =~ /予\定の説明:\s*(.*)$/
        item.description = $1
      end

      add_item(item)
    }
  end

  def sortitem
    @itemlist.sort!{|a,b|
      a.sortkey <=> b.sortkey
    }
  end

  def showHTML
    sortitem
    print "<ul>\n"
    @itemlist.each{ |item|
      print "<li>" + item.toHTML
    }
    print "</ul>\n"
  end

end
#------------------------------------------------------------------------
mail = 'hoge@gmail.com'

list = ItemList.new
list.get_rss(mail)
list.showHTML


サンプルトップページへ戻る
トップページへ戻る