add_to_calendar 0.2.0 → 0.2.5

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: b1fba2b9dfdd72ba02d3d29413d1035c6f726569610e18227802cfd85f11e7af
4
- data.tar.gz: ab89af6a02c276049dbbcac88fca397e37c3305084836a5e8467629064d414f2
3
+ metadata.gz: 24986348b563ba6eee3ee7c510092434f8e24d76c1ddd402484e31951cbb94f0
4
+ data.tar.gz: eda31a7a266b15e4b82db84ed250a2da999b0f5efe6fc565b75c8e7ea3286a57
5
5
  SHA512:
6
- metadata.gz: ddc95426b93e001ea114f67b587b721ddea084d2f7607316181ee8c56e002a5c881ae10653d0a4ba9f4fdfee57c918f92e3d3320f54e4cbf9a9bf79faea59b8d
7
- data.tar.gz: 4b0015473216a8da08b990ee5e290e80e8e2b8b873971a2197c84da30aaa1489d6878a10c03ed5efbffa5f719148b60434ca99dbeee1eee6cdbd3fccdf3a3a03
6
+ metadata.gz: 4da59f54a6a6099646425189a66481e0450e6ac9cd6ea56806c455e74fcddd1f0055150a9951db600821a7c854593f23a049879eb85c972b1677205463397af9
7
+ data.tar.gz: 3d3eef19ecd6bf9f56440253c2f1cbf9d3ea090ea16e83d067191ecc61ac2fdabd49a20398adc206498a451a36355287ff06e8a726b89b416cbe45888418b3dc
@@ -1,9 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- add_to_calendar (0.2.0)
5
- tzinfo (~> 2.0.2)
6
- tzinfo-data (~> 1.2020.1)
4
+ add_to_calendar (0.2.5)
5
+ tzinfo (>= 1.1, < 3)
6
+ tzinfo-data (~> 1.2020)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # AddToCalendar
2
2
 
3
- A ruby gem to generate 'Add To Calendar' URLs for Apple, Google, Office 365, Outlook, Outlook.com and Yahoo calendars.
3
+ A ruby gem to generate 'Add To Calendar' URLs for Android, Apple, Google, Office 365, Outlook, Outlook.com and Yahoo calendars.
4
4
 
