zimbreasy 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -2,6 +2,4 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in zimbreasy.gemspec
4
4
  gemspec
5
- gem 'test-unit'
6
- gem 'savon', '~> 1.1.0'
7
- gem 'nokogiri'
5
+
data/README.md CHANGED
@@ -1,6 +1,21 @@
1
1
  # Zimbreasy
2
2
 
3
- Thanks to Crankin's 2007 for assisting me with this.
3
+ 2007!
4
+
5
+ Crankin will get that joke, he is to be thanked for assistance on this.
6
+
7
+ This is an open sourced wrapper for the Zimbra API. I only added functionality for CRUD on Calender Appointments,
8
+ because that's all I needed for the job I'm getting done. However, the code already contained within the libraries for calendars
9
+ and the structure make this an easily extensible gem if you need it for other purposes.
10
+
11
+ The API documentation I am using is located at
12
+
13
+ http://files.zimbra.com/docs/soap_api/8.0/soapapi-zimbra-doc/api-reference/index.html
14
+
15
+ Everybody who's interested in finally wrapping Zimbra well for Ruby, please download the gem and submit pull requests
16
+ with more of the methods on this API built out(there are over 100.)
17
+
18
+ This gem is still in it's infancy and has little to no error handling! I appreciate all the help I can get on this project, Zimbra is big!
4
19
 
5
20
  ## Installation
6
21
 
@@ -18,10 +33,38 @@ Or install it yourself as:
18
33
 
19
34
  ## Usage
20
35
 
21
- TODO: Write usage instructions here
36
+ It's pretty simple to use, I will post some examples:
37
+
38
+ zs = Zimbreasy::Account.new('username', 'password', "https://yourzimbraserver.com/service/soap"); #login
39
+ zm = Zimbreasy::Mail.new(zs); #create a Zimbreasy::Mail object. This has methods for the ZimbraMail submodule of their API.
40
+ z = zm.create_appointment({:appointee_email => "neo@matrix.com", :start_time => Time.now+1.days, :end_time => (Time.now+1.days+1.hours), :name => "Joss Whedon Meeting", :subject => "Hallelujah", :desc => "Ridiculous stuff happening here"}) #I create an appointment.
41
+
42
+ => "BEGIN:VCALENDAR\r\nCALSCALE:GREGORIAN\r\nPRODID:iCalendar-Ruby\r\nVERSION:2.0\r\nBEGIN:VEVENT\r\nDESCRIPTION:Poopmaster\r\nDTEND:20130208T171612\r\nDTSTAMP:20130207T161614\r\nDTSTART:20130208T161612\r\nCLASS:PRIVATE\r\nSEQUENCE:0\r\nSUMMARY:Jossss\r\nUID:336-335\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"
43
+
44
+
45
+ create_appointment returns ics formatted data, for use with icalendar. Notice that the UID in the data is 336-335. This is an invitation id, not an appointment id.
46
+ The appointment id is 336, the first part of it.
47
+
48
+ The Other methods of note:
49
+
50
+ zm.get_appointment(336) #takes appt id
51
+
52
+ zm.modify_appointment({:appointee_email => "neo@matrix.com", :start_time => Time.now, :end_time => (Time.now+2.hours), :name => "Joss Whedon!!!", :subject => "Hallelujah 2: The Electric Boogaloo", :desc => "Yoda Fights Back", :inv_id => "336-335"})
53
+
54
+ zm.cancel_appointment("336-335")
55
+
56
+ You'll notice get_appointment uses an actual appointment id, whereas modify appt and cancel appt need inv ids. I don't know why this is,
57
+ it seems Zimbra API only works with invitation, not appointment ids, when it comes to these methods. Get just needs appt ids. The final method of note is
58
+
59
+ zm.get_appt_summaries(Time.now-1.days, Time.now)
60
+
61
+ This just returns appointment Ics texts in an array.
22
62
 
23
63
  ## Contributing
24
64
 
65
+ It'd be great if someone could write tests for these methods, I haven't had the time. If you want to write tests,
66
+ please do!
67
+
25
68
  1. Fork it
26
69
  2. Create your feature branch (`git checkout -b my-new-feature`)
