rews 0.1.0 → 0.2.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.
data/README.rdoc CHANGED
@@ -35,6 +35,12 @@ to use :
35
35
 
36
36
  == Install
37
37
 
38
+ to use NTLM authentication, you need versions of httpclient and ntlm-http
39
+ gems with fixes for NTLM authentication
40
+
41
+ * httpclient branch ntlm_domain : https://github.com/mccraigmccraig/httpclient/tree/ntlm_domain
42
+ * ntlm-http branch fix_unicode : https://github.com/trampoline/ntlm-http/tree/fix_unicode
43
+
38
44
  gem install rews
39
45
 
40
46
  == Note on Patches/Pull Requests
data/Rakefile CHANGED
@@ -11,11 +11,12 @@ begin
11
11
  gem.homepage = "http://github.com/trampoline/rews"
12
12
  gem.authors = ["Trampoline Systems Ltd"]
13
13
  gem.add_dependency "savon", ">= 0.8.6"
14
- gem.add_dependency "ntlm-http", ">= 0.1.1"
14
+ gem.add_dependency "ntlm-http", ">= 0.1.1.1"
15
15
  gem.add_dependency "httpclient", ">= 2.1.6.1.1"
16
16
  gem.add_dependency "fetch_in", ">= 0.2.0"
17
17
  gem.add_development_dependency "rspec", ">= 1.2.9"
18
18
  gem.add_development_dependency "rr", ">= 0.10.5"
19
+ gem.add_development_dependency "nokogiri", ">= 1.4.4"
19
20
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
20
21
  end
21
22
  Jeweler::GemcutterTasks.new
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
@@ -0,0 +1,48 @@
1
+ module Rews
2
+ class Client
3
+ attr_reader :client
4
+ attr_accessor :logdev
5
+
6
+ # create a +Client+ to access Exchange Web Services
7
+ # * using NTLM authentication
8
+ # Rews::Client.new('https://exchange.foo.com/EWS/Exchange.asmx', :ntlm, 'DOMAIN\\user', 'password')
9
+ # * using basic authentication
10
+ # Rews::Client.new('https://exchange.foo.com/EWS/Exchange.asmx', :basic, 'DOMAIN\\user', 'password')
11
+ def initialize(endpoint, auth_type, user, password)
12
+ @endpoint=endpoint
13
+ @auth_type = auth_type
14
+ @user=user
15
+ @password=password
16
+ @client = Savon::Client.new do
17
+ wsdl.endpoint = endpoint
18
+ wsdl.namespace = SCHEMA_MESSAGES
19
+
20
+ http.auth.ssl.verify_mode = :none
21
+ http.auth.send(auth_type, user, password)
22
+ end
23
+ end
24
+
25
+ def inspect
26
+ "#<#{self.class} @endpoint=#{@endpoint}, @auth_type=#{@auth_type}, @user=#{@user}, @password=#{@password}>"
27
+ end
28
+
29
+ # get a <tt>Folder::DistinguishedFolderId</tt> referencing one of the named top-level Folders in an Exchange mailbox
30
+ # * get a folder from the default mailbox
31
+ # client.distinguished_folder_id('inbox')
32
+ # * get a folder from another mailbox
33
+ # client.distinguished_folder_id('inbox', 'foo@bar.com')
34
+ def distinguished_folder_id(id, mailbox_email=nil)
35
+ Folder::DistinguishedFolderId.new(client, id, mailbox_email)
36
+ end
37
+
38
+ # yield a +Logger+ if +logdev+ has been set
39
+ def log
40
+ yield logger if @logdev
41
+ end
42
+
43
+ def logger
44
+ return @logger if @logger
45
+ @logger = Logger.new(@logdev) if @logdev
46
+ end
47
+ end
48
+ end
data/lib/rews/folder.rb CHANGED
@@ -1,24 +1,41 @@
1
1
  module Rews
2
2
  module Folder
3
+
4
+ # represents a Folder in a mailbox on an Exchange server
3
5
  class Folder
4
6
  attr_reader :client
5
7
  attr_reader :folder_id
6
8
  attr_reader :attributes
