Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added paging to folder items #169

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ source 'https://rubygems.org/'
gemspec

group :development do
gem 'rspec', '<3.0'
gem 'guard'
gem 'awesome_print'
gem 'guard-rspec'
gem 'rb-inotify', :require => false
gem 'guard'
gem 'pry-nav'
gem 'rb-inotify', require: false
gem 'rspec', '<3.0'
gem 'turn'
gem "pry-nav"
end
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,17 @@ inbox.items_since sd
sd = Date.iso8601 '2013-01-01'
ed = Date.iso8601 '2013-02-01'
inbox.items_between sd, ed

# with paging
inbox.paging_items 10

# paging with parameters where:
# first parameter is the maximum number of items returned
# second parameter is the offset from the starting point
# and the last parameter is the starting point in the list of items
# the valid options for this parameter are 'Beginning' and 'End'
# the default is 'Beginning'
inbox.paging_items 10, 5, 'End'
```
### Free/Busy Calendar Accessors

Expand Down
28 changes: 28 additions & 0 deletions lib/ews/soap/parsers/ews_dom_parser.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module Viewpoint::EWS::SOAP
class EwsDomParser
include Viewpoint::EWS
include Viewpoint::StringUtils

def self.parse(soap_resp)
doc = Nokogiri::XML soap_resp
node_hash doc.root
end

def self.node_hash(node)
node_hash_value = {}
node_hash_value[:elems] = node.element_children.map { |child_element| node_hash child_element } unless node.element_children.empty?
node_hash_value[:attribs] = attributes_hash(node) unless node.attributes.empty?
node_hash_value[:text] = node.children.first.content if !node.children.empty? && node.children.first.text?
{ ruby_case(node.name).to_sym => node_hash_value }
end

def self.attributes_hash(node)
attr_hash = {}
node.attributes.each do |attr|
attr_hash[ruby_case(attr.first).to_sym] = attr[1].value
end

attr_hash
end
end
end
12 changes: 1 addition & 11 deletions lib/ews/soap/parsers/ews_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,11 @@ class EwsParser
# @param [String] soap_resp
def initialize(soap_resp)
@soap_resp = soap_resp
@sax_doc = EwsSaxDocument.new
end

def parse(opts = {})
opts[:response_class] ||= EwsSoapResponse
sax_parser.parse(@soap_resp)
opts[:response_class].new @sax_doc.struct
opts[:response_class].new Viewpoint::EWS::SOAP::EwsDomParser.parse(@soap_resp)
end


private

def sax_parser
@parser ||= Nokogiri::XML::SAX::Parser.new(@sax_doc)
end

end # EwsParser
end # Viewpoint
9 changes: 4 additions & 5 deletions lib/ews/soap/parsers/ews_sax_document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,14 @@ def start_element_namespace(name, attributes = [], prefix = nil, uri = nil, ns =
name = ruby_case(name).to_sym
elem = {}
unless attributes.empty?
elem[:attribs] = attributes.collect{|a|
{ ruby_case(a.localname).to_sym => a.value}
}.inject(&:merge)
elem[:attribs] = attributes.collect do |a|
{ ruby_case(a.localname).to_sym => a.value }
end.inject(&:merge)
end
@elems << elem
end

def end_element_namespace name, prefix=nil, uri=nil
def end_element_namespace(name, prefix = nil, uri = nil)
name = ruby_case(name).to_sym
elem = @elems.pop
if @elems.empty?
Expand All @@ -65,6 +65,5 @@ def end_element_namespace name, prefix=nil, uri=nil
@elems.last[:elems] << {name => elem}
end
end

end
end
13 changes: 13 additions & 0 deletions lib/ews/types/generic_folder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,19 @@ def items_between(start_date, end_date, opts={})
end
end

# Fetch items with paging
# @param [Integer] max_entries Maximum number of items returned
# @param [Integer] offset Offset from the starting point. This is optional.
# @param [String] basepoint Starting point in the list of items.
# The valid options for this parameter are 'Beginning' and 'End'. This is optional.
def paging_items(max_entries, offset = 0, basepoint = 'Beginning')
items(indexed_page_item_view: {
'MaxEntriesReturned' => max_entries,
'Offset' => offset,
'BasePoint' => basepoint
})
end

# Search on the item subject
# @param [String] match_str A simple string paramater to match against the
# subject. The search ignores case and does not accept regexes... only strings.
Expand Down
16 changes: 0 additions & 16 deletions lib/ews/types/item_field_uri_map.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ module ItemFieldUriMap
:effective_rights => {:text => 'folder:EffectiveRights', :writable => true},
:sharing_effective_rights => {:text => 'folder:SharingEffectiveRights', :writable => true},
:item_id => {:text => 'item:ItemId', :writable => true},
:parent_folder_id => {:text => 'item:ParentFolderId', :writable => true},
:item_class => {:text => 'item:ItemClass', :writable => true},
:mime_content => {:text => 'item:MimeContent', :writable => true},
:attachments => {:text => 'item:Attachments', :writable => true},
Expand Down Expand Up @@ -63,7 +62,6 @@ module ItemFieldUriMap
:display_to => {:text => 'item:DisplayTo', :writable => true},
:display_cc => {:text => 'item:DisplayCc', :writable => true},
:culture => {:text => 'item:Culture', :writable => true},
:effective_rights => {:text => 'item:EffectiveRights', :writable => true},
:last_modified_name => {:text => 'item:LastModifiedName', :writable => true},
:last_modified_time => {:text => 'item:LastModifiedTime', :writable => true},
:conversation_id => {:text => 'item:ConversationId', :writable => true},
Expand Down Expand Up @@ -102,7 +100,6 @@ module ItemFieldUriMap
:is_cancelled => {:text => 'calendar:IsCancelled', :writable => true},
:is_recurring => {:text => 'calendar:IsRecurring', :writable => true},
:meeting_request_was_sent => {:text => 'calendar:MeetingRequestWasSent', :writable => true},
:is_response_requested => {:text => 'calendar:IsResponseRequested', :writable => true},
:calendar_item_type => {:text => 'calendar:CalendarItemType', :writable => true},
:my_response_type => {:text => 'calendar:MyResponseType', :writable => true},
:organizer => {:text => 'calendar:Organizer', :writable => true},
Expand Down Expand Up @@ -146,12 +143,10 @@ module ItemFieldUriMap
:due_date => {:text => 'task:DueDate', :writable => true},
:is_assignment_editable => {:text => 'task:IsAssignmentEditable', :writable => true},
:is_complete => {:text => 'task:IsComplete', :writable => true},
:is_recurring => {:text => 'task:IsRecurring', :writable => true},
:is_team_task => {:text => 'task:IsTeamTask', :writable => true},
:mileage => {:text => 'task:Mileage', :writable => true},
:owner => {:text => 'task:Owner', :writable => true},
:percent_complete => {:text => 'task:PercentComplete', :writable => true},
:recurrence => {:text => 'task:Recurrence', :writable => true},
:start_date => {:text => 'task:StartDate', :writable => true},
:status => {:text => 'task:Status', :writable => true},
:status_description => {:text => 'task:StatusDescription', :writable => true},
Expand All @@ -160,13 +155,10 @@ module ItemFieldUriMap
:birthday => {:text => 'contacts:Birthday', :writable => true},
:business_home_page => {:text => 'contacts:BusinessHomePage', :writable => true},
:children => {:text => 'contacts:Children', :writable => true},
:companies => {:text => 'contacts:Companies', :writable => true},
:company_name => {:text => 'contacts:CompanyName', :writable => true},
:complete_name => {:text => 'contacts:CompleteName', :writable => true},
:contact_source => {:text => 'contacts:ContactSource', :writable => true},
:culture => {:text => 'contacts:Culture', :writable => true},
:department => {:text => 'contacts:Department', :writable => true},
:display_name => {:text => 'contacts:DisplayName', :writable => true},
:email_addresses => {:ftype => :indexed_field_uRI, :text => 'contacts:EmailAddress', :writable => true},
:file_as => {:text => 'contacts:FileAs', :writable => true},
:file_as_mapping => {:text => 'contacts:FileAsMapping', :writable => true},
Expand All @@ -178,7 +170,6 @@ module ItemFieldUriMap
:job_title => {:text => 'contacts:JobTitle', :writable => true},
:manager => {:text => 'contacts:Manager', :writable => true},
:middle_name => {:text => 'contacts:MiddleName', :writable => true},
:mileage => {:text => 'contacts:Mileage', :writable => true},
:nickname => {:text => 'contacts:Nickname', :writable => true},
:office_location => {:text => 'contacts:OfficeLocation', :writable => true},
:phone_numbers => {:ftype => :indexed_field_uRI, :text => 'contacts:PhoneNumber', :writable => true},
Expand All @@ -190,8 +181,6 @@ module ItemFieldUriMap
:wedding_anniversary => {:text => 'contacts:WeddingAnniversary', :writable => true},
:members => {:text => 'distributionlist:Members', :writable => true},
:posted_time => {:text => 'postitem:PostedTime', :writable => true},
:conversation_id => {:text => 'conversation:ConversationId', :writable => true},
:conversation_topic => {:text => 'conversation:ConversationTopic', :writable => true},
:unique_recipients => {:text => 'conversation:UniqueRecipients', :writable => true},
:global_unique_recipients => {:text => 'conversation:GlobalUniqueRecipients', :writable => true},
:unique_unread_senders => {:text => 'conversation:UniqueUnreadSenders', :writable => true},
Expand All @@ -200,21 +189,16 @@ module ItemFieldUriMap
:global_unique_senders => {:text => 'conversation:GlobalUniqueSenders', :writable => true},
:last_delivery_time => {:text => 'conversation:LastDeliveryTime', :writable => true},
:global_last_delivery_time => {:text => 'conversation:GlobalLastDeliveryTime', :writable => true},
:categories => {:text => 'conversation:Categories', :writable => true},
:global_categories => {:text => 'conversation:GlobalCategories', :writable => true},
:flag_status => {:text => 'conversation:FlagStatus', :writable => true},
:global_flag_status => {:text => 'conversation:GlobalFlagStatus', :writable => true},
:has_attachments => {:text => 'conversation:HasAttachments', :writable => true},
:global_has_attachments => {:text => 'conversation:GlobalHasAttachments', :writable => true},
:message_count => {:text => 'conversation:MessageCount', :writable => true},
:global_message_count => {:text => 'conversation:GlobalMessageCount', :writable => true},
:unread_count => {:text => 'conversation:UnreadCount', :writable => true},
:global_unread_count => {:text => 'conversation:GlobalUnreadCount', :writable => true},
:size => {:text => 'conversation:Size', :writable => true},
:global_size => {:text => 'conversation:GlobalSize', :writable => true},
:item_classes => {:text => 'conversation:ItemClasses', :writable => true},
:global_item_classes => {:text => 'conversation:GlobalItemClasses', :writable => true},
:importance => {:text => 'conversation:Importance', :writable => true},
:global_importance => {:text => 'conversation:GlobalImportance', :writable => true},
:item_ids => {:text => 'conversation:ItemIds', :writable => true},
:global_item_ids => {:text => 'conversation:GlobalItemIds', :writable => true}
Expand Down
1 change: 1 addition & 0 deletions lib/viewpoint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
require 'ews/soap/builders/ews_builder'
require 'ews/soap/parsers/ews_parser'
require 'ews/soap/parsers/ews_sax_document'
require 'ews/soap/parsers/ews_dom_parser'
# Mix-ins for the ExchangeWebService
require 'ews/soap/exchange_data_services'
require 'ews/soap/exchange_notification'
Expand Down
7 changes: 7 additions & 0 deletions spec/soap_data/get_text_item_response.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Header><h:ServerVersionInfo MajorVersion="14" MinorVersion="3" MajorBuildNumber="195" MinorBuildNumber="1" Version="Exchange2010_SP2" xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types" xmlns="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"/></s:Header><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><m:GetItemResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"><m:ResponseMessages><m:GetItemResponseMessage ResponseClass="Success"><m:ResponseCode>NoError</m:ResponseCode><m:Items><t:Message><t:ItemId Id="AAMkADg4NGVhZGUyLTU2ZTQtNGMwZS1iODRjLWY0YWE2NTYxMGE4ZQBGAAAAAADOrkJOZi/nSp0H8kv4afZtBwDDehUq0W+iQrSvaM5VNEX8AAAAAE5bAACCesYbTRQFQqmH6sMUNPnlAAAAkWs1AAA=" ChangeKey="CQAAABYAAACCesYbTRQFQqmH6sMUNPnlAAAAkdWa"/><t:ParentFolderId Id="AAMkADg4NGVhZGUyLTU2ZTQtNGMwZS1iODRjLWY0YWE2NTYxMGE4ZQAuAAAAAADOrkJOZi/nSp0H8kv4afZtAQDDehUq0W+iQrSvaM5VNEX8AAAAAE5bAAA=" ChangeKey="AQAAAA=="/><t:ItemClass>IPM.Note</t:ItemClass><t:Subject>Re: Insatisfação total</t:Subject><t:Sensitivity>Normal</t:Sensitivity><t:Body BodyType="Text">Em 17/01/2015 16:36, [email protected]&#x2;O coiso escreveu:
&gt;
&gt; Meu nome é José da Silva Sauro
&gt; CPF.12345678901
&gt;   Minha reclamação é do coiso em relação a meu pedido
&gt; O que vcs tem pra me informar??
</t:Body><t:DateTimeReceived>2015-01-21T13:03:52Z</t:DateTimeReceived><t:Size>2445</t:Size><t:Importance>Normal</t:Importance><t:IsSubmitted>false</t:IsSubmitted><t:IsDraft>false</t:IsDraft><t:IsFromMe>false</t:IsFromMe><t:IsResend>false</t:IsResend><t:IsUnmodified>true</t:IsUnmodified><t:DateTimeSent>2015-01-21T13:03:47Z</t:DateTimeSent><t:DateTimeCreated>2015-01-21T13:03:52Z</t:DateTimeCreated><t:ResponseObjects><t:ReplyToItem/><t:ReplyAllToItem/><t:ForwardItem/></t:ResponseObjects><t:DisplayCc/><t:DisplayTo>atendimento</t:DisplayTo><t:HasAttachments>false</t:HasAttachments><t:Culture>pt-BR</t:Culture><t:EffectiveRights><t:CreateAssociated>false</t:CreateAssociated><t:CreateContents>false</t:CreateContents><t:CreateHierarchy>false</t:CreateHierarchy><t:Delete>true</t:Delete><t:Modify>true</t:Modify><t:Read>true</t:Read></t:EffectiveRights><t:LastModifiedName>Coiso da Coisa</t:LastModifiedName><t:LastModifiedTime>2015-01-21T13:03:52Z</t:LastModifiedTime><t:IsAssociated>false</t:IsAssociated><t:WebClientReadFormQueryString>?ae=Item&amp;a=Open&amp;t=IPM.Note&amp;id=RgAAAADOrkJOZi%2fnSp0H8kv4afZtBwDDehUq0W%2biQrSvaM5VNEX8AAAAAE5bAACCesYbTRQFQqmH6sMUNPnlAAAAkWs1AAAJ&amp;exvsurl=1</t:WebClientReadFormQueryString><t:ConversationId Id="AAQkADg4NGVhZGUyLTU2ZTQtNGMwZS1iODRjLWY0YWE2NTYxMGE4ZQAQAO7cPg/JE9FBocl5VhMomEo="/><t:Sender><t:Mailbox><t:Name>Coiso da Coisa</t:Name><t:EmailAddress>[email protected]</t:EmailAddress><t:RoutingType>SMTP</t:RoutingType><t:MailboxType>OneOff</t:MailboxType></t:Mailbox></t:Sender><t:ToRecipients><t:Mailbox><t:Name>atendimento</t:Name><t:EmailAddress>[email protected]</t:EmailAddress><t:RoutingType>SMTP</t:RoutingType><t:MailboxType>Mailbox</t:MailboxType></t:Mailbox></t:ToRecipients><t:IsReadReceiptRequested>false</t:IsReadReceiptRequested><t:ConversationIndex>AQHQNXqx7tw+D8kT0UGhyXlWEyiYSg==</t:ConversationIndex><t:ConversationTopic>Insatisfação total</t:ConversationTopic><t:From><t:Mailbox><t:Name>Coisa da Coisa</t:Name><t:EmailAddress>[email protected]</t:EmailAddress><t:RoutingType>SMTP</t:RoutingType><t:MailboxType>OneOff</t:MailboxType></t:Mailbox></t:From><t:InternetMessageId>&lt;[email protected]&gt;</t:InternetMessageId><t:IsRead>true</t:IsRead><t:ReceivedBy><t:Mailbox><t:Name>atendimento</t:Name><t:EmailAddress>[email protected]</t:EmailAddress><t:RoutingType>SMTP</t:RoutingType><t:MailboxType>Mailbox</t:MailboxType></t:Mailbox></t:ReceivedBy><t:ReceivedRepresenting><t:Mailbox><t:Name>atendimento</t:Name><t:EmailAddress>[email protected]</t:EmailAddress><t:RoutingType>SMTP</t:RoutingType><t:MailboxType>Mailbox</t:MailboxType></t:Mailbox></t:ReceivedRepresenting></t:Message></m:Items></m:GetItemResponseMessage></m:ResponseMessages></m:GetItemResponse></s:Body></s:Envelope>
5 changes: 4 additions & 1 deletion spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
require 'turn/autorun'
require_relative 'xml_matcher'

RSpec.configure do |c|
RSpec.configure do |rspec|
rspec.mock_with :rspec do |mocks|
mocks.yield_receiver_to_any_instance_implementation_blocks = false
end
end

Turn.config.format = :outline
Expand Down
Loading