add_to_calendar 0.2.5 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 24986348b563ba6eee3ee7c510092434f8e24d76c1ddd402484e31951cbb94f0
4
- data.tar.gz: eda31a7a266b15e4b82db84ed250a2da999b0f5efe6fc565b75c8e7ea3286a57
3
+ metadata.gz: 2c0a0f2f9901bd47c14f386ec09c72207eeebf34e04e592473c57e2b00bc3d18
4
+ data.tar.gz: f2cb5bf74e64fb36e47d293e8a525b784018280851a16b08817eb716c4453393
5
5
  SHA512:
6
- metadata.gz: 4da59f54a6a6099646425189a66481e0450e6ac9cd6ea56806c455e74fcddd1f0055150a9951db600821a7c854593f23a049879eb85c972b1677205463397af9
7
- data.tar.gz: 3d3eef19ecd6bf9f56440253c2f1cbf9d3ea090ea16e83d067191ecc61ac2fdabd49a20398adc206498a451a36355287ff06e8a726b89b416cbe45888418b3dc
6
+ metadata.gz: ab6dee17a03164fce02ce552f522b4fdda9414328063355611e39784e89b8d85cad3a800d9c3360d5128d2187cbaa9094596451fb2dce702c3acd91faead4024
7
+ data.tar.gz: 66eb54a91cba9b7adcf625e25a89ea1c64018b36e045130ba3a01a1cc317c55072fc42607903eee88103eecd102022610fb7e1b9315d284922d46eedfb6c0ce9
data/Gemfile.lock CHANGED
@@ -1,22 +1,23 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- add_to_calendar (0.2.5)
4
+ add_to_calendar (0.4.0)
5
5
  tzinfo (>= 1.1, < 3)
6
6
  tzinfo-data (~> 1.2020)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- coderay (1.1.2)
12
- concurrent-ruby (1.1.6)
11
+ coderay (1.1.3)
12
+ concurrent-ruby (1.1.10)
13
13
  method_source (1.0.0)
14
- minitest (5.14.0)
15
- pry (0.13.1)
14
+ minitest (5.18.0)
15
+ pry (0.14.2)
16
16
  coderay (~> 1.1)
17
17
  method_source (~> 1.0)
18
18
  rake (13.0.1)
19
- tzinfo (2.0.2)
19
+ timecop (0.9.6)
20
+ tzinfo (2.0.5)
20
21
  concurrent-ruby (~> 1.0)
21
22
  tzinfo-data (1.2020.1)
22
23
  tzinfo (>= 1.0.0)
@@ -28,8 +29,9 @@ DEPENDENCIES
28
29
  add_to_calendar!
29
30
  bundler (~> 2.0)
30
31
  minitest (~> 5.0)
31
- pry (~> 0.13.1)
32
+ pry (~> 0.14)
32
33
  rake (~> 13.0.1)
34
+ timecop (~> 0.9)
33
35
 
34
36
  BUNDLED WITH
35
- 2.0.2
37
+ 2.3.9
data/README.md CHANGED
@@ -78,10 +78,15 @@ event_attributes = {
78
78
  location: "20 W 34th St, New York, NY 10001",
79
79
  url: "https://www.ruby-lang.org/en/",
80
80
  description: "Join us to learn all about Ruby.",
81
- add_url_to_description: true # defaults to true
81
+ add_url_to_description: true, # defaults to true
82
+ all_day: true, # defaults to false
83
+ organizer: {
84
+ name: "First Last",
85
+ email: "email@example.com"
86
+ }
82
87
  }
83
88
 
