Class: Flycal::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/flycal/client.rb

Overview

Entry point for Flycal core. Auth credentials are injected by the caller (FlycalApp / Flycal::Cli), never obtained inside core.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(credentials:) ⇒ Client

Returns a new instance of Client.

Raises:

  • (ArgumentError)


12
13
14
15
16
17
# File 'lib/flycal/client.rb', line 12

def initialize(credentials:)
  raise ArgumentError, "credentials are required" if credentials.nil?

  @credentials = Credentials.wrap(credentials)
  @calendar = CalendarService.new(@credentials)
end

Instance Attribute Details

#calendarObject (readonly)

Returns the value of attribute calendar.



10
11
12
# File 'lib/flycal/client.rb', line 10

def calendar
  @calendar
end

#credentialsObject (readonly)

Returns the value of attribute credentials.



10
11
12
# File 'lib/flycal/client.rb', line 10

def credentials
  @credentials
end

Instance Method Details

#create_event(calendar_id: "primary", summary:, start_time:, end_time:, all_day: false) ⇒ Object



31
32
33
34
35
36
37
38
39
# File 'lib/flycal/client.rb', line 31

def create_event(calendar_id: "primary", summary:, start_time:, end_time:, all_day: false)
  calendar.create_event(
    calendar_id: calendar_id,
    summary: summary,
    start_time: start_time,
    end_time: end_time,
    all_day: all_day
  )
end

#fetch_events(calendar_id:, time_min:, time_max:) ⇒ Object

Returns Rails/web-friendly event hashes (skips cancelled events).



53
54
55
56
57
# File 'lib/flycal/client.rb', line 53

def fetch_events(calendar_id:, time_min:, time_max:)
  list_events(calendar_id, time_min: time_min, time_max: time_max)
    .reject { |event| event.status == "cancelled" }
    .filter_map { |event| EventMapper.to_h(event) }
end

#list_all_events(calendar_ids, time_min:, time_max:, query: nil) ⇒ Object



27
28
29
# File 'lib/flycal/client.rb', line 27

def list_all_events(calendar_ids, time_min:, time_max:, query: nil)
  calendar.list_all_events(calendar_ids, time_min: time_min, time_max: time_max, query: query)
end

#list_calendarsObject



19
20
21
# File 'lib/flycal/client.rb', line 19

def list_calendars
  calendar.list_calendars
end

#list_events(calendar_id, time_min:, time_max:, query: nil) ⇒ Object



23
24
25
# File 'lib/flycal/client.rb', line 23

def list_events(calendar_id, time_min:, time_max:, query: nil)
  calendar.list_events(calendar_id, time_min: time_min, time_max: time_max, query: query)
end

#resolve_slots_query(params = {}) ⇒ Object

Resolved slots inputs (defaults applied) suitable for CacheKey.generate. Does not call Google APIs.



68
69
70
# File 'lib/flycal/client.rb', line 68

def resolve_slots_query(params = {})
  SlotQuery.resolve(params)
end

#search(params = {}) ⇒ Object



59
60
61
62
63
64
# File 'lib/flycal/client.rb', line 59

def search(params = {})
  bag = params.is_a?(Pipeline::Params) ? params : Pipeline::Params.new(params)
  bag[:format] ||= "json"
  bag[:locale] ||= Locale.current_locale
  Pipeline::SearchPipeline.new(calendar).run(bag)
end

#slots(params = {}, events: nil) ⇒ Object

Find free slots. params keys (string/symbol):

calendar_ids (required), duration, from, to, in,
free_before, free_after, hours, days,
template (work|dinner), template_custom ({ days:, hours: } YAML shape),
locale, timezone (IANA, default Europe/Rome or the Google calendar TZ),
calendar (label for meta)

Pass events: to skip Google (tests / mock).



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
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/flycal/client.rb', line 79

def slots(params = {}, events: nil)
  previous_locale = Thread.current[:flycal_locale_override]
  p = params.respond_to?(:with_indifferent_access) ? params.with_indifferent_access : params

  calendar_list = nil
  unless events
    calendar_list = begin
      list_calendars
    rescue StandardError
      nil
    end
  end

  timezone = TimeFormat.resolve(
    explicit: p[:timezone],
    calendars: calendar_list,
    calendar_ids: p[:calendar_ids]
  )

  TimeFormat.with_zone(timezone) do
    q = resolve_slots_query(p.merge(timezone: timezone))
    Locale.override!(q[:locale])

    calendar_meta, loaded_events = load_slot_events(q, events, calendars: calendar_list)
    finder = SlotFinder.new(
      events: loaded_events,
      time_min: q[:time_min],
      time_max: q[:time_max],
      slot_duration_seconds: q[:slot_duration_seconds],
      hours: q[:hours],
      days: q[:days],
      free_before_seconds: q[:free_before_seconds],
      free_after_seconds: q[:free_after_seconds]
    )

    SlotFormatter.payload_hash(
      slots_by_day: finder.slots_by_day,
      time_min: q[:time_min],
      time_max: q[:time_max],
      duration: q[:duration],
      template: q[:template],
      calendars: calendar_meta,
      locale: q[:locale],
      timezone: timezone,
      calendar_option: q[:calendar],
      from_option: p[:from],
      to_option: p[:to],
      in_option: p[:in],
      free_before: q[:free_before],
      free_after: q[:free_after],
      empty_message: Locale.t("slots.no_available")
    )
  end
ensure
  Thread.current[:flycal_locale_override] = previous_locale
end

#update_event(calendar_id: "primary", event_id:, summary:, start_time:, end_time:, all_day: false) ⇒ Object



41
42
43
44
45
46
47
48
49
50
# File 'lib/flycal/client.rb', line 41

def update_event(calendar_id: "primary", event_id:, summary:, start_time:, end_time:, all_day: false)
  calendar.update_event(
    calendar_id: calendar_id,
    event_id: event_id,
    summary: summary,
    start_time: start_time,
    end_time: end_time,
    all_day: all_day
  )
end