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,233 +1,9 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
option CalendarAssistant::Config::Keys::Options::LOCAL_STORE,
|
12
|
-
type: :string,
|
13
|
-
banner: "FILENAME",
|
14
|
-
desc: "Load events from a local file instead of Google Calendar"
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.has_attendees
|
18
|
-
option CalendarAssistant::Config::Keys::Options::ATTENDEES,
|
19
|
-
type: :string,
|
20
|
-
banner: "ATTENDEE1[,ATTENDEE2[,...]]",
|
21
|
-
desc: "[default 'me'] people (email IDs) to whom this command will be applied",
|
22
|
-
aliases: ["-a"]
|
23
|
-
end
|
24
|
-
|
25
|
-
default_config = CalendarAssistant::Config.new options: options # used in option descriptions
|
26
|
-
|
27
|
-
class_option :help,
|
28
|
-
type: :boolean,
|
29
|
-
aliases: ["-h", "-?"]
|
30
|
-
class_option CalendarAssistant::Config::Keys::Options::DEBUG,
|
31
|
-
type: :boolean,
|
32
|
-
desc: "how dare you suggest there are bugs"
|
33
|
-
|
34
|
-
|
35
|
-
desc "version",
|
36
|
-
"Display the version of calendar-assistant"
|
37
|
-
def version
|
38
|
-
return if handle_help_args
|
39
|
-
out.puts CalendarAssistant::VERSION
|
40
|
-
end
|
41
|
-
|
42
|
-
|
43
|
-
desc "config",
|
44
|
-
"Dump your configuration parameters (merge of defaults and overrides from #{CalendarAssistant::Config::CONFIG_FILE_PATH})"
|
45
|
-
def config
|
46
|
-
return if handle_help_args
|
47
|
-
settings = CalendarAssistant::Config.new.settings
|
48
|
-
out.puts TOML::Generator.new({CalendarAssistant::Config::Keys::SETTINGS => settings}).body
|
49
|
-
end
|
50
|
-
|
51
|
-
|
52
|
-
desc "setup",
|
53
|
-
"Link your local calendar-assistant installation to a Google API Client"
|
54
|
-
long_desc <<~EOD
|
55
|
-
This command will walk you through setting up a Google Cloud
|
56
|
-
Project, enabling the Google Calendar API, and saving the
|
57
|
-
credentials necessary to access the API on behalf of users.
|
58
|
-
|
59
|
-
If you already have downloaded client credentials, you don't
|
60
|
-
need to run this command. Instead, rename the downloaded JSON
|
61
|
-
file to `#{CalendarAssistant::Authorizer::CREDENTIALS_PATH}`
|
62
|
-
EOD
|
63
|
-
def setup
|
64
|
-
# TODO ugh see #34 for advice on how to clean this up
|
65
|
-
return if handle_help_args
|
66
|
-
if File.exist? CalendarAssistant::Authorizer::CREDENTIALS_PATH
|
67
|
-
out.puts sprintf("Credentials already exist in %s",
|
68
|
-
CalendarAssistant::Authorizer::CREDENTIALS_PATH)
|
69
|
-
return
|
70
|
-
end
|
71
|
-
|
72
|
-
out.launch "https://developers.google.com/calendar/quickstart/ruby"
|
73
|
-
sleep 1
|
74
|
-
out.puts <<~EOT
|
75
|
-
Please click on "ENABLE THE GOOGLE CALENDAR API" and either create a new project or select an existing project.
|
76
|
-
|
77
|
-
(If you create a new project, name it something like "yourname-calendar-assistant" so you remember why it exists.)
|
78
|
-
|
79
|
-
Then click "DOWNLOAD CLIENT CONFIGURATION" to download the credentials to local disk.
|
80
|
-
|
81
|
-
Finally, paste the contents of the downloaded file here (it should be a complete JSON object):
|
82
|
-
EOT
|
83
|
-
|
84
|
-
json = out.prompt "Paste JSON here"
|
85
|
-
File.open(CalendarAssistant::Authorizer::CREDENTIALS_PATH, "w") do |f|
|
86
|
-
f.write json
|
87
|
-
end
|
88
|
-
FileUtils.chmod 0600, CalendarAssistant::Authorizer::CREDENTIALS_PATH
|
89
|
-
|
90
|
-
out.puts "\nOK! Your next step is to run `calendar-assistant authorize`."
|
91
|
-
end
|
92
|
-
|
93
|
-
|
94
|
-
desc "authorize PROFILE_NAME",
|
95
|
-
"create (or validate) a profile named NAME with calendar access"
|
96
|
-
long_desc <<~EOD
|
97
|
-
Create and authorize a named profile (e.g., "work", "home",
|
98
|
-
"flastname@company.tld") to access your calendar.
|
99
|
-
|
100
|
-
When setting up a profile, you'll be asked to visit a URL to
|
101
|
-
authenticate, grant authorization, and generate and persist an
|
102
|
-
access token.
|
103
|
-
|
104
|
-
In order for this to work, you'll need to have set up your API client
|
105
|
-
credentials. Run `calendar-assistant help setup` for instructions.
|
106
|
-
EOD
|
107
|
-
def authorize profile_name=nil
|
108
|
-
return if handle_help_args
|
109
|
-
return help! if profile_name.nil?
|
110
|
-
|
111
|
-
CalendarAssistant.authorize profile_name
|
112
|
-
puts "\nYou're authorized!\n\n"
|
113
|
-
end
|
114
|
-
|
115
|
-
|
116
|
-
desc "show [DATE | DATERANGE | TIMERANGE]",
|
117
|
-
"Show your events for a date or range of dates (default 'today')"
|
118
|
-
option CalendarAssistant::Config::Keys::Options::COMMITMENTS,
|
119
|
-
type: :boolean,
|
120
|
-
desc: "only show events that you've accepted with another person",
|
121
|
-
aliases: ["-c"]
|
122
|
-
will_create_a_service
|
123
|
-
has_attendees
|
124
|
-
def show datespec="today"
|
125
|
-
return if handle_help_args
|
126
|
-
config = CalendarAssistant::Config.new(options: options)
|
127
|
-
ca = CalendarAssistant.new config
|
128
|
-
ca.in_env do
|
129
|
-
event_set = ca.find_events CLIHelpers.parse_datespec(datespec)
|
130
|
-
out.print_events ca, event_set
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
|
135
|
-
desc "join [TIME]",
|
136
|
-
"Open the URL for a video call attached to your meeting at time TIME (default 'now')"
|
137
|
-
option CalendarAssistant::Config::Keys::Options::JOIN,
|
138
|
-
type: :boolean, default: true,
|
139
|
-
desc: "launch a browser to join the video call URL"
|
140
|
-
will_create_a_service
|
141
|
-
def join timespec="now"
|
142
|
-
return if handle_help_args
|
143
|
-
ca = CalendarAssistant.new CalendarAssistant::Config.new(options: options)
|
144
|
-
ca.in_env do
|
145
|
-
event_set, url = CLIHelpers.find_av_uri ca, timespec
|
146
|
-
if ! event_set.empty?
|
147
|
-
out.print_events ca, event_set
|
148
|
-
out.puts url
|
149
|
-
out.launch url if options[CalendarAssistant::Config::Keys::Options::JOIN]
|
150
|
-
else
|
151
|
-
out.puts "Could not find a meeting '#{timespec}' with a video call to join."
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
|
157
|
-
desc "location [DATE | DATERANGE]",
|
158
|
-
"Show your location for a date or range of dates (default 'today')"
|
159
|
-
will_create_a_service
|
160
|
-
def location datespec="today"
|
161
|
-
return if handle_help_args
|
162
|
-
ca = CalendarAssistant.new CalendarAssistant::Config.new(options: options)
|
163
|
-
ca.in_env do
|
164
|
-
event_set = ca.find_location_events CLIHelpers.parse_datespec(datespec)
|
165
|
-
out.print_events ca, event_set
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
|
170
|
-
desc "location-set LOCATION [DATE | DATERANGE]",
|
171
|
-
"Set your location to LOCATION for a date or range of dates (default 'today')"
|
172
|
-
will_create_a_service
|
173
|
-
def location_set location=nil, datespec="today"
|
174
|
-
return if handle_help_args
|
175
|
-
return help! if location.nil?
|
176
|
-
|
177
|
-
ca = CalendarAssistant.new CalendarAssistant::Config.new(options: options)
|
178
|
-
ca.in_env do
|
179
|
-
event_set = ca.create_location_event CLIHelpers.parse_datespec(datespec), location
|
180
|
-
out.print_events ca, event_set
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
|
185
|
-
desc "availability [DATE | DATERANGE | TIMERANGE]",
|
186
|
-
"Show your availability for a date or range of dates (default 'today')"
|
187
|
-
option CalendarAssistant::Config::Keys::Settings::MEETING_LENGTH,
|
188
|
-
type: :string,
|
189
|
-
banner: "LENGTH",
|
190
|
-
desc: sprintf("[default %s] find chunks of available time at least as long as LENGTH (which is a ChronicDuration string like '30m' or '2h')",
|
191
|
-
default_config.setting(CalendarAssistant::Config::Keys::Settings::MEETING_LENGTH)),
|
192
|
-
aliases: ["-l"]
|
193
|
-
option CalendarAssistant::Config::Keys::Settings::START_OF_DAY,
|
194
|
-
type: :string,
|
195
|
-
banner: "TIME",
|
196
|
-
desc: sprintf("[default %s] find chunks of available time after TIME (which is a BusinessTime string like '9am' or '14:30')",
|
197
|
-
default_config.setting(CalendarAssistant::Config::Keys::Settings::START_OF_DAY)),
|
198
|
-
aliases: ["-s"]
|
199
|
-
option CalendarAssistant::Config::Keys::Settings::END_OF_DAY,
|
200
|
-
type: :string,
|
201
|
-
banner: "TIME",
|
202
|
-
desc: sprintf("[default %s] find chunks of available time before TIME (which is a BusinessTime string like '9am' or '14:30')",
|
203
|
-
default_config.setting(CalendarAssistant::Config::Keys::Settings::END_OF_DAY)),
|
204
|
-
aliases: ["-e"]
|
205
|
-
has_attendees
|
206
|
-
will_create_a_service
|
207
|
-
def availability datespec="today"
|
208
|
-
return if handle_help_args
|
209
|
-
ca = CalendarAssistant.new CalendarAssistant::Config.new(options: options)
|
210
|
-
ca.in_env do
|
211
|
-
event_set = ca.availability CLIHelpers.parse_datespec(datespec)
|
212
|
-
out.print_available_blocks ca, event_set
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
private
|
217
|
-
|
218
|
-
def out
|
219
|
-
@out ||= CLIHelpers::Out.new
|
220
|
-
end
|
221
|
-
|
222
|
-
def help!
|
223
|
-
help(current_command_chain.first)
|
224
|
-
end
|
225
|
-
|
226
|
-
def handle_help_args
|
227
|
-
if options[:help]
|
228
|
-
help!
|
229
|
-
return true
|
230
|
-
end
|
231
|
-
end
|
232
|
-
end
|
233
|
-
end
|
1
|
+
require_relative 'cli/config'
|
2
|
+
require_relative 'cli/helpers'
|
3
|
+
require_relative 'cli/printer'
|
4
|
+
require_relative 'cli/event_presenter'
|
5
|
+
require_relative 'cli/event_set_presenter'
|
6
|
+
require_relative 'cli/linter_event_presenter'
|
7
|
+
require_relative 'cli/linter_event_set_presenter'
|
8
|
+
require_relative 'cli/authorizer'
|
9
|
+
require_relative 'cli/commands'
|
@@ -0,0 +1,88 @@
|
|
1
|
+
#
|
2
|
+
# code in this file is inspired by
|
3
|
+
#
|
4
|
+
# https://github.com/gsuitedevs/ruby-samples/blob/master/calendar/quickstart/quickstart.rb
|
5
|
+
#
|
6
|
+
# Copyright 2018 Google LLC
|
7
|
+
#
|
8
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
9
|
+
# you may not use this file except in compliance with the License.
|
10
|
+
# You may obtain a copy of the License at
|
11
|
+
#
|
12
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
13
|
+
#
|
14
|
+
# Unless required by applicable law or agreed to in writing, software
|
15
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
16
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
17
|
+
# See the License for the specific language governing permissions and
|
18
|
+
# limitations under the License.
|
19
|
+
|
20
|
+
class CalendarAssistant
|
21
|
+
module CLI
|
22
|
+
class Authorizer
|
23
|
+
class NoCredentials < CalendarAssistant::BaseException ; end
|
24
|
+
class UnauthorizedError < CalendarAssistant::BaseException ; end
|
25
|
+
|
26
|
+
OOB_URI = 'urn:ietf:wg:oauth:2.0:oob'.freeze
|
27
|
+
APPLICATION_NAME = "Flavorjones Calendar Assistant".freeze
|
28
|
+
CREDENTIALS_PATH = File.join (ENV['CA_HOME'] || ENV["HOME"]), ".calendar-assistant.client"
|
29
|
+
SCOPE = Google::Apis::CalendarV3::AUTH_CALENDAR
|
30
|
+
|
31
|
+
attr_reader :profile_name, :config_token_store
|
32
|
+
|
33
|
+
def initialize profile_name, config_token_store
|
34
|
+
@profile_name = profile_name
|
35
|
+
@config_token_store = config_token_store
|
36
|
+
end
|
37
|
+
|
38
|
+
def authorize
|
39
|
+
credentials || prompt_user_for_authorization
|
40
|
+
end
|
41
|
+
|
42
|
+
def service
|
43
|
+
if credentials.nil?
|
44
|
+
raise UnauthorizedError, "Not authorized. Please run `calendar-assistant authorize #{profile_name}`"
|
45
|
+
end
|
46
|
+
|
47
|
+
Google::Apis::CalendarV3::CalendarService.new.tap do |service|
|
48
|
+
service.client_options.application_name = APPLICATION_NAME
|
49
|
+
service.authorization = credentials
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def credentials
|
56
|
+
@credentials ||= authorizer.get_credentials profile_name
|
57
|
+
end
|
58
|
+
|
59
|
+
def prompt_user_for_authorization
|
60
|
+
url = authorizer.get_authorization_url(base_url: OOB_URI)
|
61
|
+
|
62
|
+
puts Rainbow("Please open this URL in your browser:").bold
|
63
|
+
puts
|
64
|
+
puts " " + url
|
65
|
+
puts
|
66
|
+
|
67
|
+
puts Rainbow("Then authorize '#{APPLICATION_NAME}' to manage your calendar and copy/paste the resulting code here:").bold
|
68
|
+
puts
|
69
|
+
print "> "
|
70
|
+
code = STDIN.gets
|
71
|
+
|
72
|
+
authorizer.get_and_store_credentials_from_code(user_id: profile_name, code: code, base_url: OOB_URI)
|
73
|
+
end
|
74
|
+
|
75
|
+
def authorizer
|
76
|
+
@authorizer ||= begin
|
77
|
+
if ! File.exists?(CREDENTIALS_PATH)
|
78
|
+
raise NoCredentials, "No credentials found. Please run `calendar-assistant help setup` for instructions"
|
79
|
+
end
|
80
|
+
|
81
|
+
FileUtils.chmod 0600, CREDENTIALS_PATH
|
82
|
+
client_id = Google::Auth::ClientId.from_file(CREDENTIALS_PATH)
|
83
|
+
Google::Auth::UserAuthorizer.new(client_id, SCOPE, config_token_store)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,284 @@
|
|
1
|
+
require "calendar_assistant/cli/helpers"
|
2
|
+
|
3
|
+
class CalendarAssistant
|
4
|
+
module CLI
|
5
|
+
class Commands < Thor
|
6
|
+
def self.will_create_a_service
|
7
|
+
option CalendarAssistant::Config::Keys::Settings::PROFILE,
|
8
|
+
type: :string,
|
9
|
+
desc: "the profile you'd like to use (if different from default)",
|
10
|
+
aliases: ["-p"]
|
11
|
+
|
12
|
+
option CalendarAssistant::Config::Keys::Options::LOCAL_STORE,
|
13
|
+
type: :string,
|
14
|
+
banner: "FILENAME",
|
15
|
+
desc: "Load events from a local file instead of Google Calendar"
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.has_attendees
|
19
|
+
option CalendarAssistant::Config::Keys::Options::ATTENDEES,
|
20
|
+
type: :string,
|
21
|
+
banner: "ATTENDEE1[,ATTENDEE2[,...]]",
|
22
|
+
desc: "[default 'me'] people (email IDs) to whom this command will be applied",
|
23
|
+
aliases: ["-a"]
|
24
|
+
end
|
25
|
+
|
26
|
+
default_config = CalendarAssistant::CLI::Config.new options: options # used in option descriptions
|
27
|
+
|
28
|
+
class_option :help,
|
29
|
+
type: :boolean,
|
30
|
+
aliases: ["-h", "-?"]
|
31
|
+
class_option CalendarAssistant::Config::Keys::Options::DEBUG,
|
32
|
+
type: :boolean,
|
33
|
+
desc: "how dare you suggest there are bugs"
|
34
|
+
|
35
|
+
class_option CalendarAssistant::Config::Keys::Options::FORMATTING,
|
36
|
+
type: :boolean,
|
37
|
+
desc: "Enable Text Formatting",
|
38
|
+
default: CalendarAssistant::Config::DEFAULT_SETTINGS[CalendarAssistant::Config::Keys::Options::FORMATTING]
|
39
|
+
|
40
|
+
desc "version",
|
41
|
+
"Display the version of calendar-assistant"
|
42
|
+
|
43
|
+
def version
|
44
|
+
return if handle_help_args
|
45
|
+
out.puts CalendarAssistant::VERSION
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
desc "config",
|
50
|
+
"Dump your configuration parameters (merge of defaults and overrides from #{CalendarAssistant::CLI::Config::CONFIG_FILE_PATH})"
|
51
|
+
|
52
|
+
def config
|
53
|
+
return if handle_help_args
|
54
|
+
settings = CalendarAssistant::CLI::Config.new.settings
|
55
|
+
out.puts TOML::Generator.new({CalendarAssistant::Config::Keys::SETTINGS => settings}).body
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
desc "setup",
|
60
|
+
"Link your local calendar-assistant installation to a Google API Client"
|
61
|
+
long_desc <<~EOD
|
62
|
+
This command will walk you through setting up a Google Cloud
|
63
|
+
Project, enabling the Google Calendar API, and saving the
|
64
|
+
credentials necessary to access the API on behalf of users.
|
65
|
+
|
66
|
+
If you already have downloaded client credentials, you don't
|
67
|
+
need to run this command. Instead, rename the downloaded JSON
|
68
|
+
file to `#{CalendarAssistant::CLI::Authorizer::CREDENTIALS_PATH}`
|
69
|
+
EOD
|
70
|
+
|
71
|
+
def setup
|
72
|
+
# TODO ugh see #34 for advice on how to clean this up
|
73
|
+
return if handle_help_args
|
74
|
+
if File.exist? CalendarAssistant::CLI::Authorizer::CREDENTIALS_PATH
|
75
|
+
out.puts sprintf("Credentials already exist in %s",
|
76
|
+
CalendarAssistant::CLI::Authorizer::CREDENTIALS_PATH)
|
77
|
+
return
|
78
|
+
end
|
79
|
+
|
80
|
+
out.launch "https://developers.google.com/calendar/quickstart/ruby"
|
81
|
+
sleep 1
|
82
|
+
out.puts <<~EOT
|
83
|
+
Please click on "ENABLE THE GOOGLE CALENDAR API" and either create a new project or select an existing project.
|
84
|
+
|
85
|
+
(If you create a new project, name it something like "yourname-calendar-assistant" so you remember why it exists.)
|
86
|
+
|
87
|
+
Then click "DOWNLOAD CLIENT CONFIGURATION" to download the credentials to local disk.
|
88
|
+
|
89
|
+
Finally, paste the contents of the downloaded file here (it should be a complete JSON object):
|
90
|
+
EOT
|
91
|
+
|
92
|
+
json = out.prompt "Paste JSON here"
|
93
|
+
File.open(CalendarAssistant::CLI::Authorizer::CREDENTIALS_PATH, "w") do |f|
|
94
|
+
f.write json
|
95
|
+
end
|
96
|
+
FileUtils.chmod 0600, CalendarAssistant::CLI::Authorizer::CREDENTIALS_PATH
|
97
|
+
|
98
|
+
out.puts "\nOK! Your next step is to run `calendar-assistant authorize`."
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
desc "authorize PROFILE_NAME",
|
103
|
+
"create (or validate) a profile named NAME with calendar access"
|
104
|
+
long_desc <<~EOD
|
105
|
+
Create and authorize a named profile (e.g., "work", "home",
|
106
|
+
"flastname@company.tld") to access your calendar.
|
107
|
+
|
108
|
+
When setting up a profile, you'll be asked to visit a URL to
|
109
|
+
authenticate, grant authorization, and generate and persist an
|
110
|
+
access token.
|
111
|
+
|
112
|
+
In order for this to work, you'll need to have set up your API client
|
113
|
+
credentials. Run `calendar-assistant help setup` for instructions.
|
114
|
+
EOD
|
115
|
+
|
116
|
+
def authorize profile_name = nil
|
117
|
+
return if handle_help_args
|
118
|
+
return help! if profile_name.nil?
|
119
|
+
|
120
|
+
get_authorizer(profile_name: profile_name).authorize
|
121
|
+
|
122
|
+
puts "\nYou're authorized!\n\n"
|
123
|
+
end
|
124
|
+
|
125
|
+
desc "lint [DATE | DATERANGE | TIMERANGE]",
|
126
|
+
"Lint your events for a date or range of dates (default 'today')"
|
127
|
+
will_create_a_service
|
128
|
+
has_attendees
|
129
|
+
|
130
|
+
def lint datespec = "today"
|
131
|
+
calendar_assistant(datespec) do |ca, date|
|
132
|
+
event_set = ca.lint_events date
|
133
|
+
out.print_events ca, event_set, presenter_class: CalendarAssistant::CLI::LinterEventSetPresenter
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
desc "show [DATE | DATERANGE | TIMERANGE]",
|
138
|
+
"Show your events for a date or range of dates (default 'today')"
|
139
|
+
option CalendarAssistant::Config::Keys::Options::COMMITMENTS,
|
140
|
+
type: :boolean,
|
141
|
+
desc: "only show events that you've accepted with another person",
|
142
|
+
aliases: ["-c"]
|
143
|
+
will_create_a_service
|
144
|
+
has_attendees
|
145
|
+
|
146
|
+
def show datespec = "today"
|
147
|
+
calendar_assistant(datespec) do |ca, date|
|
148
|
+
event_set = ca.find_events date
|
149
|
+
out.print_events ca, event_set
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
desc "join [TIME]",
|
155
|
+
"Open the URL for a video call attached to your meeting at time TIME (default 'now')"
|
156
|
+
option CalendarAssistant::Config::Keys::Options::JOIN,
|
157
|
+
type: :boolean, default: true,
|
158
|
+
desc: "launch a browser to join the video call URL"
|
159
|
+
will_create_a_service
|
160
|
+
|
161
|
+
def join timespec = "now"
|
162
|
+
return if handle_help_args
|
163
|
+
set_formatting
|
164
|
+
ca = CalendarAssistant.new get_config, service: service
|
165
|
+
ca.in_env do
|
166
|
+
event_set, url = CalendarAssistant::CLI::Helpers.find_av_uri ca, timespec
|
167
|
+
if !event_set.empty?
|
168
|
+
out.print_events ca, event_set
|
169
|
+
out.puts url
|
170
|
+
out.launch url if options[CalendarAssistant::Config::Keys::Options::JOIN]
|
171
|
+
else
|
172
|
+
out.puts "Could not find a meeting '#{timespec}' with a video call to join."
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
|
178
|
+
desc "location [DATE | DATERANGE]",
|
179
|
+
"Show your location for a date or range of dates (default 'today')"
|
180
|
+
will_create_a_service
|
181
|
+
|
182
|
+
def location datespec = "today"
|
183
|
+
calendar_assistant(datespec) do |ca, date|
|
184
|
+
event_set = ca.find_location_events date
|
185
|
+
out.print_events ca, event_set
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
|
190
|
+
desc "location-set LOCATION [DATE | DATERANGE]",
|
191
|
+
"Set your location to LOCATION for a date or range of dates (default 'today')"
|
192
|
+
will_create_a_service
|
193
|
+
|
194
|
+
def location_set location = nil, datespec = "today"
|
195
|
+
return help! if location.nil?
|
196
|
+
|
197
|
+
calendar_assistant(datespec) do |ca, date|
|
198
|
+
event_set = ca.create_location_event date, location
|
199
|
+
out.print_events ca, event_set
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
|
204
|
+
desc "availability [DATE | DATERANGE | TIMERANGE]",
|
205
|
+
"Show your availability for a date or range of dates (default 'today')"
|
206
|
+
option CalendarAssistant::Config::Keys::Settings::MEETING_LENGTH,
|
207
|
+
type: :string,
|
208
|
+
banner: "LENGTH",
|
209
|
+
desc: sprintf("[default %s] find chunks of available time at least as long as LENGTH (which is a ChronicDuration string like '30m' or '2h')",
|
210
|
+
default_config.setting(CalendarAssistant::Config::Keys::Settings::MEETING_LENGTH)),
|
211
|
+
aliases: ["-l"]
|
212
|
+
option CalendarAssistant::Config::Keys::Settings::START_OF_DAY,
|
213
|
+
type: :string,
|
214
|
+
banner: "TIME",
|
215
|
+
desc: sprintf("[default %s] find chunks of available time after TIME (which is a BusinessTime string like '9am' or '14:30')",
|
216
|
+
default_config.setting(CalendarAssistant::Config::Keys::Settings::START_OF_DAY)),
|
217
|
+
aliases: ["-s"]
|
218
|
+
option CalendarAssistant::Config::Keys::Settings::END_OF_DAY,
|
219
|
+
type: :string,
|
220
|
+
banner: "TIME",
|
221
|
+
desc: sprintf("[default %s] find chunks of available time before TIME (which is a BusinessTime string like '9am' or '14:30')",
|
222
|
+
default_config.setting(CalendarAssistant::Config::Keys::Settings::END_OF_DAY)),
|
223
|
+
aliases: ["-e"]
|
224
|
+
has_attendees
|
225
|
+
will_create_a_service
|
226
|
+
|
227
|
+
def availability datespec = "today"
|
228
|
+
calendar_assistant(datespec) do |ca, date|
|
229
|
+
event_set = ca.availability date
|
230
|
+
out.print_available_blocks ca, event_set
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
private
|
235
|
+
|
236
|
+
def set_formatting
|
237
|
+
Rainbow.enabled = !!options[:formatting]
|
238
|
+
end
|
239
|
+
|
240
|
+
def service
|
241
|
+
@service ||= begin
|
242
|
+
if filename = get_config.setting(Config::Keys::Options::LOCAL_STORE)
|
243
|
+
CalendarAssistant::LocalService.new(file: filename)
|
244
|
+
else
|
245
|
+
get_authorizer.service
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
def get_authorizer(profile_name: get_config.profile_name, token_store: get_config.token_store)
|
251
|
+
@authorizer ||= {}
|
252
|
+
@authorizer[profile_name] ||= Authorizer.new(profile_name, token_store)
|
253
|
+
end
|
254
|
+
|
255
|
+
def calendar_assistant datespec = "today"
|
256
|
+
return if handle_help_args
|
257
|
+
set_formatting
|
258
|
+
ca = CalendarAssistant.new(get_config, service: service)
|
259
|
+
ca.in_env do
|
260
|
+
yield(ca, CalendarAssistant::CLI::Helpers.parse_datespec(datespec))
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
def get_config
|
265
|
+
@config ||= CalendarAssistant::CLI::Config.new(options: options)
|
266
|
+
end
|
267
|
+
|
268
|
+
def out
|
269
|
+
@out ||= CalendarAssistant::CLI::Printer.new
|
270
|
+
end
|
271
|
+
|
272
|
+
def help!
|
273
|
+
help(current_command_chain.first)
|
274
|
+
end
|
275
|
+
|
276
|
+
def handle_help_args
|
277
|
+
if options[:help]
|
278
|
+
help!
|
279
|
+
return true
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|