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 +1 -3
- data/README.md +45 -2
- data/lib/zimbreasy/mail.rb +122 -13
- data/lib/zimbreasy/version.rb +1 -1
- data/lib/zimbreasy.rb +1 -0
- data/zimbreasy.gemspec +5 -0
- metadata +47 -3
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,21 @@
|
|
1
1
|
# Zimbreasy
|
2
2
|
|
3
|
-
|
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
|
-
|
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'`)
|
data/lib/zimbreasy/mail.rb
CHANGED
@@ -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
|
-
#:
|
16
|
+
#:desc(opt)
|
16
17
|
#:mime_type(opt)
|
17
|
-
|
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
|
-
|
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
|
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
|
data/lib/zimbreasy/version.rb
CHANGED
data/lib/zimbreasy.rb
CHANGED
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.
|
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-
|
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
|