7
9
 
8
10
  def initialize(client, folder)
11
+ @client = client
9
12
  @folder_id = VanillaFolderId.new(client, folder[:folder_id])
10
13
  @attributes = folder
11
14
  end
12
15
 
16
+ def ==(other)
17
+ other.is_a?(Folder) &&
18
+ @client == other.client &&
19
+ @folder_id == other.folder_id &&
20
+ @attributes == other.attributes
21
+ end
22
+
23
+ # access the +Folder+ +attributes+
13
24
  def [](key)
14
25
  @attributes[key]
15
26
  end
16
27
 
28
+ # keys of the +Folder+ +attributes+
17
29
  def keys
18
30
  @attributes.keys
19
31
  end
32
+
33
+ def inspect
34
+ "#<#{self.class} @folder_id=#{@folder_id.inspect}, @attributes=#{@attributes.inspect}>"
35
+ end
20
36
  end
21
37
 
38
+ # <tt>find_*</tt> methods on <tt>Folder::BaseFolderId</tt> return a +FindResult+
22
39
  class FindResult
23
40
  VIEW_ATTRS = [:includes_last_item_in_range,
24
41
  :indexed_paging_offset,
@@ -27,6 +44,8 @@ module Rews
27
44
  VIEW_ATTRS.each do |attr|
28
45
  attr_reader attr
29
46
  end
47
+
48
+ # the +result+ of the +find_*+ call
30
49
  attr_reader :result
31
50
 
32
51
  def initialize(view, &proc)
@@ -36,19 +55,28 @@ module Rews
36
55
  @result = proc.call(view) if proc
37
56
  end
38
57
 
58
+ # count of items in the +result+
39
59
  def length
40
60
  result.length
41
61
  end
42
62
 
63
+ # alias for +length+
43
64
  def size
44
65
  result.size
45
66
  end
46
67
 
68
+ # access an element from +result+
47
69
  def [](key)
48
70
  result[key]
49
71
  end
72
+
73
+ def inspect
74
+ attrs = VIEW_ATTRS.map{|attr| "@#{attr}=#{self.send(attr)}"}.join(", ")
75
+ "#<#{self.class} #{attrs}, @result=#{@result.inspect}>"
76
+ end
50
77
  end
51
78
 
79
+ # Identifies a Folder
52
80
  class BaseFolderId
53
81
  include Util
54
82
 
@@ -63,6 +91,7 @@ module Rews
63
91
  :indexed_page_folder_view=>View::INDEXED_PAGE_VIEW_OPTS,
64
92
  :folder_shape=>Shape::FOLDER_SHAPE_OPTS}
65
93
 
94
+ # find <tt>Folder::Folder</tt>s within a <tt>Folder::Folder</tt>
66
95
  def find_folder(opts={})
67
96
  opts = check_opts(FIND_FOLDER_OPTS, opts)
68
97
 
@@ -76,7 +105,7 @@ module Rews
76
105
  xml << Restriction.new(opts[:restriction]).to_xml if opts[:restriction]
77
106
 
78
107
  xml.wsdl :ParentFolderIds do
79
- xml << Gyoku.xml(self.to_xml_hash)
108
+ xml << self.to_xml
80
109
  end
81
110
  soap.body = xml.target!
82
111
  end
@@ -91,6 +120,7 @@ module Rews
91
120
  end
92
121
  end
93
122
 
123
+ # find <tt>Folder::FolderIds</tt>s within a <tt>Folder::FolderIds</tt>
94
124
  def find_folder_id(opts={})
95
125
  opts = check_opts(FIND_FOLDER_OPTS, opts)
96
126
 
@@ -108,7 +138,7 @@ module Rews
108
138
  :indexed_page_item_view=>View::INDEXED_PAGE_VIEW_OPTS,
109
139
  :item_shape=>Shape::ITEM_SHAPE_OPTS}
110
140
 
111
- # find message-ids in a folder
141
+ # find <tt>Item::Item</tt>s in a folder
112
142
  def find_item(opts={})
113
143
  opts = check_opts(FIND_ITEM_OPTS, opts)
114
144
 
