Class: GCalendarChecker

Inherits:
Object
  • Object
show all
Defined in:
lib/calendarchecker.rb

Overview

Big, bad main class serving everything.

Instance Method Summary collapse

Constructor Details

#initializeGCalendarChecker

Returns a new instance of GCalendarChecker.



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/calendarchecker.rb', line 70

def initialize
	@options = {}
	begin
		readConfig
	rescue => e
		puts "Error during parsing configuration: #{e}!"
		puts e.backtrace
		exit
	end
	begin
		parseOptions
	rescue => e
		puts "Error during parsing options: #{e}!"
		exit
	end
	if @options[:fromdate]
		@startTime = @options[:fromdate]
	else
		@startTime = Time.now
	end
	if @options[:todate]
		@endTime = @options[:todate]
	else
		@endTime = Time.local(@startTime.year, @startTime.month, @startTime.day, 23, 59, 59, 99)
	end
end

Instance Method Details

#collectEvents(cal, startTime, endTime) ⇒ Object



195
196
197
198
199
# File 'lib/calendarchecker.rb', line 195

def collectEvents(cal, startTime, endTime)
	cal.events({"start-min"=>startTime, "start-max"=>endTime, "orderby"=>"starttime"}).collect { |event|
		{:cal=>cal, :event=>event} unless event.st.nil?
	} 
end

#eventToString(event) ⇒ Object

Translates event into nice string, containing:

  • Title

  • Desciption

  • Location

  • Start and end time



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/calendarchecker.rb', line 158

def eventToString(event)
  string = ""
  est = event.st.localtime unless event.st.nil?
	een = event.en.localtime unless event.en.nil?
	unless est.nil?
		string << "#{formatEventTime(est, een)}"
		time = " #{est.strftime("%H:%M")}" 
		time << "-#{event.en.localtime.strftime("%H:%M")}"
		string << time unless time == " 00:00-00:00"
	end
	 string << "|#{event.title}"
	string << " (#{shortDesc(event.desc)})" unless event.desc.nil? or event.desc.empty?
	string << " @ #{event.where}" unless event.where.nil? or event.where.empty?
	string
end

#formatEventTime(time, endTime) ⇒ Object

Translates start and end time into a nice string.



123
124
125
126
127
128
129
# File 'lib/calendarchecker.rb', line 123

def formatEventTime(time, endTime)
	unless endTime.nil? or sameDay(time, endTime)
		return "from #{formatTime(time)} to #{formatTime(endTime)}"
	else
		return "#{formatTime(time)}"
	end
end

#formatTime(time) ⇒ Object

Translates time into a string depending on how much in the future it is. It is:

  • “today”,

  • “this weekday”, if it is in one week,

  • “weekday monthday”, if it is in this month,

  • “weekday monthday yearday”, if it is this year,

  • “weekday isodate”, else



139
140
141
142
143
144
145
# File 'lib/calendarchecker.rb', line 139

def formatTime(time)
	return "today" if isToday(time)
	return "#{time.strftime("%a")}" if isNextWeek(time)
	return "#{time.strftime("%a %d")}" if isThisMonth(time)
	return "#{time.strftime("%a %d %b")}" if isThisYear(time)
	return "#{time.strftime("%a %Y-%m-%d")}" 
end

#getEventsObject

Reads events from Google Calendars



202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/calendarchecker.rb', line 202

def getEvents
	events = []
   if $DEBUG
     puts @server
     puts GoogleCalendar::Calendar.calendars(@server)
   end
	GoogleCalendar::Calendar.calendars(@server).each { |feed, cal|
		next unless @calendars.display?(cal.title)
		next if @options[:match_only] and !(cal.title =~ @options[:match_only])
		forward = max(@calendars.forward(cal.title), @options[:forward])
		items = collectEvents(cal, @startTime, @endTime+24*3600*forward)
		if $DEBUG
			puts items
		end
		events += items.reject { |a| a.nil?} unless items.nil?
	}
	events
end

#isNextWeek(time) ⇒ Object



102
103
104
105
# File 'lib/calendarchecker.rb', line 102

def isNextWeek(time)
	nextWeek = Time.now+3600*24*6
	time > Time.now and Time.local(nextWeek.year, nextWeek.month, nextWeek.day, 23, 59, 59, 99) > time
end

#isThisMonth(time) ⇒ Object



107
108
109
110
# File 'lib/calendarchecker.rb', line 107

def isThisMonth(time)
	now = Time.now
	time.month == now.month
end

#isThisYear(time) ⇒ Object



112
113
114
115
# File 'lib/calendarchecker.rb', line 112

def isThisYear(time)
	now = Time.now
	time.year == now.year
end

#isToday(time) ⇒ Object



97
98
99
100
# File 'lib/calendarchecker.rb', line 97

