omnievent-icalendar 0.1.0.pre1 → 0.1.0.pre3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eac596fd4368bab161d6ee2a6a2d82934d7dfdcd3e7b0aad53c443b21aa91e05
4
- data.tar.gz: 3bac6210eb54e610aae86530ed7a331f9ebcc542a1203f6d927986ce0f8fdad4
3
+ metadata.gz: 478361c4c57731a099c80c38f58324a9596e5868b6b24f50e3c404382b56b3b9
4
+ data.tar.gz: fa69074455c32057662f0d1e66496b6337bdde8c529bcae4c5eaa8e392916896
5
5
  SHA512:
6
- metadata.gz: 0e5e5c18854bc19ad1289f07da2d15a73ba5f68ecf3ad97b18ad99d659466f5b0cab033d0022c5c0290605f4b858556a8b7f7a215b381cd5f664f109e91bd905
7
- data.tar.gz: c1ce879167ef15c0b5793833a8e62dc0e4f2599d66eac80f38c4f1ec5e917273a58ae9e923ce31a10baeee7813d9b2a630154f185cc6578fd2a947fdd0a2c65b
6
+ metadata.gz: 7aa84afb2b0062dde09e598554fb68ac416fbff767ce3aa923b2bfd737048f2b64811d61bb4552c39165348cf1aa4f2fe0f7dbf8643c59095b1b1e2cd34dd6ff
7
+ data.tar.gz: 96b84d19fbd6dcb7de58ffc6043a091c4eecf660dcfcb9c4d60799fbaf37997d00953f590309ee21737287a6db151c962e370aafe62c1276342f824f5e05cf21
data/.rspec CHANGED
@@ -1,3 +1,4 @@
1
1
  --format documentation
2
2
  --color
3
+ --exclude-pattern vendor/**/*_spec.rb
3
4
  --require spec_helper
data/CHANGELOG.md CHANGED
@@ -3,3 +3,11 @@
3
3
  ## [0.1.0.pre1] - 2022-09-05
4
4
 
5
5
  - Pre release
6
+
7
+ ## [0.1.0.pre2] - 2022-10-21
8
+
9
+ - Add recurrence support
10
+
11
+ ## [0.1.0.pre3] - 2022-11-20
12
+
13
+ - Fix various recurrence issues
data/Gemfile.lock CHANGED
@@ -1,11 +1,12 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- omnievent-icalendar (0.1.0.pre1)
4
+ omnievent-icalendar (0.1.0.pre3)
5
5
  addressable (~> 2.7)
6
6
  icalendar
7
+ icalendar-recurrence (~> 1.1)
7
8
  omnievent
8
- open-uri
9
+ open-uri (= 0.1.0)
9
10
 
10
11
  GEM
11
12
  remote: https://rubygems.org/
@@ -17,64 +18,59 @@ GEM
17
18
  concurrent-ruby (1.1.10)
18
19
  crack (0.4.5)
19
20
  rexml
20
- date (3.2.2)
21
21
  diff-lcs (1.5.0)
22
22
  hashdiff (1.0.1)
23
23
  hashie (5.0.0)
24
24
  icalendar (2.8.0)
25
25
  ice_cube (~> 0.16)
26
+ icalendar-recurrence (1.1.3)
27
+ icalendar (~> 2.0)
28
+ ice_cube (~> 0.16)
26
29
  ice_cube (0.16.4)
27
30
  iso-639 (0.3.5)
28
31
  json (2.6.2)
29
- omnievent (0.1.0.pre1)
32
+ omnievent (0.1.0.pre3)
30
33
  hashie (>= 3.4.6)
31
34
  iso-639 (~> 0.3.5)
32
35
  tzinfo (~> 2.0)
33
- open-uri (0.2.0)
34
- stringio
35
- time
36
- uri
36
+ open-uri (0.1.0)
37
37
  parallel (1.22.1)
38
38
  parser (3.1.2.1)
39
39
  ast (~> 2.4.1)
40
40
  public_suffix (5.0.0)
41
41
  rainbow (3.1.1)
42
42
  rake (13.0.6)
43
- regexp_parser (2.6.0)
43
+ regexp_parser (2.6.1)
44
44
  rexml (3.2.5)
45
- rspec (3.11.0)
46
- rspec-core (~> 3.11.0)
47
- rspec-expectations (~> 3.11.0)
48
- rspec-mocks (~> 3.11.0)
49
- rspec-core (3.11.0)
50
- rspec-support (~> 3.11.0)
51
- rspec-expectations (3.11.1)
45
+ rspec (3.12.0)
46
+ rspec-core (~> 3.12.0)
47
+ rspec-expectations (~> 3.12.0)
48
+ rspec-mocks (~> 3.12.0)
49
+ rspec-core (3.12.0)
50
+ rspec-support (~> 3.12.0)
51
+ rspec-expectations (3.12.0)
52
52
  diff-lcs (>= 1.2.0, < 2.0)
