calendar_subscriptions.rb 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. require 'icalendar/tzinfo'
  3. class CalendarSubscriptions
  4. def initialize(user)
  5. @user = user
  6. @time_zone = Setting.get('timezone_default')
  7. @preferences = Service::User::CalendarSubscription::Preferences.new(@user).execute
  8. end
  9. def all
  10. to_ical @preferences
  11. .keys
  12. .map { |object_name| generic_call(object_name) }
  13. .flatten
  14. end
  15. def generic(object_name, method_name = 'all')
  16. to_ical generic_call(object_name, method_name)
  17. end
  18. def generic_call(object_name, method_name = 'all')
  19. return [] if @preferences[ object_name ].blank?
  20. sub_class_name = object_name.to_s.capitalize
  21. object = "CalendarSubscriptions::#{sub_class_name}".constantize
  22. instance = object.new(@user, @preferences[ object_name ], @time_zone)
  23. raise Exceptions::UnprocessableEntity, __('An unknown method name was requested.') if object::ALLOWED_METHODS.exclude?(method_name)
  24. instance.send(method_name)
  25. end
  26. def to_ical(events_data)
  27. cal = Icalendar::Calendar.new
  28. tz = ActiveSupport::TimeZone.find_tzinfo(@time_zone)
  29. # https://github.com/zammad/zammad/issues/3989
  30. # https://datatracker.ietf.org/doc/html/rfc5545#section-3.2.19
  31. if events_data.any?
  32. cal.add_timezone tz.ical_timezone(DateTime.parse(events_data.first[:dtstart].to_s))
  33. end
  34. events_data.each do |event_data|
  35. cal.event do |e|
  36. dtstart = DateTime.parse(event_data[:dtstart].to_s)
  37. dtend = DateTime.parse(event_data[:dtend].to_s)
  38. # by design all new/open ticket events are scheduled at midnight:
  39. # skip adding TZ offset
  40. if event_data[:type] != 'new_open'
  41. dtstart = tz.utc_to_local(dtstart)
  42. dtend = tz.utc_to_local(dtend)
  43. end
  44. e.dtstart = Icalendar::Values::DateTime.new(dtstart, 'tzid' => @time_zone)
  45. e.dtend = Icalendar::Values::DateTime.new(dtend, 'tzid' => @time_zone)
  46. if event_data[:alarm]
  47. e.alarm do |a|
  48. a.action = 'DISPLAY'
  49. a.summary = event_data[:alarm][:summary]
  50. a.trigger = event_data[:alarm][:trigger]
  51. end
  52. end
  53. e.summary = event_data[:summary]
  54. e.description = event_data[:description]
  55. e.ip_class = 'PRIVATE'
  56. end
  57. end
  58. cal.to_ical
  59. end
  60. end