agcaldav 0.2 → 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.
data/README.md ADDED
@@ -0,0 +1,49 @@
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
+ ##Usage
5
+
6
+ First, you've to install the gem
7
+
8
+ gem install agcaldav
9
+
10
+ and require it
11
+
12
+ require "agcaldav"
13
+
14
+ 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.
15
+
16
+
17
+ Now you can e.g. create a new AgCalDAV-Client:
18
+
19
+ cal = AgCalDAV::Client.new(:uri => "http://localhost:5232/user/calendar", :user => "user" , :password => "")
20
+
21
+ Alternatively, the proxy parameters can be specified:
22
+
23
+ cal = AgCalDAV::Client.new(:uri => "http://localhost:5232/user/calendar",:user => "user" , :password => "password, :proxy_uri => "http://my-proxy.com:8080")
24
+
25
+
26
+ ####Create an Event and save it
27
+
28
+ result = cal.create_event(:start => "2012-12-29 10:00", :end => "2012-12-30 12:00", :title => "12345", :description => "sdkvjsdf sdkf sdkfj sdkf dsfj")
29
+
30
+ Determine Event UID:
31
+
32
+ result[:uid]
33
+
34
+
35
+ Find Event:
36
+
37
+ r = cal.find_event(result[:uid])
38
+
39
+
40
+ Find Events within time interval:
41
+
42
+ result = cal.find_events(:start => "2012-10-01 08:00", :end => "2013-01-01")
43
+ #TODO.... (no XML -> Icalendar with multiple events....)
44
+
45
+
46
+
47
+ ... next tomorrow ...
48
+
49
+
data/agcaldav.gemspec CHANGED
@@ -1,11 +1,11 @@
1
1
  # -*- encoding: utf-8 -*-
2
- require File.expand_path('../lib/caldav/version', __FILE__)
2
+ require File.expand_path('../lib/agcaldav/version', __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "agcaldav"
6
- s.version = CalDAV::VERSION
7
- s.summary = "new Ruby CalDAV client"
8
- s.description = "yet another new Ruby client for CalDAV calendar and tasks."
6
+ s.version = AgCalDAV::VERSION
7
+ s.summary = "Ruby CalDAV client"
8
+ s.description = "yet another great Ruby client for CalDAV calendar and tasks."
9
9
 
10
10
  s.required_ruby_version = '>= 1.9.2'
11
11
 
@@ -22,7 +22,8 @@ Gem::Specification.new do |s|
22
22
  s.add_runtime_dependency 'uuid'
23
23
  s.add_runtime_dependency 'builder'
24
24
  #s.add_dependency "json"
25
- #s.add_development_dependency "rspec"
25
+ s.add_development_dependency "rspec"
26
+ # sorry for no tests atm :-/
26
27
 
27
28
  s.files = `git ls-files`.split("\n")
28
29
  s.require_paths = ["lib"]
@@ -0,0 +1,154 @@
1
+ module AgCalDAV
2
+ class Client
3
+ include Icalendar
4
+ attr_accessor :host, :port, :url, :user, :password, :ssl
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
+ uri = URI(data[:uri])
21
+ @host = uri.host
22
+ @port = uri.port.to_i
23
+ @url = uri.path
24
+ @user = data[:user]
25
+ @password = data[:password]
26
+ @ssl = uri.scheme == 'https'
27
+ end
28
+
29
+ def __create_http
30
+ if @proxy_uri.nil?
31
+ http = Net::HTTP.new(@host, @port)
32
+ else
33
+ http = Net::HTTP.new(@host, @port, @proxy_host, @proxy_port)
34
+ end
35
+ if @ssl
36
+ http.use_ssl = @ssl
37
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
38
+ end
39
+ http
40
+ end
41
+
42
+ def find_events data
43
+ datetime_start = data[:start]
44
+ datetime_stop = data[:end]
45
+ res = nil
46
+ __create_http.start {|http|
47
+ req = Net::HTTP::Report.new(@url, initheader = {'Content-Type'=>'application/xml'} )
48
+ req.basic_auth @user, @password
49
+ req.body = AgCalDAV::Request::ReportVEVENT.new(DateTime.parse(datetime_start).strftime("%Y%m%dT%H%M"),
50
+ DateTime.parse(datetime_stop).strftime("%Y%m%dT%H%M") ).to_xml
51
+ res = http.request( req )
52
+ }
53
+ format.parse_calendar( res.body ) #TODO
54
+ #result = Icalendar.parse(res.body)
55
+ end
56
+
57
+ def find_event uuid
58
+ res = nil
59
+ __create_http.start {|http|
60
+ req = Net::HTTP::Get.new("#{@url}/#{uuid}.ics")
61
+ req.basic_auth @user, @password
62
+ res = http.request( req )
63
+ }
64
+ #raise AuthenticationError if res.code.to_i == 401
65
+ #raise APIError if res.code.to_i >= 500
66
+ result = Icalendar.parse(res.body)
67
+ result
68
+ end
69
+
70
+ def delete_event uuid
71
+ __create_http.start {|http|
72
+ req = Net::HTTP::Delete.new("#{@url}/#{uuid}.ics")
73
+ req.basic_auth @user, @password
74
+ res = http.request( req )
75
+ }
76
+ end
77
+
78
+ def create_event event
79
+ c = Calendar.new
80
+ uuid = UUID.new.generate
81
+ c.event do
82
+ uid uuid # still a BUG
83
+ dtstart DateTime.parse(event[:start])
84
+ dtend DateTime.parse(event[:end])
85
+ duration event[:duration]
86
+ summary event[:title]
87
+ description event[:description]
88
+ klass event[:accessibility] #PUBLIC, PRIVATE, CONFIDENTIAL
89
+ location event[:location]
90
+ geo_location event[:geo_location]
91
+ status event[:status]
92
+ end
93
+ c.publish
94
+ c.event.uid = uuid
95
+ cstring = c.to_ical
96
+ res = nil
97
+ http = Net::HTTP.new(@host, @port)
98
+ __create_http.start { |http|
99
+ req = Net::HTTP::Put.new("#{@url}/#{uuid}.ics")
100
+ req['Content-Type'] = 'text/calendar'
101
+ req.basic_auth @user, @password
102
+ req.body = cstring
103
+ res = http.request( req )
104
+ }
105
+ raise AuthenticationError if res.code.to_i == 401
106
+ raise APIError if res.code.to_i >= 500
107
+ {:uid => uuid, :cal => c, :cal_string => cstring, :response_code => res.code} #TODO
108
+ end
109
+
110
+ def add_alarm tevent, altCal="Calendar"
111
+ # FIXME create icalendar event -> cal.event.new (tevent)
112
+
113
+ # TODO
114
+
115
+
116
+
117
+
118
+ end
119
+
120
+ def update event
121
+ # FIXME old one not neat
122
+
123
+ # TODO
124
+ end
125
+
126
+ def todo
127
+ res = nil
128
+ __create_http.start {|http|
129
+ req = Net::HTTP::Report.new(@url, initheader = {'Content-Type'=>'application/xml'} )
130
+ req.basic_auth @user, @password
131
+ req.body = AgCalDAV::Request::ReportVTODO.new.to_xml
132
+ res = http.request( req )
133
+ }
134
+ # FIXME: process HTTP code
135
+ format.parse_todo( res.body )
136
+ end
137
+
138
+ def filterTimezone( vcal )
139
+ data = ""
140
+ inTZ = false
141
+ vcal.split("\n").each{ |l|
142
+ inTZ = true if l.index("BEGIN:VTIMEZONE")
143
+ data << l+"\n" unless inTZ
144
+ inTZ = false if l.index("END:VTIMEZONE")
145
+ }
146
+ return data
147
+ end
148
+ end
149
+
150
+ class AgCalDAVError < StandardError
151
+ end
152
+ class AuthenticationError < AgCalDAVError; end
153
+ class APIError < AgCalDAVError; end
154
+ end
@@ -1,4 +1,4 @@
1
- module CalDAV
1
+ module AgCalDAV
2
2
  module Filter
3
3
  class Base
4
4
  attr_accessor :parent, :child
@@ -1,4 +1,4 @@
1
- module CalDAV
1
+ module AgCalDAV
2
2
  module Format
3
3
  class Raw
4
4
  def method_missing(m, *args, &block)
@@ -1,11 +1,11 @@
1
- module CalDAV
1
+ module AgCalDAV
2
2
  class Query
3
3
  attr_accessor :child
4
4
 
5
5
  #TODO: raise error if to_xml is called before child is assigned
6
6
  def to_xml(xml = Builder::XmlMarkup.new(:indent => 2))
7
7
  xml.instruct!
8
- xml.tag! "cal:calendar-query", CalDAV::NAMESPACES do
8
+ xml.tag! "cal:calendar-query", AgCalDAV::NAMESPACES do
9
9
  xml.tag! "dav:prop" do
10
10
  xml.tag! "dav:getetag"
11
11
  xml.tag! "cal:calendar-data"
@@ -1,6 +1,6 @@
1
1
  require 'builder'
2
2
 
3
- module CalDAV
3
+ module AgCalDAV
4
4
  NAMESPACES = { "xmlns:d" => 'DAV:', "xmlns:c" => "urn:ietf:params:xml:ns:caldav" }
5
5
  module Request
6
6
  class Base
@@ -0,0 +1,3 @@
1
+ module AgCalDAV
2
+ VERSION="0.2.1"
3
+ end
@@ -2,18 +2,18 @@ require 'net/https'
2
2
  require 'uuid'
3
3
  require 'rexml/document'
4
4
  require 'rexml/xpath'
5
- require 'date'
6
5
  require 'icalendar'
7
6
  require 'time'
7
+ require 'date'
8
8
 
9
9
  ['client.rb', 'request.rb', 'net.rb', 'query.rb', 'filter.rb', 'format.rb'].each do |f|
10
- require File.join( File.dirname(__FILE__), 'caldav', f )
10
+ require File.join( File.dirname(__FILE__), 'agcaldav', f )
11
11
  end
12
12
 
13
13
  class Event
14
- attr_accessor :uid, :created, :dtstart, :dtend, :lastmodified, :summary, :description, :name, :action
14
+ attr_accessor :uid, :created, :dtstart, :dtend, :lastmodified, :summary, :description, :name, :action, :to_ical
15
15
  end
16
16
 
17
17
  class Todo
18
18
  attr_accessor :uid, :created, :summary, :dtstart, :status, :completed
19
- end
19
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: agcaldav
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.2'
4
+ version: 0.2.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-28 00:00:00.000000000 Z
12
+ date: 2012-12-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: icalendar
@@ -59,23 +59,39 @@ dependencies:
59
59
  - - ! '>='
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
- description: yet another new Ruby client for CalDAV calendar and tasks.
62
+ - !ruby/object:Gem::Dependency
63
+ name: rspec
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description: yet another great Ruby client for CalDAV calendar and tasks.
63
79
  email: ebeling-hoppe@agilastic.de
64
80
  executables: []
65
81
  extensions: []
66
82
  extra_rdoc_files: []
67
83
  files:
68
84
  - .gitignore
69
- - README.rdoc
85
+ - README.md
70
86
  - agcaldav.gemspec
71
- - lib/caldav.rb
72
- - lib/caldav/client.rb
73
- - lib/caldav/filter.rb
74
- - lib/caldav/format.rb
75
- - lib/caldav/net.rb
76
- - lib/caldav/query.rb
77
- - lib/caldav/request.rb
78
- - lib/caldav/version.rb
87
+ - lib/agcaldav.rb
88
+ - lib/agcaldav/client.rb
89
+ - lib/agcaldav/filter.rb
90
+ - lib/agcaldav/format.rb
91
+ - lib/agcaldav/net.rb
92
+ - lib/agcaldav/query.rb
93
+ - lib/agcaldav/request.rb
94
+ - lib/agcaldav/version.rb
79
95
  homepage: https://github.com/agilastic/agcaldav
80
96
  licenses:
81
97
  - MIT
@@ -100,5 +116,5 @@ rubyforge_project:
100
116
  rubygems_version: 1.8.24
101
117
  signing_key:
102
118
  specification_version: 3
103
- summary: new Ruby CalDAV client
119
+ summary: Ruby CalDAV client
104
120
  test_files: []
data/README.rdoc DELETED
@@ -1,3 +0,0 @@
1
- CalDAV library
2
-
3
- based on 4fthawaiian/ruby-caldav and collectiveidea/caldav and martinpovolny/ruby-caldav
data/lib/caldav/client.rb DELETED
@@ -1,214 +0,0 @@
1
- module CalDAV
2
- class Client
3
- include Icalendar
4
- attr_accessor :host, :port, :url, :user, :password, :ssl
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( *args )
15
- case args.length
16
- when 3
17
- __init_from_uri( *args )
18
- when 5
19
- __init_from_host_port( *args )
20
- else
21
- raise "#{self.class.to_s}: invalid number of arguments: #{args.length}"
22
- end
23
- end
24
-
25
- def __init_from_uri( suri, user, password )
26
- uri = URI( suri )
27
- @host = uri.host
28
- @port = uri.port
29
- @url = [ uri.scheme, '://', uri.host, uri.path ].join('') # FIXME: port?
30
- @user = user
31
- @password = password
32
- @ssl = uri.scheme == 'https'
33
- end
34
-
35
- def __init_from_host_port( host, port, url, user, password )
36
- @host = host
37
- @port = port
38
- @url = url
39
- @user = user
40
- @password = password
41
- @ssl = port == 443
42
- end
43
-
44
- def __create_http
45
- http = Net::HTTP.new(@host, @port)
46
- http.use_ssl = @ssl
47
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
48
- #http.set_debug_output $stderr
49
- http
50
- end
51
-
52
- def report datetime_start, datetime_stop
53
- res = nil
54
- __create_http.start {|http|
55
- req = Net::HTTP::Report.new(@url, initheader = {'Content-Type'=>'application/xml'} )
56
- req.basic_auth @user, @password
57
- req.body = CalDAV::Request::ReportVEVENT.new(DateTime.parse(datetime_start).strftime("%Y%m%dT%H%M"),
58
- DateTime.parse(datetime_stop).strftime("%Y%m%dT%H%M") ).to_xml
59
- res = http.request( req )
60
- }
61
- format.parse_calendar( res.body )
62
- end
63
-
64
- def get uuid
65
- res = nil
66
- __create_http.start {|http|
67
- req = Net::HTTP::Get.new("#{@url}/#{uuid}.ics")
68
- req.basic_auth @user, @password
69
- res = http.request( req )
70
- }
71
-
72
- # FIXME: process HTTP code
73
- format.parse_single( res.body )
74
- end
75
-
76
- def delete uuid
77
- __create_http.start {|http|
78
- req = Net::HTTP::Delete.new("#{@url}/#{uuid}.ics")
79
- req.basic_auth @user, @password
80
- res = http.request( req )
81
- }
82
- end
83
-
84
- def create event
85
- event.uid = UUID.generate
86
- event.dtstamp = DateTime.now.strftime "%Y%m%dT%H%M%SZ"
87
- event.dtstart = event.dtstart.strftime("%Y%m%dT%H%M%S")
88
- event.dtend = event.dtend.strftime("%Y%m%dT%H%M%S")
89
- cal = Calendar.new
90
- cal.event = Event.new(event)
91
- c = cal.to_ical
92
- res = nil
93
- http = Net::HTTP.new(@host, @port)
94
- __create_http.start { |http|
95
- req = Net::HTTP::Put.new("#{@url}/#{event.uid}.ics")
96
- req['Content-Type'] = 'text/calendar'
97
- req.basic_auth @user, @password
98
- req.body = dings
99
- res = http.request( req )
100
- }
101
- return event.uid, res
102
- end
103
-
104
- def add_alarm tevent, altCal="Calendar"
105
- #[#<Icalendar::Alarm:0x10b9d1b90 @name=\"VALARM\", @components={}, @properties={\"trigger\"=>\"-PT5M\", \"action\"=>\"DISPLAY\", \"description\"=>\"\"}>]
106
- dtstart_string = ( Time.parse(tevent.dtstart.to_s) + Time.now.utc_offset.to_i.abs ).strftime "%Y%m%dT%H%M%S"
107
- dtend_string = ( Time.parse(tevent.dtend.to_s) + Time.now.utc_offset.to_i.abs ).strftime "%Y%m%dT%H%M%S"
108
- alarmText = <<EOL
109
- BEGIN:VCALENDAR
110
- VERSION:2.0
111
- PRODID:Ruby iCalendar
112
- BEGIN:VEVENT
113
- UID:#{tevent.uid}
114
- SUMMARY:#{tevent.summary}
115
- DESCRIPTION:#{tevent.description}
116
- DTSTART:#{dtstart_string}
117
- DTEND:#{dtend_string}
118
- BEGIN:VALARM
119
- ACTION:DISPLAY
120
- TRIGGER;RELATED=START:-PT5M
121
- DESCRIPTION:Reminder
122
- END:VALARM
123
- BEGIN:VALARM
124
- TRIGGER:-PT5M
125
- ACTION:EMAIL
126
- ATTENDEE:#{tevent.organizer}
127
- SUMMARY:#{tevent.summary}
128
- DESCRIPTION:#{tevent.description}
129
- TRIGGER:-PT5M
130
- END:VALARM
131
- END:VEVENT
132
- END:VCALENDAR
133
- EOL
134
- p alarmText
135
- res = nil
136
- puts "#{@url}/#{tevent.uid}.ics"
137
- thttp = __create_http.start
138
- #thttp.set_debug_output $stderr
139
- req = Net::HTTP::Put.new("#{@url}/#{tevent.uid}.ics", initheader = {'Content-Type'=>'text/calendar'} )
140
- req.basic_auth @user, @password
141
- req.body = alarmText
142
- res = thttp.request( req )
143
- p res.inspect
144
-
145
- return tevent.uid
146
- end
147
-
148
- def update event
149
- dings = """BEGIN:VCALENDAR
150
- PRODID:Caldav.rb
151
- VERSION:2.0
152
-
153
- BEGIN:VTIMEZONE
154
- TZID:/Europe/Vienna
155
- X-LIC-LOCATION:Europe/Vienna
156
- BEGIN:DAYLIGHT
157
- TZOFFSETFROM:+0100
158
- TZOFFSETTO:+0200
159
- TZNAME:CEST
160
- DTSTART:19700329T020000
161
- RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=3
162
- END:DAYLIGHT
163
- BEGIN:STANDARD
164
- TZOFFSETFROM:+0200
165
- TZOFFSETTO:+0100
166
- TZNAME:CET
167
- DTSTART:19701025T030000
168
- RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10
169
- END:STANDARD
170
- END:VTIMEZONE
171
-
172
- BEGIN:VEVENT
173
- CREATED:#{event.created}
174
- UID:#{event.uid}
175
- SUMMARY:#{event.summary}
176
- DTSTART;TZID=Europe/Vienna:#{event.dtstart}
177
- DTEND;TZID=Europe/Vienna:#{event.dtend.rfc3339}
178
- END:VEVENT
179
- END:VCALENDAR"""
180
-
181
- res = nil
182
- __create_http.start {|http|
183
- req = Net::HTTP::Put.new("#{@url}/#{event.uid}.ics", initheader = {'Content-Type'=>'text/calendar'} )
184
- req.basic_auth @user, @password
185
- req.body = dings
186
- res = http.request( req )
187
- }
188
- return event.uid
189
- end
190
-
191
- def todo
192
- res = nil
193
- __create_http.start {|http|
194
- req = Net::HTTP::Report.new(@url, initheader = {'Content-Type'=>'application/xml'} )
195
- req.basic_auth @user, @password
196
- req.body = CalDAV::Request::ReportVTODO.new.to_xml
197
- res = http.request( req )
198
- }
199
- # FIXME: process HTTP code
200
- format.parse_todo( res.body )
201
- end
202
-
203
- def filterTimezone( vcal )
204
- data = ""
205
- inTZ = false
206
- vcal.split("\n").each{ |l|
207
- inTZ = true if l.index("BEGIN:VTIMEZONE")
208
- data << l+"\n" unless inTZ
209
- inTZ = false if l.index("END:VTIMEZONE")
210
- }
211
- return data
212
- end
213
- end
214
- end
@@ -1,3 +0,0 @@
1
- module CalDAV
2
- VERSION=0.2
3
- end
File without changes