53
- rspec-support (~> 3.11.0)
54
- rspec-mocks (3.11.1)
53
+ rspec-support (~> 3.12.0)
54
+ rspec-mocks (3.12.0)
55
55
  diff-lcs (>= 1.2.0, < 2.0)
56
- rspec-support (~> 3.11.0)
57
- rspec-support (3.11.1)
58
- rubocop (1.36.0)
56
+ rspec-support (~> 3.12.0)
57
+ rspec-support (3.12.0)
58
+ rubocop (1.39.0)
59
59
  json (~> 2.3)
60
60
  parallel (~> 1.10)
61
61
  parser (>= 3.1.2.1)
62
62
  rainbow (>= 2.2.2, < 4.0)
63
63
  regexp_parser (>= 1.8, < 3.0)
64
64
  rexml (>= 3.2.5, < 4.0)
65
- rubocop-ast (>= 1.20.1, < 2.0)
65
+ rubocop-ast (>= 1.23.0, < 2.0)
66
66
  ruby-progressbar (~> 1.7)
67
67
  unicode-display_width (>= 1.4.0, < 3.0)
68
- rubocop-ast (1.21.0)
68
+ rubocop-ast (1.23.0)
69
69
  parser (>= 3.1.1.0)
70
70
  ruby-progressbar (1.11.0)
71
- stringio (3.0.2)
72
- time (0.2.0)
73
- date
74
71
  tzinfo (2.0.5)
75
72
  concurrent-ruby (~> 1.0)
76
73
  unicode-display_width (2.3.0)
77
- uri (0.11.0)
78
74
  webmock (3.18.1)
79
75
  addressable (>= 2.8.0)
80
76
  crack (>= 0.3.2)
@@ -92,4 +88,4 @@ DEPENDENCIES
92
88
  webmock
93
89
 
94
90
  BUNDLED WITH
95
- 2.3.14
91
+ 2.3.24
data/README.md CHANGED
@@ -1,11 +1,11 @@
1
1
  # OmniEvent iCalendar (Pre Release)
2
2
 