@@ -124,7 +154,7 @@ module Rews
124
154
  xml << SortOrder.new(opts[:sort_order]).to_xml if opts[:sort_order]
125
155
 
126
156
  xml.wsdl :ParentFolderIds do
127
- xml << Gyoku.xml(self.to_xml_hash)
157
+ xml << self.to_xml
128
158
  end
129
159
 
130
160
  soap.body = xml.target!
@@ -136,6 +166,7 @@ module Rews
136
166
  end
137
167
  end
138
168
 
169
+ # find <tt>Item::ItemIds</tt>s in a folder
139
170
  def find_item_id(opts={})
140
171
  opts = check_opts(FIND_ITEM_OPTS, opts)
141
172
 
@@ -152,7 +183,9 @@ module Rews
152
183
  :ignore_change_keys=>nil
153
184
  }
154
185
 
155
- # get a bunch of messages in one api hit
186
+ # retrieve a bunch of <tt>Item::Item</tt>s in one API hit.
187
+ # takes a list of <tt>Item::ItemId</tt>s, or a list of <tt>Item::Item</tt>,
188
+ # or a <tt>Folder::FindResult</tt> and options to specify +Shape::ItemShape+
156
189
  def get_item(message_ids, opts={})
157
190
  opts = check_opts(GET_ITEM_OPTS, opts)
158
191
  message_ids = message_ids.result if message_ids.is_a?(FindResult)
@@ -166,7 +199,8 @@ module Rews
166
199
  xml << Shape::ItemShape.new(opts[:item_shape]||{}).to_xml
167
200
  xml.wsdl :ItemIds do
168
201
  message_ids.each do |mid|
169
- xml << Gyoku.xml(mid.to_xml_hash(opts[:ignore_change_keys]))
202
+ mid = mid.item_id if mid.is_a?(Item::Item)
203
+ xml << mid.to_xml(opts[:ignore_change_keys])
170
204
  end
171
205
  end
172
206
 
@@ -181,6 +215,9 @@ module Rews
181
215
  :ignore_change_keys=>false
182
216
  }
183
217
 
218
+ # delete a bunch of Items in one API hit.
219
+ # takes a list of <tt>Item::ItemId</tt>s, or a list of <tt>Item::Item</tt>,
220
+ # or a <tt>Folder::FindResult</tt> and options to specify DeleteType
184
221
  def delete_item(message_ids, opts={})
185
222
  opts = check_opts(DELETE_ITEM_OPTS, opts)
186
223
  message_ids = message_ids.result if message_ids.is_a?(FindResult)
@@ -193,7 +230,8 @@ module Rews
193
230
 
194
231
  xml.wsdl :ItemIds do
195
232
  message_ids.each do |mid|
196
- xml << Gyoku.xml(mid.to_xml_hash(opts[:ignore_change_keys]))
233
+ mid = mid.item_id if mid.is_a?(Item::Item)
234
+ xml << mid.to_xml(opts[:ignore_change_keys])
197
235
  end
198
236
  end
199
237
 
@@ -204,8 +242,12 @@ module Rews
204
242
  end
205
243
  end
206
244
 
245
+ # identifies a regular (non-distinguished) Folder on an Exchange server
207
246
  class VanillaFolderId < BaseFolderId
247
+ # the Id of the Folder
208
248
  attr_reader :id
249
+
250
+ # +change_key+ identifies a specific version of the Folder
209
251
  attr_reader :change_key
210
252
 
211
253
  def initialize(client, folder_id)
@@ -215,30 +257,33 @@ module Rews
215
257
  raise "no id" if !@id
216
258
  end
217
259
 
218
- def to_xml_hash
219
- if change_key
220
- {
221
- "t:FolderId"=>"",
222
- :attributes! => {
223
- "t:FolderId" => {
224
- "Id" => id.to_s,
225
- "ChangeKey" => change_key.to_s}}}
226
- else
227
- {
228
- "t:FolderId"=>"",
229
- :attributes! => {
230
- "t:FolderId" => {
231
- "Id" => id.to_s}}}
232
- end
260
+ def ==(other)
261
+ other.is_a?(VanillaFolderId) &&
262
+ @client == other.client &&
263
+ @id == other.id &&
264
+ @change_key == other.change_key
265
+ end
266
+
267
+ def to_xml
268
+ xml = Builder::XmlMarkup.new
269
+ attrs = {:Id=>id.to_s}
270
+ attrs[:ChangeKey] = change_key.to_s if change_key
271
+ xml.t :FolderId, attrs
272
+ xml.target!
233
273
  end