84
- cal = AddToCalendar::URLs.new(event_attributes)
89
+ cal = AddToCalendar::URLs.new(**event_attributes)
85
90
  ```
86
91
 
87
92
  | Attribute | Required? | Class | Notes |
@@ -93,7 +98,9 @@ cal = AddToCalendar::URLs.new(event_attributes)
93
98
  | location | No | String | |
94
99
  | url | No | String | Most providers do not have a native URL field. If you set `url` it will be added to the end of the description field (see `add_url_to_description`) |
95
100
  | description | No | String | Accepts newlines by passing `\n` Eg. `"Join us for fun & drinks\n\nPS. Smart casual"` |
96
- | add_url_to_description | No | true/false | defaults to `true`. Set `add_url_to_description: false` to stop the URL from being added to the description |
101
+ | add_url_to_description | No | true/false | Defaults to `true`. Set `add_url_to_description: false` to stop the URL from being added to the description |
102
+ | all_day | No | true/false | <ul><li>Defaults to `false`.</li><li>When set to `true` the times will be ignored.</li><li>If no end_datetime provided it will be a single day event.</li><li>When providing end_datetime, use the final day of the event (eg. 1 day event start: 2023-05-01, end: 2023-05-01; 3 day event start: 2023-05-01, end: 2023-05-03).</li><li>Some calendars require you to specify the _day after_ as the end date which feels counterintuitive, this Gem takes care of that for you.</li></ul> |
103
+ | organizer | No | Hash | <ul><li>Only supported by ical</li><li>If used you must provide both `name` and `email`</li><li>Must be in format `{ name: "First Last", email: "email@example.com" }`</li></ul> |
97
104
 
98
105
  ### Timezones and offsets
99
106
 
@@ -34,5 +34,6 @@ Gem::Specification.new do |spec|
34
34
  spec.add_development_dependency "bundler", "~> 2.0"
35
35
  spec.add_development_dependency "rake", "~> 13.0.1"
36
36
  spec.add_development_dependency "minitest", "~> 5.0"
37
- spec.add_development_dependency "pry", "~> 0.13.1"
37
+ spec.add_development_dependency "pry", "~> 0.14"
38
+ spec.add_development_dependency "timecop", "~> 0.9"
38
39
  end
@@ -1,3 +1,3 @@
1
1
  module AddToCalendar
2
- VERSION = "0.2.5"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -8,13 +8,12 @@ require 'tzinfo'
8
8
  require 'date'
9
9
  # require 'pry'
10
10
 
11
-
12
11
  module AddToCalendar
13
12
  class Error < StandardError; end
14
13
 
15
14
  class URLs
16
- attr_accessor :start_datetime, :end_datetime, :title, :timezone, :location, :url, :description, :add_url_to_description
17
- def initialize(start_datetime:, end_datetime: nil, title:, timezone:, location: nil, url: nil, description: nil, add_url_to_description: true)
15
+ attr_accessor :start_datetime, :end_datetime, :title, :timezone, :location, :url, :description, :add_url_to_description, :all_day, :organizer
16
+ def initialize(start_datetime:, end_datetime: nil, title:, timezone:, location: nil, url: nil, description: nil, add_url_to_description: true, all_day: false, organizer: nil)
18
17
  @start_datetime = start_datetime
19
18
  @end_datetime = end_datetime
20
19
  @title = title
@@ -23,6 +22,8 @@ module AddToCalendar
23
22
  @url = url
24
23
  @description = description
25
24
  @add_url_to_description = add_url_to_description
25
+ @all_day = all_day
26
+ @organizer = organizer
26
27
 
27
28
  validate_attributes
28
29
  end
@@ -32,11 +33,7 @@ module AddToCalendar
32
33
  calendar_url = "https://www.google.com/calendar/render?action=TEMPLATE"
33
34
  params = {}
34
35
  params[:text] = url_encode(title)
35
- if end_datetime
36
- params[:dates] = "#{format_date_google(start_datetime)}/#{format_date_google(end_datetime)}"
37
- else
38
- params[:dates] = "#{format_date_google(start_datetime)}/#{format_date_google(start_datetime + 60*60)}" # end time is 1 hour later
39
- end
36
+ params[:dates] = google_dates(start_datetime, end_datetime, all_day)
40
37
  params[:ctz] = timezone.identifier
41
38
  params[:location] = url_encode(location) if location
42
39
  params[:details] = url_encode(description) if description
@@ -56,17 +53,28 @@ module AddToCalendar
56
53
  end
57
54
 
58
55
  def yahoo_url
59
- # Eg. https://calendar.yahoo.com/?v=60&view=d&type=20&title=Holly%27s%208th%20Birthday!&st=20200615T170000Z&dur=0100&desc=Join%20us%20to%20celebrate%20with%20lots%20of%20games%20and%20cake!&in_loc=7%20Apartments,%20London
60
- calendar_url = "https://calendar.yahoo.com/?v=60&view=d&type=20"
56
+ # Eg. https://calendar.yahoo.com/?v=60&title=Holly%27s%208th%20Birthday!&st=20200615T170000Z&dur=0100&desc=Join%20us%20to%20celebrate%20with%20lots%20of%20games%20and%20cake!&in_loc=7%20Apartments,%20London
57
+ calendar_url = "https://calendar.yahoo.com/?v=60"
61
58
  params = {}
62
59
  params[:title] = url_encode(title)
63
- params[:st] = utc_datetime(start_datetime)
64
- if end_datetime
65
- seconds = duration_seconds(start_datetime, end_datetime)
66
- params[:dur] = seconds_to_hours_minutes(seconds)
60
+ if all_day
61
+ params[:st] = format_date(start_datetime)
62
+ if end_datetime
63
+ params[:et] = format_date(end_datetime)
64
+ else
65
+ params[:et] = format_date(start_datetime)
66
+ end
67
+ params[:dur] = "allday"
67
68
  else
68
- params[:dur] = "0100"
69
+ params[:st] = utc_datetime(start_datetime)
70
+ if end_datetime
71
+ seconds = duration_seconds(start_datetime, end_datetime)
72
+ params[:dur] = seconds_to_hours_minutes(seconds)
73
+ else
74
+ params[:dur] = "0100"
75
+ end
69
76
  end
77
+
70
78
  params[:desc] = url_encode(description) if description
71
79
  if add_url_to_description && url
72
80
  if params[:desc]
@@ -78,7 +86,7 @@ module AddToCalendar
78
86
  params[:in_loc] = url_encode(location) if location
79
87
 
80
88
  params.each do |key, value|
81
- calendar_url << "&#{key}=#{value}"
89
+ calendar_url << "&#{yahoo_param(key)}=#{value}"
82
90
  end
83
91
 
84
92
  return calendar_url
@@ -97,15 +105,30 @@ module AddToCalendar
97
105
  def ical_url
98
106
  # Downloads a *.ics file provided as a data-uri
99
107
  # Eg. "data:text/calendar;charset=utf8,BEGIN:VCALENDAR%0AVERSION:2.0%0ABEGIN:VEVENT%0ADTSTART:20200512T123000Z%0ADTEND:20200512T160000Z%0ASUMMARY:Holly%27s%208th%20Birthday%21%0AURL:https%3A%2F%2Fwww.example.com%2Fevent-details%0ADESCRIPTION:Come%20join%20us%20for%20lots%20of%20fun%20%26%20cake%21\\n\\nhttps%3A%2F%2Fwww.example.com%2Fevent-details%0ALOCATION:Flat%204%5C%2C%20The%20Edge%5C%2C%2038%20Smith-Dorrien%20St%5C%2C%20London%5C%2C%20N1%207GU%0AUID:-https%3A%2F%2Fwww.example.com%2Fevent-details%0AEND:VEVENT%0AEND:VCALENDAR"
100
- calendar_url = "data:text/calendar;charset=utf8,BEGIN:VCALENDAR%0AVERSION:2.0%0ABEGIN:VEVENT"
108
+ calendar_url = "data:text/calendar;charset=utf8,BEGIN:VCALENDAR%0AVERSION:2.0%0APRODID:-//AddToCalendar//RubyGem//EN%0ABEGIN:VEVENT"
109
+
101
110
  params = {}
102
- params[:DTSTART] = utc_datetime(start_datetime)
103
- if end_datetime
104
- params[:DTEND] = utc_datetime(end_datetime)
111
+ params[:DTSTAMP] = Time.now.strftime("%Y%m%dT%H%M%SZ")
112
+ if all_day
113
+ one_day = 1 * 24 * 60 * 60
114
+ params["DTSTART;VALUE=DATE"] = format_date(start_datetime)
115
+ if end_datetime
116
+ params["DTEND;VALUE=DATE"] = format_date(end_datetime + one_day)
117
+ else
118
+ params["DTEND;VALUE=DATE"] = format_date(start_datetime + one_day)
119
+ end
105
120
  else
106
- params[:DTEND] = utc_datetime(start_datetime + 60*60) # 1 hour later
121
+ params[:DTSTART] = utc_datetime(start_datetime)
122
+ if end_datetime
123
+ params[:DTEND] = utc_datetime(end_datetime)
124
+ else
125
+ params[:DTEND] = utc_datetime(start_datetime + 60*60) # 1 hour later
126
+ end
107
127
  end
108
128
  params[:SUMMARY] = url_encode_ical(title)
129
+ if organizer
130
+ params[:ORGANIZER] = url_encode_ical("CN=\"#{organizer[:name]}\":mailto:#{organizer[:email]}")
131
+ end
109
132
  params[:URL] = url_encode(url) if url
110
133
  params[:DESCRIPTION] = url_encode_ical(description) if description
111
134
  if add_url_to_description && url
@@ -121,7 +144,11 @@ module AddToCalendar
121
144
 
122
145
  new_line = "%0A"
123
146
  params.each do |key, value|
124
- calendar_url << "#{new_line}#{key}:#{value}"
147
+ if key == :ORGANIZER
148
+ calendar_url << "#{new_line}#{key};#{value}"
149
+ else
150
+ calendar_url << "#{new_line}#{key}:#{value}"
151
+ end
125
152
  end
126
153
 
127
154
  calendar_url << "%0AEND:VEVENT%0AEND:VCALENDAR"
@@ -161,6 +188,12 @@ module AddToCalendar
161
188
  if description
162
189
  raise(ArgumentError, ":description must be a string") unless self.description.kind_of? String
163
190
  end
191
+
192
+ if organizer
193
+ unless self.organizer.is_a?(Hash) && self.organizer[:name].is_a?(String) && self.organizer[:email].is_a?(String)
194
+ raise(ArgumentError, ":organizer must be a Hash of format { name: \"First Last\", email: \"email@example.com\" }")
195
+ end
196
+ end
164
197
  end
165
198
 
166
199
  def microsoft(service)
@@ -174,11 +207,22 @@ module AddToCalendar
174
207
  end
175
208
  params = {}
176
209
  params[:subject] = url_encode(title.gsub(' & ', ' and '))
177
- params[:startdt] = utc_datetime_microsoft(start_datetime)
178
- if end_datetime
179
- params[:enddt] = utc_datetime_microsoft(end_datetime)
210
+ if all_day
211
+ one_day = 1 * 24 * 60 * 60
212
+ params[:startdt] = microsoft_date(start_datetime)
213
+ if end_datetime
214
+ params[:enddt] = microsoft_date(end_datetime + one_day)
215
+ else
216
+ params[:enddt] = microsoft_date(start_datetime + one_day)
217
+ end
218
+ params[:allday] = "true"
180
219
  else
181
- params[:enddt] = utc_datetime_microsoft(start_datetime + 60*60) # 1 hour later
220
+ params[:startdt] = utc_datetime_microsoft(start_datetime)
221
+ if end_datetime
222
+ params[:enddt] = utc_datetime_microsoft(end_datetime)
223
+ else
224
+ params[:enddt] = utc_datetime_microsoft(start_datetime + 60*60) # 1 hour later
225
+ end
182
226
  end
183
227
  params[:body] = url_encode(newlines_to_html_br(description)) if description
184
228
  if add_url_to_description && url
@@ -226,11 +270,34 @@ module AddToCalendar
226
270
 
227
271
  return t.strftime('%Y-%m-%dT%H:%M:%SZ')
228
272
  end
273
+
274
+ def microsoft_date(date)
275
+ date.strftime('%Y-%m-%d')
276
+ end
277
+
278
+ def google_dates(start_datetime, end_datetime, all_day)
279
+ one_day = 1 * 24 * 60 * 60
280
+ if all_day
281
+ if end_datetime
282
+ "#{format_date(start_datetime)}/#{format_date(end_datetime + one_day)}"
283
+ else
284
+ "#{format_date(start_datetime)}/#{format_date(start_datetime + one_day)}"
285
+ end
286
+ elsif end_datetime
287
+ "#{format_datetime_google(start_datetime)}/#{format_datetime_google(end_datetime)}"
288
+ else
289
+ "#{format_datetime_google(start_datetime)}/#{format_datetime_google(start_datetime + 60*60)}" # end time is 1 hour later
290
+ end
291
+ end
229
292
 
230
- def format_date_google(start_datetime)
293
+ def format_datetime_google(start_datetime)
231
294
  start_datetime.strftime('%Y%m%dT%H%M%S')
232
295
  end
233
296
 
297
+ def format_date(date)
298
+ date.strftime('%Y%m%d')
299
+ end
300
+
234
301
  def duration_seconds(start_time, end_time)
235
302
  (start_time.to_i - end_time.to_i).abs
236
303
  end
@@ -258,5 +325,13 @@ module AddToCalendar
258
325
  end
259
326
  }.join("\\n")
260
327
  end
328
+
329
+ def yahoo_param(key)
330
+ if key == :in_loc
331
+ key.to_s
332
+ else
333
+ key.to_s.upcase
334
+ end
335
+ end
261
336
  end
262
- end
337
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: add_to_calendar
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jared Turner
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-07-02 00:00:00.000000000 Z
11
+ date: 2023-10-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tzinfo
@@ -92,14 +92,28 @@ dependencies:
92
92
  requirements:
93
93
  - - "~>"
94
94
  - !ruby/object:Gem::Version
95
- version: 0.13.1
95
+ version: '0.14'
96
96
  type: :development
97
97
  prerelease: false
98
98
  version_requirements: !ruby/object:Gem::Requirement
99
99
  requirements:
100
100
  - - "~>"
101
101
  - !ruby/object:Gem::Version
102
- version: 0.13.1
102
+ version: '0.14'
103
+ - !ruby/object:Gem::Dependency
104
+ name: timecop
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '0.9'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: '0.9'
103
117
  description:
104
118
  email:
105
119
  - jaredlt01@gmail.com
@@ -142,7 +156,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
142
156
  - !ruby/object:Gem::Version
143
157
  version: '0'
144
158
  requirements: []
145
- rubygems_version: 3.0.6
159
+ rubygems_version: 3.2.32
146
160
  signing_key:
147
161
  specification_version: 4
148
162
  summary: Generate 'Add To Calendar' URLs for Android, Apple, Google, Office 365, Outlook,