3
+ > Please note that this gem is pre release and is not yet ready for production.
4
+
3
5
  This gem contains a generic iCalendar strategy for [OmniEvent](https://github.com/paviliondev/omnievent).
4
6
 
5
7
  ## Installation
6
8
 
7
- > Please note that this gem is pre release and is not yet ready for production.
8
-
9
9
  First install [OmniEvent](https://rubygems.org/gems/omnievent).
10
10
 
11
11
  $ gem install omnievent
@@ -16,8 +16,6 @@ Then install this gem:
16
16
 
17
17
  ## Usage
18
18
 
19
- > Please note that this gem is pre release and is not yet ready for production.
20
-
21
19
  Please see ["Usage" in the OmniEvent Readme](https://github.com/paviliondev/omnievent#usage)
22
20
 
23
21
  ## Development
@@ -2,6 +2,6 @@
2
2
 
3
3
  module OmniEvent
4
4
  module Icalendar
5
- VERSION = "0.1.0.pre1"
5
+ VERSION = "0.1.0.pre3"
6
6
  end
7
7
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative "../../omnievent/icalendar/version"
4
4
  require "icalendar"
5
+ require "icalendar-recurrence"
5
6
  require "open-uri"
6
7
  require "addressable/uri"
7
8
 
@@ -14,6 +15,7 @@ module OmniEvent
14
15
  include OmniEvent::Strategy
15
16
 
16
17
  option :name, "icalendar"
18
+ option :expand_recurrences
17
19
  option :uri, ""
18
20
 
19
21
  def raw_events
@@ -32,6 +34,8 @@ module OmniEvent
32
34
  result += calendar.events
33
35
  end
34
36
 
37
+ result = expand_recurrences(result) if options.expand_recurrences
38
+
35
39
  result
36
40
  end
37
41
 
@@ -44,18 +48,10 @@ module OmniEvent
44
48
  url: raw_event.url.to_s
45
49
  }
46
50
 
47
- metadata = {
48
- uid: format_uid(raw_event),
49
- taxonomies: raw_event.categories.to_s,
50
- status: convert_status(raw_event.status),
51
- created_at: format_time(raw_event.created),
52
- updated_at: format_time(raw_event.last_modified)
53
- }
54
-
55
51
  OmniEvent::EventHash.new(
56
52
  provider: name,
57
53
  data: data,
58
- metadata: metadata
54
+ metadata: retrieve_metadata(raw_event)
59
55
  )
60
56
  end
61
57
 
@@ -76,11 +72,31 @@ module OmniEvent
76
72
  end
77
73
  end
78
74
 
75
+ def retrieve_metadata(event)
76
+ metadata = {
77
+ uid: format_uid(event),
78
+ taxonomies: event.categories.to_s,
79
+ status: convert_status(event.status),
80
+ created_at: format_time(event.created),
81
+ updated_at: format_time(event.last_modified),
82
+ sequence: nil,
83
+ series_id: nil,
84
+ occurrence_id: nil
85
+ }
86
+
87
+ metadata[:sequence] = event.sequence.to_s if event.sequence
88
+
89
+ if event.recurrence_id
90
+ metadata[:series_id] = event.uid.to_s
91
+ metadata[:occurrence_id] = event.recurrence_id.to_s
92
+ end
93
+
94
+ metadata
95
+ end
96
+
79
97
  def format_uid(event)
80
- # See https://datatracker.ietf.org/doc/html/rfc5545#section-3.8.4.4
81
98
  event_uid = event.uid.to_s
82
99
  event_uid += "#{options.uid_delimiter}#{event.recurrence_id}" if event.recurrence_id
83
- event_uid += "#{options.uid_delimiter}#{event.sequence}" if event.sequence
84
100
  event_uid
85
101
  end
86
102
 
@@ -96,6 +112,56 @@ module OmniEvent
96
112
  "published"
97
113
  end
98
114
  end
115
+
116
+ def expand_recurrences(events)
117
+ result = []
118
+
119
+ events.each do |event|
120
+ if recurrence?(event)
121
+ schedule = ::Icalendar::Recurrence::Schedule.new(event)
122
+ exceptions = events.select { |e| e.recurrence_id && (e.uid == event.uid) }
123
+
124
+ extract_occurences(schedule).each do |occurrence|
125
+ next if exception?(exceptions, occurrence)
126
+
127
+ occurrence_event = event.clone
128
+ occurrence_event.recurrence_id = occurrence.start_time
129
+ occurrence_event.dtstart = occurrence.start_time
130
+ occurrence_event.dtend = occurrence.end_time
131
+
132
+ result << occurrence_event
133
+ end
134
+ else
135
+ siblings = events
136
+ .select { |e| e.recurrence_id.to_i == event.recurrence_id.to_i }
137
+ .sort_by(&:sequence)
138
+
139
+ result << event if siblings.none? || (siblings.last.sequence == event.sequence)
140
+ end
141
+ end
142
+
143
+ result.sort_by(&:dtstart)
144
+ end
145
+
146
+ def extract_occurences(schedule)
147
+ if options.from_time && options.to_time
148
+ schedule.occurrences_between(options.from_time, options.to_time)
149
+ else
150
+ schedule.all_occurrences
151
+ end
152
+ end
153
+
154
+ def recurrence?(event)
155
+ present?(event.rrule) || present?(event.rdate)
156
+ end
157
+
158
+ def present?(property)
159
+ !!property && property.any?
160
+ end
161
+
162
+ def exception?(exceptions, occurrence)
163
+ exceptions.any? { |e| e.recurrence_id.to_i == occurrence.start_time.to_i }
164
+ end
99
165
  end
100
166
  end
101
167
  end
@@ -30,8 +30,9 @@ Gem::Specification.new do |spec|
30
30
 
31
31
  spec.add_dependency "addressable", "~> 2.7"
32
32
  spec.add_dependency "icalendar"
33
+ spec.add_dependency "icalendar-recurrence", "~> 1.1"
33
34
  spec.add_dependency "omnievent"
34
- spec.add_dependency "open-uri"
35
+ spec.add_dependency "open-uri", "0.1.0"
35
36
  spec.add_development_dependency "byebug"
36
37
  spec.add_development_dependency "webmock"
37
38
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omnievent-icalendar
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.pre1
4
+ version: 0.1.0.pre3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Angus McLeod
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-10-03 00:00:00.000000000 Z
11
+ date: 2022-11-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: icalendar-recurrence
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.1'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.1'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: omnievent
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -56,16 +70,16 @@ dependencies:
56
70
  name: open-uri
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
- - - ">="
73
+ - - '='
60
74
  - !ruby/object:Gem::Version
61
- version: '0'
75
+ version: 0.1.0
62
76
  type: :runtime
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
- - - ">="
80
+ - - '='
67
81
  - !ruby/object:Gem::Version
68
- version: '0'
82
+ version: 0.1.0
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: byebug
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -137,7 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
137
151
  - !ruby/object:Gem::Version
138
152
  version: 1.3.1
139
153
  requirements: []
140
- rubygems_version: 3.1.4
154
+ rubygems_version: 3.1.6
141
155
  signing_key:
142
156
  specification_version: 4
143
157
  summary: OmniEvent iCalendar strategy