234
274
 
235
275
  def inspect
236
- "#{self.class}(id: #{id}, change_key: #{change_key})"
276
+ "#<#{self.class} @id=#{id}, @change_key=#{change_key}>"
237
277
  end
238
278
  end
239
279
 
280
+ # identifies a DistinguishedFolder in a mailbox on an Exchange server.
281
+ # the <tt>Client.distinguished_folder_id</tt> method returns <tt>DistinguishedFolderId</tt>s
240
282
  class DistinguishedFolderId < BaseFolderId
283
+ # the Id of the DistinguishedFolder e.g. <tt>"inbox"</tt>
241
284
  attr_reader :id
285
+
286
+ # the email address of the mailbox containing the DistinguishedFolder
242
287
  attr_reader :mailbox_email
243
288
 
244
289
  def initialize(client, id, mailbox_email=nil)
@@ -248,26 +293,27 @@ module Rews
248
293
  raise "no id" if !@id
249
294
  end
250
295
 
251
- def to_xml_hash
252
- {
253
- "t:DistinguishedFolderId"=>mailbox_xml_hash,
254
- :attributes! => {"t:DistinguishedFolderId"=>{"Id"=>id}}}
296
+ def ==(other)
297
+ other.is_a?(DistinguishedFolderId) &&
298
+ @client = other.client &&
299
+ @id = other.id &&
300
+ @mailbox_email = other.mailbox_email
255
301
  end
256
302
 
257
- def inspect
258
- "#{self.class}(id: #{id}, mailbox_email: #{mailbox_email})"
303
+ def to_xml
304
+ xml = Builder::XmlMarkup.new
305
+ xml.t :DistinguishedFolderId, :Id=>id do
306
+ if mailbox_email
307
+ xml.t :Mailbox do
308
+ xml.t :EmailAddress, mailbox_email
309
+ end
310
+ end
311
+ end
312
+ xml.target!
259
313
  end
260
314
 
261
- private
262
-
263
- def mailbox_xml_hash
264
- if mailbox_email
265
- {
266
- "t:Mailbox"=>{
267
- "t:EmailAddress"=>mailbox_email}}
268
- else
269
- ""
270
- end
315
+ def inspect
316
+ "#<#{self.class} @id=#{id}, @mailbox_email=#{mailbox_email}>"
271
317
  end
272
318
  end
273
319
  end
data/lib/rews/item.rb CHANGED
@@ -20,6 +20,7 @@ module Rews
20
20
  end.flatten
21
21
  end
22
22
 
23
+ # represents an Item from a mailbox on an Exchange server
23
24
  class Item
24
25
  attr_reader :client
25
26
  attr_reader :item_id
@@ -27,25 +28,45 @@ module Rews
27
28
  attr_reader :attributes
28
29
 
29
30
  def initialize(client, item_class, attributes)
31
+ @client = client
30
32
  @item_id = ItemId.new(client, attributes[:item_id])
31
33
  @item_class = item_class
32
34
  @attributes = attributes
33
35
  end
34
36
 
37
+ def ==(other)
38
+ other.is_a?(Item) &&
39
+ @client == other.client &&
40
+ @item_id == other.item_id &&
41
+ @item_class == other.item_class &&
42
+ @attributes == other.attributes
43
+ end
44
+
45
+ # access the Item attributes
35
46
  def [](key)
36
47
  @attributes[key]
37
48
  end
38
-
49
+
50
+ # names of the Item attributes
39
51
  def keys
40
52
  @attributes.keys
41
53
  end
54
+
55
+ def inspect
56
+ "#<#{self.class} @item_class=#{@item_class}, @item_id=#{@folder_id.inspect}, @attributes=#{@attributes.inspect}>"
57
+ end
42
58
  end
