Class: Viewpoint::EWS::Item

Inherits:
Object
  • Object
show all
Includes:
ItemFieldUriMap, Model
Defined in:
lib/model/item.rb

Constant Summary

Constants included from ItemFieldUriMap

Viewpoint::EWS::ItemFieldUriMap::FIELD_URIS

Instance Attribute Summary collapse

Attributes included from Model

#ews_methods, #ews_methods_undef

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ews_item, opts = {}) ⇒ Item

Initialize an Exchange Web Services item

Parameters:

  • ews_item (Hash)

    A hash representing this item

  • shallow (Boolean)

    Whether or not we have retrieved all the elements for this object



68
69
70
71
72
73
74
75
76
77
78
# File 'lib/model/item.rb', line 68

def initialize(ews_item, opts={})
  super() # Calls initialize in Model (creates @ews_methods Array)
  @ews_item = ews_item
  @shallow = opts.has_key?(:shallow) ? opts[:shallow] : true
  @item_id = ews_item[:item_id][:id]
  @change_key = ews_item[:item_id][:change_key]
  @text_only = false
  @updates = {}

  init_methods
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(m, *args, &block) ⇒ Object (private)



300
301
302
303
304
305
306
307
308
# File 'lib/model/item.rb', line 300

def method_missing(m, *args, &block)
  if(@shallow)
    deepen!
    send(m, *args, &block)
  else
    warn "!!! No such method: #{m}" if $DEBUG
    nil
  end
end

Instance Attribute Details

#change_keyObject (readonly)

Returns the value of attribute change_key.



62
63
64
# File 'lib/model/item.rb', line 62

def change_key
  @change_key
end

#item_idObject (readonly) Also known as: id

Returns the value of attribute item_id.



62
63
64
# File 'lib/model/item.rb', line 62

def item_id
  @item_id
end

#parent_folder_idObject (readonly)

Returns the value of attribute parent_folder_id.



62
63
64
# File 'lib/model/item.rb', line 62

def parent_folder_id
  @parent_folder_id
end

Class Method Details

.add_attachments(parent_id, attachments) ⇒ Object

Add attachments to the passed in ParentId

Parameters:

  • parent_id (String, Hash)

    Either a String ItemId or a Hash ItemId with a ChangeKey

  • attachments (Array<File>)

    An Array of File objects to read in.

Options Hash (parent_id):

  • :id (String)

    The Id

  • :change_key (String)

    The ChangeKey



51
52
53
54
55
56
57
58
59
60
# File 'lib/model/item.rb', line 51

def self.add_attachments(parent_id, attachments)
  conn = Viewpoint::EWS::EWS.instance
  b64attach = []
  attachments.each do |a|
    b64attach << {:name => {:text =>(File.basename a.path)}, :content => {:text => Base64.encode64(a.read)}}
  end
  resp = conn.ews.create_attachment(parent_id, b64attach) 
  (resp.status == 'Success') || (raise EwsError, "Could not create attachments. #{resp.code}: #{resp.message}")
  {:id => resp.items.first[:attachment_id][:root_item_id], :change_key => resp.items.first[:attachment_id][:root_item_change_key]}
end

.get_item(item_id, shape = :default) ⇒ Item

TODO:

Add support to fetch an item with a ChangeKey

This is a class method that fetches an existing Item from the

Exchange Store.

Parameters:

  • item_id (String)

    The id of the item.

  • shape (Symbol) (defaults to: :default)

    The optional shape of the item :id_only/:default/:all_properties

Returns:

  • (Item)

    Returns an Item or subclass of Item



34
35
36
37
38
39
40
41
42
43
44
# File 'lib/model/item.rb', line 34

def self.get_item(item_id, shape = :default)
  item_shape = {:base_shape => shape.to_s.camelcase}
  resp = (Viewpoint::EWS::EWS.instance).ews.get_item([item_id], item_shape)
  if(resp.status == 'Success')
    item = resp.items.shift
    type = item.keys.first
    eval "#{type.to_s.camel_case}.new(item[type])"
  else
    raise EwsError, "Could not retrieve item. #{resp.code}: #{resp.message}"
  end
end

Instance Method Details

#attachmentsArray, Attachment

Return the attachments for this Item

Returns:

  • (Array, Attachment)

    An array of Attachments for this Item



225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/model/item.rb', line 225

