calendav 0.3.0 → 0.5.0

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.
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "contextual_url"
4
+ require_relative "parsers/todo_xml"
5
+
6
+ module Calendav
7
+ class Todo
8
+ ATTRIBUTES = %i[url calendar_data etag].freeze
9
+
10
+ def self.from_xml(host, node)
11
+ new(
12
+ {
13
+ url: ContextualURL.call(host, node.xpath("./dav:href").text)
14
+ }.merge(
15
+ Parsers::TodoXML.call(node)
16
+ )
17
+ )
18
+ end
19
+
20
+ def initialize(attributes = {})
21
+ @attributes = attributes
22
+ end
23
+
24
+ ATTRIBUTES.each do |attribute|
25
+ define_method(attribute) { attributes[attribute] }
26
+ end
27
+
28
+ def to_h
29
+ attributes.dup
30
+ end
31
+
32
+ def summary
33
+ inner_todo.summary
34
+ end
35
+
36
+ def due
37
+ inner_todo.due
38
+ end
39
+
40
+ def status
41
+ inner_todo.status
42
+ end
43
+
44
+ def unloaded?
45
+ calendar_data.nil?
46
+ end
47
+
48
+ private
49
+
50
+ attr_reader :attributes
51
+
52
+ def inner_calendar
53
+ Icalendar::Calendar.parse(calendar_data).first
54
+ end
55
+
56
+ def inner_todo
57
+ @inner_todo = inner_calendar.todos.first
58
+ end
59
+ end
60
+ end
data/lib/calendav.rb CHANGED
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "./calendav/credentials/apple"
4
- require_relative "./calendav/credentials/fastmail"
5
- require_relative "./calendav/credentials/google"
6
- require_relative "./calendav/client"
3
+ require_relative "calendav/credentials/apple"
4
+ require_relative "calendav/credentials/fastmail"
5
+ require_relative "calendav/credentials/google"
6
+ require_relative "calendav/client"
7
7
 
8
8
  module Calendav
