Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Hey Calendar URL #52

Merged
merged 1 commit into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ Or install it yourself as:
@cal.yahoo_url
#=> "https://calendar.yahoo.com/?v=60&view=d&type=20&title=Christmas%20party%21&st=20201212T133000Z&dur=0100"

@cal.hey_url
#=> "https://app.hey.com/calendar/ical_events/new?ical_source=BEGIN%3AVCALENDAR%0AVERSION%3A2.0%0APRODID%3A-//AddToCalendar//RubyGem//EN%0ABEGIN%3AVEVENT%0ASUMMARY%3AHolly%27s%209th%20birthday%21%0ADTSTAMP%3A20240913T151029Z%0ADTSTART%3A20240906T123000Z%0ADTEND%3A20240906T133000Z%0AUID%3A-20240906T123000Z-Holly%27s%209th%20birthday%21%0AEND%3AVEVENT%0AEND%3AVCALENDAR"

@cal.office365_url
#=> "https://outlook.office.com/calendar/0/deeplink/compose?path=/calendar/action/compose&rru=addevent&subject=Christmas%20party%21&startdt=2020-12-12T13:30:00Z&enddt=2020-12-12T14:30:00Z"

Expand Down
64 changes: 64 additions & 0 deletions lib/add_to_calendar.rb
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,59 @@ def yahoo_url
return calendar_url
end

def hey_url
calendar_url = "https://app.hey.com/calendar/ical_events/new?ical_source=BEGIN%3AVCALENDAR%0AVERSION%3A2.0%0APRODID%3A-//AddToCalendar//RubyGem//EN%0ABEGIN%3AVEVENT"

params = {}
params[:SUMMARY] = url_encode(title)
params[:DTSTAMP] = Time.now.strftime("%Y%m%dT%H%M%SZ")

if all_day
one_day = 1 * 24 * 60 * 60
params["DTSTART%3BVALUE=DATE"] = format_date(start_datetime)
if end_datetime
params["DTEND%3BVALUE=DATE"] = format_date(end_datetime + one_day)
else
params["DTEND%3BVALUE=DATE"] = format_date(start_datetime + one_day)
end
else
params[:DTSTART] = utc_datetime(start_datetime)
if end_datetime
params[:DTEND] = utc_datetime(end_datetime)
else
params[:DTEND] = utc_datetime(start_datetime + 60*60) # 1 hour later
end
end

params[:URL] = url_encode(url) if url
params[:UID] = "-#{utc_datetime(start_datetime)}-#{url_encode(title)}"
params[:DESCRIPTION] = url_encode_hey(description) if description
if add_url_to_description && url
if params[:DESCRIPTION]
params[:DESCRIPTION] << "\n\n#{url_encode(url)}"
else
params[:DESCRIPTION] = url_encode(url)
end
end
if organizer
params[:ORGANIZER] = url_encode("CN=\"#{organizer[:name]}\"%3Amailto%3A#{organizer[:email]}")
end
params[:LOCATION] = url_encode(location) if location

new_line = "%0A"
params.each do |key, value|
if key == :ORGANIZER
calendar_url << "#{new_line}#{key}%3B#{value}"
else
calendar_url << "#{new_line}#{key}%3A#{value}"
end
end

calendar_url << "%0AEND%3AVEVENT%0AEND%3AVCALENDAR"

return calendar_url
end

def office365_url
# Eg. https://outlook.live.com/calendar/0/deeplink/compose?path=/calendar/action/compose&rru=addevent&subject=Holly%27s%208th%20Birthday%21&startdt=2020-05-12T12:30:00Z&enddt=2020-05-12T16:00:00Z&body=Come%20join%20us%20for%20lots%20of%20fun%20%26%20cake%21%0A%0Ahttps%3A%2F%2Fwww.example.com%2Fevent-details&location=Flat%204%2C%20The%20Edge%2C%2038%20Smith-Dorrien%20St%2C%20London%2C%20N1%207GU
microsoft("office365")
Expand Down Expand Up @@ -326,6 +379,17 @@ def url_encode_ical(s)
}.join("\\n")
end

def url_encode_hey(s)
string = s.dup # don't modify original input
string.split("\n").map { |e|
if e.empty?
e
else
url_encode(e)
end
}.join("\n")
end

def yahoo_param(key)
if key == :in_loc
key.to_s
Expand Down
68 changes: 68 additions & 0 deletions test/support/assertions/hey_url_assertions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
require 'uri'
require 'cgi'

module Minitest::Assertions
def assert_hey_urls_equal(expected, actual, msg = nil)
differences = compare_hey_urls(expected, actual)

if differences.empty?
assert true # URLs are identical
else
failure_message = build_failure_message(differences)
msg = message(msg) { failure_message }
assert false, msg
end
end

private

def decode_ical_source(url)
uri = URI(url)
CGI.unescape(URI.decode_www_form(uri.query).to_h['ical_source']).split("\n")
end

def compare_hey_urls(url1, url2)
ical1 = decode_ical_source(url1)
ical2 = decode_ical_source(url2)

differences = []

# Compare each line of the decoded ical_source
ical1.zip(ical2).each_with_index do |(line1, line2), index|
if line1 != line2
differences << {
line_number: index + 1,
expected_line: line2,
actual_line: line1
}
end
end

# Handle case where one ical_source is longer than the other
if ical1.length != ical2.length
start = [ical1.length, ical2.length].min
longer = ical1.length > ical2.length ? ical1 : ical2
longer_label = ical1.length > ical2.length ? 'actual' : 'expected'

longer[start..-1].each_with_index do |line, i|
differences << {
line_number: start + i + 1,
"#{longer_label}_line": line,
"#{longer_label == 'actual' ? 'expected_line' : 'actual_line'}": nil
}
end
end

differences
end

def build_failure_message(differences)
message = "Hey URLs do not match. Differences found:\n"
differences.each do |diff|
message << "Line #{diff[:line_number]}:\n"
message << " Expected: #{diff[:expected_line]}\n"
message << " Actual: #{diff[:actual_line]}\n\n"
end
message
end
end
2 changes: 2 additions & 0 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@
require "minitest/autorun"
require "timecop"
require "pry"

Dir[File.expand_path('support/**/*.rb', __dir__)].each { |file| require file }
Loading
Loading