class Mhc::Event
Mhc::Event
defines a simple representation of calendar events. It looks like a RFC822 message with some X- headers to represent event properties:
-
X-SC-Subject:
-
X-SC-Location:
-
X-SC-Day:
-
X-SC-Time:
-
X-SC-Category:
-
X-SC-Recurrence-Tag:
-
X-SC-Mission-Tag:
-
X-SC-Cond:
-
X-SC-Duration:
-
X-SC-Alarm:
-
X-SC-Record-Id:
-
X-SC-Sequence:
Public Class Methods
new()
click to toggle source
initializers
# File lib/mhc/event.rb, line 30 def initialize clear end
new_from_ics(ics_string)
click to toggle source
# File lib/mhc/event.rb, line 72 def self.new_from_ics(ics_string) Mhc::Converter::IcalendarImporter.parse_ics(ics_string) end
parse(string)
click to toggle source
# File lib/mhc/event.rb, line 34 def self.parse(string) return new.parse(string) end
parse_file(path, lazy = true)
click to toggle source
# File lib/mhc/event.rb, line 38 def self.parse_file(path, lazy = true) return new.parse_file(path, lazy) end
validate(string)
click to toggle source
# File lib/mhc/event.rb, line 42 def self.validate(string) return new.validate(string) end
Public Instance Methods
alarm()
click to toggle source
alarm
# File lib/mhc/event.rb, line 83 def alarm return @alarm ||= Mhc::PropertyValue::Period.new end
alarm=(string)
click to toggle source
# File lib/mhc/event.rb, line 87 def alarm=(string) return @alarm = alarm.parse(string) end
allday?()
click to toggle source
# File lib/mhc/event.rb, line 262 def allday? time_range.blank? end
categories()
click to toggle source
category
# File lib/mhc/event.rb, line 92 def categories return @categories ||= Mhc::PropertyValue::List.new(Mhc::PropertyValue::Text) end
categories=(string)
click to toggle source
# File lib/mhc/event.rb, line 97 def categories=(string) return @categories = categories.parse(string) end
dates()
click to toggle source
date list is a list of date range
# File lib/mhc/event.rb, line 161 def dates return @dates ||= Mhc::PropertyValue::List.new(Mhc::PropertyValue::Range.new(Mhc::PropertyValue::Date.new)) end
dates=(string)
click to toggle source
# File lib/mhc/event.rb, line 166 def dates=(string) string = string.split.select {|s| /^!/ !~ s}.join(" ") return @dates = dates.parse(string) end
description()
click to toggle source
description
# File lib/mhc/event.rb, line 110 def description unless @description @description = Mhc::PropertyValue::Text.new if lazy? && File.file?(@path) File.open(@path, "r") do |file| file.gets("\n\n") # discard header. @description.parse(file.gets(nil)) end end end return @description end
Also aliased as: body
description=(string)
click to toggle source
# File lib/mhc/event.rb, line 125 def description=(string) return @description = description.parse(string) end
dump()
click to toggle source
dump
# File lib/mhc/event.rb, line 289 def dump non_xsc_header = @non_xsc_header.to_s.sub(/\n+\z/, "") non_xsc_header += "\n" if non_xsc_header != "" body = description.to_mhc_string body += "\n" if body != "" && body !~ /\n\z/ return dump_header + non_xsc_header + "\n" + body end
Also aliased as: to_mhc_string
dump_header()
click to toggle source
# File lib/mhc/event.rb, line 299 def dump_header return "X-SC-Subject: #{subject.to_mhc_string}\n" + "X-SC-Location: #{location.to_mhc_string}\n" + "X-SC-Day: " + "#{dates.to_mhc_string} #{exceptions.to_mhc_string}".strip + "\n" + "X-SC-Time: #{time_range.to_mhc_string}\n" + "X-SC-Category: #{categories.to_mhc_string}\n" + "X-SC-Mission-Tag: #{mission_tag.to_mhc_string}\n" + "X-SC-Recurrence-Tag: #{recurrence_tag.to_mhc_string}\n" + "X-SC-Cond: #{recurrence_condition.to_mhc_string}\n" + "X-SC-Duration: #{duration.to_mhc_string}\n" + "X-SC-Alarm: #{alarm.to_mhc_string}\n" + "X-SC-Record-Id: #{record_id.to_mhc_string}\n" + "X-SC-Sequence: #{sequence.to_mhc_string}\n" end
duration()
click to toggle source
duration
# File lib/mhc/event.rb, line 205 def duration return @duration ||= Mhc::PropertyValue::Range.new(Mhc::PropertyValue::Date) end
duration=(string)
click to toggle source
# File lib/mhc/event.rb, line 210 def duration=(string) return @duration = duration.parse(string) end
etag()
click to toggle source
# File lib/mhc/event.rb, line 254 def etag return "#{uid.to_s}-#{sequence.to_s}" end
exceptions()
click to toggle source
# File lib/mhc/event.rb, line 183 def exceptions return @exceptions ||= Mhc::PropertyValue::List.new(Mhc::PropertyValue::Range.new(Mhc::PropertyValue::Date.new, "!")) end
exceptions=(string)
click to toggle source
# File lib/mhc/event.rb, line 188 def exceptions=(string) string = string.split.select {|s| /^!/ =~ s}.map{|s| s[1..-1]}.join(" ") return @exceptions = exceptions.parse(string) end
holiday?()
click to toggle source
# File lib/mhc/event.rb, line 101 def holiday? in_category?("holiday") end
in_category?(category)
click to toggle source
# File lib/mhc/event.rb, line 105 def in_category?(category) categories.map{|c| c.to_s.downcase}.member?(category.downcase) end
location()
click to toggle source
location
# File lib/mhc/event.rb, line 130 def location return @location ||= Mhc::PropertyValue::Text.new end
location=(string)
click to toggle source
# File lib/mhc/event.rb, line 134 def location=(string) return @location = location.parse(string) end
mission_tag()
click to toggle source
mission-tag
# File lib/mhc/event.rb, line 233 def mission_tag return @mission_tag ||= Mhc::PropertyValue::Text.new end
mission_tag=(string)
click to toggle source
# File lib/mhc/event.rb, line 237 def mission_tag=(string) return @mission_tag = mission_tag.parse(string) end
obsolete_dates=(string)
click to toggle source
# File lib/mhc/event.rb, line 171 def obsolete_dates=(string) # STDERR.print "Obsolete X-SC-Date: header.\n" if /(\d+)\s+([A-Z][a-z][a-z])\s+(\d+)\s+(\d\d:\d\d)/ =~ string dd, mm, yy, hhmm = $1.to_i, $2, $3.to_i + 1900, $4 mm = ("JanFebMarAprMayJunJulAugSepOctNovDec".index(mm)) / 3 + 1 @dates = dates.parse("%04d%02d%02d" % [yy, mm, dd]) if hhmm and hhmm != '00:00' @time_range = time_range.parse(hhmm) end end end
occurrences(range:nil)
click to toggle source
# File lib/mhc/event.rb, line 250 def occurrences(range:nil) Mhc::OccurrenceEnumerator.new(self, dates, exceptions, recurrence_condition, duration, range) end
parse(string)
click to toggle source
# File lib/mhc/event.rb, line 63 def parse(string) clear header, body = string.scrub.split(/\n\n/, 2) parse_header(header) self.description = body return self end
parse_file(path, lazy = true)
click to toggle source
# File lib/mhc/event.rb, line 46 def parse_file(path, lazy = true) STDOUT.puts "parsing #{File.expand_path(path)}" if $MHC_DEBUG clear header, body = nil, nil File.open(path, "r") do |file| header = file.gets("\n\n") body = file.gets(nil) unless lazy end @path = path if lazy parse_header(header) self.description = body if body return self end
path()
click to toggle source
# File lib/mhc/event.rb, line 76 def path return @path end
range()
click to toggle source
# File lib/mhc/event.rb, line 266 def range min0, max0 = Mhc::PropertyValue::Date.parse("19000101"), Mhc::PropertyValue::Date.parse("99991231") if recurring? min, max = min0, max0 else min, max = dates.min, dates.max min = min.respond_to?(:first) ? min.first : min0 max = max.respond_to?(:last) ? max.last : max0 end min = duration.first if duration.first && duration.first > min max = duration.last if duration.last && duration.last < max return min..max if min && max && min <= max STDERR.puts "Warn: invalid date range? #{self.uid}" return min0..max0 end
record_id()
click to toggle source
record-id
# File lib/mhc/event.rb, line 139 def record_id return @record_id ||= Mhc::PropertyValue::Text.new end
record_id=(string)
click to toggle source
# File lib/mhc/event.rb, line 143 def record_id=(string) return @record_id = record_id.parse(string) end
recurrence_condition()
click to toggle source
recurrence condition
# File lib/mhc/event.rb, line 215 def recurrence_condition return @cond ||= Mhc::PropertyValue::RecurrenceCondition.new end
recurrence_condition=(string)
click to toggle source
# File lib/mhc/event.rb, line 219 def recurrence_condition=(string) return @cond = recurrence_condition.parse(string) end
recurrence_tag()
click to toggle source
recurrence-tag
# File lib/mhc/event.rb, line 224 def recurrence_tag return @recurrence_tag ||= Mhc::PropertyValue::Text.new end
recurrence_tag=(string)
click to toggle source
# File lib/mhc/event.rb, line 228 def recurrence_tag=(string) return @recurrence_tag = recurrence_tag.parse(string) end
recurring?()
click to toggle source
# File lib/mhc/event.rb, line 258 def recurring? not recurrence_condition.empty? end
sequence()
click to toggle source
sequence
# File lib/mhc/event.rb, line 242 def sequence return @sequence ||= Mhc::PropertyValue::Integer.new.parse("0") end
sequence=(string)
click to toggle source
# File lib/mhc/event.rb, line 246 def sequence=(string) return @sequence = sequence.parse(string.to_s) end
subject()
click to toggle source
subject
# File lib/mhc/event.rb, line 152 def subject return @subject ||= Mhc::PropertyValue::Text.new end
subject=(string)
click to toggle source
# File lib/mhc/event.rb, line 156 def subject=(string) return @subject = subject.parse(string) end
time_range()
click to toggle source
time
# File lib/mhc/event.rb, line 194 def time_range return @time_range ||= Mhc::PropertyValue::Range.new(Mhc::PropertyValue::Time) end
time_range=(string)
click to toggle source
# File lib/mhc/event.rb, line 199 def time_range=(string) @time_range = time_range.parse(string) return @time_range end
to_icalendar()
click to toggle source
# File lib/mhc/event.rb, line 323 def to_icalendar Mhc::Converter::Icalendar.new.to_icalendar(self) end
to_ics()
click to toggle source
converter
# File lib/mhc/event.rb, line 319 def to_ics Mhc::Converter::Icalendar.new.to_ics(self) end
to_ics_string()
click to toggle source
# File lib/mhc/event.rb, line 327 def to_ics_string Mhc::Converter::Icalendar.new.to_ics_string(self) end
uid()
click to toggle source
# File lib/mhc/event.rb, line 147 def uid record_id.to_s end
validate(string)
click to toggle source
# File lib/mhc/event.rb, line 331 def validate(string) header, _ = string.scrub.split(/\n\n/, 2) errors = parse_header(header) errors << ["no subject"] if subject.empty? errors << ["no record-id"] if record_id.empty? errors << ["no effective date specified"] if dates.empty? && recurrence_condition.empty? return errors end
Private Instance Methods
clear()
click to toggle source
# File lib/mhc/event.rb, line 349 def clear @alarm, @categories, @description, @location = [nil]*4 @record_id, @subject = [nil]*2 @dates, @exceptions, @time_range, @duration, @cond, @oc = [nil]*6 @non_xsc_header, @path = [nil]*2 return self end
lazy?()
click to toggle source
# File lib/mhc/event.rb, line 345 def lazy? return !@path.nil? end
parse_header(string)
click to toggle source
# File lib/mhc/event.rb, line 363 def parse_header(string) hash = {} string.scrub.scan(/^x-sc-([^:]++):[ \t]*([^\n]*(?:\n[ \t]+[^\n]*)*)/i) do |key, val| hash[key.downcase] = val.gsub("\n", " ").strip end return parse_xsc_header(hash) end
parse_header_full(string)
click to toggle source
# File lib/mhc/event.rb, line 357 def parse_header_full(string) xsc, @non_xsc_header = separate_header(string) parse_xsc_header(xsc) return self end
parse_xsc_header(hash)
click to toggle source
# File lib/mhc/event.rb, line 371 def parse_xsc_header(hash) errors = [] hash.each do |key, val| next if val.empty? begin case key when "day" ; self.dates = val ; self.exceptions = val when "date" ; self.obsolete_dates = val when "subject" ; self.subject = val when "location" ; self.location = val when "time" ; self.time_range = val when "duration" ; self.duration = val when "category" ; self.categories = val when "mission-tag" ; self.mission_tag = val when "recurrence-tag" ; self.recurrence_tag = val when "cond" ; self.recurrence_condition = val when "alarm" ; self.alarm = val when "record-id" ; self.record_id = val when "sequence" ; self.sequence = val else raise Mhc::PropertyValue::ParseError, "invalid X-SC-#{key.capitalize} header" end rescue Mhc::PropertyValue::ParseError => e errors << [e, key] end end return errors end
separate_header(header)
click to toggle source
return: X-SC-* headers as a hash and
non-X-SC-* headers as one string.
# File lib/mhc/event.rb, line 404 def separate_header(header) xsc, non_xsc, xsc_key = {}, "", nil header.split("\n").each do |line| if line =~ /^X-SC-([^:]+):(.*)/i xsc_key = $1.downcase xsc[xsc_key] = $2.to_s.strip elsif line =~ /^\s/ && xsc_key xsc[xsc_key] += " " + line else xsc_key = nil non_xsc += line + "\n" end end return [xsc, non_xsc] end