43
59
 
60
+ # identifies an Item
44
61
  class ItemId
45
62
  include Util
46
63
 
47
64
  attr_reader :client
65
+
66
+ # the +Id+ of the Item
48
67
  attr_reader :id
68
+
69
+ # the version of the Item
49
70
  attr_reader :change_key
50
71
 
51
72
  def initialize(client, item_id)
@@ -55,11 +76,18 @@ module Rews
55
76
  raise "no id" if !@id
56
77
  end
57
78
 
79
+ def ==(other)
80
+ @client == other.client &&
81
+ @id == other.id &&
82
+ @change_key == other.change_key
83
+ end
84
+
58
85
  GET_ITEM_OPTS = {
59
86
  :item_shape=>Shape::ITEM_SHAPE_OPTS,
60
87
  :ignore_change_keys=>nil
61
88
  }
62
89
 
90
+ # get the <tt>Item::Item</tt> identified by this <tt>Item::ItemId</tt>
63
91
  def get_item(opts={})
64
92
  opts = check_opts(GET_ITEM_OPTS, opts)
65
93
  r = with_error_check(client, :get_item_response,:response_messages,:get_item_response_message) do
@@ -70,7 +98,7 @@ module Rews
70
98
 
71
99
  xml << Shape::ItemShape.new(opts[:item_shape]||{}).to_xml
72
100
  xml.wsdl :ItemIds do
73
- xml << Gyoku.xml(self.to_xml_hash(opts[:ignore_change_keys]))
101
+ xml << self.to_xml(opts[:ignore_change_keys])
74
102
  end
75
103
 
76
104
  soap.body = xml.target!
@@ -84,6 +112,7 @@ module Rews
84
112
  :ignore_change_keys=>false
85
113
  }
86
114
 
115
+ # delete the Item from the server
87
116
  def delete_item(opts={})
88
117
  opts = check_opts(DELETE_ITEM_OPTS, opts)
89
118
  r = with_error_check(client, :delete_item_response, :response_messages, :delete_item_response_message) do
@@ -93,7 +122,7 @@ module Rews
93
122
  xml = Builder::XmlMarkup.new
94
123
 
95
124
  xml.wsdl :ItemIds do
96
- xml << Gyoku.xml(self.to_xml_hash(opts[:ignore_change_keys]))
125
+ xml << self.to_xml(opts[:ignore_change_keys])
97
126
  end
98
127
 
99
128
  soap.body = xml.target!
@@ -102,25 +131,16 @@ module Rews
102
131
  true
103
132
  end
104
133
 
105
- def to_xml_hash(ignore_change_key=false)
106
- if change_key && !ignore_change_key
107
- {
108
- "t:ItemId"=>"",
109
- :attributes! => {
110
- "t:ItemId" => {
111
- "Id" => id.to_s,
112
- "ChangeKey" => change_key.to_s}}}
113
- else
114
- {
115
- "t:ItemId"=>"",
116
- :attributes! => {
117
- "t:ItemId" => {
118
- "Id" => id.to_s}}}
119
- end
134
+ def to_xml(ignore_change_key=false)
135
+ xml = Builder::XmlMarkup.new
136
+ attrs = {:Id=>id.to_s}
137
+ attrs[:ChangeKey] = change_key.to_s if change_key && !ignore_change_key
138
+ xml.t :ItemId, attrs
139
+ xml.target!
120
140
  end
121
141
 
122
142
  def inspect
123
- "#{self.class}(id: #{id}, change_key: #{change_key})"
143
+ "#<#{self.class} @id=#{id}, @change_key=#{change_key}>"
124
144
  end
125
145
  end
126
146
  end
@@ -1,8 +1,11 @@
1
- # takes restrictions written in Ruby s-expressions and
2
- # outputs Exchange Web Services Restriction XML
3
- #
4
- #
5
1
  module Rews
2
+ # models Restrictions for <tt>find_*</tt> operations
3
+ # on <tt>Folder::BaseFolderId</tt>
4
+ #
5
+ # takes restrictions written in Ruby s-expressions and
6
+ # outputs Exchange Web Services Restriction XML. e.g.
7
+ #
8
+ # <tt>[[:and, [:==, "item:Subject", "hello"], [:>=, "item:DateTimeSent", DateTime.parse("2011-03-16T15:57:37+00:00")]]</tt>
6
9
  class Restriction
7
10
 
8
11
  attr_reader :expr
@@ -12,7 +15,7 @@ module Rews
12
15
  end
13
16
 
14
17
  def inspect
15
- "#{self.class}: #{@expr.inspect}"
18
+ "#<#{self.class} @expr=#{@expr.inspect}>"
16
19
  end
17
20
 
18
21
  def to_xml
@@ -81,7 +84,9 @@ module Rews
81
84
  }
82
85
  def write_logical(xml, expr)
83
86
  xml.t LOGICAL_OPS[expr[0]] do
84
- write_xml(xml ,expr[1..-1])
87
+ expr[1..-1].each do |clause|
88
+ Xml::write_expr(xml, clause)
89
+ end
85
90
  end
86
91
  end
87
92
  end
data/lib/rews/shape.rb CHANGED
@@ -24,9 +24,15 @@ module Rews
24
24
  end
25
25
  end
26
26
 
27
+ # models ItemShape and FolderShape used in <tt>Folder::BaseFolderId.find_*</tt> and
28
+ # <tt>Folder::BaseFolderId.get_*</tt> methods
27
29
  class Base
28
30
  include Util
29
31
  attr_reader :shape
32
+
33
+ def inspect
34
+ "#<#{self.class} @shape=#{@shape}>"
35
+ end
30
36
  end
31
37
 
32
38
  ITEM_SHAPE_OPTS = {
@@ -35,6 +41,8 @@ module Rews
35
41
  :additional_properties=>nil
36
42
  }
37
43
 
44
+ # models ItemShape used in <tt>Folder::BaseFolderId.find_item</tt> and
45
+ # <tt>Folder::BaseFolderId.get_item</tt> methods
38
46
  class ItemShape < Base
39
47
  def initialize(shape)
40
48
  @shape = check_opts(ITEM_SHAPE_OPTS, shape)
@@ -54,6 +62,7 @@ module Rews
54
62
  :additional_properties=>nil
55
63
  }
56
64
 
65
+ # models +FolderShape+ used in <tt>Folder::BaseFolderId.find_folder</tt> method
57
66
  class FolderShape < Base
58
67
  def initialize(shape)
59
68
  @shape = check_opts(FOLDER_SHAPE_OPTS, shape)
@@ -1,6 +1,10 @@
1
- # takes sort_orders written in Ruby s-expressions and
2
- # outputs EWS SortOrder XML
3
1
  module Rews
2
+ # models SortOrder used in <tt>Folder::BaseFolderId.find_*</tt> methods
3
+ #
4
+ # takes sort_orders written in Ruby s-expressions and
5
+ # outputs EWS SortOrder XML e.g.
6
+ #
7
+ # <tt>[["item:DateTimeReceived", "Ascending"], ["item:Size", "Descending"]]</tt>
4
8
  class SortOrder
5
9
  attr_reader :expr
6
10
 
@@ -9,7 +13,7 @@ module Rews
9
13
  end
10
14
 
11
15
  def inspect
12
- "#{self.class}: #{@expr.inspect}"
16
+ "#<#{self.class} @expr=#{@expr.inspect}>"
13
17
  end
14
18
 
15
19
  def to_xml
data/lib/rews/util.rb CHANGED
@@ -6,10 +6,10 @@ module Rews
6
6
 
7
7
  # validates an options hash against a constraints hash
8
8
  # in the constraints hash :
9
- # - keys ending in ! indicate option is required
10
- # - keys not ending in ! indicate option is not required
11
- # - non-nil values provide defaults
12
- # - hash values provide constraints for sub-hashes
9
+ # * keys ending in ! indicate option is required
10
+ # * keys not ending in ! indicate option is not required
11
+ # * non-nil values provide defaults
12
+ # * hash values provide constraints for sub-hashes
13
13
  def check_opts(constraints, opts={}, prefix=nil)
