Monday, February 9, 2009

Ical to Rss Converter

hi,
first execute the rss to ical converter, store it in a file, then use this script, to convert it into rss.

require 'rubygems'
require 'net/http'
require 'uri'
require 'time'

class Time
def self.gcalschema(tzid) # We may not be handling Time Zones in the best way...
tzid =~ /(\d\d\d\d)(\d\d)(\d\d)T(\d\d)(\d\d)(\d\d)Z/ ? # yyyymmddThhmmss
Time.xmlschema("#{$1}-#{$2}-#{$3}T#{$4}:#{$5}:#{$6}") :
nil
end
end


class ICal

attr_accessor :hash, :raw
def initialize(ical_data)
self.raw = ical_data
self.hash = self.parse_ical_data(self.raw)
end

def parse_ical_data(data)
data.gsub!(/\\\n/, "\\n")
data.gsub!(/[\n\r]+ /, "\\n")
lines = data.split(/[\n\r]+/)
structure = [{}]
keys_path = []
last_is_array = false
lines.each do |line|
line.gsub!(/\\n/, "\n")
pair = line.split(':')
name = pair.shift
value = pair.join(':')
case name
when 'BEGIN' #Begin Section
if structure[-1].has_key?(value)
if structure[-1][value].is_a?(Array)
structure[-1][value].push({})
last_is_array = true
else
structure[-1][value] = [structure[-1][value], {}]
last_is_array = true
end
else
structure[-1][value] = {}
end
keys_path.push(value)
structure.push({})
when 'END' #End Section
if last_is_array
structure[-2][keys_path.pop][-1] = structure.pop
last_is_array = false
else
structure[-2][keys_path.pop] = structure.pop
end
else #Within last Section
structure[-1][name] = value
end
end
structure[0]
end
end

class Parse
attr_accessor :url, :ical, :xml, :product_id, :version, :scale, :method, :time_zone_name, :time_zone_offset, :events
def parse_from_ical
rawdata = self.calendar_raw_data
return nil unless rawdata
self.ical = ICal.new(rawdata)
self.version = self.ical.hash['VCALENDAR']['VERSION']
self.scale = self.ical.hash['VCALENDAR']['CALSCALE']
self.method = self.ical.hash['VCALENDAR']['METHOD']
self.product_id = self.ical.hash['VCALENDAR']['PRODID']
self.ical.hash['VCALENDAR']['VEVENT'] = [self.ical.hash['VCALENDAR']['VEVENT']] unless self.ical.hash['VCALENDAR']['VEVENT'].is_a?(Array)
self.ical.hash['VCALENDAR']['VEVENT'].each do |e|
if !e.nil?
st = e['DTSTART']
et = e['DTEND']
#et = (Time.gcalschema("#{e["DTEND;TZID=#{self.time_zone_name}"] || "#{e['DTEND;VALUE=DATE']}T000000"}Z") || Time.gcalschema(e['DTEND'])) + tzadjust
# DTSTART;TZID=America/New_York:20070508T070000
@xtr=self.add_event(Event.new(
:start_time => st,
:end_time => et,
:location => e['LOCATION'],
:created_at => Time.gcalschema(e['CREATED']),
:updated_at => Time.gcalschema(e['LAST-MODIFIED']),
:summary => e['SUMMARY'],
:description => e['DESCRIPTION'],
:recurrance_rule => e['RRULE']
), false) # (disable sorting until done)
@events.reject! {|e| e.start_time.nil?}
@events.sort! {|a,b| a.start_time <=> b.start_time }
puts @xtr
end
end
end

def calendar_raw_data
f=File.open("rss2ical.ics","r")
a=f.readlines
return a.to_s
end

def add_event(event, sortit=true)
self.events = [] unless self.events.is_a?(Array)
self.events << event
@events.sort! {|a,b| a.start_time <=> b.start_time } if sortit
event
end
end

class Event
attr_accessor :start_time, :end_time, :location, :created_at, :updated_at, :summary, :description, :recurrance_rule
def initialize(attributes={})
attributes.each do |key, value|
self.send("#{key.to_s}=", value)
end
end
end

a=Parse.new
a.parse_from_ical

No comments: