cal-invite 0.1.3 → 0.1.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 100b68a6d13bbb3b58234eee38701ffc1c6d215daf126ba98c89e249829d716e
4
- data.tar.gz: ed0388023bf7245fb09c14294ce91610c189996f7c49cf246f47589efd17c1d2
3
+ metadata.gz: c3f79844d8b3618ca4539da1033070e310d84d8d6a004d921ce28b7230fda371
4
+ data.tar.gz: c7f43118837065df3744b139fc5e0abcbedbb4e9a6490f660c0d79b0bff85d6b
5
5
  SHA512:
6
- metadata.gz: 9755f61af9fbed611988f3355647991c4dabe8b9a1f4ff3c0c8e77aa0c9d2c744e270aa09e01c0f7284fd0c40bce1af07a0a0a68f557e19be901969a89f32c3d
7
- data.tar.gz: 18b4e856b14b6d5a49a2dce096b56e8b068813f058cf6648ceb9f37f04d5793454ff46bb1a7f1ed4e1f35f1e8faa796595915e84334d9763323b814744d47808
6
+ metadata.gz: 884ac33c88abc0b496496ba495e6bc4381c617df1c327cfd52e8995121f3a607c576724f3c7095b8186a3ffc10c5020ddd7643c4d79ad7746e7419b4da4277f0
7
+ data.tar.gz: b026672548b98ad349ab094a5def2d1f3c7b7904592ed1528caec8978c9d6c0c4f584e68706d307d31fdcfe769ca119d71df516f535bbc5ccc50a03768fefeac
data/.DS_Store ADDED
Binary file
data/.rdoc_options ADDED
@@ -0,0 +1,85 @@
1
+ ---
2
+ encoding: UTF-8
3
+ static_path: ["./doc/images"]
4
+ charset: UTF-8
5
+ exclude: ["vendor/*", "tmp/*", ".*/*"]
6
+ hyperlink_all: true
7
+ line_numbers: true
8
+ locale: en
9
+ main: README.md
10
+ markup: markdown
11
+ output_decoration: true
12
+ show_hash: false
13
+ tab_width: 2
14
+ template_stylesheets: []
15
+ title: "CalInvite - Calendar Invite Generator by DashAPI"
16
+ visibility: :public
17
+ webcvs: https://github.com/the-pew-inc/cal-invite
18
+
19
+ # Custom sections for better organization
20
+ sections:
21
+ - title: Calendar Providers
22
+ dir: lib/cal_invite/providers
23
+ include: ["**/*.rb"]
24
+ - title: Core
25
+ dir: lib/cal_invite
26
+ include: ["*.rb"]
27
+
28
+ extra_docs:
29
+ - README.md
30
+ - CHANGELOG.md
31
+ - LICENSE.txt
32
+
33
+ # Options for better documentation organization
34
+ options:
35
+ all:
36
+ - "--title=CalInvite - Calendar Invite Generator by DashAPI"
37
+ - "--line-numbers"
38
+ - "--diagram" # Include diagrams if you have any
39
+ - "--main=README.md"
40
+ SystemExtension:
41
+ - "--title=CalInvite System Extensions"
42
+
43
+ # Documentation sections
44
+ doc_sections:
45
+ - "Calendar Provider Implementation"
46
+ - "Configuration"
47
+ - "Event Management"
48
+ - "Utility Functions"
49
+
50
+ # Additional documentation metadata
51
+ metadata:
52
+ copyright: "© 2024 ThePew Inc. All rights reserved."
53
+ authors:
54
+ - "Stephane Paquet"
55
+ website: "https://github.com/the-pew-inc/cal-invite"
56
+ license: "MIT"
57
+
58
+ # Documentation themes and styles
59
+ template:
60
+ css: [] # You can add custom CSS files if needed
61
+ javascript: [] # You can add custom JS files if needed
62
+
63
+ # Search engine optimization
64
+ search_index:
65
+ include:
66
+ - "**/*.rb"
67
+ exclude:
68
+ - "test/**/*"
69
+ - "spec/**/*"
70
+ - "vendor/**/*"
71
+
72
+ # Documentation organization
73
+ groups:
74
+ Core:
75
+ - CalInvite
76
+ - CalInvite::Configuration
77
+ - CalInvite::Event
78
+ Providers:
79
+ - CalInvite::Providers::BaseProvider
80
+ - CalInvite::Providers::Google
81
+ - CalInvite::Providers::Outlook
82
+ - CalInvite::Providers::Office365
83
+ - CalInvite::Providers::Yahoo
84
+ - CalInvite::Providers::Ics
85
+ - CalInvite::Providers::Ical
data/CHANGELOG.md CHANGED
@@ -4,6 +4,10 @@
4
4
 
5
5
  ## [v0.1.3] - 2024-12-19
6
6
 
7
+ - Add support to RDoc
8
+
9
+ ## [v0.1.3] - 2024-12-19
10
+
7
11
  - Apple iCal and ics file can now be either generated or wrap to be downloaded
8
12
  - Add Caching management support
9
13
  - Add CACHING.md for more details about how to use caching in a Rails app
@@ -12,6 +16,8 @@
12
16
 
13
17
  ## [v0.1.2] - 2024-12-17
14
18
 
19
+ ⚠️ This version should not be used
20
+
15
21
  - Add support to Microsoft office 365 calendar invite URL
16
22
  - Update the README
17
23
  - Add an example
@@ -19,6 +25,8 @@
19
25
 
20
26
  ## [v0.1.1] - 2024-12-17
21
27
 
28
+ ⚠️ This version should not be used
29
+
22
30
  Fixing a bug in the gemspec file
23
31
 
24
32
  ## [Unreleased]
data/README.md CHANGED
@@ -242,6 +242,12 @@ Run all the tests before submitting: `bundle exec rake test`
242
242
 
243
243
  Bug reports and pull requests are welcome on GitHub at https://github.com/the-pew-inc/cal-invite. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/the-pew-inc/cal-invite/blob/master/CODE_OF_CONDUCT.md).
244
244
 
245
+ ## Documentation
246
+
247
+ The documentation is spread accross the README, CAHCING and the doc folder.
248
+
249
+ The documentation can be generated using `bundle exec rake rdoc`
250
+
245
251
  ## License
246
252
 
247
253
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile CHANGED
@@ -2,11 +2,37 @@
2
2
 
3
3
  require "bundler/gem_tasks"
4
4
  require "rake/testtask"
5
+ require "rdoc/task"
5
6
 
7
+ # Test task configuration
6
8
  Rake::TestTask.new(:test) do |t|
7
9
  t.libs << "test"
8
10
  t.libs << "lib"
9
11
  t.test_files = FileList["test/**/*_test.rb"]
10
12
  end
11
13
 
14
+ # RDoc task configuration
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'doc'
17
+ rdoc.title = 'CalInvite Documentation'
18
+ rdoc.main = 'README.md'
19
+
20
+ # Configure RDoc options
21
+ rdoc.options << '--line-numbers'
22
+ rdoc.options << '--charset' << 'UTF-8'
23
+ rdoc.options << '--markup' << 'markdown'
24
+ rdoc.options << '--all'
25
+ rdoc.options << '--exclude' << '^(test|spec|features)/'
26
+
27
+ # Include files to document
28
+ rdoc.rdoc_files.include('README.md', 'LICENSE.txt', 'lib/**/*.rb')
29
+ rdoc.rdoc_files.exclude('lib/cal_invite/version.rb')
30
+ end
31
+
32
+ # Define a task to clean documentation
33
+ task 'rdoc:clean' do
34
+ rm_rf 'doc'
35
+ end
36
+
37
+ # Keep test as the default task
12
38
  task default: :test
data/lib/.DS_Store ADDED
Binary file
Binary file
@@ -1,10 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # lib/cal_invite/configuration.rb
4
+ # Configuration class for the CalInvite gem.
5
+ # Handles all configurable options including cache settings, timezone, and webhook secrets.
6
+ #
7
+ # @attr_reader [ActiveSupport::Cache::Store, nil] cache_store The cache store to use
8
+ # @attr_reader [String] cache_prefix The prefix to use for cache keys
9
+ # @attr_reader [Integer] cache_expires_in The default cache expiration time in seconds
10
+ # @attr_reader [String, nil] webhook_secret The secret key for webhook verification
11
+ # @attr_reader [String] timezone The default timezone for events
4
12
  module CalInvite
5
13
  class Configuration
6
14
  attr_reader :cache_store, :cache_prefix, :cache_expires_in, :webhook_secret, :timezone
7
15
 
16
+ # Initializes a new Configuration instance with default values.
8
17
  def initialize
9
18
  @cache_store = nil
10
19
  @cache_prefix = 'cal_invite'
@@ -13,6 +22,13 @@ module CalInvite
13
22
  @timezone = 'UTC'
14
23
  end
15
24
 
25
+ # Sets the cache store to use for caching calendar URLs.
26
+ #
27
+ # @param store [Symbol, #read, #write, #delete] The cache store to use
28
+ # @raise [ArgumentError] If an unsupported cache store is provided
29
+ #
30
+ # @example Set memory store
31
+ # config.cache_store = :memory_store
16
32
  def cache_store=(store)
17
33
  @cache_store = case store
18
34
  when :memory_store
@@ -30,18 +46,30 @@ module CalInvite
30
46
  end
31
47
  end
32
48
 
49
+ # Sets the prefix used for cache keys.
50
+ #
51
+ # @param prefix [#to_s] The prefix to use for cache keys
33
52
  def cache_prefix=(prefix)
34
53
  @cache_prefix = prefix.to_s
35
54
  end
36
55
 
56
+ # Sets the default cache expiration time.
57
+ #
58
+ # @param duration [#to_i] The duration in seconds
37
59
  def cache_expires_in=(duration)
38
60
  @cache_expires_in = duration.to_i
39
61
  end
40
62
 
63
+ # Sets the webhook secret for verification.
64
+ #
65
+ # @param secret [String, nil] The secret key
41
66
  def webhook_secret=(secret)
42
67
  @webhook_secret = secret
43
68
  end
44
69
 
70
+ # Sets the default timezone for events.
71
+ #
72
+ # @param tz [#to_s] The timezone identifier
45
73
  def timezone=(tz)
46
74
  @timezone = tz.to_s
47
75
  end
@@ -1,7 +1,22 @@
1
1
  # frozen_string_literal: true
2
- # lib/cal_invite/event.rb
2
+
3
3
  require 'digest'
4
4
 
5
+ # lib/cal_invite/event.rb
6
+ # Represents a calendar event with all its attributes and generation capabilities.
7
+ #
8
+ # @attr_accessor [String] title The title of the event
9
+ # @attr_accessor [Time] start_time The start time of the event
10
+ # @attr_accessor [Time] end_time The end time of the event
11
+ # @attr_accessor [String] description The description of the event
12
+ # @attr_accessor [String] location The location of the event
13
+ # @attr_accessor [String] url The URL associated with the event
14
+ # @attr_accessor [Array<String>] attendees The list of attendee email addresses
15
+ # @attr_accessor [String] timezone The timezone for the event
16
+ # @attr_accessor [Boolean] show_attendees Whether to include attendees in calendar invites
17
+ # @attr_accessor [String] notes Additional notes for the event
18
+ # @attr_accessor [Array<Hash>] multi_day_sessions Sessions for multi-day events
19
+ # @attr_accessor [Boolean] all_day Whether this is an all-day event
5
20
  module CalInvite
6
21
  class Event
7
22
  attr_accessor :title,
@@ -17,6 +32,23 @@ module CalInvite
17
32
  :multi_day_sessions,
18
33
  :all_day
19
34
 
35
+ # Initializes a new Event instance with the given attributes.
36
+ #
37
+ # @param attributes [Hash] The attributes to initialize the event with
38
+ # @option attributes [String] :title The event title
39
+ # @option attributes [Time] :start_time The event start time
40
+ # @option attributes [Time] :end_time The event end time
41
+ # @option attributes [String] :description The event description
42
+ # @option attributes [String] :location The event location
43
+ # @option attributes [String] :url The event URL
44
+ # @option attributes [Array<String>] :attendees The event attendees
45
+ # @option attributes [String] :timezone ('UTC') The event timezone
46
+ # @option attributes [Boolean] :show_attendees (false) Whether to show attendees
47
+ # @option attributes [String] :notes Additional notes
48
+ # @option attributes [Array<Hash>] :multi_day_sessions Multi-day session details
49
+ # @option attributes [Boolean] :all_day (false) Whether it's an all-day event
50
+ #
51
+ # @raise [ArgumentError] If required attributes are missing
20
52
  def initialize(attributes = {})
21
53
  @show_attendees = attributes.delete(:show_attendees) || false
22
54
  @timezone = attributes.delete(:timezone) || 'UTC'
@@ -30,6 +62,17 @@ module CalInvite
30
62
  validate!
31
63
  end
32
64
 
65
+ # Generates a calendar URL for the specified provider.
66
+ #
67
+ # @param provider [Symbol] The calendar provider to generate the URL for
68
+ # @return [String] The generated calendar URL
69
+ # @raise [ArgumentError] If required event attributes are missing
70
+ #
71
+ # @example Generate a Google Calendar URL
72
+ # event.generate_calendar_url(:google)
73
+ #
74
+ # @example Generate an Outlook Calendar URL
75
+ # event.generate_calendar_url(:outlook)
33
76
  def generate_calendar_url(provider)
34
77
  validate!
35
78
 
@@ -50,6 +93,17 @@ module CalInvite
50
93
  url
51
94
  end
52
95
 
96
+ # Updates the event attributes with new values.
97
+ #
98
+ # @param new_attributes [Hash] The new attributes to update
99
+ # @return [void]
100
+ # @raise [ArgumentError] If the updated attributes make the event invalid
101
+ #
102
+ # @example Update event title and time
103
+ # event.update_attributes(
104
+ # title: "Updated Meeting",
105
+ # start_time: Time.now + 3600
106
+ # )
53
107
  def update_attributes(new_attributes)
54
108
  new_attributes.each do |key, value|
55
109
  send("#{key}=", value) if respond_to?("#{key}=")
@@ -61,10 +115,19 @@ module CalInvite
61
115
 
62
116
  private
63
117
 
118
+ # Capitalizes each part of the provider name.
119
+ #
120
+ # @param string [String] The provider name to capitalize
121
+ # @return [String] The capitalized provider name
122
+ # @example
123
+ # capitalize_provider('google_calendar') # => "GoogleCalendar"
64
124
  def capitalize_provider(string)
65
125
  string.split('_').map(&:capitalize).join
66
126
  end
67
127
 
128
+ # Validates the event attributes.
129
+ #
130
+ # @raise [ArgumentError] If required attributes are missing or invalid
68
131
  def validate!
69
132
  raise ArgumentError, "Title is required" if title.nil? || title.strip.empty?
70
133
 
@@ -74,12 +137,19 @@ module CalInvite
74
137
  end
75
138
  end
76
139
 
140
+ # Checks if caching is enabled in the configuration.
141
+ #
142
+ # @return [Boolean] true if caching is enabled, false otherwise
77
143
  def caching_enabled?
78
144
  CalInvite.configuration &&
79
145
  CalInvite.configuration.respond_to?(:cache_store) &&
80
146
  CalInvite.configuration.cache_store
81
147
  end
82
148
 
149
+ # Generates a cache key for the event and provider combination.
150
+ #
151
+ # @param provider [Symbol] The calendar provider
152
+ # @return [String, nil] The cache key or nil if caching is disabled
83
153
  def cache_key_for(provider)
84
154
  return nil unless caching_enabled?
85
155
 
@@ -104,11 +174,20 @@ module CalInvite
104
174
  "cal_invite:event:#{attributes_hash}"
105
175
  end
106
176
 
177
+ # Retrieves a value from the cache store.
178
+ #
179
+ # @param key [String] The cache key
180
+ # @return [String, nil] The cached value or nil if not found
107
181
  def fetch_from_cache(key)
108
182
  return nil unless key && caching_enabled?
109
183
  CalInvite.configuration.cache_store.read(key)
110
184
  end
111
185
 
186
+ # Writes a value to the cache store.
187
+ #
188
+ # @param key [String] The cache key
189
+ # @param value [String] The value to cache
190
+ # @return [void]
112
191
  def write_to_cache(key, value)
113
192
  return unless key && caching_enabled?
114
193
 
@@ -120,6 +199,9 @@ module CalInvite
120
199
  )
121
200
  end
122
201
 
202
+ # Invalidates all cached URLs for this event.
203
+ #
204
+ # @return [void]
123
205
  def invalidate_cache
124
206
  return unless caching_enabled?
125
207
 
@@ -1,17 +1,36 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # app/lib/base_provider.rb
4
+ # Base class for calendar providers that implements common functionality
5
+ # and defines the interface that all providers must implement.
6
+ #
7
+ # @abstract Subclass and override {#generate} to implement a calendar provider
2
8
  class BaseProvider
3
9
  attr_reader :event
4
10
 
11
+ # Initialize a new calendar provider
12
+ #
13
+ # @param event [CalInvite::Event] The event to generate a calendar URL for
5
14
  def initialize(event)
6
15
  @event = event
7
16
  end
8
17
 
18
+ # Generate a calendar URL or content for the event.
19
+ # This method must be implemented by all provider subclasses.
20
+ #
21
+ # @abstract
22
+ # @return [String] The generated calendar URL or content
23
+ # @raise [NotImplementedError] if the provider class doesn't implement this method
9
24
  def generate
10
25
  raise NotImplementedError, "#{self.class} must implement #generate"
11
26
  end
12
27
 
13
28
  protected
14
29
 
30
+ # URL encode a string for use in calendar URLs
31
+ #
32
+ # @param str [#to_s] The string to encode
33
+ # @return [String] The URL encoded string
15
34
  def url_encode(str)
16
35
  URI.encode_www_form_component(str.to_s)
17
36
  end
@@ -3,7 +3,34 @@
3
3
  # lib/cal_invite/providers/google.rb
4
4
  module CalInvite
5
5
  module Providers
6
+ # Google Calendar provider for generating event URLs.
7
+ # This provider generates URLs that open the Google Calendar event creation page
8
+ # with pre-filled event details.
9
+ #
10
+ # @example Creating a regular event URL
11
+ # event = CalInvite::Event.new(
12
+ # title: "Team Meeting",
13
+ # start_time: Time.now,
14
+ # end_time: Time.now + 3600
15
+ # )
16
+ # google = CalInvite::Providers::Google.new(event)
17
+ # url = google.generate
18
+ #
19
+ # @example Creating an all-day event URL
20
+ # event = CalInvite::Event.new(
21
+ # title: "Company Holiday",
22
+ # all_day: true,
23
+ # start_time: Date.today,
24
+ # end_time: Date.today + 1
25
+ # )
26
+ # url = CalInvite::Providers::Google.new(event).generate
6
27
  class Google < BaseProvider
28
+ # Generates a Google Calendar URL for the event.
29
+ # Handles both regular and all-day events appropriately.
30
+ #
31
+ # @return [String] The generated Google Calendar URL
32
+ # @see #generate_all_day_event
33
+ # @see #generate_single_event
7
34
  def generate