5
5
  If this gem brings you some value feel free to buy me a coffee :) [![ko-fi](https://www.ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/P5P71PK9T)
6
6
 
@@ -50,14 +50,9 @@ Or install it yourself as:
50
50
 
51
51
  # ical provides a data-uri which will download a properly formatted *.ics file (see 'Creating HTML links' section)
52
52
  @cal.ical_url
53
- #=> "data:text/calendar;charset=utf8,BEGIN:VCALENDAR%0AVERSION:2.0%0ABEGIN:VEVENT%0ADTSTART=20201212T133000Z%0ADTEND=20201212T143000Z%0ASUMMARY=Christmas%20party%21%0AUID=-20201212T133000Z-Christmas%20party%21%0AEND:VEVENT%0AEND:VCALENDAR"
53
+ #=> "data:text/calendar;charset=utf8,BEGIN:VCALENDAR%0AVERSION:2.0%0ABEGIN:VEVENT%0ADTSTART:20201212T133000Z%0ADTEND:20201212T143000Z%0ASUMMARY:Christmas%20party%21%0AUID:-20201212T133000Z-Christmas%20party%21%0AEND:VEVENT%0AEND:VCALENDAR"
54
54
 
55
- # apple_url and outlook_url are simply helper methods that call ical_url
56
- @cal.apple_url
57
- #=> "data:text/calendar;charset=utf8,BEGIN:VCALENDAR%0AVERSION:2.0%0ABEGIN:VEVENT%0ADTSTART=20201212T133000Z%0ADTEND=20201212T143000Z%0ASUMMARY=Christmas%20party%21%0AUID=-20201212T133000Z-Christmas%20party%21%0AEND:VEVENT%0AEND:VCALENDAR"
58
-
59
- @cal.outlook_url
60
- #=> "data:text/calendar;charset=utf8,BEGIN:VCALENDAR%0AVERSION:2.0%0ABEGIN:VEVENT%0ADTSTART=20201212T133000Z%0ADTEND=20201212T143000Z%0ASUMMARY=Christmas%20party%21%0AUID=-20201212T133000Z-Christmas%20party%21%0AEND:VEVENT%0AEND:VCALENDAR"
55
+ # android_url, apple_url and outlook_url are simply helper methods that call ical_url and return the same string.
61
56
  ```
62
57
 
63
58
  ### Creating HTML links
@@ -68,7 +63,7 @@ Or install it yourself as:
68
63
 
69
64
  <a href="<%= @cal.yahoo_url %>">Add to Yahoo Calendar</a>
70
65
 
71
- <!-- for ical_url, apple_url and outlook_url you can set the filename like so -->
66
+ <!-- for ical_url, android_url, apple_url and outlook_url you can set the filename like so -->
72
67
  <a download="calendar-event.ics" href="<%= @cal.ical_url %>">Download iCal</a>
73
68
  ```
74
69
 
@@ -104,11 +99,13 @@ cal = AddToCalendar::URLs.new(event_attributes)
104
99
 
105
100
  - Offset values eg. "2020-05-13 15:31:00 **+05:00**" are ignored. It is only important that you have the correct date and time numbers set. The timezone is set directly using its own attribute `timezone`.
106
101
  - You must set a timezone so that when users add the event to their calendar it shows at their correct local time.
107
- - Eg. London event @ `2020-05-13 13:30:00` will save in a New Yorkers calendar as local time `2020-05-13 17:30:00`
102
+ - Eg. London event @ `2020-05-13 13:30:00` will save in a New Yorker's calendar as local time `2020-05-13 17:30:00`
108
103
 
109
104
  ### Browser support
110
105
 
111
- - IE11 and lower will not work for `ical_url`, `apple_url` and `outlook_url` (IE does not properly support [data-uri links](https://caniuse.com/#feat=datauri). See [#16](https://github.com/jaredlt/add_to_calendar/issues/16)).
106
+ - IE11 and lower will not work for `ical_url`, `apple_url` and `outlook_url` (IE does not properly support [data-uri links](https://caniuse.com/#feat=datauri). See [#16](https://github.com/jaredlt/add_to_calendar/issues/16)).
107
+ - IE11 will also not work with `Yahoo`, but this is because Yahoo is deprecating IE 11 support and only offers a simplified interface which does not work with the add event URL.
108
+ - `Office 365` and `Outlook.com` do not work on mobile. This seems to be an issue on Microsoft's side. Their mobile web interface does not support the 'create event' URLs and the links do not open the apps if you have them installed.
112
109
 
113
110
  ### More details
114
111
 
@@ -118,6 +115,10 @@ cal = AddToCalendar::URLs.new(event_attributes)
118
115
 
119
116
  I couldn't find an approriate gem or javascript library that did exactly what I wanted. So I decided to scratch my own itch to solve a problem for a startup I'm working on: https://www.littlefutures.org
120
117
 
118
+ ## Releases
119
+
120
+ - https://rubygems.org/gems/add_to_calendar
121
+
121
122
  ## Development
122
123
 
123
124
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
8
8
  spec.authors = ["Jared Turner"]
9
9
  spec.email = ["jaredlt01@gmail.com"]
10
10
 
11
- spec.summary = "Generate 'Add To Calendar' URLs for Google, Apple, Office 365, Outlook, Yahoo calendars"
11
+ spec.summary = "Generate 'Add To Calendar' URLs for Android, Apple, Google, Office 365, Outlook, Outlook.com and Yahoo calendars"
12
12
  # spec.description = %q{TODO: Write a longer description or delete this line.}
13
13
  spec.homepage = "https://github.com/jaredlt/add_to_calendar"
14
14
  spec.license = "MIT"
@@ -28,8 +28,8 @@ Gem::Specification.new do |spec|
28
28
 
29
29
  spec.required_ruby_version = '>= 2.0'
30
30
 
31
- spec.add_dependency "tzinfo", "~> 2.0.2"
32
- spec.add_dependency "tzinfo-data", "~> 1.2020.1"
31
+ spec.add_dependency "tzinfo", ">= 1.1", "< 3"
32
+ spec.add_dependency "tzinfo-data", "~> 1.2020"
33
33
 
34
34
  spec.add_development_dependency "bundler", "~> 2.0"
35
35
  spec.add_development_dependency "rake", "~> 13.0.1"
@@ -95,8 +95,8 @@ module AddToCalendar
95
95
  end
96
96
 
97
97
  def ical_url
98
- # Downloads a *.ics file provided as a data:text href
99
- # Eg. data:text/calendar;charset=utf8,BEGIN:VCALENDAR%0AVERSION:2.0%0ABEGIN:VEVENT%0ADTSTART=20200610T123000Z%0ADTEND=20200610T133000Z%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%2C%20The%20Edge%2C%2038%20Smith-Dorrien%20St%2C%20London%2C%20N1%207GU%0AUID=-https%3A%2F%2Fwww.example.com%2Fevent-details%0AEND:VEVENT%0AEND:VCALENDAR
98
+ # Downloads a *.ics file provided as a data-uri
99
+ # 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
100
  calendar_url = "data:text/calendar;charset=utf8,BEGIN:VCALENDAR%0AVERSION:2.0%0ABEGIN:VEVENT"
101
101
  params = {}
102
102
  params[:DTSTART] = utc_datetime(start_datetime)
@@ -105,23 +105,23 @@ module AddToCalendar
105
105
  else
106
106
  params[:DTEND] = utc_datetime(start_datetime + 60*60) # 1 hour later
107
107
  end
108
- params[:SUMMARY] = url_encode(title)
108
+ params[:SUMMARY] = url_encode_ical(title)
109
109
  params[:URL] = url_encode(url) if url
110
- params[:DESCRIPTION] = url_encode(description) if description
110
+ params[:DESCRIPTION] = url_encode_ical(description) if description
111
111
  if add_url_to_description && url
112
112
  if params[:DESCRIPTION]
113
- params[:DESCRIPTION] << "\n\n#{url_encode(url)}"
113
+ params[:DESCRIPTION] << "\\n\\n#{url_encode(url)}"
114
114
  else
115
115
  params[:DESCRIPTION] = url_encode(url)
116
116
  end
117
117
  end
118
- params[:LOCATION] = url_encode(location) if location
118
+ params[:LOCATION] = url_encode_ical(location) if location
119
119
  params[:UID] = "-#{url_encode(url)}" if url
120
- params[:UID] = "-#{utc_datetime(start_datetime)}-#{url_encode(title)}" unless params[:UID] # set uid based on starttime and title only if url is unavailable
121
-
120
+ params[:UID] = "-#{utc_datetime(start_datetime)}-#{url_encode_ical(title)}" unless params[:UID] # set uid based on starttime and title only if url is unavailable
121
+
122
122
  new_line = "%0A"
123
123
  params.each do |key, value|
124
- calendar_url << "#{new_line}#{key}=#{value}"
124
+ calendar_url << "#{new_line}#{key}:#{value}"
125
125
  end
126
126
 
127
127
  calendar_url << "%0AEND:VEVENT%0AEND:VCALENDAR"
@@ -136,6 +136,10 @@ module AddToCalendar
136
136
  def outlook_url
137
137
  ical_url
138
138
  end
139
+
140
+ def android_url
141
+ ical_url
142
+ end
139
143
 
140
144
  private
141
145
  def validate_attributes
@@ -169,17 +173,17 @@ module AddToCalendar
169
173
  raise MicrosoftServiceError, ":service must be 'outlook.com' or 'office365'. '#{service}' given"
170
174
  end
171
175
  params = {}
172
- params[:subject] = url_encode(title)
176
+ params[:subject] = url_encode(title.gsub(' & ', ' and '))
173
177
  params[:startdt] = utc_datetime_microsoft(start_datetime)
174
178
  if end_datetime
175
179
  params[:enddt] = utc_datetime_microsoft(end_datetime)
176
180
  else
177
181
  params[:enddt] = utc_datetime_microsoft(start_datetime + 60*60) # 1 hour later
178
182
  end
179
- params[:body] = url_encode(description) if description
183
+ params[:body] = url_encode(newlines_to_html_br(description)) if description
180
184
  if add_url_to_description && url
181
185
  if params[:body]
182
- params[:body] << url_encode("\n\n#{url}")
186
+ params[:body] << url_encode(newlines_to_html_br("\n\n#{url}"))
183
187
  else
184
188
  params[:body] = url_encode(url)
185
189
  end
@@ -194,27 +198,31 @@ module AddToCalendar
194
198
  end
195
199
 
196
200
  def utc_datetime(datetime)
197
- t = timezone.local_time(
198
- datetime.strftime("%Y").to_i,
199
- datetime.strftime("%m").to_i,
200
- datetime.strftime("%d").to_i,
201
- datetime.strftime("%H").to_i,
202
- datetime.strftime("%M").to_i,
203
- datetime.strftime("%S").to_i
204
- ).utc
201
+ t = timezone.local_to_utc(
202
+ Time.new(
203
+ datetime.strftime("%Y").to_i,
204
+ datetime.strftime("%m").to_i,
205
+ datetime.strftime("%d").to_i,
206
+ datetime.strftime("%H").to_i,
207
+ datetime.strftime("%M").to_i,
208
+ datetime.strftime("%S").to_i
209
+ )
210
+ )
205
211
 
206
212
  return t.strftime('%Y%m%dT%H%M%SZ')
207
213
  end
208
214
 
209
215
  def utc_datetime_microsoft(datetime)
210
- t = timezone.local_time(
211
- datetime.strftime("%Y").to_i,
212
- datetime.strftime("%m").to_i,
213
- datetime.strftime("%d").to_i,
214
- datetime.strftime("%H").to_i,
215
- datetime.strftime("%M").to_i,
216
- datetime.strftime("%S").to_i
217
- ).utc
216
+ t = timezone.local_to_utc(
217
+ Time.new(
218
+ datetime.strftime("%Y").to_i,
219
+ datetime.strftime("%m").to_i,
220
+ datetime.strftime("%d").to_i,
221
+ datetime.strftime("%H").to_i,
222
+ datetime.strftime("%M").to_i,
223
+ datetime.strftime("%S").to_i
224
+ )
225
+ )
218
226
 
219
227
  return t.strftime('%Y-%m-%dT%H:%M:%SZ')
220
228
  end
@@ -230,5 +238,25 @@ module AddToCalendar
230
238
  def seconds_to_hours_minutes(sec)
231
239
  "%02d%02d" % [sec / 3600, sec / 60 % 60]
232
240
  end
241
+
242
+ def newlines_to_html_br(string)
243
+ string.gsub(/(?:\n\r?|\r\n?)/, '<br>')
244
+ end
245
+
246
+ def url_encode_ical(s)
247
+ # per https://tools.ietf.org/html/rfc5545#section-3.3.11
248
+ string = s.dup # don't modify original input
249
+ string.gsub!("\\", "\\\\\\") # \ >> \\ --yes, really: https://stackoverflow.com/questions/6209480/how-to-replace-backslash-with-double-backslash
250
+ string.gsub!(",", "\\,")
251
+ string.gsub!(";", "\\;")
252
+ string.gsub!("\r\n", "\n") # so can handle all newlines the same
253
+ string.split("\n").map { |e|
254
+ if e.empty?
255
+ e
256
+ else
257
+ url_encode(e)
258
+ end
259
+ }.join("\\n")
260
+ end
233
261
  end
234
262
  end
@@ -1,3 +1,3 @@
1
1
  module AddToCalendar
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.5"
3
3
  end
metadata CHANGED
@@ -1,43 +1,49 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: add_to_calendar
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.5
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-06-08 00:00:00.000000000 Z
11
+ date: 2020-07-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tzinfo
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '1.1'
20
+ - - "<"
18
21
  - !ruby/object:Gem::Version
19
- version: 2.0.2
22
+ version: '3'
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '1.1'
30
+ - - "<"
25
31
  - !ruby/object:Gem::Version
26
- version: 2.0.2
32
+ version: '3'
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: tzinfo-data
29
35
  requirement: !ruby/object:Gem::Requirement
30
36
  requirements:
31
37
  - - "~>"
32
38
  - !ruby/object:Gem::Version
33
- version: 1.2020.1
39
+ version: '1.2020'
34
40
  type: :runtime
35
41
  prerelease: false
36
42
  version_requirements: !ruby/object:Gem::Requirement
37
43
  requirements:
38
44
  - - "~>"
39
45
  - !ruby/object:Gem::Version
40
- version: 1.2020.1
46
+ version: '1.2020'
41
47
  - !ruby/object:Gem::Dependency
42
48
  name: bundler
43
49
  requirement: !ruby/object:Gem::Requirement
@@ -139,6 +145,6 @@ requirements: []
139
145
  rubygems_version: 3.0.6
140
146
  signing_key:
141
147
  specification_version: 4
142
- summary: Generate 'Add To Calendar' URLs for Google, Apple, Office 365, Outlook, Yahoo
143
- calendars
148
+ summary: Generate 'Add To Calendar' URLs for Android, Apple, Google, Office 365, Outlook,
149
+ Outlook.com and Yahoo calendars
144
150
  test_files: []