Class: Code::Object::Ics
Constant Summary collapse
- CLASS_DOCUMENTATION =
{ name: "Ics", description: "parses icalendar text and exposes events as dictionaries.", examples: [ "Ics.parse(\"BEGIN:VCALENDAR\\nBEGIN:VEVENT\\nSUMMARY:meet\\nEND:VEVENT\\nEND:VCALENDAR\")", "Ics.parse(\"BEGIN:VCALENDAR\\nVERSION:2.0\\nEND:VCALENDAR\")", "Ics.parse(\"\")" ] }.freeze
- CLASS_FUNCTIONS =
{ "parse" => { name: "parse", description: "returns event dictionaries parsed from icalendar text.", examples: [ "Ics.parse(\"BEGIN:VCALENDAR\\nBEGIN:VEVENT\\nUID:1\\nSUMMARY:demo\\nEND:VEVENT\\nEND:VCALENDAR\")", "Ics.parse(\"BEGIN:VCALENDAR\\nEND:VCALENDAR\")", "Ics.parse(\"not calendar data\")" ] } }.freeze
- EVENT_ATTRIBUTES =
%i[ uid summary description location url status organizer categories attendees geo ].freeze
- MISSING_ATTRIBUTE =
Object.new.freeze
Class Method Summary collapse
- .call(**args) ⇒ Object
- .code_parse(value) ⇒ Object
- .event_attribute(event, attribute) ⇒ Object
- .function_documentation(scope) ⇒ Object
- .normalize_string(value) ⇒ Object
- .scalar_event_attribute?(attribute) ⇒ Boolean
- .serialize_date_like(value) ⇒ Object
- .serialize_event(event) ⇒ Object
- .serialize_value(value) ⇒ Object
Class Method Details
.call(**args) ⇒ Object
48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/code/object/ics.rb', line 48 def self.call(**args) code_operator = args.fetch(:operator, nil).to_code code_arguments = args.fetch(:arguments, []).to_code code_value = code_arguments.code_first case code_operator.to_s when "parse" sig(args) { String } code_parse(code_value) else super end end |
.code_parse(value) ⇒ Object
62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/code/object/ics.rb', line 62 def self.code_parse(value) source = value.to_code.raw calendars = ::Icalendar::Calendar.parse(source) events = calendars.flat_map(&:events) events.map { |event| serialize_event(event) }.to_code rescue ::Code::Error raise rescue StandardError [].to_code end |
.event_attribute(event, attribute) ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/code/object/ics.rb', line 100 def self.event_attribute(event, attribute) case attribute when :uid event.uid when :summary event.summary when :description event.description when :location event.location when :url event.url when :status event.status when :organizer event.organizer when :categories event.categories when :attendees event.attendees when :geo event.geo end rescue NoMethodError MISSING_ATTRIBUTE end |
.function_documentation(scope) ⇒ Object
28 29 30 31 32 |
# File 'lib/code/object/ics.rb', line 28 def self.function_documentation(scope) return CLASS_FUNCTIONS if scope == :class {} end |
.normalize_string(value) ⇒ Object
155 156 157 158 159 160 |
# File 'lib/code/object/ics.rb', line 155 def self.normalize_string(value) value .dup .force_encoding(::Encoding::UTF_8) .encode(::Encoding::UTF_8, invalid: :replace, undef: :replace) end |
.scalar_event_attribute?(attribute) ⇒ Boolean
151 152 153 |
# File 'lib/code/object/ics.rb', line 151 def self.scalar_event_attribute?(attribute) !%i[categories attendees geo].include?(attribute) end |
.serialize_date_like(value) ⇒ Object
162 163 164 165 166 167 168 169 170 171 |
# File 'lib/code/object/ics.rb', line 162 def self.serialize_date_like(value) case value when ::Time, ::Date, ::ActiveSupport::TimeWithZone value when ::DateTime value.to_time when ::Icalendar::Value serialize_date_like(value.value) end end |
.serialize_event(event) ⇒ Object
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/code/object/ics.rb', line 74 def self.serialize_event(event) EVENT_ATTRIBUTES .each_with_object({}) do |attribute, result| serialized = serialize_value(event_attribute(event, attribute)) next if serialized == MISSING_ATTRIBUTE serialized = if attribute == :categories && serialized.is_a?(::Array) serialized.flatten(1) elsif scalar_event_attribute?(attribute) && serialized.is_a?(::Array) serialized.join(",") else serialized end result[attribute] = serialized unless serialized.nil? end .merge( timestamp: serialize_value(event.dtstamp), starts_at: serialize_value(event.dtstart), ends_at: serialize_value(event.dtend), all_day: !!serialize_date_like(event.dtstart).is_a?(::Date) ) .compact end |
.serialize_value(value) ⇒ Object
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/code/object/ics.rb', line 127 def self.serialize_value(value) case value when nil nil when ::String normalize_string(value) when ::Symbol, ::Integer, ::Float, ::BigDecimal, true, false value when ::Array value.map { |item| serialize_value(item) } when ::Hash value.transform_values { |item| serialize_value(item) } else serialized_date = serialize_date_like(value) return serialized_date unless serialized_date.nil? if value.is_a?(::Icalendar::Value) serialize_value(value.value) else normalize_string(value.to_s) end end end |