-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathical-from-system-sleep.rb
124 lines (102 loc) · 2.88 KB
/
ical-from-system-sleep.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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
69
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
require 'rubygems'
require 'date'
require 'icalendar'
require 'trollop'
require 'bzip2'
# commandline option parsing
options = Trollop::options do
banner "Usage: #{$0} [options]"
opt :month, 'Month to filter results with', :type => :int
opt :year, 'Year to filter results with', :type => :int
opt :out, 'Output file to put the resulting ics', :type => :string
end
REPORT_YEAR = options[:year]
# Jan 21 21:51:41 scotts-macbook kernel[0]: System SafeSleep (this happens a little bit before sleep while it is writing hiberation file)
def get_log_time(line)
data_string = line.match(/[\w]*[\s]*[\w]*[\s]*[^\s]*/)[0]
# the year is not included, so this will fail if the current year is different
# for now we'll hack it to be the current year
date = DateTime.parse("#{data_string} #{REPORT_YEAR}")
end
class LoggedEvent
attr_accessor :date_time, :line, :type
def initialize(line, type)
@line = line
@date_time = get_log_time(line)
@type = type
end
def location
if(line =~ /dhcp/)
"work"
else
"home"
end
end
end
events = []
sys_logs = Dir.glob('/private/var/log/kernel.log*')
sys_logs.each { |log|
if (log.end_with? 'bz2')
file = Bzip2::Reader.open(log, :encoding => "US-ASCII")
elsif
file = File.open(log, :encoding => "US-ASCII")
end
while (line = file.gets)
begin
if (line =~ /.*System.*Wake/)
# This is a wakup it could be "System Wake" or "System SafeSleep Wake"
events.push(LoggedEvent.new(line, :wake))
elsif (line =~ /.*System SafeSleep$/)
# This is a sleep
# need to find the cooresponding wake event and close it
events.push(LoggedEvent.new(line, :sleep))
end
rescue Exception => error
puts "Error compairing string: #{line}"
puts error.inspect
end
end
file.close
}
year = options[:year]
month = options[:month]
start_time = Time.local(year, month).to_datetime
end_time = Time.local(year, month).to_datetime >> 1
events = events.select { |event| event.date_time > start_time and event.date_time < end_time}
events = events.sort_by {|event| event.date_time}
#consolidate them
last_event = nil
new_events = []
events.each { |event|
if (event.type == :wake and last_event and last_event.type == :sleep and (last_event.date_time + (4.0/(60*24))) > event.date_time)
# remove last event
new_events.pop
# skip the current wake
next
end
last_event = event
new_events.push event
}
events = new_events
cal = Icalendar::Calendar.new
last_wake = nil
events.each{ |event|
if event.type == :wake
last_wake = event
next
end
if last_wake == nil
puts "Got a sleep without a preceeding wake"
next
end
cal.event {
dtstart last_wake.date_time
dtend event.date_time
description event.line
summary "Laptop at #{event.location}"
}
last_wake = nil
}
File.open(options[:out], 'w') {|f|
f.write cal.to_ical
}