27
70
  3. Commit your changes (`git commit -am 'Added some feature'`)
@@ -1,5 +1,6 @@
1
1
  module Zimbreasy
2
2
  class Mail
3
+ include Icalendar
3
4
  attr_accessor :account, :zimbra_namespace
4
5
  def initialize(account)
5
6
  @account = account
@@ -12,25 +13,133 @@ module Zimbreasy
12
13
  #:end_time(opt)
13
14
  #:name(opt)
14
15
  #:subject(opt)
15
- #:content(opt)
16
+ #:desc(opt)
16
17
  #:mime_type(opt)
17
- #:organizer(opt)
18
+ #Returns Appt's Inv id as UID in an i_cal text.. Is normally a number like 140-141,
19
+ #the first number is the appt id, which you need for getting.
18
20
  def create_appointment(params)
19
- account.make_call("CreateAppointmentRequest") do |xml|
21
+ params[:start_time] = Zimbreasy.zimbra_date(params[:start_time]) if params[:start_time]
22
+ params[:end_time] = Zimbreasy.zimbra_date(params[:end_time]) if params[:end_time]
23
+
24
+ response = account.make_call("CreateAppointmentRequest") do |xml|
20
25
  xml.CreateAppointmentRequest({ "xmlns" => @zimbra_namespace}) do |xml|
21
- xml.m({"su" => params[:subject]}) do |xml|
22
- xml.content(params[:content])
23
- xml.mp({"ct" =>(params[:mime_type] || "text/plain")})
24
- xml.inv({"rsvp" => "1", "compNum" => "0", "method" => "none", "name" => params[:name] }) do |xml|
25
- xml.s({"d" => Zimbreasy.zimbra_date(params[:start_time])}) if params[:start_time]
26
- xml.e({"d" => Zimbreasy.zimbra_date(params[:end_time])}) if params[:end_time]
27
- end
28
-
29
- xml.e({"a" => params[:appointee_email], "t" => "t", "or" => params[:organizer]})
30
- end
26
+ appointment_xml_block(xml, params)
31
27
  end
32
28
  end
29
+ params.merge!({:appt_id => response.body[:create_appointment_response][:@inv_id]})
30
+ make_ical(params)
31
+ end
32
+
33
+ def make_ical(params)
34
+ calendar = Calendar.new
35
+ calendar.event do
36
+ dtstart params[:start_time]
37
+ dtend params[:end_time]
38
+ summary params[:name]
39
+ description params[:desc]
40
+ uid params[:appt_id]
41
+ klass "PRIVATE"
42
+ end
43
+
44
+ calendar.to_ical
45
+ end
46
+
47
+ def get_appointment(appt_id)
48
+ response = account.make_call("GetAppointmentRequest") do |xml|
49
+ xml.GetAppointmentRequest({ "xmlns" => @zimbra_namespace, "id" => appt_id})
50
+ end
51
+
52
+ comp = response[:get_appointment_response][:appt][:inv][:comp]
53
+
54
+ hash = {
55
+ :start_time => comp[:s][:@d],
56
+ :end_time => comp[:e][:@d],
57
+ :desc => comp[:desc],
58
+ :name => comp[:@name],
59
+ :appt_id => appt_id
60
+ }
61
+
62
+ make_ical(hash)
63
+ end
64
+
65
+ def get_appt_summaries(start_date, end_date)
66
+ start_date = start_date.to_i*1000 #it wants millis, to_i gives seconds.
67
+ end_date = end_date.to_i*1000
68
+
69
+ response = account.make_call("GetApptSummariesRequest") do |xml|
70
+ xml.GetApptSummariesRequest({ "xmlns" => @zimbra_namespace, "e" => end_date, "s" => start_date})
71
+ end
72
+
73
+ return [] if response[:get_appt_summaries_response][:appt].nil?
74
+
75
+ appts = []
76
+
77
+ response[:get_appt_summaries_response][:appt].each do |appt|
78
+
79
+ inst = appt[:inst]
80
+
81
+ hash = {
82
+ :start_time => Zimbreasy.zimbra_date(Time.at(inst[:@s].to_f/1000.0)),
83
+ :name => appt[:@name],
84
+ :appt_id => appt[:@id]
85
+ }
33
86
 