8
35
  if event.all_day
9
36
  generate_all_day_event
@@ -14,36 +41,53 @@ module CalInvite
14
41
 
15
42
  private
16
43
 
44
+ # Generates a URL for an all-day event.
45
+ # Uses a simpler date format without time components.
46
+ #
47
+ # @return [String] The Google Calendar URL for an all-day event
48
+ # @see #format_all_day_dates
17
49
  def generate_all_day_event
18
50
  params = {
19
51
  action: 'TEMPLATE',
20
52
  text: url_encode(event.title),
21
53
  dates: format_all_day_dates
22
54
  }
23
-
24
55
  add_optional_params(params)
25
56
  build_url(params)
26
57
  end
27
58
 
59
+ # Generates a URL for a regular (time-specific) event.
60
+ #
61
+ # @return [String] The Google Calendar URL for a regular event
62
+ # @raise [ArgumentError] If start_time or end_time is missing
63
+ # @see #format_dates
28
64
  def generate_single_event
29
65
  params = {
30
66
  action: 'TEMPLATE',
31
67
  text: url_encode(event.title),
32
68
  dates: format_dates
33
69
  }
34
-
35
70
  add_optional_params(params)
36
71
  build_url(params)
37
72
  end
38
73
 
74
+ # Formats dates for an all-day event according to Google Calendar's requirements.
75
+ # If start_time is not specified, uses current date.
76
+ # If end_time is not specified, adds one day to start_time.
77
+ #
78
+ # @return [String] Date range in format 'YYYYMMDD/YYYYMMDD'
39
79
  def format_all_day_dates
40
- # For all-day events, use current date if no start_time specified
41
80
  start_date = event.start_time || Time.now
42
81
  end_date = event.end_time || (start_date + 86400) # Add one day if no end_time
43
82
 
44
83
  "#{start_date.strftime('%Y%m%d')}/#{end_date.strftime('%Y%m%d')}"
45
84
  end
46
85
 
86
+ # Formats dates and times according to Google Calendar's requirements.
87
+ # Times are converted to UTC and formatted appropriately.
88
+ #
89
+ # @return [String] Date/time range in format 'YYYYMMDDTHHmmSSZ/YYYYMMDDTHHmmSSZ'
90
+ # @raise [ArgumentError] If either start_time or end_time is missing
47
91
  def format_dates
48
92
  raise ArgumentError, "Start time is required" unless event.start_time
49
93
  raise ArgumentError, "End time is required" unless event.end_time
@@ -54,16 +98,24 @@ module CalInvite
54
98
  "#{start_time.utc.strftime('%Y%m%dT%H%M%SZ')}/#{end_time.utc.strftime('%Y%m%dT%H%M%SZ')}"
55
99
  end
56
100
 
101
+ # Adds optional parameters to the URL parameters hash.
102
+ # Handles description, virtual meeting URL, and location.
103
+ #
104
+ # @param params [Hash] The parameters hash to update
105
+ # @return [Hash] The updated parameters hash with optional parameters added
57
106
  def add_optional_params(params)
58
107
  description_parts = []
59
108
  description_parts << format_description if format_description
60
109
  description_parts << "Virtual Meeting URL: #{format_url}" if format_url
61
110
  params[:details] = url_encode(description_parts.join("\n\n")) if description_parts.any?
62
-
63
111
  params[:location] = url_encode(format_location) if format_location
64
112
  params
65
113
  end
66
114
 
115
+ # Builds the final Google Calendar URL from the parameters hash.
116
+ #
117
+ # @param params [Hash] The parameters to include in the URL
118
+ # @return [String] The complete Google Calendar URL
67
119
  def build_url(params)
68
120
  query = params.map { |k, v| "#{k}=#{v}" }.join('&')
69
121
  "https://calendar.google.com/calendar/render?#{query}"