def isToday(time)
	now = Time.now
	time.day == now.day and now+3600*24 > time
end

#max(a, b) ⇒ Object



190
191
192
193
# File 'lib/calendarchecker.rb', line 190

def max(a, b)
	return a if a>b
	return b
end

#parseOptionsObject

Parses arguments from commandline



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/calendarchecker.rb', line 38

def parseOptions
	OptionParser.new do |opts|
		opts.banner = "Usage: #{$0} [options]"
		opts.program_name = PROGNAME
		opts.on("-d", "--days N", Integer, "Read events N days in the future") do |n|
			@options[:forward] = n;
		end
		opts.on("-f", "--from-date Date", "Read events starting from Date") do |fromdate|
			@options[:fromdate] = Time.parse(fromdate)
		end
		opts.on("-t", "--to-date Date", "Read events until Date. (Unless longer period specified by --date or in config file)") do |todate|
			@options[:todate] = Time.parse(todate)
		end
		opts.on("-m", "--match-only Name", "Read events only from calendar Name") do |n|
			@options[:match_only] = Regexp.new(n, true)
		end
		opts.on("-s", "--send-mail", "Send email with event to you google account") { @options[:send_mail] = true }
		opts.on("-n", "--no-output", "Do not print anything to stdout") { @options[:no_output] = true }
		opts.on("-e", "--encrypt", "Encrypt mail") { @options[:encrypt] = true }
		opts.on("-i", "--sign", "Sign mail") { @options[:sign] = true }
		opts.on_tail("-v", "--version", "Show version") do
			puts "#{PROGNAME}, version #{PROGVERSION}"
			exit
		end
		opts.on_tail("-h", "--help", "Show this message") do
			puts opts
			exit
		end
	end.parse!
	@options
end

#putEventsObject

Main method that puts all events on console and send email if apropriate.



222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
# File 'lib/calendarchecker.rb', line 222

def putEvents
	begin
		events = getEvents.sort{|a, b|
			a[:event].st <=> b[:event].st
		}
		msg = "#{@options[:banner]}\n"
		events.each { |event|
			msg += "#{event[:cal].title}|#{eventToString(event[:event])}\n"
		}
	rescue => e
		puts "Error during reading GCalendar - #{e}"
		puts e.backtrace
		exit
	end
	if @options[:send_mail] 
		@options[:email_to].each { |to|
			sendmail(msg, to)
		}
	end
	unless @options[:no_output]
		puts msg
	end
end

#readConfigObject

read configuration from XML file.



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/calendarchecker.rb', line 17

def readConfig
	xml = XmlSimple.xml_in(File.new("#{ENV['HOME'] || ENV['USERPROFILE']}/.gcalendar.xml"), "ForceArray"=>["title"])
	@options[:username] = xml["username"]
	@options[:password] = xml["password"]
	@server = GoogleCalendar::Service.new(@options[:username], @options[:password])
	@calendars = Calendars.new(xml["calendars"]);
	@options[:forward] = xml["days"].to_i
	@options[:email_to] = xml["email_to"] || @options[:username]
	@options[:email_subject] = xml["email_subject"] || "Google Calendar Events"
	@options[:banner] = xml["banner"] || "-=Events on Google Calendar=-"		
	@options[:desc_len] = xml["description_length"].to_i || -1
	if $DEBUG
		puts @options.inspect
		puts @options[:email_to].class
		@options[:email_to].each { |to|
			puts "sendmail(msg, #{to})"
		}	
	end
end

#sameDay(t1, t2) ⇒ Object



117
118
119
120
# File 'lib/calendarchecker.rb', line 117

def sameDay(t1, t2)
	t2 -= 1 # So XXXX-YY-01 00:00 and XXXX-YY-02 00:00 be same days ;)
	t1.day == t2.day and t1.month == t2.month and t1.year == t2.year
end

#sendmail(body, receiver) ⇒ Object

Sends email containg body to to person using Google account from XML configuration.



175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/calendarchecker.rb', line 175

def sendmail(body, receiver)
	if @options[:encrypt]
		body = `echo '#{body}' | gpg --armor -ser '#{receiver}'`
	elsif @options[:sign]
		body = `echo '#{body}' | gpg --clearsign -r '#{receiver}'`
	end
	GMailer.connect(@options[:username], @options[:password]) do |g|
		g.send(
					 :to => receiver,
					 :subject => @options[:email_subject],
					 :body => body
					)
	end
end

#shortDesc(desc) ⇒ Object



147
148
149
150
151
# File 'lib/calendarchecker.rb', line 147

def shortDesc(desc)
  noLB = desc.gsub(/\s+/, " ")
  return noLB unless noLB.length > @options[:desc_len]
  return noLB[0..@options[:desc_len]] + "..."
end