sabredav_client 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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