add_to_calendar 0.2.4 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +5 -3
- data/README.md +10 -12
- data/add_to_calendar.gemspec +2 -1
- data/lib/add_to_calendar/version.rb +1 -1
- data/lib/add_to_calendar.rb +93 -27
- metadata +19 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3067d7dd6fcf157682aa1e25172ad8fd591262168b42f7a453712c5d7483b36d
|
4
|
+
data.tar.gz: 8152eee8b227acecaf7e7abba6625b7a785e18f2cd786f2f56b777179d9b1647
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b5c7a1dc4e614fcd1d1d819ee788f29689a815f0b944429423586f71b1b4841ea6377eab52400b8a8c507daf84280f99171fa04d1c98f583145ddd249e40eb0e
|
7
|
+
data.tar.gz: 1f2419f32a56d07bcfd9d632a700aae5f89d79cf87a4255fd8ddeb5e302cd809b2c17b166efb33e31f267137f81ba3e15c91804ff80ab5e0fdb99f6fa3f31ddd
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
add_to_calendar (0.
|
4
|
+
add_to_calendar (0.3.0)
|
5
5
|
tzinfo (>= 1.1, < 3)
|
6
6
|
tzinfo-data (~> 1.2020)
|
7
7
|
|
@@ -11,11 +11,12 @@ GEM
|
|
11
11
|
coderay (1.1.2)
|
12
12
|
concurrent-ruby (1.1.6)
|
13
13
|
method_source (1.0.0)
|
14
|
-
minitest (5.
|
14
|
+
minitest (5.18.0)
|
15
15
|
pry (0.13.1)
|
16
16
|
coderay (~> 1.1)
|
17
17
|
method_source (~> 1.0)
|
18
18
|
rake (13.0.1)
|
19
|
+
timecop (0.9.6)
|
19
20
|
tzinfo (2.0.2)
|
20
21
|
concurrent-ruby (~> 1.0)
|
21
22
|
tzinfo-data (1.2020.1)
|
@@ -30,6 +31,7 @@ DEPENDENCIES
|
|
30
31
|
minitest (~> 5.0)
|
31
32
|
pry (~> 0.13.1)
|
32
33
|
rake (~> 13.0.1)
|
34
|
+
timecop (~> 0.9)
|
33
35
|
|
34
36
|
BUNDLED WITH
|
35
|
-
2.
|
37
|
+
2.4.12
|
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
|
|
@@ -52,12 +52,7 @@ Or install it yourself as:
|
|
52
52
|
@cal.ical_url
|
53
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
|
|
@@ -83,10 +78,11 @@ event_attributes = {
|
|
83
78
|
location: "20 W 34th St, New York, NY 10001",
|
84
79
|
url: "https://www.ruby-lang.org/en/",
|
85
80
|
description: "Join us to learn all about Ruby.",
|
86
|
-
add_url_to_description: true # defaults to true
|
81
|
+
add_url_to_description: true # defaults to true,
|
82
|
+
all_day: true # defaults to false
|
87
83
|
}
|
88
84
|
|
89
|
-
cal = AddToCalendar::URLs.new(event_attributes)
|
85
|
+
cal = AddToCalendar::URLs.new(**event_attributes)
|
90
86
|
```
|
91
87
|
|
92
88
|
| Attribute | Required? | Class | Notes |
|
@@ -98,7 +94,8 @@ cal = AddToCalendar::URLs.new(event_attributes)
|
|
98
94
|
| location | No | String | |
|
99
95
|
| 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`) |
|
100
96
|
| description | No | String | Accepts newlines by passing `\n` Eg. `"Join us for fun & drinks\n\nPS. Smart casual"` |
|
101
|
-
| add_url_to_description | No | true/false |
|
97
|
+
| 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 |
|
98
|
+
| 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> |
|
102
99
|
|
103
100
|
### Timezones and offsets
|
104
101
|
|
@@ -109,7 +106,8 @@ cal = AddToCalendar::URLs.new(event_attributes)
|
|
109
106
|
### Browser support
|
110
107
|
|
111
108
|
- 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)).
|
112
|
-
- IE11 will also not work with `Yahoo`, but this is because Yahoo only offers a simplified interface
|
109
|
+
- 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.
|
110
|
+
- `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.
|
113
111
|
|
114
112
|
### More details
|
115
113
|
|
data/add_to_calendar.gemspec
CHANGED
@@ -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 Apple, Google, Office 365, Outlook, Outlook.com and 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"
|
@@ -35,4 +35,5 @@ Gem::Specification.new do |spec|
|
|
35
35
|
spec.add_development_dependency "rake", "~> 13.0.1"
|
36
36
|
spec.add_development_dependency "minitest", "~> 5.0"
|
37
37
|
spec.add_development_dependency "pry", "~> 0.13.1"
|
38
|
+
spec.add_development_dependency "timecop", "~> 0.9"
|
38
39
|
end
|
data/lib/add_to_calendar.rb
CHANGED
@@ -13,8 +13,8 @@ module AddToCalendar
|
|
13
13
|
class Error < StandardError; end
|
14
14
|
|
15
15
|
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)
|
16
|
+
attr_accessor :start_datetime, :end_datetime, :title, :timezone, :location, :url, :description, :add_url_to_description, :all_day
|
17
|
+
def initialize(start_datetime:, end_datetime: nil, title:, timezone:, location: nil, url: nil, description: nil, add_url_to_description: true, all_day: false)
|
18
18
|
@start_datetime = start_datetime
|
19
19
|
@end_datetime = end_datetime
|
20
20
|
@title = title
|
@@ -23,6 +23,7 @@ module AddToCalendar
|
|
23
23
|
@url = url
|
24
24
|
@description = description
|
25
25
|
@add_url_to_description = add_url_to_description
|
26
|
+
@all_day = all_day
|
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
|
-
|
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&
|
60
|
-
calendar_url = "https://calendar.yahoo.com/?v=60
|
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
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
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[:
|
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,13 +105,25 @@ 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[:
|
103
|
-
if
|
104
|
-
|
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[:
|
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)
|
109
129
|
params[:URL] = url_encode(url) if url
|
@@ -136,6 +156,10 @@ module AddToCalendar
|
|
136
156
|
def outlook_url
|
137
157
|
ical_url
|
138
158
|
end
|
159
|
+
|
160
|
+
def android_url
|
161
|
+
ical_url
|
162
|
+
end
|
139
163
|
|
140
164
|
private
|
141
165
|
def validate_attributes
|
@@ -169,12 +193,23 @@ module AddToCalendar
|
|
169
193
|
raise MicrosoftServiceError, ":service must be 'outlook.com' or 'office365'. '#{service}' given"
|
170
194
|
end
|
171
195
|
params = {}
|
172
|
-
params[:subject] = url_encode(title)
|
173
|
-
|
174
|
-
|
175
|
-
params[:
|
196
|
+
params[:subject] = url_encode(title.gsub(' & ', ' and '))
|
197
|
+
if all_day
|
198
|
+
one_day = 1 * 24 * 60 * 60
|
199
|
+
params[:startdt] = microsoft_date(start_datetime)
|
200
|
+
if end_datetime
|
201
|
+
params[:enddt] = microsoft_date(end_datetime + one_day)
|
202
|
+
else
|
203
|
+
params[:enddt] = microsoft_date(start_datetime + one_day)
|
204
|
+
end
|
205
|
+
params[:allday] = "true"
|
176
206
|
else
|
177
|
-
params[:
|
207
|
+
params[:startdt] = utc_datetime_microsoft(start_datetime)
|
208
|
+
if end_datetime
|
209
|
+
params[:enddt] = utc_datetime_microsoft(end_datetime)
|
210
|
+
else
|
211
|
+
params[:enddt] = utc_datetime_microsoft(start_datetime + 60*60) # 1 hour later
|
212
|
+
end
|
178
213
|
end
|
179
214
|
params[:body] = url_encode(newlines_to_html_br(description)) if description
|
180
215
|
if add_url_to_description && url
|
@@ -222,11 +257,34 @@ module AddToCalendar
|
|
222
257
|
|
223
258
|
return t.strftime('%Y-%m-%dT%H:%M:%SZ')
|
224
259
|
end
|
260
|
+
|
261
|
+
def microsoft_date(date)
|
262
|
+
date.strftime('%Y-%m-%d')
|
263
|
+
end
|
264
|
+
|
265
|
+
def google_dates(start_datetime, end_datetime, all_day)
|
266
|
+
one_day = 1 * 24 * 60 * 60
|
267
|
+
if all_day
|
268
|
+
if end_datetime
|
269
|
+
"#{format_date(start_datetime)}/#{format_date(end_datetime + one_day)}"
|
270
|
+
else
|
271
|
+
"#{format_date(start_datetime)}/#{format_date(start_datetime + one_day)}"
|
272
|
+
end
|
273
|
+
elsif end_datetime
|
274
|
+
"#{format_datetime_google(start_datetime)}/#{format_datetime_google(end_datetime)}"
|
275
|
+
else
|
276
|
+
"#{format_datetime_google(start_datetime)}/#{format_datetime_google(start_datetime + 60*60)}" # end time is 1 hour later
|
277
|
+
end
|
278
|
+
end
|
225
279
|
|
226
|
-
def
|
280
|
+
def format_datetime_google(start_datetime)
|
227
281
|
start_datetime.strftime('%Y%m%dT%H%M%S')
|
228
282
|
end
|
229
283
|
|
284
|
+
def format_date(date)
|
285
|
+
date.strftime('%Y%m%d')
|
286
|
+
end
|
287
|
+
|
230
288
|
def duration_seconds(start_time, end_time)
|
231
289
|
(start_time.to_i - end_time.to_i).abs
|
232
290
|
end
|
@@ -254,5 +312,13 @@ module AddToCalendar
|
|
254
312
|
end
|
255
313
|
}.join("\\n")
|
256
314
|
end
|
315
|
+
|
316
|
+
def yahoo_param(key)
|
317
|
+
if key == :in_loc
|
318
|
+
key.to_s
|
319
|
+
else
|
320
|
+
key.to_s.upcase
|
321
|
+
end
|
322
|
+
end
|
257
323
|
end
|
258
|
-
end
|
324
|
+
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.
|
4
|
+
version: 0.3.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:
|
11
|
+
date: 2023-05-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: tzinfo
|
@@ -100,6 +100,20 @@ dependencies:
|
|
100
100
|
- - "~>"
|
101
101
|
- !ruby/object:Gem::Version
|
102
102
|
version: 0.13.1
|
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,9 +156,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
142
156
|
- !ruby/object:Gem::Version
|
143
157
|
version: '0'
|
144
158
|
requirements: []
|
145
|
-
rubygems_version: 3.
|
159
|
+
rubygems_version: 3.3.26
|
146
160
|
signing_key:
|
147
161
|
specification_version: 4
|
148
|
-
summary: Generate 'Add To Calendar' URLs for Apple, Google, Office 365, Outlook,
|
149
|
-
and Yahoo calendars
|
162
|
+
summary: Generate 'Add To Calendar' URLs for Android, Apple, Google, Office 365, Outlook,
|
163
|
+
Outlook.com and Yahoo calendars
|
150
164
|
test_files: []
|