def attachments
  # TODO: should an exception be raised if someone calls this method without first
  # checking has_attachments?
  return [] unless has_attachments?

  # If we've already called this don't waste the time to process attachments again.
  return @attachments if defined?(@attachments)

  deepen!
  @attachments = []
  @ews_item[:attachments].each_pair do |k,v|
    # k should be file_attachment or item_attachment
    if(v.is_a?(Hash))
      @attachments << (eval "#{k.to_s.camel_case}.new(v[:attachment_id][:id])")
    else
      v.each do |att|
        @attachments << (eval "#{k.to_s.camel_case}.new(att[:attachment_id][:id])")
      end
    end
  end
  @attachments
end

#clear_updates!TrueClass

Clear out any pending updates

Returns:

  • (TrueClass)


106
107
108
109
# File 'lib/model/item.rb', line 106

def clear_updates!
  @updates = {}
  true
end

#copy(new_folder) ⇒ Item

Copy this item to a new folder

Parameters:

  • new_folder (String, Symbol, GenericFolder)

    The new folder to move it to. This should be a subclass of GenericFolder, a DistinguishedFolderId (must me a Symbol) or a FolderId (String)

Returns:

  • (Item)

    The Item object of the copy



211
212
213
214
215
216
217
218
219
220
221
# File 'lib/model/item.rb', line 211

def copy(new_folder)
  new_folder = new_folder.id if new_folder.kind_of?(GenericFolder)
  resp = (Viewpoint::EWS::EWS.instance).ews.copy_item([@item_id], new_folder)
  if(resp.status == 'Success')
    item = resp.items.first
    i_type = item.keys.first.to_s.camel_case
    return(eval "#{i_type}.new(item[item.keys.first])")
  else
    raise EwsError, "Could not copy item. #{resp.code}: #{resp.message}"
  end
end

#deepen!Object



178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/model/item.rb', line 178

def deepen!
  return true unless @shallow
  conn = Viewpoint::EWS::EWS.instance
  shape = {:base_shape => 'AllProperties', :body_type => (@text_only ? 'Text' : 'Best')}
  resp = conn.ews.get_item([@item_id], shape) 
  resp = resp.items.shift
  @ews_item = resp[resp.keys.first]
  @shallow = false
  @ews_methods = []
  @ews_methods_undef = []
  init_methods
  true
end

#delete!(soft = false) ⇒ Boolean

TODO:

Add exception handling for failed deletes

Delete this item

Parameters:

Returns:

  • (Boolean)

    Whether or not the item was deleted



254
255
256
257
258
259
# File 'lib/model/item.rb', line 254

def delete!(soft=false)
  deltype = soft ? 'SoftDelete' : 'HardDelete'
  resp = (Viewpoint::EWS::EWS.instance).ews.delete_item([@item_id], deltype)
  self.clear_object!
  (resp.status == 'Success') || (raise EwsError, "Could not delete message. #{resp.code}: #{resp.message}")
end

#mark_read!Object

Mark this Item as read



164
165
166
167
168
# File 'lib/model/item.rb', line 164

def mark_read!
  field = :is_read
  update!({:set_item_field=>{:field_uRI=>{:field_uRI=>FIELD_URIS[field][:text]}, :message=>{field=>{:text=>"true"}}}})
  @is_read = true
end

#mark_unread!Object

Mark this Item as unread



171
172
173
174
175
176
# File 'lib/model/item.rb', line 171

def mark_unread!
  field = :is_read
  update!({:set_item_field=>{:field_uRI=>{:field_uRI=>FIELD_URIS[field][:text]}, :message=>{field=>{:text=>"false"}}}})
  @is_read = false
  true
end

#move!(new_folder) ⇒ Object

Move this item to a new folder

Parameters:

  • new_folder (String, Symbol, GenericFolder)

    The new folder to move it to. This should be a subclass of GenericFolder, a DistinguishedFolderId (must me a Symbol) or a FolderId (String)



195
196
197
198
199
200
201
202
203
204
205
# File 'lib/model/item.rb', line 195

def move!(new_folder)
  new_folder = new_folder.id if new_folder.kind_of?(GenericFolder)
  resp = (Viewpoint::EWS::EWS.instance).ews.move_item([@item_id], new_folder)
  if(resp.status == 'Success')
    @item_id = resp.items.first[resp.items.first.keys.first][:item_id][:id]
    @change_key = resp.items.first[resp.items.first.keys.first][:item_id][:change_key]
    true
  else
    raise EwsError, "Could not move item. #{resp.code}: #{resp.message}"
  end
