calendar-assistant 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|