87
+ appts << make_ical(hash)
88
+ end
89
+
90
+ appts
34
91
  end
92
+
93
+ #same param options as create_appointment, but you can add :inv_id too.
94
+ def modify_appointment(params)
95
+ params[:start_time] = Zimbreasy.zimbra_date(params[:start_time]) if params[:start_time]
96
+ params[:end_time] = Zimbreasy.zimbra_date(params[:end_time]) if params[:end_time]
97
+
98
+ response = account.make_call("ModifyAppointmentRequest") do |xml|
99
+ xml.ModifyAppointmentRequest({
100
+ "xmlns" => @zimbra_namespace,
101
+ "id" => params[:inv_id]
102
+ }) do |xml|
103
+ appointment_xml_block(xml, params)
104
+ end
105
+ end
106
+
107
+ make_ical(params)
108
+ end
109
+
110
+ #returns true if it worked, inv_id is not appt_id, it's normally something like 320-319, the first number is appt_id.
111
+ def cancel_appointment(inv_id)
112
+ unless inv_id and inv_id.is_a?(String) and inv_id.match(/-/) and inv_id.split("-").count==2 #so it has x-y formatting.
113
+ raise 'inv_id must be string of format x-y, where x and y are numbers.'
114
+ end
115
+
116
+ response = account.make_call("CancelAppointmentRequest") do |xml|
117
+ xml.CancelAppointmentRequest({
118
+ "xmlns" => @zimbra_namespace,
119
+ "id" => inv_id,
120
+ "comp" => 0
121
+ }) do |xml|
122
+ xml.inv({"id" => inv_id, "method" => "none", "compNum" => "0", "rsvp" => "1"})
123
+ end
124
+ end
125
+
126
+ return !response.body[:cancel_appointment_response].nil?
127
+ end
128
+
129
+ private
130
+
131
+ def appointment_xml_block(xml, params)
132
+ xml.m({"su" => params[:subject]}) do |xml|
133
+ xml.mp({"ct" =>(params[:mime_type] || "text/plain")})
134
+ xml.inv({"rsvp" => "1", "compNum" => "0", "method" => "none", "name" => params[:name] }) do |xml|
135
+ xml.mp({"ct" =>(params[:mime_type] || "text/plain")})
136
+ xml.desc(params[:desc])
137
+ xml.s({"d" => params[:start_time]}) if params[:start_time]
138
+ xml.e({"d" => params[:end_time]}) if params[:end_time]
139
+ end
140
+
141
+ xml.e({"a" => params[:appointee_email], "t" => "t"})
142
+ end
143
+ end
35
144
  end
36
145
  end
@@ -1,3 +1,3 @@
1
1
  module Zimbreasy
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/lib/zimbreasy.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require "icalendar"
1
2
  require "zimbreasy/version"
2
3
  require "zimbreasy/mail"
3
4
  require "zimbreasy/account"
data/zimbreasy.gemspec CHANGED
@@ -14,4 +14,9 @@ Gem::Specification.new do |gem|
14
14
  gem.name = "zimbreasy"
15
15
  gem.require_paths = ["lib"]
16
16
  gem.version = Zimbreasy::VERSION
17
+
18
+ gem.add_dependency 'test-unit'
19
+ gem.add_dependency 'savon', '~> 1.1.0'
20
+ gem.add_dependency 'nokogiri'
21
+ gem.add_dependency 'icalendar'
17
22
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zimbreasy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,8 +9,52 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-06 00:00:00.000000000 Z
13
- dependencies: []
12
+ date: 2013-02-07 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: test-unit
16
+ requirement: &22555720 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *22555720
25
+ - !ruby/object:Gem::Dependency
26
+ name: savon
27
+ requirement: &22546860 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 1.1.0
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *22546860
36
+ - !ruby/object:Gem::Dependency
37
+ name: nokogiri
38
+ requirement: &22541180 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *22541180
47
+ - !ruby/object:Gem::Dependency
48
+ name: icalendar
49
+ requirement: &22537660 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *22537660
14
58
  description: A no-nonsense gem for the nonsensical Zimbra API.
15
59
  email:
16
60
  - jordanmprince@gmail.com