14
14
  required_keys = Hash[constraints.keys.select{|k| k.to_s[-1..-1] == '!'}.map{|k| [strip_bang(k),k]}]
15
15
  optional_keys = constraints.keys.select{|k| k.to_s[-1..-1] != '!'}
@@ -30,10 +30,11 @@ module Rews
30
30
  raise "required options not given: #{required_keys.keys.map{|k| [prefix,k].compact.join('.')}.join(", ")}" if required_keys.size>0
31
31
 
32
32
  # defaults
33
- optional_keys.each{|k| opts[k] = constraints[k] if !constraints[k].is_a?(Hash)}
33
+ optional_keys.each{|k| opts[k] = constraints[k] if constraints[k] && !constraints[k].is_a?(Hash)}
34
34
  opts
35
35
  end
36
36
 
37
+ # strip a ! from the end of a +String+ or +Symbol+
37
38
  def strip_bang(k)
38
39
  if k.is_a? Symbol
39
40
  k.to_s[0...-1].to_sym
@@ -42,14 +43,19 @@ module Rews
42
43
  end
43
44
  end
44
45
 
46
+ # camel-case a +String+
45
47
  def camelize(s)
46
48
  s.split('_').map(&:capitalize).join
47
49
  end
48
50
 
51
+ # camel-case the keys of a +Hash+
49
52
  def camel_keys(h)
50
53
  Hash[h.map{|k,v| [camelize(k.to_s), v]}]
51
54
  end
52
55
 
56
+ # check the response codes of an Exchange Web Services request.
57
+ # the supplied block makes a SOAP request, and the response is parsed
58
+ # out and checked
53
59
  def with_error_check(client, *response_msg_keys)
54
60
  raise "no block" if !block_given?
55
61
 
@@ -69,6 +75,7 @@ module Rews
69
75
  statuses
70
76
  end
71
77
 
78
+ # check the status of the response of a single part of a multi-part request
72
79
  def single_error_check(client, status)
73
80
  begin
74
81
  response_class = status[:response_class]
@@ -77,9 +84,9 @@ module Rews
77
84
  end
78
85
 
79
86
  if status[:response_class] == "Error"
80
- return "Rews: #{status[:response_code]} - #{status[:message_text]}"
87
+ return "#{status[:response_code]} - #{status[:message_text]}"
81
88
  elsif status[:response_class] == "Warning"
82
- client.log{|logger| logger.warn("#{status[:message_text]}")}
89
+ client.log{|logger| logger.warn("#{status[:response_code]} - #{status[:message_text]}")}
83
90
  end
84
91
  end
85
92
  end
data/lib/rews/view.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  module Rews
2
+ # models IndexedPageItemView and IndexedPageFolderView definitions used by
3
+ # <tt>Folder::BaseFolderId.find_*</tt> methods
2
4
  module View
3
5
  module Xml
4
6
  module_function
@@ -16,10 +18,15 @@ module Rews
16
18
  include Util
17
19
 
18
20
  attr_reader :view
21
+
22
+ def inspect
23
+ "#<#{self.class} @view=#{@view.inspect}>"
24
+ end
19
25
  end
20
26
 
21
27
  INDEXED_PAGE_VIEW_OPTS = {:max_entries_returned=>nil, :offset=>0, :base_point=>:Beginning}
22
28
 
29
+ # models the IndexedPageItemView used in <tt>Folder::BaseFolderId.find_item</tt> method
23
30
  class IndexedPageItemView < Base
24
31
  def initialize(view)
25
32
  @view = check_opts(INDEXED_PAGE_VIEW_OPTS, view)
@@ -30,6 +37,7 @@ module Rews
30
37
  end
31
38
  end
32
39
 
40
+ # models the IndexedPageFolderView used in <tt>Folder::BaseFolderId.find_folder</tt> methods
33
41
  class IndexedPageFolderView < Base
34
42
  def initialize(view)
35
43
  @view = check_opts(INDEXED_PAGE_VIEW_OPTS, view)