flycal-cli 0.7.4 → 1.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 +6 -174
- data/bin/flycal +2 -2
- data/lib/flycal/cache_annotator.rb +83 -0
- data/lib/flycal/cache_key.rb +82 -0
- data/lib/flycal/calendar_query.rb +60 -0
- data/lib/flycal/calendar_service.rb +115 -0
- data/lib/{flycal_cli/cli.rb → flycal/cli/app.rb} +320 -250
- data/lib/{flycal_cli → flycal/cli}/auth.rb +5 -3
- data/lib/{flycal_cli → flycal/cli}/clipboard.rb +3 -1
- data/lib/{flycal_cli → flycal/cli}/config.rb +4 -2
- data/lib/flycal/cli/file_cache.rb +44 -0
- data/lib/flycal/cli/locale.rb +58 -0
- data/lib/flycal/cli.rb +14 -0
- data/lib/flycal/client.rb +186 -0
- data/lib/flycal/credentials.rb +34 -0
- data/lib/{flycal_cli → flycal}/date_time_parser.rb +4 -4
- data/lib/flycal/description_query.rb +32 -0
- data/lib/{flycal_cli → flycal}/duration_parser.rb +3 -3
- data/lib/flycal/error.rb +5 -0
- data/lib/flycal/event_mapper.rb +58 -0
- data/lib/{flycal_cli → flycal}/locale.rb +35 -3
- data/lib/flycal/mock/calendar_service.rb +43 -0
- data/lib/flycal/mock/config.rb +171 -0
- data/lib/flycal/mock/event_generator.rb +71 -0
- data/lib/flycal/mock.rb +6 -0
- data/lib/flycal/pipeline/aggregator.rb +226 -0
- data/lib/flycal/pipeline/json_renderer.rb +145 -0
- data/lib/flycal/pipeline/params.rb +46 -0
- data/lib/flycal/pipeline/renderer.rb +27 -0
- data/lib/flycal/pipeline/retriever.rb +72 -0
- data/lib/flycal/pipeline/search_pipeline.rb +18 -0
- data/lib/flycal/pipeline/text_renderer.rb +134 -0
- data/lib/flycal/pipeline.rb +6 -0
- data/lib/{flycal_cli → flycal}/slot_finder.rb +1 -1
- data/lib/flycal/slot_formatter.rb +195 -0
- data/lib/flycal/version.rb +11 -0
- data/lib/flycal.rb +12 -0
- data/lib/flycal_cli.rb +37 -14
- data/mcp/tools.json +36 -9
- data/mockTemplates/mock1.json +11 -0
- data/mocks/mock1.json +11 -0
- metadata +38 -12
- data/lib/flycal_cli/calendar_service.rb +0 -74
- data/lib/flycal_cli/slot_formatter.rb +0 -68
- data/lib/flycal_cli/version.rb +0 -5
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: flycal-cli
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0
|
|
4
|
+
version: '1.0'
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- flycal-cli
|
|
@@ -134,22 +134,48 @@ files:
|
|
|
134
134
|
- README.md
|
|
135
135
|
- bin/flycal
|
|
136
136
|
- config/defaults.yml
|
|
137
|
+
- lib/flycal.rb
|
|
138
|
+
- lib/flycal/cache_annotator.rb
|
|
139
|
+
- lib/flycal/cache_key.rb
|
|
140
|
+
- lib/flycal/calendar_query.rb
|
|
141
|
+
- lib/flycal/calendar_service.rb
|
|
142
|
+
- lib/flycal/cli.rb
|
|
143
|
+
- lib/flycal/cli/app.rb
|
|
144
|
+
- lib/flycal/cli/auth.rb
|
|
145
|
+
- lib/flycal/cli/clipboard.rb
|
|
146
|
+
- lib/flycal/cli/config.rb
|
|
147
|
+
- lib/flycal/cli/file_cache.rb
|
|
148
|
+
- lib/flycal/cli/locale.rb
|
|
149
|
+
- lib/flycal/client.rb
|
|
150
|
+
- lib/flycal/credentials.rb
|
|
151
|
+
- lib/flycal/date_time_parser.rb
|
|
152
|
+
- lib/flycal/description_query.rb
|
|
153
|
+
- lib/flycal/duration_parser.rb
|
|
154
|
+
- lib/flycal/error.rb
|
|
155
|
+
- lib/flycal/event_mapper.rb
|
|
156
|
+
- lib/flycal/locale.rb
|
|
157
|
+
- lib/flycal/mock.rb
|
|
158
|
+
- lib/flycal/mock/calendar_service.rb
|
|
159
|
+
- lib/flycal/mock/config.rb
|
|
160
|
+
- lib/flycal/mock/event_generator.rb
|
|
161
|
+
- lib/flycal/pipeline.rb
|
|
162
|
+
- lib/flycal/pipeline/aggregator.rb
|
|
163
|
+
- lib/flycal/pipeline/json_renderer.rb
|
|
164
|
+
- lib/flycal/pipeline/params.rb
|
|
165
|
+
- lib/flycal/pipeline/renderer.rb
|
|
166
|
+
- lib/flycal/pipeline/retriever.rb
|
|
167
|
+
- lib/flycal/pipeline/search_pipeline.rb
|
|
168
|
+
- lib/flycal/pipeline/text_renderer.rb
|
|
169
|
+
- lib/flycal/slot_finder.rb
|
|
170
|
+
- lib/flycal/slot_formatter.rb
|
|
171
|
+
- lib/flycal/version.rb
|
|
137
172
|
- lib/flycal_cli.rb
|
|
138
|
-
- lib/flycal_cli/auth.rb
|
|
139
|
-
- lib/flycal_cli/calendar_service.rb
|
|
140
|
-
- lib/flycal_cli/cli.rb
|
|
141
|
-
- lib/flycal_cli/clipboard.rb
|
|
142
|
-
- lib/flycal_cli/config.rb
|
|
143
|
-
- lib/flycal_cli/date_time_parser.rb
|
|
144
|
-
- lib/flycal_cli/duration_parser.rb
|
|
145
|
-
- lib/flycal_cli/locale.rb
|
|
146
|
-
- lib/flycal_cli/slot_finder.rb
|
|
147
|
-
- lib/flycal_cli/slot_formatter.rb
|
|
148
|
-
- lib/flycal_cli/version.rb
|
|
149
173
|
- locales/en.json
|
|
150
174
|
- locales/it.json
|
|
151
175
|
- mcp/README.md
|
|
152
176
|
- mcp/tools.json
|
|
177
|
+
- mockTemplates/mock1.json
|
|
178
|
+
- mocks/mock1.json
|
|
153
179
|
homepage: https://github.com/magnum/flycal-cli
|
|
154
180
|
licenses:
|
|
155
181
|
- MIT
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "google/apis/calendar_v3"
|
|
4
|
-
|
|
5
|
-
module FlycalCli
|
|
6
|
-
class CalendarService
|
|
7
|
-
def initialize(credentials)
|
|
8
|
-
@service = Google::Apis::CalendarV3::CalendarService.new
|
|
9
|
-
@service.authorization = credentials
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def list_calendars
|
|
13
|
-
result = @service.list_calendar_lists
|
|
14
|
-
result.items || []
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def get_calendar(calendar_id)
|
|
18
|
-
@service.get_calendar(calendar_id)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def list_events(calendar_id, time_min:, time_max:, query: nil)
|
|
22
|
-
events = []
|
|
23
|
-
page_token = nil
|
|
24
|
-
|
|
25
|
-
loop do
|
|
26
|
-
result = @service.list_events(
|
|
27
|
-
calendar_id,
|
|
28
|
-
time_min: time_min.iso8601,
|
|
29
|
-
time_max: time_max.iso8601,
|
|
30
|
-
q: query,
|
|
31
|
-
single_events: true,
|
|
32
|
-
order_by: "startTime",
|
|
33
|
-
page_token: page_token
|
|
34
|
-
)
|
|
35
|
-
|
|
36
|
-
events.concat(result.items || [])
|
|
37
|
-
|
|
38
|
-
page_token = result.next_page_token
|
|
39
|
-
break if page_token.nil? || page_token.empty?
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
events
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def list_all_events(calendar_ids, time_min:, time_max:, query: nil)
|
|
46
|
-
all_events = []
|
|
47
|
-
|
|
48
|
-
# When --description is used: fetch all events and filter client-side to guarantee
|
|
49
|
-
# contains/like behavior. We do not use the API's q param so we can ensure we
|
|
50
|
-
# return all events where the string appears in summary or description (case-insensitive).
|
|
51
|
-
calendar_ids.each do |cal_id|
|
|
52
|
-
begin
|
|
53
|
-
events = list_events(cal_id, time_min: time_min, time_max: time_max, query: nil)
|
|
54
|
-
events.each { |e| all_events << { calendar_id: cal_id, event: e } }
|
|
55
|
-
rescue Google::Apis::Errors::Error => e
|
|
56
|
-
warn "Error in calendar #{cal_id}: #{e.message}"
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
# Filter: only events where summary or description contains the search string (case-insensitive)
|
|
61
|
-
if query && !query.to_s.strip.empty?
|
|
62
|
-
q = query.strip.downcase
|
|
63
|
-
all_events.select! do |item|
|
|
64
|
-
event = item[:event]
|
|
65
|
-
summary = (event.summary || "").downcase
|
|
66
|
-
description = (event.description || "").downcase
|
|
67
|
-
summary.include?(q) || description.include?(q)
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
all_events
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
end
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module FlycalCli
|
|
4
|
-
class SlotFormatter
|
|
5
|
-
class << self
|
|
6
|
-
def format_header(from:, to:, duration:, calendars:, count:, template: nil)
|
|
7
|
-
lines = []
|
|
8
|
-
lines << Locale.t(
|
|
9
|
-
"slots.header",
|
|
10
|
-
count: underline(count),
|
|
11
|
-
from: underline(Locale.format_long_date(from)),
|
|
12
|
-
to: underline(Locale.format_long_date(to)),
|
|
13
|
-
duration: underline(duration),
|
|
14
|
-
template: underline(template.to_s)
|
|
15
|
-
)
|
|
16
|
-
calendars.each do |cal|
|
|
17
|
-
lines << "- #{cal[:name]}"
|
|
18
|
-
end
|
|
19
|
-
lines << "link: #{google_calendar_day_url(from)}"
|
|
20
|
-
lines.join("\n")
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def format_output(slots_by_day)
|
|
24
|
-
lines = []
|
|
25
|
-
|
|
26
|
-
slots_by_day.sort_by(&:first).each do |date, slots|
|
|
27
|
-
lines << "" unless lines.empty?
|
|
28
|
-
lines << underline(day_header(date))
|
|
29
|
-
slots.each do |start_at, end_at|
|
|
30
|
-
lines << slot_range(start_at, end_at)
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
lines.join("\n")
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def strip_ansi(text)
|
|
38
|
-
text.to_s.gsub(/\e\[[0-9;]*m/, "")
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
private
|
|
42
|
-
|
|
43
|
-
def underline(str)
|
|
44
|
-
"\e[4m#{str}\e[0m"
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def google_calendar_day_url(from)
|
|
48
|
-
t = from.respond_to?(:to_time) ? from.to_time : from
|
|
49
|
-
"https://calendar.google.com/calendar/r/day/#{t.year}/#{t.month}/#{t.day}"
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def day_header(date)
|
|
53
|
-
"#{Locale.day_name(date)} #{date.day}/#{date.month}"
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def slot_range(start_at, end_at)
|
|
57
|
-
"#{format_time(start_at)} - #{format_time(end_at)}"
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def format_time(time)
|
|
61
|
-
return time.strftime("%-H") if time.min.zero?
|
|
62
|
-
|
|
63
|
-
minutes = sprintf("%02d", time.min)
|
|
64
|
-
"#{time.hour}.#{minutes}"
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
end
|