9
9
  PROVIDERS = {
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: calendav
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pat Allan
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2022-03-14 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: http
@@ -52,184 +51,28 @@ dependencies:
52
51
  - - ">="
53
52
  - !ruby/object:Gem::Version
54
53
  version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: dotenv
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: google-api-client
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: googleauth
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: rake
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
- - !ruby/object:Gem::Dependency
112
- name: rspec
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: '0'
125
- - !ruby/object:Gem::Dependency
126
- name: rubocop
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - ">="
130
- - !ruby/object:Gem::Version
131
- version: '0'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - ">="
137
- - !ruby/object:Gem::Version
138
- version: '0'
139
- - !ruby/object:Gem::Dependency
140
- name: timecop
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - ">="
144
- - !ruby/object:Gem::Version
145
- version: '0'
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - ">="
151
- - !ruby/object:Gem::Version
152
- version: '0'
153
- - !ruby/object:Gem::Dependency
154
- name: tzinfo
155
- requirement: !ruby/object:Gem::Requirement
156
- requirements:
157
- - - ">="
158
- - !ruby/object:Gem::Version
159
- version: '0'
160
- type: :development
161
- prerelease: false
162
- version_requirements: !ruby/object:Gem::Requirement
163
- requirements:
164
- - - ">="
165
- - !ruby/object:Gem::Version
166
- version: '0'
167
- - !ruby/object:Gem::Dependency
168
- name: vcr
169
- requirement: !ruby/object:Gem::Requirement
170
- requirements:
171
- - - ">="
172
- - !ruby/object:Gem::Version
173
- version: '0'
174
- type: :development
175
- prerelease: false
176
- version_requirements: !ruby/object:Gem::Requirement
177
- requirements:
178
- - - ">="
179
- - !ruby/object:Gem::Version
180
- version: '0'
181
- - !ruby/object:Gem::Dependency
182
- name: vcr_assistant
183
- requirement: !ruby/object:Gem::Requirement
184
- requirements:
185
- - - ">="
186
- - !ruby/object:Gem::Version
187
- version: '0'
188
- type: :development
189
- prerelease: false
190
- version_requirements: !ruby/object:Gem::Requirement
191
- requirements:
192
- - - ">="
193
- - !ruby/object:Gem::Version
194
- version: '0'
195
- - !ruby/object:Gem::Dependency
196
- name: webmock
197
- requirement: !ruby/object:Gem::Requirement
198
- requirements:
199
- - - ">="
200
- - !ruby/object:Gem::Version
201
- version: '0'
202
- type: :development
203
- prerelease: false
204
- version_requirements: !ruby/object:Gem::Requirement
205
- requirements:
206
- - - ">="
207
- - !ruby/object:Gem::Version
208
- version: '0'
209
- description:
210
54
  email:
211
55
  - pat@freelancing-gods.com
212
56
  executables: []
213
57
  extensions: []
214
58
  extra_rdoc_files: []
215
59
  files:
216
- - ".rspec"
217
60
  - CHANGELOG.md
218
- - Gemfile
219
61
  - LICENSE.md
220
62
  - README.md
221
- - Rakefile
222
63
  - lib/calendav.rb
223
64
  - lib/calendav/calendar.rb
224
65
  - lib/calendav/client.rb
225
66
  - lib/calendav/clients/calendars_client.rb
226
67
  - lib/calendav/clients/events_client.rb
68
+ - lib/calendav/clients/todos_client.rb
227
69
  - lib/calendav/contextual_url.rb
228
70
  - lib/calendav/credentials/apple.rb
229
71
  - lib/calendav/credentials/fastmail.rb
230
72
  - lib/calendav/credentials/google.rb
231
73
  - lib/calendav/credentials/standard.rb
232
74
  - lib/calendav/endpoint.rb
75
+ - lib/calendav/error_handler.rb
233
76
  - lib/calendav/errors.rb
234
77
  - lib/calendav/event.rb
235
78
  - lib/calendav/multi_response.rb
@@ -238,24 +81,17 @@ files:
238
81
  - lib/calendav/parsers/event_xml.rb
239
82
  - lib/calendav/parsers/response_xml.rb
240
83
  - lib/calendav/parsers/sync_xml.rb
84
+ - lib/calendav/parsers/todo_xml.rb
241
85
  - lib/calendav/requests/calendar_home_set.rb
242
86
  - lib/calendav/requests/current_user_principal.rb
243
87
  - lib/calendav/requests/list_calendars.rb
244
88
  - lib/calendav/requests/list_events.rb
89
+ - lib/calendav/requests/list_todos.rb
245
90
  - lib/calendav/requests/make_calendar.rb
246
91
  - lib/calendav/requests/sync_collection.rb
247
92
  - lib/calendav/requests/update_calendar.rb
248
93
  - lib/calendav/sync_collection.rb
249
- - spec/acceptance/apple_spec.rb
250
- - spec/acceptance/google_spec.rb
251
- - spec/acceptance/radicale_spec.rb
252
- - spec/acceptance/shared.rb
253
- - spec/data/radicale/config.ini
254
- - spec/data/radicale/users
255
- - spec/spec_helper.rb
256
- - spec/support/encoded_matchers.rb
257
- - spec/support/event_helpers.rb
258
- - spec/support/vcr.rb
94
+ - lib/calendav/todo.rb
259
95
  homepage: https://github.com/pat/calendav
260
96
  licenses:
261
97
  - Hippocratic-2.1
@@ -264,7 +100,6 @@ metadata:
264
100
  source_code_uri: https://github.com/pat/calendav
265
101
  changelog_uri: https://github.com/pat/calendav/blob/main/CHANGELOG.md
266
102
  rubygems_mfa_required: 'true'
267
- post_install_message:
268
103
  rdoc_options: []
269
104
  require_paths:
270
105
  - lib
@@ -279,21 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
279
114
  - !ruby/object:Gem::Version
280
115
  version: '0'
281
116
  requirements: []
282
- rubygems_version: 3.2.32
283
- signing_key:
117
+ rubygems_version: 3.6.9
284
118
  specification_version: 4
285
119
  summary: CalDAV client
286
- test_files:
287
- - spec/acceptance/apple_spec.rb
288
- - spec/acceptance/google_spec.rb
289
- - spec/acceptance/radicale_spec.rb
290
- - spec/acceptance/shared.rb
291
- - spec/data/radicale/config.ini
292
- - spec/data/radicale/users
293
- - spec/spec_helper.rb
294
- - spec/support/encoded_matchers.rb
295
- - spec/support/event_helpers.rb
296
- - spec/support/vcr.rb
297
- - ".rspec"
298
- - Gemfile
299
- - Rakefile
120
+ test_files: []
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --format documentation
2
- --color
3
- --require spec_helper
data/Gemfile DELETED
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- source "https://rubygems.org"
4
-
5
- gemspec
6
-
7
- gem "icalendar",
8
- git: "https://github.com/pat/icalendar.git",
9
- branch: "fix/activesupport-7"
data/Rakefile DELETED
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "bundler/gem_tasks"
4
- require "rspec/core/rake_task"
5
-
6
- RSpec::Core::RakeTask.new(:spec)
7
-
8
- require "rubocop/rake_task"
9
-
10
- RuboCop::RakeTask.new
11
-
12
- task default: %i[spec rubocop]
@@ -1,45 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "securerandom"
4
-
5
- require_relative "./shared"
6
-
7
- RSpec.describe "Apple", :vcr do
8
- let(:provider) { :apple }
9
- let(:username) { ENV.fetch("APPLE_USERNAME") }
10
- let(:password) { ENV.fetch("APPLE_PASSWORD") }
11
- let(:credentials) { Calendav.credentials(provider, username, password) }
12
- let(:host) { "https://p49-caldav.icloud.com/20264203208/calendars/" }
13
-
14
- subject { Calendav.client(credentials) }
15
-
16
- it "determines the user's principal URL" do
17
- expect(subject.principal_url)
18
- .to eq_encoded_url("https://caldav.icloud.com/20264203208/principal/")
19
- end
20
-
21
- it "determines the user's calendar URL" do
22
- expect(subject.calendars.home_url)
23
- .to eq_encoded_url("https://p49-caldav.icloud.com/20264203208/calendars/")
24
- end
25
-
26
- it_behaves_like "supporting calendar management"
27
-
28
- context "with a calendar" do
29
- let(:calendar_url) do
30
- subject.calendars.create(@name, display_name: "Calendav Test")
31
- end
32
- let(:calendar) { subject.calendars.find(calendar_url) }
33
-
34
- before :each do |example|
35
- @name = Digest::MD5.hexdigest(example.metadata[:full_description])
36
- end
37
-
38
- after :each do
39
- subject.calendars.delete(calendar.url)
40
- end
41
-
42
- it_behaves_like "supporting event management"
43
- it_behaves_like "supporting event deletion with etags"
44
- end
45
- end
@@ -1,101 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "google/apis/calendar_v3"
4
- require "googleauth"
5
- require "icalendar"
6
- require "securerandom"
7
- require "uri"
8
-
9
- require_relative "./shared"
10
-
11
- RSpec.describe "Google", :vcr do
12
- let(:provider) { :google }
13
- let(:username) { ENV.fetch("GOOGLE_USERNAME") }
14
- let(:access_token) { @access_token }
15
- let(:credentials) { Calendav.credentials(provider, username, access_token) }
16
- let(:google_auth) { @google_auth }
17
-
18
- subject { Calendav.client(credentials) }
19
-
20
- before :each do
21
- @google_auth = Google::Auth::UserRefreshCredentials.new(
22
- client_id: ENV.fetch("GOOGLE_CLIENT_ID"),
23
- scope: [],
24
- client_secret: ENV.fetch("GOOGLE_CLIENT_SECRET"),
25
- refresh_token: ENV.fetch("GOOGLE_REFRESH_TOKEN"),
26
- additional_parameters: { "access_type" => "offline" }
27
- )
28
-
29
- @access_token = begin
30
- @google_auth.fetch_access_token!
31
- @google_auth.access_token
32
- end
33
- end
34
-
35
- it "determines the user's principal URL" do
36
- expect(subject.principal_url).to eq_encoded_url(
37
- "https://apidata.googleusercontent.com/caldav/v2/#{username}/user"
38
- )
39
- end
40
-
41
- it "determines the user's calendar URL" do
42
- expect(subject.calendars.home_url).to eq_encoded_url(
43
- "https://apidata.googleusercontent.com/caldav/v2/#{username}/"
44
- )
45
- end
46
-
47
- it "cannot create calendars" do
48
- expect(subject.calendars.create?).to eq(false)
49
- end
50
-
51
- it "can find and update calendars" do
52
- calendars = subject.calendars.list
53
- calendar = calendars.detect { |cal| cal.display_name == "Calendav Test" }
54
-
55
- expect(calendar).to_not be_nil
56
-
57
- subject.calendars.update(calendar.url, display_name: "Calendav Update")
58
-
59
- calendars = subject.calendars.list
60
- calendar = calendars.detect { |cal| cal.display_name == "Calendav Update" }
61
-
62
- subject.calendars.update(calendar.url, display_name: "Calendav Test")
63
- end
64
-
65
- context "with a calendar" do
66
- let(:calendars) { subject.calendars.list }
67
- let(:calendar) { calendars.detect { |cal| cal.display_name == name } }
68
- let(:name) { "Calendav Test #{Time.now.to_i}" }
69
- let(:service) { Google::Apis::CalendarV3::CalendarService.new }
70
- let(:entry) { Google::Apis::CalendarV3::Calendar.new(summary: name) }
71
-
72
- before :each do
73
- service.authorization = google_auth
74
-
75
- result = service.insert_calendar entry
76
- entry.update!(**result.to_h)
77
- end
78
-
79
- after :each do
80
- service.delete_calendar entry.id
81
- end
82
-
83
- it_behaves_like "supporting event management"
84
-
85
- it "does not respect etag conditions for deletions" do
86
- event_url = subject.events.create(
87
- calendar.url, "calendav-event.ics", ical_event("Brunch", 10, 30)
88
- )
89
- event = subject.events.find(event_url)
90
-
91
- expect(
92
- subject.events.update(
93
- event_url, update_summary(event, "Coffee"), etag: event.etag
94
- )
95
- ).to eq(true)
96
-
97
- # Google doesn't care about the If-Match header on DELETE requests :(
98
- expect(subject.events.delete(event_url, etag: event.etag)).to eq(true)
99
- end
100
- end
101
- end
@@ -1,48 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "securerandom"
4
-
5
- require_relative "./shared"
6
-
7
- RSpec.describe "Radicale" do
8
- let(:provider) { :radicale }
9
- let(:username) { ENV.fetch("RADICALE_USERNAME") }
10
- let(:password) { ENV.fetch("RADICALE_PASSWORD") }
11
- let(:host) { ENV.fetch("RADICALE_HOST") }
12
- let(:credentials) do
13
- Calendav::Credentials::Standard.new(
14
- host: host,
15
- username: username,
16
- password: password,
17
- authentication: :basic_auth
18
- )
19
- end
20
-
21
- subject { Calendav.client(credentials) }
22
-
23
- it "determines the user's principal URL" do
24
- expect(subject.principal_url)
25
- .to eq_encoded_url("#{host}/test/")
26
- end
27
-
28
- it "determines the user's calendar URL" do
29
- expect(subject.calendars.home_url)
30
- .to eq_encoded_url("#{host}/test/")
31
- end
32
-
33
- it_behaves_like "supporting calendar management"
34
-
35
- context "with a calendar" do
36
- let(:calendar_url) do
37
- subject.calendars.create("calendav-test", display_name: "Calendav Test")
38
- end
39
- let(:calendar) { subject.calendars.find(calendar_url) }
40
-
41
- after :each do
42
- subject.calendars.delete(calendar.url)
43
- end
44
-
45
- it_behaves_like "supporting event management"
46
- it_behaves_like "supporting event deletion with etags"
47
- end
48
- end