calendar-assistant 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +152 -67
- data/Rakefile +13 -3
- data/bin/calendar-assistant +3 -1
- data/lib/calendar_assistant.rb +0 -1
- data/lib/calendar_assistant/calendar_assistant.rb +16 -14
- data/lib/calendar_assistant/cli.rb +9 -233
- data/lib/calendar_assistant/cli/authorizer.rb +88 -0
- data/lib/calendar_assistant/cli/commands.rb +284 -0
- data/lib/calendar_assistant/cli/config.rb +51 -0
- data/lib/calendar_assistant/cli/event_presenter.rb +71 -0
- data/lib/calendar_assistant/cli/event_set_presenter.rb +69 -0
- data/lib/calendar_assistant/cli/helpers.rb +54 -0
- data/lib/calendar_assistant/cli/linter_event_presenter.rb +56 -0
- data/lib/calendar_assistant/cli/linter_event_set_presenter.rb +23 -0
- data/lib/calendar_assistant/cli/printer.rb +90 -0
- data/lib/calendar_assistant/config.rb +21 -45
- data/lib/calendar_assistant/event.rb +16 -12
- data/lib/calendar_assistant/event_repository.rb +18 -9
- data/lib/calendar_assistant/event_repository_factory.rb +2 -2
- data/lib/calendar_assistant/version.rb +1 -1
- metadata +78 -38
- data/lib/calendar_assistant/authorizer.rb +0 -86
- data/lib/calendar_assistant/cli_helpers.rb +0 -228
@@ -1,228 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
class CalendarAssistant
|
3
|
-
module CLIHelpers
|
4
|
-
class ChronicParseException < CalendarAssistant::BaseException ; end
|
5
|
-
|
6
|
-
def self.parse_datespec userspec
|
7
|
-
start_userspec, end_userspec = userspec.split(/ ?\.\.\.? ?/)
|
8
|
-
|
9
|
-
if end_userspec.nil?
|
10
|
-
time = Chronic.parse(userspec) || raise(ChronicParseException, "could not parse '#{userspec}'")
|
11
|
-
return time.beginning_of_day..time.end_of_day
|
12
|
-
end
|
13
|
-
|
14
|
-
start_time = Chronic.parse(start_userspec) || raise(ChronicParseException, "could not parse '#{start_userspec}'")
|
15
|
-
end_time = Chronic.parse(end_userspec) || raise(ChronicParseException, "could not parse '#{end_userspec}'")
|
16
|
-
|
17
|
-
if start_time.to_date == end_time.to_date
|
18
|
-
start_time..end_time
|
19
|
-
else
|
20
|
-
start_time.beginning_of_day..end_time.end_of_day
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.now
|
25
|
-
CalendarAssistant::Event.new(
|
26
|
-
Google::Apis::CalendarV3::Event.new(start: Google::Apis::CalendarV3::EventDateTime.new(date_time: Time.now),
|
27
|
-
end: Google::Apis::CalendarV3::EventDateTime.new(date_time: Time.now),
|
28
|
-
summary: Rainbow(" now ").inverse.faint)
|
29
|
-
)
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.find_av_uri ca, timespec
|
33
|
-
time = Chronic.parse timespec
|
34
|
-
range = time..(time+5.minutes)
|
35
|
-
event_set = ca.find_events range
|
36
|
-
|
37
|
-
[CalendarAssistant::Event::Response::ACCEPTED,
|
38
|
-
CalendarAssistant::Event::Response::TENTATIVE,
|
39
|
-
CalendarAssistant::Event::Response::NEEDS_ACTION,
|
40
|
-
].each do |response|
|
41
|
-
event_set.events.reverse.select do |event|
|
42
|
-
event.response_status == response
|
43
|
-
end.each do |event|
|
44
|
-
return [event_set.new(event), event.av_uri] if event.av_uri
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
event_set.new(nil)
|
49
|
-
end
|
50
|
-
|
51
|
-
class Out
|
52
|
-
EMOJI_WARN = "⚠"
|
53
|
-
|
54
|
-
attr_reader :io
|
55
|
-
|
56
|
-
def initialize io=STDOUT
|
57
|
-
@io = io
|
58
|
-
end
|
59
|
-
|
60
|
-
def launch url
|
61
|
-
Launchy.open url
|
62
|
-
end
|
63
|
-
|
64
|
-
def puts *args
|
65
|
-
io.puts(*args)
|
66
|
-
end
|
67
|
-
|
68
|
-
def prompt query, default=nil
|
69
|
-
loop do
|
70
|
-
message = query
|
71
|
-
message += " [#{default}]" if default
|
72
|
-
message += ": "
|
73
|
-
print Rainbow(message).bold
|
74
|
-
answer = STDIN.gets.chomp.strip
|
75
|
-
if answer.empty?
|
76
|
-
return default if default
|
77
|
-
puts Rainbow("Please provide an answer.").red
|
78
|
-
else
|
79
|
-
return answer
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def print_now! ca, event, printed_now
|
85
|
-
return true if printed_now
|
86
|
-
return false if event.start_date != Date.today
|
87
|
-
|
88
|
-
if event.start_time > Time.now
|
89
|
-
puts event_description(CLIHelpers.now)
|
90
|
-
return true
|
91
|
-
end
|
92
|
-
|
93
|
-
false
|
94
|
-
end
|
95
|
-
|
96
|
-
def print_events ca, event_set, omit_title: false
|
97
|
-
unless omit_title
|
98
|
-
er = event_set.event_repository
|
99
|
-
puts Rainbow("#{er.calendar.id} (all times in #{er.calendar.time_zone})\n").italic
|
100
|
-
end
|
101
|
-
|
102
|
-
if event_set.is_a?(EventSet::Hash)
|
103
|
-
event_set.events.each do |key, value|
|
104
|
-
puts Rainbow(key.to_s.capitalize + ":").bold.italic
|
105
|
-
print_events ca, event_set.new(value), omit_title: true
|
106
|
-
end
|
107
|
-
return
|
108
|
-
end
|
109
|
-
|
110
|
-
events = Array(event_set.events)
|
111
|
-
if events.empty?
|
112
|
-
puts "No events in this time range."
|
113
|
-
return
|
114
|
-
end
|
115
|
-
|
116
|
-
display_events = events.select do |event|
|
117
|
-
! ca.config.setting(CalendarAssistant::Config::Keys::Options::COMMITMENTS) || event.commitment?
|
118
|
-
end
|
119
|
-
|
120
|
-
printed_now = false
|
121
|
-
display_events.each do |event|
|
122
|
-
printed_now = print_now! ca, event, printed_now
|
123
|
-
puts event_description(event)
|
124
|
-
pp event if ca.config.debug?
|
125
|
-
end
|
126
|
-
|
127
|
-
puts
|
128
|
-
end
|
129
|
-
|
130
|
-
def print_available_blocks ca, event_set, omit_title: false
|
131
|
-
ers = ca.config.attendees.map { |calendar_id| ca.event_repository calendar_id }
|
132
|
-
time_zones = ers.map { |er| er.calendar.time_zone }.uniq
|
133
|
-
|
134
|
-
unless omit_title
|
135
|
-
puts Rainbow(ers.map { |er| er.calendar.id }.join(", ")).italic
|
136
|
-
puts Rainbow(sprintf("- looking for blocks at least %s long",
|
137
|
-
ChronicDuration.output(
|
138
|
-
ChronicDuration.parse(
|
139
|
-
ca.config.setting(Config::Keys::Settings::MEETING_LENGTH))))).italic
|
140
|
-
time_zones.each do |time_zone|
|
141
|
-
puts Rainbow(sprintf("- between %s and %s in %s",
|
142
|
-
ca.config.setting(Config::Keys::Settings::START_OF_DAY),
|
143
|
-
ca.config.setting(Config::Keys::Settings::END_OF_DAY),
|
144
|
-
time_zone,
|
145
|
-
)).italic
|
146
|
-
end
|
147
|
-
puts
|
148
|
-
end
|
149
|
-
|
150
|
-
if event_set.is_a?(EventSet::Hash)
|
151
|
-
event_set.events.each do |key, value|
|
152
|
-
puts(sprintf(Rainbow("Availability on %s:\n").bold,
|
153
|
-
key.strftime("%A, %B %-d")))
|
154
|
-
print_available_blocks ca, event_set.new(value), omit_title: true
|
155
|
-
puts
|
156
|
-
end
|
157
|
-
return
|
158
|
-
end
|
159
|
-
|
160
|
-
events = Array(event_set.events)
|
161
|
-
if events.empty?
|
162
|
-
puts " (No available blocks in this time range.)"
|
163
|
-
return
|
164
|
-
end
|
165
|
-
|
166
|
-
events.each do |event|
|
167
|
-
line = []
|
168
|
-
time_zones.each do |time_zone|
|
169
|
-
line << sprintf("%s - %s",
|
170
|
-
event.start_time.in_time_zone(time_zone).strftime("%l:%M%P"),
|
171
|
-
event.end_time.in_time_zone(time_zone).strftime("%l:%M%P %Z"))
|
172
|
-
end
|
173
|
-
line.uniq!
|
174
|
-
puts " • " + line.join(" / ") + Rainbow(" (" + event.duration + ")").italic
|
175
|
-
pp event if ca.config.debug?
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
def event_description event
|
180
|
-
s = sprintf("%-25.25s", event_date_description(event))
|
181
|
-
|
182
|
-
date_ansi_codes = []
|
183
|
-
date_ansi_codes << :bright if event.current?
|
184
|
-
date_ansi_codes << :faint if event.past?
|
185
|
-
s = date_ansi_codes.inject(Rainbow(s)) { |text, ansi| text.send ansi }
|
186
|
-
|
187
|
-
s += Rainbow(sprintf(" | %s", event.view_summary)).bold
|
188
|
-
|
189
|
-
attributes = []
|
190
|
-
unless event.private?
|
191
|
-
attributes << "recurring" if event.recurring?
|
192
|
-
attributes << "not-busy" unless event.busy?
|
193
|
-
attributes << "self" if event.self? && !event.private?
|
194
|
-
attributes << "1:1" if event.one_on_one?
|
195
|
-
attributes << "awaiting" if event.awaiting?
|
196
|
-
attributes << "tentative" if event.tentative?
|
197
|
-
attributes << Rainbow(sprintf(" %s abandoned %s ", EMOJI_WARN, EMOJI_WARN)).red.bold.inverse if event.abandoned?
|
198
|
-
end
|
199
|
-
|
200
|
-
attributes << event.visibility if event.explicitly_visible?
|
201
|
-
|
202
|
-
s += Rainbow(sprintf(" (%s)", attributes.to_a.sort.join(", "))).italic unless attributes.empty?
|
203
|
-
|
204
|
-
s = Rainbow(Rainbow.uncolor(s)).faint.strike if event.declined?
|
205
|
-
|
206
|
-
s
|
207
|
-
end
|
208
|
-
|
209
|
-
def event_date_description event
|
210
|
-
if event.all_day?
|
211
|
-
start_date = event.start_date
|
212
|
-
end_date = event.end_date
|
213
|
-
if (end_date - start_date) <= 1
|
214
|
-
event.start.to_s
|
215
|
-
else
|
216
|
-
sprintf("%s - %s", start_date, end_date - 1.day)
|
217
|
-
end
|
218
|
-
else
|
219
|
-
if event.start_date == event.end_date
|
220
|
-
sprintf("%s - %s", event.start.date_time.strftime("%Y-%m-%d %H:%M"), event.end.date_time.strftime("%H:%M"))
|
221
|
-
else
|
222
|
-
sprintf("%s - %s", event.start.date_time.strftime("%Y-%m-%d %H:%M"), event.end.date_time.strftime("%Y-%m-%d %H:%M"))
|
223
|
-
end
|
224
|
-
end
|
225
|
-
end
|
226
|
-
end
|
227
|
-
end
|
228
|
-
end
|