sabredav_client 0.1.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.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +3 -0
  3. data/.rspec +1 -0
  4. data/CHANGELOG.rdoc +8 -0
  5. data/Gemfile +3 -0
  6. data/Gemfile.lock +46 -0
  7. data/README.md +131 -0
  8. data/Rakefile +6 -0
  9. data/lib/sabredav_client/calendar.rb +111 -0
  10. data/lib/sabredav_client/client.rb +57 -0
  11. data/lib/sabredav_client/errors/errors.rb +38 -0
  12. data/lib/sabredav_client/events.rb +97 -0
  13. data/lib/sabredav_client/format.rb +54 -0
  14. data/lib/sabredav_client/net.rb +15 -0
  15. data/lib/sabredav_client/principal.rb +36 -0
  16. data/lib/sabredav_client/request.rb +97 -0
  17. data/lib/sabredav_client/version.rb +3 -0
  18. data/lib/sabredav_client/xml_request_builder/base.rb +17 -0
  19. data/lib/sabredav_client/xml_request_builder/mkcalendar.rb +25 -0
  20. data/lib/sabredav_client/xml_request_builder/mkcol_principal.rb +28 -0
  21. data/lib/sabredav_client/xml_request_builder/post_sharing.rb +41 -0
  22. data/lib/sabredav_client/xml_request_builder/propfind_calendar.rb +41 -0
  23. data/lib/sabredav_client/xml_request_builder/propfind_owner.rb +19 -0
  24. data/lib/sabredav_client/xml_request_builder/proppatch_owner.rb +23 -0
  25. data/lib/sabredav_client/xml_request_builder/report_event_changes.rb +22 -0
  26. data/lib/sabredav_client/xml_request_builder/report_vevent.rb +30 -0
  27. data/lib/sabredav_client/xml_request_builder/report_vtodo.rb +20 -0
  28. data/lib/sabredav_client/xml_request_builder.rb +6 -0
  29. data/lib/sabredav_client.rb +12 -0
  30. data/sabredav_client.gemspec +33 -0
  31. data/spec/fixtures/calendar_fetch_changes.xml +26 -0
  32. data/spec/fixtures/calendar_info.xml +14 -0
  33. data/spec/fixtures/event.ics +23 -0
  34. data/spec/fixtures/events_find_multiple.xml +51 -0
  35. data/spec/fixtures/events_owner.xml +12 -0
  36. data/spec/fixtures/xml_request_builder/mkcalendar.xml +9 -0
  37. data/spec/fixtures/xml_request_builder/mkcol_principal.xml +12 -0
  38. data/spec/fixtures/xml_request_builder/post_sharing.xml +18 -0
  39. data/spec/fixtures/xml_request_builder/propfind_calendar/all_properties.xml +8 -0
  40. data/spec/fixtures/xml_request_builder/propfind_owner.xml +6 -0
  41. data/spec/fixtures/xml_request_builder/proppatch_owner.xml +8 -0
  42. data/spec/fixtures/xml_request_builder/report_event_changes.xml +8 -0
  43. data/spec/sabredav_client/calendar_spec.rb +101 -0
  44. data/spec/sabredav_client/client_spec.rb +41 -0
  45. data/spec/sabredav_client/events_spec.rb +91 -0
  46. data/spec/sabredav_client/principal_spec.rb +38 -0
  47. data/spec/sabredav_client/request_spec.rb +55 -0
  48. data/spec/sabredav_client/xml_request_builder_specs/base_spec.rb +30 -0
  49. data/spec/sabredav_client/xml_request_builder_specs/mkcalendar_spec.rb +13 -0
  50. data/spec/sabredav_client/xml_request_builder_specs/mkcol_principal_spec.rb +13 -0
  51. data/spec/sabredav_client/xml_request_builder_specs/post_sharing_spec.rb +15 -0
  52. data/spec/sabredav_client/xml_request_builder_specs/propfind_calendar_spec.rb +24 -0
  53. data/spec/sabredav_client/xml_request_builder_specs/propfind_owner_spec.rb +14 -0
  54. data/spec/sabredav_client/xml_request_builder_specs/proppatch_owner_spec.rb +14 -0
  55. data/spec/sabredav_client/xml_request_builder_specs/report_event_changes_spec.rb +15 -0
  56. data/spec/spec.opts +5 -0
  57. data/spec/spec_helper.rb +8 -0
  58. metadata +185 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5a3c684d5190fe9608d786b4619fc6494ead48b7