end

#parent_folderGenericFolder

Get the parent folder of this item

Returns:

  • (GenericFolder)

    returns a GenericFolder of subclass of that type.



273
274
275
276
# File 'lib/model/item.rb', line 273

def parent_folder
  #deepen!
  GenericFolder.get_folder @parent_folder_id
end

#recycle!Boolean

TODO:

Add exception handling for failed deletes

Delete this item by moving it to the Deleted Items folder

Returns:

  • (Boolean)

    Whether or not the item was deleted

See Also:



265
266
267
268
269
# File 'lib/model/item.rb', line 265

def recycle!
  resp = (Viewpoint::EWS::EWS.instance).ews.delete_item([@item_id], 'MoveToDeletedItems')
  self.clear_object!
  (resp.status == 'Success') || (raise EwsError, "Could not recycle message. #{resp.code}: #{resp.message}")
end

#save!Object

Save any pending updates that were manipulated via setter methods.



94
95
96
97
98
99
100
101
102
# File 'lib/model/item.rb', line 94

def save!
  return true if @updates.empty?
  if update_attribs!(@updates)
    @updates = {}
    true
  else
    false
  end
end

#text_only=(txt) ⇒ Object

Set whether or not the body should be text-only or not

Parameters:

  • txt (Boolean)

    if true the body will return only text, otherwise it may be HTML or text.



89
90
91
# File 'lib/model/item.rb', line 89

def text_only=(txt)
  @text_only = ( txt == true ? true : false)
end

#text_only?Boolean

See if this item is set to return only text in its body.

Returns:

  • (Boolean)

    if true the body will return only text, otherwise it may be HTML or text.



83
84
85
# File 'lib/model/item.rb', line 83

def text_only?
  @text_only
end

#update!(updates) ⇒ Object

Call UpdateItem for this item with the passed updates

Examples:

:set_item_field=>{:field_uRI=>{:field_uRI=>“message:IsRead”, :message=>:is_read=>{:text=>“true”}}}

Parameters:

  • updates (Hash)

    a well-formed update hash



114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/model/item.rb', line 114

def update!(updates)
  conn = Viewpoint::EWS::EWS.instance
  resp = conn.ews.update_item([{:id => @item_id, :change_key => @change_key}], {:updates => updates})
  if resp.status == 'Success'
    @item_id = resp.items.first[resp.items.first.keys.first][:item_id][:id]
    @change_key = resp.items.first[resp.items.first.keys.first][:item_id][:change_key]
    @shallow = true
    deepen!
  else
    raise EwsError, "Trouble updating Item. #{resp.code}: #{resp.message}"
  end

end

#update_attribs(updates, update_type = :replace) ⇒ Object

This takes a hash of attributes with new values and builds the appropriate udpate hash.

It does not commit the changes to Exchange, call #update! with the returned values from
this method or look at #update_attribs! for a version of this method that autocommits the
changes back.

You can also specify a preformatted Array of data like so:

{:preformatted => [misc data]}
This will simply be passed to the update! method

Examples:

=> {:text => ‘Normal’, :display_name => => ‘Test User’}

Parameters:

  • updates (Hash)

    a hash that is formed like so :item_attr => newvalue

  • update_type (Symbol) (defaults to: :replace)

    :append, :replace, :delete



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/model/item.rb', line 139

def update_attribs(updates, update_type = :replace)
  utype_map = {:append => :append_to_item_field, :replace => :set_item_field, :delete => :delete_item_field}
  changes = []
  type = self.class.name.split(/::/).last.ruby_case.to_sym

  updates.each_pair do |k,v|
    if(k == :preformatted)
      changes += v
      next
    end
    raise EwsError, "Field (#{FIELD_URIS[k][:text]}) not writable by update." unless FIELD_URIS[k][:writable]
    changes << {utype_map[update_type]=>[{:field_uRI => {:field_uRI=>FIELD_URIS[k][:text]}}, {type=>{k => v}}]}
  end

  changes
end

#update_attribs!(updates, update_type = :replace) ⇒ Object

This is the same as #update_attribs, but it will commit the changes back to Exchange.

See Also:



158
159
160
161
# File 'lib/model/item.rb', line 158

def update_attribs!(updates, update_type = :replace)
  changes = update_attribs(updates, update_type)
  update!(changes)
end