sabredav_client 0.2.0 → 0.2.1
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 +4 -4
- data/.gitignore +3 -3
- data/.rspec +1 -1
- data/CHANGELOG.rdoc +8 -8
- data/Gemfile +3 -3
- data/Gemfile.lock +39 -38
- data/README.md +49 -49
- data/Rakefile +5 -5
- data/lib/sabredav_client.rb +10 -10
- data/lib/sabredav_client/calendar.rb +171 -171
- data/lib/sabredav_client/client.rb +57 -57
- data/lib/sabredav_client/errors/errors.rb +41 -41
- data/lib/sabredav_client/events.rb +106 -105
- data/lib/sabredav_client/net.rb +15 -15
- data/lib/sabredav_client/principal.rb +51 -51
- data/lib/sabredav_client/request.rb +97 -97
- data/lib/sabredav_client/version.rb +3 -3
- data/lib/sabredav_client/xml_request_builder.rb +7 -7
- data/lib/sabredav_client/xml_request_builder/base.rb +17 -17
- data/lib/sabredav_client/xml_request_builder/mkcalendar.rb +25 -25
- data/lib/sabredav_client/xml_request_builder/mkcol_principal.rb +28 -28
- data/lib/sabredav_client/xml_request_builder/post_sharing.rb +41 -41
- data/lib/sabredav_client/xml_request_builder/propfind_calendar.rb +41 -41
- data/lib/sabredav_client/xml_request_builder/propfind_invite.rb +19 -19
- data/lib/sabredav_client/xml_request_builder/propfind_owner.rb +19 -19
- data/lib/sabredav_client/xml_request_builder/proppatch_calendar.rb +25 -25
- data/lib/sabredav_client/xml_request_builder/proppatch_events_owner.rb +23 -23
- data/lib/sabredav_client/xml_request_builder/proppatch_principal.rb +25 -25
- data/lib/sabredav_client/xml_request_builder/report_event_changes.rb +22 -22
- data/lib/sabredav_client/xml_request_builder/report_vevent.rb +30 -30
- data/lib/sabredav_client/xml_request_builder/report_vtodo.rb +20 -20
- data/sabredav_client.gemspec +31 -31
- data/spec/fixtures/calendar_fetch_changes.xml +26 -26
- data/spec/fixtures/calendar_info.xml +14 -14
- data/spec/fixtures/calendar_sharees.xml +35 -35
- data/spec/fixtures/calendar_sharees_without_common_name.xml +26 -26
- data/spec/fixtures/event.ics +23 -23
- data/spec/fixtures/events_find_multiple.xml +51 -51
- data/spec/fixtures/events_owner.xml +12 -12
- data/spec/fixtures/xml_request_builder/mkcalendar.xml +9 -9
- data/spec/fixtures/xml_request_builder/mkcol_principal.xml +12 -12
- data/spec/fixtures/xml_request_builder/post_sharing.xml +18 -18
- data/spec/fixtures/xml_request_builder/propfind_calendar/all_properties.xml +8 -8
- data/spec/fixtures/xml_request_builder/propfind_invite.xml +6 -6
- data/spec/fixtures/xml_request_builder/propfind_owner.xml +6 -6
- data/spec/fixtures/xml_request_builder/proppatch_calendar.xml +9 -9
- data/spec/fixtures/xml_request_builder/proppatch_events_owner.xml +8 -8
- data/spec/fixtures/xml_request_builder/proppatch_principal.xml +9 -9
- data/spec/fixtures/xml_request_builder/report_event_changes.xml +8 -8
- data/spec/sabredav_client/calendar_spec.rb +142 -142
- data/spec/sabredav_client/client_spec.rb +41 -41
- data/spec/sabredav_client/events_spec.rb +119 -119
- data/spec/sabredav_client/principal_spec.rb +51 -51
- data/spec/sabredav_client/request_spec.rb +55 -55
- data/spec/sabredav_client/xml_request_builder_specs/base_spec.rb +30 -30
- data/spec/sabredav_client/xml_request_builder_specs/mkcalendar_spec.rb +13 -13
- data/spec/sabredav_client/xml_request_builder_specs/mkcol_principal_spec.rb +13 -13
- data/spec/sabredav_client/xml_request_builder_specs/post_sharing_spec.rb +15 -15
- data/spec/sabredav_client/xml_request_builder_specs/propfind_calendar_spec.rb +24 -24
- data/spec/sabredav_client/xml_request_builder_specs/propfind_invite_spec.rb +14 -14
- data/spec/sabredav_client/xml_request_builder_specs/propfind_owner_spec.rb +14 -14
- data/spec/sabredav_client/xml_request_builder_specs/proppatch_calendar.rb +15 -15
- data/spec/sabredav_client/xml_request_builder_specs/proppatch_events_owner_spec.rb +14 -14
- data/spec/sabredav_client/xml_request_builder_specs/proppatch_principal_spec.rb +24 -24
- data/spec/sabredav_client/xml_request_builder_specs/report_event_changes_spec.rb +15 -15
- data/spec/spec.opts +4 -4
- data/spec/spec_helper.rb +8 -8
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 11c25bf20375fd292eb2f8fd549bef7771796f8a
|
4
|
+
data.tar.gz: 1bb37a65d948d9a4c7d194dfdc5ff2077b855e76
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 05fd7ae58ab53bed9c5dbb37f1befa06eb34b013714a278175f29f2f465c107f4ccaa1e66609b23a0498feaa5ae7eadf7c175599173987ec436969ee68583578
|
7
|
+
data.tar.gz: e1c3cda4ce08b8b13c143ba603a54af4c7dc992141bcc66dafdebd1a0864aff8ddd585ecad5b20664e5e23ea131fa5332d5a1a80d175a7f0c5c8f2d49ffb8eee
|
data/.gitignore
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
caldaver-test.sh
|
2
|
-
*.gem
|
3
|
-
*.tmp
|
1
|
+
caldaver-test.sh
|
2
|
+
*.gem
|
3
|
+
*.tmp
|
data/.rspec
CHANGED
@@ -1 +1 @@
|
|
1
|
-
--colour
|
1
|
+
--colour
|
data/CHANGELOG.rdoc
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
= v0.2.5.3
|
2
|
-
|
3
|
-
* Fixed gemspec
|
4
|
-
|
5
|
-
= v0.2.5.2
|
6
|
-
|
7
|
-
* client.update_event *args* changed. UID has to be provided
|
8
|
-
now -> client.update_event(:uid => "123", ...)
|
1
|
+
= v0.2.5.3
|
2
|
+
|
3
|
+
* Fixed gemspec
|
4
|
+
|
5
|
+
= v0.2.5.2
|
6
|
+
|
7
|
+
* client.update_event *args* changed. UID has to be provided
|
8
|
+
now -> client.update_event(:uid => "123", ...)
|
data/Gemfile
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
source 'https://rubygems.org'
|
2
|
-
|
3
|
-
gemspec
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gemspec
|
data/Gemfile.lock
CHANGED
@@ -1,38 +1,39 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
sabredav_client (0.1
|
5
|
-
builder (~> 3.2)
|
6
|
-
net-http-digest_auth (~> 1.4)
|
7
|
-
|
8
|
-
GEM
|
9
|
-
remote: https://rubygems.org/
|
10
|
-
specs:
|
11
|
-
builder (3.2.2)
|
12
|
-
diff-lcs (1.2.5)
|
13
|
-
fakeweb (1.3.0)
|
14
|
-
net-http-digest_auth (1.4)
|
15
|
-
rspec (3.5.0)
|
16
|
-
rspec-core (~> 3.5.0)
|
17
|
-
rspec-expectations (~> 3.5.0)
|
18
|
-
rspec-mocks (~> 3.5.0)
|
19
|
-
rspec-core (3.5.2)
|
20
|
-
rspec-support (~> 3.5.0)
|
21
|
-
rspec-expectations (3.5.0)
|
22
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
23
|
-
rspec-support (~> 3.5.0)
|
24
|
-
rspec-mocks (3.5.0)
|
25
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
26
|
-
rspec-support (~> 3.5.0)
|
27
|
-
rspec-support (3.5.0)
|
28
|
-
|
29
|
-
PLATFORMS
|
30
|
-
ruby
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
sabredav_client (0.2.1)
|
5
|
+
builder (~> 3.2)
|
6
|
+
net-http-digest_auth (~> 1.4)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
builder (3.2.2)
|
12
|
+
diff-lcs (1.2.5)
|
13
|
+
fakeweb (1.3.0)
|
14
|
+
net-http-digest_auth (1.4)
|
15
|
+
rspec (3.5.0)
|
16
|
+
rspec-core (~> 3.5.0)
|
17
|
+
rspec-expectations (~> 3.5.0)
|
18
|
+
rspec-mocks (~> 3.5.0)
|
19
|
+
rspec-core (3.5.2)
|
20
|
+
rspec-support (~> 3.5.0)
|
21
|
+
rspec-expectations (3.5.0)
|
22
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
23
|
+
rspec-support (~> 3.5.0)
|
24
|
+
rspec-mocks (3.5.0)
|
25
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
26
|
+
rspec-support (~> 3.5.0)
|
27
|
+
rspec-support (3.5.0)
|
28
|
+
|
29
|
+
PLATFORMS
|
30
|
+
ruby
|
31
|
+
x86-mingw32
|
32
|
+
|
33
|
+
DEPENDENCIES
|
34
|
+
fakeweb (~> 1.3)
|
35
|
+
rspec (~> 3.5)
|
36
|
+
sabredav_client!
|
37
|
+
|
38
|
+
BUNDLED WITH
|
39
|
+
1.12.5
|
data/README.md
CHANGED
@@ -1,49 +1,49 @@
|
|
1
|
-
#Ruby CalDAV library named "sabredav_client"
|
2
|
-
**sabredav_client is a CalDAV library based on martinpovolny/ruby-caldav and 4fthawaiian/ruby-caldav and collectiveidea/caldav and agilstatic/agcaldav**"
|
3
|
-
|
4
|
-
**Please keep in mind, sabredav_client ist still under heavy development and still not finished...**
|
5
|
-
|
6
|
-
##Usage Events
|
7
|
-
|
8
|
-
First, you've to install the gem
|
9
|
-
|
10
|
-
gem install sabredav_client
|
11
|
-
|
12
|
-
and require it
|
13
|
-
|
14
|
-
require "sabredav_client"
|
15
|
-
|
16
|
-
####Create an Event
|
17
|
-
|
18
|
-
####Find an Event (via UUID)
|
19
|
-
|
20
|
-
####Find Events within time interval
|
21
|
-
|
22
|
-
####Update Event
|
23
|
-
|
24
|
-
####Delete Event
|
25
|
-
|
26
|
-
##Usage ToDo
|
27
|
-
|
28
|
-
##Testing
|
29
|
-
|
30
|
-
sabredav_client will use RSpec for its test coverage. Inside the gem
|
31
|
-
directory, you can run the specs for RoR 3.x with:
|
32
|
-
|
33
|
-
##Licence
|
34
|
-
|
35
|
-
MIT
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
##Contributors
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
1. Fork it.
|
44
|
-
2. Create a branch (`git checkout -b my_feature_branch`)
|
45
|
-
3. Commit your changes (`git commit -am "bugfixed abc..."`)
|
46
|
-
4. Push to the branch (`git push origin my_feature_branch`)
|
47
|
-
5. Open a Pull Request
|
48
|
-
6. Enjoy a refreshing Club Mate and wait
|
49
|
-
|
1
|
+
#Ruby CalDAV library named "sabredav_client"
|
2
|
+
**sabredav_client is a CalDAV library based on martinpovolny/ruby-caldav and 4fthawaiian/ruby-caldav and collectiveidea/caldav and agilstatic/agcaldav**"
|
3
|
+
|
4
|
+
**Please keep in mind, sabredav_client ist still under heavy development and still not finished...**
|
5
|
+
|
6
|
+
##Usage Events
|
7
|
+
|
8
|
+
First, you've to install the gem
|
9
|
+
|
10
|
+
gem install sabredav_client
|
11
|
+
|
12
|
+
and require it
|
13
|
+
|
14
|
+
require "sabredav_client"
|
15
|
+
|
16
|
+
####Create an Event
|
17
|
+
|
18
|
+
####Find an Event (via UUID)
|
19
|
+
|
20
|
+
####Find Events within time interval
|
21
|
+
|
22
|
+
####Update Event
|
23
|
+
|
24
|
+
####Delete Event
|
25
|
+
|
26
|
+
##Usage ToDo
|
27
|
+
|
28
|
+
##Testing
|
29
|
+
|
30
|
+
sabredav_client will use RSpec for its test coverage. Inside the gem
|
31
|
+
directory, you can run the specs for RoR 3.x with:
|
32
|
+
|
33
|
+
##Licence
|
34
|
+
|
35
|
+
MIT
|
36
|
+
|
37
|
+
|
38
|
+
|
39
|
+
##Contributors
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
1. Fork it.
|
44
|
+
2. Create a branch (`git checkout -b my_feature_branch`)
|
45
|
+
3. Commit your changes (`git commit -am "bugfixed abc..."`)
|
46
|
+
4. Push to the branch (`git push origin my_feature_branch`)
|
47
|
+
5. Open a Pull Request
|
48
|
+
6. Enjoy a refreshing Club Mate and wait
|
49
|
+
|
data/Rakefile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
require 'rspec/core/rake_task'
|
2
|
-
|
3
|
-
RSpec::Core::RakeTask.new('spec')
|
4
|
-
|
5
|
-
# If you want to make this the default task
|
1
|
+
require 'rspec/core/rake_task'
|
2
|
+
|
3
|
+
RSpec::Core::RakeTask.new('spec')
|
4
|
+
|
5
|
+
# If you want to make this the default task
|
6
6
|
task :default => :spec
|
data/lib/sabredav_client.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
require 'net/https'
|
2
|
-
require 'net/http/digest_auth'
|
3
|
-
require 'rexml/document'
|
4
|
-
require 'rexml/xpath'
|
5
|
-
require 'time'
|
6
|
-
require 'date'
|
7
|
-
|
8
|
-
['errors/errors.rb','xml_request_builder.rb', 'client.rb', 'request.rb', 'net.rb', "calendar.rb", "events.rb", "principal.rb"].each do |f|
|
9
|
-
require File.join( File.dirname(__FILE__), 'sabredav_client', f )
|
10
|
-
end
|
1
|
+
require 'net/https'
|
2
|
+
require 'net/http/digest_auth'
|
3
|
+
require 'rexml/document'
|
4
|
+
require 'rexml/xpath'
|
5
|
+
require 'time'
|
6
|
+
require 'date'
|
7
|
+
|
8
|
+
['errors/errors.rb','xml_request_builder.rb', 'client.rb', 'request.rb', 'net.rb', "calendar.rb", "events.rb", "principal.rb"].each do |f|
|
9
|
+
require File.join( File.dirname(__FILE__), 'sabredav_client', f )
|
10
|
+
end
|
@@ -1,171 +1,171 @@
|
|
1
|
-
module SabredavClient
|
2
|
-
|
3
|
-
class Calendar
|
4
|
-
attr_accessor :client
|
5
|
-
|
6
|
-
def initialize(data)
|
7
|
-
@client = SabredavClient::Client.new(data)
|
8
|
-
end
|
9
|
-
|
10
|
-
def events
|
11
|
-
@events ||= SabredavClient::Events.new(client)
|
12
|
-
end
|
13
|
-
|
14
|
-
def info
|
15
|
-
header = {content_type: "application/xml"}
|
16
|
-
body = SabredavClient::XmlRequestBuilder::PROPFINDCalendar.new(properties: [:displayname, :sync_token, :getctag]).to_xml
|
17
|
-
|
18
|
-
req = client.create_request(:propfind, header: header, body: body)
|
19
|
-
res = req.run
|
20
|
-
|
21
|
-
SabredavClient::Errors::errorhandling(res)
|
22
|
-
|
23
|
-
xml = REXML::Document.new(res.body)
|
24
|
-
{
|
25
|
-
displayname: REXML::XPath.first(xml, "//d:displayname").text,
|
26
|
-
ctag: REXML::XPath.first(xml, "//cs:getctag").text,
|
27
|
-
sync_token: REXML::XPath.first(xml, "//d:sync-token").text
|
28
|
-
}
|
29
|
-
end
|
30
|
-
|
31
|
-
def create(displayname: "", description: "")
|
32
|
-
body = SabredavClient::XmlRequestBuilder::Mkcalendar.new(displayname, description).to_xml
|
33
|
-
header = {dav: "resource-must-be-null", content_type: "application/xml"}
|
34
|
-
|
35
|
-
req = client.create_request(:mkcalendar, header: header, body: body)
|
36
|
-
|
37
|
-
res = req.run
|
38
|
-
|
39
|
-
SabredavClient::Errors.errorhandling(res)
|
40
|
-
info
|
41
|
-
end
|
42
|
-
|
43
|
-
def update(displayname: nil, description: nil)
|
44
|
-
body = XmlRequestBuilder::ProppatchCalendar.new(displayname, description).to_xml
|
45
|
-
header = {content_type: "application/xml"}
|
46
|
-
|
47
|
-
req = client.create_request(:proppatch, header: header, body: body)
|
48
|
-
|
49
|
-
res = req.run
|
50
|
-
|
51
|
-
if res.code.to_i.between?(200,299)
|
52
|
-
true
|
53
|
-
else
|
54
|
-
SabredavClient::Errors::errorhandling(res)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
def delete
|
59
|
-
req = client.create_request(:delete)
|
60
|
-
res = req.run
|
61
|
-
|
62
|
-
if res.code.to_i.between?(200,299)
|
63
|
-
true
|
64
|
-
else
|
65
|
-
SabredavClient::Errors::errorhandling(res)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def share(adds: [], removes: [], summary: nil, common_name: nil,
|
70
|
-
privilege: "write-read", type: nil)
|
71
|
-
|
72
|
-
header = {content_length: "xxxx", content_type: "application/xml"}
|
73
|
-
body = SabredavClient::XmlRequestBuilder::PostSharing.new(
|
74
|
-
adds, summary, common_name, privilege, removes).to_xml
|
75
|
-
|
76
|
-
req = client.create_request(:post, header: header, body: body)
|
77
|
-
|
78
|
-
res = req.run
|
79
|
-
|
80
|
-
raise SabredavClient::Errors::ShareeTypeNotSupportedError if type && type != :email
|
81
|
-
|
82
|
-
if res.code.to_i.between?(200,299)
|
83
|
-
true
|
84
|
-
else
|
85
|
-
SabredavClient::Errors::errorhandling(res)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
def fetch_sharees
|
90
|
-
body = SabredavClient::XmlRequestBuilder::PropfindInvite.new.to_xml
|
91
|
-
header = {content_type: "application/xml", depth: "0"}
|
92
|
-
|
93
|
-
req = client.create_request(:propfind, header: header, body: body)
|
94
|
-
|
95
|
-
res = req.run
|
96
|
-
|
97
|
-
SabredavClient::Errors::errorhandling(res)
|
98
|
-
|
99
|
-
sharees = []
|
100
|
-
xml = REXML::Document.new(res.body)
|
101
|
-
|
102
|
-
REXML::XPath.each(xml, "//cs:user/", {"cs"=> "http://calendarserver.org/ns/"}) do |user|
|
103
|
-
entry = REXML::Document.new.add(user)
|
104
|
-
sharee = {
|
105
|
-
href: REXML::XPath.first(entry, "//d:href").text,
|
106
|
-
}
|
107
|
-
access = REXML::XPath.first(entry, "//d:access").elements[1].to_s
|
108
|
-
sharee[:access] = access.gsub(/\A[<cs:]+|[\/>]+\Z/, "")
|
109
|
-
|
110
|
-
# So far Sabredav accepts every invite by default
|
111
|
-
sharee[:status] = !REXML::XPath.first(entry, "//cs:invite-accepted").nil? ? :accepted : nil
|
112
|
-
|
113
|
-
sharee[:common_name] = !REXML::XPath.first(entry, "//d:common-name").nil? ? REXML::XPath.first(entry, "//d:common-name").text : nil
|
114
|
-
|
115
|
-
# URI depends on a custom plugin
|
116
|
-
sharee[:uri] = !REXML::XPath.first(entry, "//cs:uri").nil? ? REXML::XPath.first(entry, "//cs:uri").text : nil
|
117
|
-
|
118
|
-
# URI depends on a custom plugin
|
119
|
-
sharee[:principal] = !REXML::XPath.first(entry, "//cs:principal").nil? ? REXML::XPath.first(entry, "//cs:principal").text : nil
|
120
|
-
|
121
|
-
sharees.push(sharee)
|
122
|
-
end
|
123
|
-
|
124
|
-
{
|
125
|
-
sharees: sharees,
|
126
|
-
organizer: {
|
127
|
-
href: REXML::XPath.first(xml, "//cs:organizer").elements[2].text,
|
128
|
-
uri: REXML::XPath.first(xml, "//cs:uri").text
|
129
|
-
}
|
130
|
-
}
|
131
|
-
|
132
|
-
end
|
133
|
-
|
134
|
-
def fetch_changes(sync_token)
|
135
|
-
|
136
|
-
body = SabredavClient::XmlRequestBuilder::ReportEventChanges.new(sync_token).to_xml
|
137
|
-
header = {content_type: "application/xml"}
|
138
|
-
|
139
|
-
req = client.create_request(:report, header: header, body: body)
|
140
|
-
|
141
|
-
res = req.run
|
142
|
-
|
143
|
-
SabredavClient::Errors::errorhandling(res)
|
144
|
-
|
145
|
-
changes = []
|
146
|
-
deletions = []
|
147
|
-
xml = REXML::Document.new(res.body)
|
148
|
-
|
149
|
-
#FIXME This is so damn ugly, but at least it`s working now
|
150
|
-
REXML::XPath.each(xml, "//d:response/", {"d"=> "DAV:"}) do |response|
|
151
|
-
entry = REXML::Document.new.add(response)
|
152
|
-
if (REXML::XPath.first(entry, "//d:status").text == "HTTP/1.1 404 Not Found")
|
153
|
-
deletions.push(
|
154
|
-
REXML::XPath.first(entry, "//d:href").text.to_s.split("/").last)
|
155
|
-
else
|
156
|
-
changes.push(
|
157
|
-
{
|
158
|
-
uri: REXML::XPath.first(entry, "//d:href").text.split("/").last,
|
159
|
-
etag: REXML::XPath.first(entry, "//d:getetag").text
|
160
|
-
})
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
{
|
165
|
-
changes: changes,
|
166
|
-
deletions: deletions,
|
167
|
-
sync_token: REXML::XPath.first(xml, "//d:sync-token").text
|
168
|
-
}
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|
1
|
+
module SabredavClient
|
2
|
+
|
3
|
+
class Calendar
|
4
|
+
attr_accessor :client
|
5
|
+
|
6
|
+
def initialize(data)
|
7
|
+
@client = SabredavClient::Client.new(data)
|
8
|
+
end
|
9
|
+
|
10
|
+
def events
|
11
|
+
@events ||= SabredavClient::Events.new(client)
|
12
|
+
end
|
13
|
+
|
14
|
+
def info
|
15
|
+
header = {content_type: "application/xml"}
|
16
|
+
body = SabredavClient::XmlRequestBuilder::PROPFINDCalendar.new(properties: [:displayname, :sync_token, :getctag]).to_xml
|
17
|
+
|
18
|
+
req = client.create_request(:propfind, header: header, body: body)
|
19
|
+
res = req.run
|
20
|
+
|
21
|
+
SabredavClient::Errors::errorhandling(res)
|
22
|
+
|
23
|
+
xml = REXML::Document.new(res.body)
|
24
|
+
{
|
25
|
+
displayname: REXML::XPath.first(xml, "//d:displayname").text,
|
26
|
+
ctag: REXML::XPath.first(xml, "//cs:getctag").text,
|
27
|
+
sync_token: REXML::XPath.first(xml, "//d:sync-token").text
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def create(displayname: "", description: "")
|
32
|
+
body = SabredavClient::XmlRequestBuilder::Mkcalendar.new(displayname, description).to_xml
|
33
|
+
header = {dav: "resource-must-be-null", content_type: "application/xml"}
|
34
|
+
|
35
|
+
req = client.create_request(:mkcalendar, header: header, body: body)
|
36
|
+
|
37
|
+
res = req.run
|
38
|
+
|
39
|
+
SabredavClient::Errors.errorhandling(res)
|
40
|
+
info
|
41
|
+
end
|
42
|
+
|
43
|
+
def update(displayname: nil, description: nil)
|
44
|
+
body = XmlRequestBuilder::ProppatchCalendar.new(displayname, description).to_xml
|
45
|
+
header = {content_type: "application/xml"}
|
46
|
+
|
47
|
+
req = client.create_request(:proppatch, header: header, body: body)
|
48
|
+
|
49
|
+
res = req.run
|
50
|
+
|
51
|
+
if res.code.to_i.between?(200,299)
|
52
|
+
true
|
53
|
+
else
|
54
|
+
SabredavClient::Errors::errorhandling(res)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def delete
|
59
|
+
req = client.create_request(:delete)
|
60
|
+
res = req.run
|
61
|
+
|
62
|
+
if res.code.to_i.between?(200,299)
|
63
|
+
true
|
64
|
+
else
|
65
|
+
SabredavClient::Errors::errorhandling(res)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def share(adds: [], removes: [], summary: nil, common_name: nil,
|
70
|
+
privilege: "write-read", type: nil)
|
71
|
+
|
72
|
+
header = {content_length: "xxxx", content_type: "application/xml"}
|
73
|
+
body = SabredavClient::XmlRequestBuilder::PostSharing.new(
|
74
|
+
adds, summary, common_name, privilege, removes).to_xml
|
75
|
+
|
76
|
+
req = client.create_request(:post, header: header, body: body)
|
77
|
+
|
78
|
+
res = req.run
|
79
|
+
|
80
|
+
raise SabredavClient::Errors::ShareeTypeNotSupportedError if type && type != :email
|
81
|
+
|
82
|
+
if res.code.to_i.between?(200,299)
|
83
|
+
true
|
84
|
+
else
|
85
|
+
SabredavClient::Errors::errorhandling(res)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def fetch_sharees
|
90
|
+
body = SabredavClient::XmlRequestBuilder::PropfindInvite.new.to_xml
|
91
|
+
header = {content_type: "application/xml", depth: "0"}
|
92
|
+
|
93
|
+
req = client.create_request(:propfind, header: header, body: body)
|
94
|
+
|
95
|
+
res = req.run
|
96
|
+
|
97
|
+
SabredavClient::Errors::errorhandling(res)
|
98
|
+
|
99
|
+
sharees = []
|
100
|
+
xml = REXML::Document.new(res.body)
|
101
|
+
|
102
|
+
REXML::XPath.each(xml, "//cs:user/", {"cs"=> "http://calendarserver.org/ns/"}) do |user|
|
103
|
+
entry = REXML::Document.new.add(user)
|
104
|
+
sharee = {
|
105
|
+
href: REXML::XPath.first(entry, "//d:href").text,
|
106
|
+
}
|
107
|
+
access = REXML::XPath.first(entry, "//d:access").elements[1].to_s
|
108
|
+
sharee[:access] = access.gsub(/\A[<cs:]+|[\/>]+\Z/, "")
|
109
|
+
|
110
|
+
# So far Sabredav accepts every invite by default
|
111
|
+
sharee[:status] = !REXML::XPath.first(entry, "//cs:invite-accepted").nil? ? :accepted : nil
|
112
|
+
|
113
|
+
sharee[:common_name] = !REXML::XPath.first(entry, "//d:common-name").nil? ? REXML::XPath.first(entry, "//d:common-name").text : nil
|
114
|
+
|
115
|
+
# URI depends on a custom plugin
|
116
|
+
sharee[:uri] = !REXML::XPath.first(entry, "//cs:uri").nil? ? REXML::XPath.first(entry, "//cs:uri").text : nil
|
117
|
+
|
118
|
+
# URI depends on a custom plugin
|
119
|
+
sharee[:principal] = !REXML::XPath.first(entry, "//cs:principal").nil? ? REXML::XPath.first(entry, "//cs:principal").text : nil
|
120
|
+
|
121
|
+
sharees.push(sharee)
|
122
|
+
end
|
123
|
+
|
124
|
+
{
|
125
|
+
sharees: sharees,
|
126
|
+
organizer: {
|
127
|
+
href: REXML::XPath.first(xml, "//cs:organizer").elements[2].text,
|
128
|
+
uri: REXML::XPath.first(xml, "//cs:uri").text
|
129
|
+
}
|
130
|
+
}
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
def fetch_changes(sync_token)
|
135
|
+
|
136
|
+
body = SabredavClient::XmlRequestBuilder::ReportEventChanges.new(sync_token).to_xml
|
137
|
+
header = {content_type: "application/xml"}
|
138
|
+
|
139
|
+
req = client.create_request(:report, header: header, body: body)
|
140
|
+
|
141
|
+
res = req.run
|
142
|
+
|
143
|
+
SabredavClient::Errors::errorhandling(res)
|
144
|
+
|
145
|
+
changes = []
|
146
|
+
deletions = []
|
147
|
+
xml = REXML::Document.new(res.body)
|
148
|
+
|
149
|
+
#FIXME This is so damn ugly, but at least it`s working now
|
150
|
+
REXML::XPath.each(xml, "//d:response/", {"d"=> "DAV:"}) do |response|
|
151
|
+
entry = REXML::Document.new.add(response)
|
152
|
+
if (REXML::XPath.first(entry, "//d:status").text == "HTTP/1.1 404 Not Found")
|
153
|
+
deletions.push(
|
154
|
+
REXML::XPath.first(entry, "//d:href").text.to_s.split("/").last)
|
155
|
+
else
|
156
|
+
changes.push(
|
157
|
+
{
|
158
|
+
uri: REXML::XPath.first(entry, "//d:href").text.split("/").last,
|
159
|
+
etag: REXML::XPath.first(entry, "//d:getetag").text
|
160
|
+
})
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
{
|
165
|
+
changes: changes,
|
166
|
+
deletions: deletions,
|
167
|
+
sync_token: REXML::XPath.first(xml, "//d:sync-token").text
|
168
|
+
}
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|