4
+ data.tar.gz: b44836242e58f0ed59c074f71b76b1ac1f145fa2
5
+ SHA512:
6
+ metadata.gz: 31bb29f8199f0a2e1fc1c3fc46120951aa79131d631637eedcf3e5d61acf463418f39684a24341a24cecb9050e6b7bdfd0a1f744aa89c07f193e05fc91ecc955
7
+ data.tar.gz: 2ac0d0920b6ae3500f8cef24e6396756fba06bcafda200bafe0e0cf3509ff27839528f75af580fd0c716dc4640da226143bfb88f4886bf751de27dd9601d1b00
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ caldaver-test.sh
2
+ *.gem
3
+ *.tmp
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour
data/CHANGELOG.rdoc ADDED
@@ -0,0 +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", ...)
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,46 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ sabredav_client (0.2.6.0)
5
+ builder (~> 3.2)
6
+ icalendar (~> 2.4)
7
+ net-http-digest_auth (~> 1.4)
8
+ uuid (~> 2.3)
9
+
10
+ GEM
11
+ remote: https://rubygems.org/
12
+ specs:
13
+ builder (3.2.2)
14
+ diff-lcs (1.2.5)
15
+ fakeweb (1.3.0)
16
+ icalendar (2.4.0)
17
+ macaddr (1.7.1)
18
+ systemu (~> 2.6.2)
19
+ net-http-digest_auth (1.4)
20
+ rspec (3.5.0)
21
+ rspec-core (~> 3.5.0)
22
+ rspec-expectations (~> 3.5.0)
23
+ rspec-mocks (~> 3.5.0)
24
+ rspec-core (3.5.2)
25
+ rspec-support (~> 3.5.0)
26
+ rspec-expectations (3.5.0)
27
+ diff-lcs (>= 1.2.0, < 2.0)
28
+ rspec-support (~> 3.5.0)
29
+ rspec-mocks (3.5.0)
30
+ diff-lcs (>= 1.2.0, < 2.0)
31
+ rspec-support (~> 3.5.0)
32
+ rspec-support (3.5.0)
33
+ systemu (2.6.5)
34
+ uuid (2.3.8)
35
+ macaddr (~> 1.0)
36
+
37
+ PLATFORMS
38
+ ruby
39
+
40
+ DEPENDENCIES
41
+ fakeweb (~> 1.3)
42
+ rspec (~> 3.5)
43
+ sabredav_client!
44
+
45
+ BUNDLED WITH
46
+ 1.12.5
data/README.md ADDED
@@ -0,0 +1,131 @@
1
+ #Ruby CalDAV library named "agcaldav"
2
+ **agcaldav is a CalDAV library based on martinpovolny/ruby-caldav and 4fthawaiian/ruby-caldav and collectiveidea/caldav**
3
+
4
+ **Please keep in mind, agcaldav 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 agcaldav
11
+
12
+ and require it
13
+
14
+ require "agcaldav"
15
+
16
+ Next you have to obtain the URI, username and password to a CalDAV-Server. If you don't have one try RADICALE (https://github.com/agilastic/Radicale). It's small, simple and written in python. In the following steps I'm using the default params of Radical.
17
+
18
+
19
+ Now you can e.g. create a new AgCalDAV-Client:
20
+
21
+ cal = AgCalDAV::Client.new(:uri => "http://localhost:5232/user/calendar", :user => "user" , :password => "")
22
+
23
+ Alternatively, the proxy parameters can be specified:
24
+
25
+ cal = AgCalDAV::Client.new(:uri => "http://localhost:5232/user/calendar",:user => "user" , :password => "password", :proxy_uri => "http://my-proxy.com:8080")
26
+
27
+
28
+ ####Create an Event
29
+
30
+ result = cal.create_event(:start => "2012-12-29 10:00", :end => "2012-12-30 12:00", :title => "12345", :description => "12345 12345")
31
+
32
+ Analyze result:
33
+
34
+ >> result
35
+ => #<Icalendar::Event:0x007ff653b47520 @name="VEVENT", @components={}, @properties={"sequence"=>0, "dtstamp"=>#<DateTime: 2012-12-30T19:59:04+00:00 (26527957193/10800,0/1,2299161)>, "description"=>"sdkvjsdf sdkf sdkfj sdkf dsfj", "dtend"=>#<DateTime: 2012-12-30T12:00:00+00:00 (2456292/1,0/1,2299161)>, "dtstart"=>#<DateTime: 2012-12-29T10:00:00+00:00 (29475491/12,0/1,2299161)>, "summary"=>"12345", "uid"=>"e795c480-34e0-0130-7d1d-109add70606c", "x-radicale_name"=>"e795c480-34e0-0130-7d1d-109add70606c.ics"}>
36
+
37
+ >> result.class
38
+ => Icalendar::Event
39
+
40
+
41
+ get UID of this Event:
42
+
43
+ >> result.uid
44
+ => "e795c480-34e0-0130-7d1d-109add70606c"
45
+
46
+
47
+ ####Find an Event (via UUID)
48
+
49
+ result = cal.find_event("e795c480-34e0-0130-7d1d-109add70606c")
50
+
51
+ >> result.class
52
+ => Icalendar::Event
53
+
54
+
55
+ ####Find Events within time interval
56
+
57
+ result = cal.find_events(:start => "2012-10-01 08:00", :end => "2013-01-01")
58
+
59
+ >> result
60
+ => [#<Icalendar::Event:0x007f8ad11cfdf0 @name="VEVENT", @components={}, @properties={"sequence"=>0, "dtstamp"=>#<DateTime: 2012-12-31T13:44:10+00:00 (4244474429/1728,0/1,2299161)>, "description"=>"sdkvjsdf sdkf sdkfj sdkf dsfj", "dtend"=>#<DateTime: 2012-12-30T12:00:00+00:00 (2456292/1,0/1,2299161)>, "dtstart"=>#<DateTime: 2012-12-29T10:00:00+00:00 (29475491/12,0/1,2299161)>, "summary"=>"12345", "uid"=>"b2c45e20-3575-0130-7d2e-109add70606c", "x-radicale_name"=>"b2c45e20-3575-0130-7d2e-109add70606c.ics"}>, #<Icalendar::Event:0x007f8ad10d7dd0 @name="VEVENT", @components={}, @properties={"sequence"=>0, "dtstamp"=>#<DateTime: 2012-12-31T13:44:10+00:00 (4244474429/1728,0/1,2299161)>, "uid"=>"b2c45e20-3575-0130-7d2e-109add70606c", "x-radicale_name"=>"b2c45e20-3575-0130-7d2e-109add70606c.ics"}>]
61
+
62
+ >> result.class
63
+ => Array
64
+
65
+ >> result.count
66
+ => 2
67
+
68
+
69
+
70
+ ####Update Event
71
+
72
+ event = {:start => "2012-12-29 10:00", :end => "2012-12-30 12:00", :title => "12345", :description => "sdkvjsdf sdkf sdkfj sdkf dsfj"}
73
+ # set UUID
74
+ event[:uid] => "e795c480-34e0-0130-7d1d-109add70606c"
75
+ c = cal.update_event(event)
76
+
77
+
78
+
79
+ ####Delete Event
80
+
81
+ cal.delete_event("e795c480-34e0-0130-7d1d-109add70606c")
82
+
83
+
84
+
85
+
86
+ ##Usage ToDo
87
+
88
+ ####not finished ATM
89
+ Have a look tomorrow...
90
+
91
+
92
+
93
+ ##Work to be done ...
94
+
95
+ 1. find and notify if overlapping events
96
+ 2. code cleanup -> more ActiveRecord style
97
+
98
+
99
+
100
+
101
+ ##Testing
102
+
103
+ agcaldav will use RSpec for its test coverage. Inside the gem
104
+ directory, you can run the specs for RoR 3.x with:
105
+
106
+ rake spec
107
+ (will be implemented in > v0.2.5)
108
+
109
+
110
+
111
+ ##Licence
112
+
113
+ MIT
114
+
115
+
116
+
117
+ ##Contributors
118
+
119
+ [Check all contributors][c]
120
+
121
+
122
+ 1. Fork it.
123
+ 2. Create a branch (`git checkout -b my_feature_branch`)
124
+ 3. Commit your changes (`git commit -am "bugfixed abc..."`)
125
+ 4. Push to the branch (`git push origin my_feature_branch`)
126
+ 5. Open a [Pull Request][1]
127
+ 6. Enjoy a refreshing Club Mate and wait
128
+
129
+ [c]: https://github.com/agilastic/agcaldav/contributors
130
+ [1]: https://github.com/agilastic/agcaldav/pulls/
131
+
data/Rakefile ADDED
@@ -0,0 +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
6
+ task :default => :spec
@@ -0,0 +1,111 @@
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 delete
44
+ req = client.create_request(:delete)
45
+ res = req.run
46
+
47
+ if res.code.to_i.between?(200,299)
48
+ true
49
+ else
50
+ SabredavClient::Errors::errorhandling(res)
51
+ end
52
+ end
53
+
54
+ def share(adds: [], removes: [], summary: nil, common_name: nil,
55
+ privilege: "write-read", type: nil)
56
+
57
+ header = {content_length: "xxxx", content_type: "application/xml"}
58
+ body = SabredavClient::XmlRequestBuilder::PostSharing.new(
59
+ adds, summary, common_name, privilege, removes).to_xml
60
+
61
+ req = client.create_request(:post, header: header, body: body)
62
+
63
+ res = req.run
64
+
65
+ raise SabredavClient::Errors::ShareeTypeNotSupportedError if type && type != :email
66
+
67
+ if res.code.to_i.between?(200,299)
68
+ true
69
+ else
70
+ SabredavClient::Errors::errorhandling(res)
71
+ end
72
+ end
73
+
74
+ def fetch_changes(sync_token)
75
+
76
+ body = SabredavClient::XmlRequestBuilder::ReportEventChanges.new(sync_token).to_xml
77
+ header = {content_type: "application/xml"}
78
+
79
+ req = client.create_request(:report, header: header, body: body)
80
+
81
+ res = req.run
82
+
83
+ SabredavClient::Errors::errorhandling(res)
84
+
85
+ changes = []
86
+ deletions = []
87
+ xml = REXML::Document.new(res.body)
88
+
89
+ #FIXME This is so damn ugly, but at least it`s working now
90
+ REXML::XPath.each(xml, "//d:response/", {"d"=> "DAV:"}) do |response|
91
+ entry = REXML::Document.new.add(response)
92
+ if (REXML::XPath.first(entry, "//d:status").text == "HTTP/1.1 404 Not Found")
93
+ deletions.push(
94
+ REXML::XPath.first(entry, "//d:href").text.to_s.split("/").last)
95
+ else
96
+ changes.push(
97
+ {
98
+ uri: REXML::XPath.first(entry, "//d:href").text.split("/").last,
99
+ etag: REXML::XPath.first(entry, "//d:getetag").text
100
+ })
101
+ end
102
+ end
103
+
104
+ {
105
+ changes: changes,
106
+ deletions: deletions,
107
+ sync_token: REXML::XPath.first(xml, "//d:sync-token").text
108
+ }
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,57 @@
1
+ module SabredavClient
2
+ class Client
3
+ attr_reader :authtype, :host, :port, :base_path, :user, :password, :ssl,
4
+ :digest_auth, :duri, :proxy_host, :proxy_uri, :proxy_port, :base_path
5
+
6
+ def format=(fmt)
7
+ @format = fmt
8
+ end
9
+
10
+ def format
11
+ @format ||= Format::Debug.new
12
+ end
13
+
14
+ def initialize(data)
15
+ unless data[:proxy_uri].nil?
16
+ proxy_uri = URI(data[:proxy_uri])
17
+ @proxy_host = proxy_uri.host
18
+ @proxy_port = proxy_uri.port.to_i
19
+ end
20
+
21
+ uri = URI(data[:uri])
22
+
23
+ @host = uri.host
24
+ @port = uri.port.to_i
25
+ @base_path = uri.path
26
+ @user = data[:user]
27
+ @password = data[:password]
28
+ @ssl = uri.scheme == 'https'
29
+
30
+ unless data[:authtype].nil?
31
+ @authtype = data[:authtype]
32
+
33
+ if @authtype == 'digest'
34
+
35
+ @digest_auth = Net::HTTP::DigestAuth.new
36
+ @duri = URI.parse data[:uri]
37
+ @duri.user = @user
38
+ @duri.password = @password
39
+
40
+ elsif @authtype == 'basic'
41
+ #Don't Raise or do anything else
42
+ else
43
+ raise "Authentication Type Specified Is Not Valid. Please use basic or digest"
44
+ end
45
+ else
46
+ @authtype = 'basic'
47
+ end
48
+ end
49
+
50
+ def create_request(method, header: {}, body: "", path: "")
51
+ request = SabredavClient::Request.new(method, self, path)
52
+ request.add_header(header) unless header.empty?
53
+ request.add_body(body) unless body.empty?
54
+ request
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,38 @@
1
+ module SabredavClient
2
+ module Errors
3
+
4
+ def self.errorhandling response
5
+ case response.code.to_i
6
+ when 401
7
+ raise SabredavClient::Errors::AuthenticationError
8
+ when 403
9
+ raise SabredavClient::Errors::ForbiddenError
10
+ when 404
11
+ raise SabredavClient::Errors::NotFoundError
12
+ when 405
13
+ raise SabredavClient::Errors::NotAllowedError
14
+ when 410
15
+ raise SabredavClient::Errors::NotExistError
16
+ when 412
17
+ raise SabredavClient::Errors::PreconditionFailed
18
+ when 500
19
+ raise SabredavClient::Errors::APIError
20
+ end
21
+ end
22
+
23
+ class SabredavClientError < StandardError; end
24
+
25
+ class PropertyNotSupportedError < SabredavClientError; end
26
+ class ShareeTypeNotSupportedError < SabredavClientError; end
27
+
28
+ class HTTPMethodNotSupportedError < SabredavClientError; end
29
+
30
+ class APIError < SabredavClientError; end
31
+ class ForbiddenError < APIError; end
32
+ class NotFoundError < APIError; end
33
+ class PreconditionFailed < APIError; end
34
+ class NotAllowedError < APIError; end
35
+ class AuthenticationError < APIError; end
36
+ class NotExistError < APIError; end
37
+ end
38
+ end
@@ -0,0 +1,97 @@
1
+ module SabredavClient
2
+
3
+ class Events
4
+ attr_accessor :client
5
+
6
+ def initialize(client)
7
+ @client = client
8
+ end
9
+
10
+ def find(uri)
11
+ req = client.create_request(:get, path: uri)
12
+ res = req.run
13
+
14
+ SabredavClient::Errors::errorhandling(res)
15
+ res.body
16
+ end
17
+
18
+ def find_multiple(starts: "", ends: "")
19
+ events = []
20
+ header = {depth: "1", content_type: "application/xml"}
21
+
22
+ if starts.is_a? Integer
23
+ body = SabredavClient::XmlRequestBuilder::ReportVEVENT.new(Time.at(starts).utc.strftime("%Y%m%dT%H%M%S"),
24
+ Time.at(ends).utc.strftime("%Y%m%dT%H%M%S") ).to_xml
25
+ else
26
+ body = SabredavClient::XmlRequestBuilder::ReportVEVENT.new(Time.parse(starts).utc.strftime("%Y%m%dT%H%M%S"),
27
+ Time.parse(ends).utc.strftime("%Y%m%dT%H%M%S") ).to_xml
28
+ end
29
+
30
+ req = client.create_request(:report, header: header)
31
+ res = req.run
32
+
33
+ SabredavClient::Errors::errorhandling(res)
34
+ result = ""
35
+
36
+ xml = REXML::Document.new(res.body)
37
+ REXML::XPath.each( xml, '//c:calendar-data/', {"c"=>"urn:ietf:params:xml:ns:caldav"} ){|c| result << c.text}
38
+
39
+ calendar = Icalendar::Calendar.parse(result).first
40
+ if calendar
41
+ calendar.events
42
+ else
43
+ false
44
+ end
45
+ end
46
+
47
+ def owner(uri)
48
+ header = {content_type: "application/xml"}
49
+ body = XmlRequestBuilder::PropfindOwner.new.to_xml
50
+ req = client.create_request(:propfind, path: uri, header: header, body: body)
51
+ res = req.run
52
+
53
+ SabredavClient::Errors::errorhandling(res)
54
+ xml = REXML::Document.new(res.body)
55
+ REXML::XPath.first(xml, "//d:objectOwner").text
56
+ end
57
+
58
+ def update_owner(uri, owner)
59
+ header = {content_type: "application/xml"}
60
+ body = XmlRequestBuilder::ProppatchOwner.new(owner).to_xml
61
+ req = client.create_request(:proppatch, path: uri, header: header, body: body)
62
+ res = req.run
63
+
64
+ if res.code.to_i.between?(200,299)
65
+ true
66
+ else
67
+ SabredavClient::Errors::errorhandling(res)
68
+ end
69
+ end
70
+
71
+ def delete(uri)
72
+ req = client.create_request(:delete, path: uri)
73
+ res = req.run
74
+
75
+ if res.code.to_i.between?(200,299)
76
+ true
77
+ else
78
+ SabredavClient::Errors::errorhandling(res)
79
+ end
80
+ end
81
+
82
+ def create_update(uri, event_ics, etag = nil)
83
+ header = {content_type: "text/calendar"}
84
+ body = event_ics
85
+
86
+ if etag
87
+ header[:if_match] = %Q/"#{etag.gsub(/\A['"]+|['"]+\Z/, "")}"/
88
+ end
89
+
90
+ req = client.create_request(:put,header: header, body: body, path: uri)
91
+ res = req.run
92
+
93
+ SabredavClient::Errors::errorhandling(res)
94
+ res['etag']
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,54 @@
1
+ module SabredavClient
2
+ module Format
3
+ class Raw
4
+ def method_missing(m, *args, &block)
5
+ return *args
6
+ end
7
+ end
8
+
9
+ class Debug < Raw
10
+ end
11
+
12
+ class Pretty < Raw
13
+ def parse_calendar(s)
14
+ result = ""
15
+ xml = REXML::Document.new(s)
16
+
17
+ REXML::XPath.each( xml, '//c:calendar-data/', {"c"=>"urn:ietf:params:xml:ns:caldav"} ){|c| result << c.text}
18
+ r = Icalendar.parse(result)
19
+ r
20
+ end
21
+
22
+ def parse_todo( body )
23
+ result = []
24
+ xml = REXML::Document.new( body )
25
+ REXML::XPath.each( xml, '//c:calendar-data/', { "c"=>"urn:ietf:params:xml:ns:caldav"} ){ |c|
26
+ p c.text
27
+ p parse_tasks( c.text )
28
+ result += parse_tasks( c.text )
29
+ }
30
+ return result
31
+ end
32
+
33
+ def parse_tasks( vcal )
34
+ return_tasks = Array.new
35
+ cals = Icalendar.parse(vcal)
36
+ cals.each { |tcal|
37
+ tcal.todos.each { |ttask| # FIXME
38
+ return_tasks << ttask
39
+ }
40
+ }
41
+ return return_tasks
42
+ end
43
+
44
+ def parse_events( vcal )
45
+ Icalendar.parse(vcal)
46
+ end
47
+
48
+ def parse_single( body )
49
+ # FIXME: parse event/todo/vcard
50
+ parse_events( body )
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,15 @@
1
+ module Net
2
+ class HTTP
3
+ class Report < HTTPRequest
4
+ METHOD = 'REPORT'
5
+ REQUEST_HAS_BODY = true
6
+ RESPONSE_HAS_BODY = true
7
+ end
8
+
9
+ class Mkcalendar < HTTPRequest
10
+ METHOD = 'MKCALENDAR'
11
+ REQUEST_HAS_BODY = true
12
+ RESPONSE_HAS_BODY = true
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,36 @@
1
+ module SabredavClient
2
+
3
+ class Principal
4
+ attr_accessor :client
5
+
6
+ def initialize(data)
7
+ @client = SabredavClient::Client.new(data)
8
+ end
9
+
10
+ def create(email, displayname = nil)
11
+ header = {content_type: "text/xml", depth: "1"}
12
+ body = SabredavClient::XmlRequestBuilder::MkcolPrincipal.new(email, displayname).to_xml
13
+ req = client.create_request(:mkcol, header: header, body: body)
14
+
15
+ res = req.run
16
+ if res.code.to_i.between?(200,299)
17
+ true
18
+ else
19
+ SabredavClient::Errors::errorhandling(res)
20
+ end
21
+ end
22
+
23
+ def delete
24
+ #FIXME seems like deleting a principal is forbidden by sabredav
25
+ req = client.create_request(:delete)
26
+ res = req.run
27
+
28
+ if res.code.to_i.between?(200,299)
29
+ true
30
+ else
31
+ SabredavClient::Errors::errorhandling(res)
32
+ end
33
+ end
34
+
35
+ end
36
+ end