Class: Stockboy::Providers::IMAP

Inherits:
Stockboy::Provider show all
Defined in:
lib/stockboy/providers/imap.rb

Overview

Read data from a file attachment in IMAP email

Job template DSL

provider :imap do
  host "imap.example.com"
  username "[email protected]"
  password "424242"
  mailbox "INBOX"
  subject "Daily Report"
  since Date.today
  file_name /report-[0-9]+\.csv/
end

Defined Under Namespace

Classes: SearchOptions

Options collapse

Attributes inherited from Stockboy::Provider

#data, #data_size, #data_time, #errors, #logger

Instance Method Summary collapse

Methods inherited from Stockboy::Provider

#data?, #inspect, #reload, #valid?

Constructor Details

#initialize(opts = {}, &block) ⇒ IMAP

Initialize a new IMAP reader



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/stockboy/providers/imap.rb', line 131

def initialize(opts={}, &block)
  super(opts, &block)
  @host         = opts[:host]
  @username     = opts[:username]
  @password     = opts[:password]
  @mailbox      = opts[:mailbox]
  @subject      = opts[:subject]
  @from         = opts[:from]
  @since        = opts[:since]
  @search       = opts[:search]
  @attachment   = opts[:attachment]
  @file_smaller = opts[:file_smaller]
  @file_larger  = opts[:file_larger]
  @pick         = opts[:pick] || :last
  DSL.new(self).instance_eval(&block) if block_given?
  @open_client  = nil
end

Instance Attribute Details

#attachmentString, Regexp

Name or pattern for matching attachment files. First matching attachment is picked, or the first attachment if not specified.

Examples:

attachment "daily-report.csv"
attachment /daily-report-[0-9]+.csv/

Returns:

  • (String, Regexp)


107
# File 'lib/stockboy/providers/imap.rb', line 107

dsl_attr :attachment, alias: :file_name

#fromString

Email address of the sender

Examples:

from "[email protected]"

Returns:

  • (String)


78
# File 'lib/stockboy/providers/imap.rb', line 78

dsl_attr :from

#hostString

Host name or IP address for IMAP server connection

Examples:

host "imap.example.com"

Returns:

  • (String)


33
# File 'lib/stockboy/providers/imap.rb', line 33

dsl_attr :host

#mailboxString

Where to look for email on the server (usually “INBOX”)

Examples:

mailbox "INBOX"

Returns:

  • (String)


60
# File 'lib/stockboy/providers/imap.rb', line 60

dsl_attr :mailbox

#passwordString

Password for connection credentials

Examples:

password "424242"

Returns:

  • (String)


51
# File 'lib/stockboy/providers/imap.rb', line 51

dsl_attr :password

#pickSymbol, Proc

Method for choosing which email message to process from potential matches. Default is last by date sent.

Examples:

pick :last
pick :first
pick ->(list) {
  list.max_by { |msgid| client.fetch(msgid, 'SENTON').to_i }
}

Returns:

  • (Symbol, Proc)


125
# File 'lib/stockboy/providers/imap.rb', line 125

dsl_attr :pick

#searchString

Key-value tokens for IMAP search options

Examples:

search ['FLAGGED', 'BODY', 'Report attached']

Returns:

  • (String)


96
# File 'lib/stockboy/providers/imap.rb', line 96

dsl_attr :search

#sinceString

Minimum time sent for matching email

Examples:

since Date.today

Returns:

  • (String)


87
# File 'lib/stockboy/providers/imap.rb', line 87

dsl_attr :since, alias: :newer_than

#subjectString

Substring to find contained in matching email subject

Examples:

subject "Daily Report"

Returns:

  • (String)


69
# File 'lib/stockboy/providers/imap.rb', line 69

dsl_attr :subject

#usernameString

User name for connection credentials

Examples:

username "[email protected]"

Returns:

  • (String)


42
# File 'lib/stockboy/providers/imap.rb', line 42

dsl_attr :username

Instance Method Details

#clearObject

Clear received data and allow for selecting a new item from the server



200
201
202
203
204
205
# File 'lib/stockboy/providers/imap.rb', line 200

def clear
  super
  @message_key = nil
  @data_time = nil
  @data_size = nil
end

#clientObject

Direct access to the configured Net::IMAP connection

Examples:

provider.client do |imap|
  imap.search("FLAGGED")
end


156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/stockboy/providers/imap.rb', line 156

def client
  raise(ArgumentError, "no block given") unless block_given?
  first_connection = @open_client.nil?
  if first_connection
    @open_client = ::Net::IMAP.new(host)
    @open_client.(username, password)
    @open_client.examine(mailbox)
  end
  yield @open_client
rescue ::Net::IMAP::Error
  errors << "IMAP connection error"
ensure
  if first_connection && @open_client
    @open_client.disconnect
    @open_client = nil
  end
end

#default_search_optionsObject



234
235
236
# File 'lib/stockboy/providers/imap.rb', line 234

def default_search_options
  {subject: subject, from: from, since: since}.reject { |k,v| v.nil? }
end

#delete_dataObject

Purge the email from the mailbox corresponding to the [#message_key]

This can only be called after selecting the message_key to confirm the selected item, or after fetching the data.



179
180
181
182
183
184
185
186
187
188
# File 'lib/stockboy/providers/imap.rb', line 179

def delete_data
  picked_message_key? or raise Stockboy::OutOfSequence,
    "must confirm #message_key or calling #data"

  client do |imap|
    logger.info "Deleting message #{inspect_message_key}"
    imap.uid_store(message_key, "+FLAGS", [:Deleted])
    imap.expunge
  end
end

#find_messages(options = nil) ⇒ Object

Search the selected mailbox for matching messages

By default, the configured options are used,

Examples:

provider.find_messages(subject: "Daily Report", before: Date.today)
provider.find_messages(["SUBJECT", "Daily Report", "BEFORE", "21-DEC-12"])
provider.find_messages("FLAGGED BEFORE 21-DEC-12")

Parameters:

  • options (Hash, Array, String) (defaults to: nil)

    Override default configured search options



218
219
220
# File 'lib/stockboy/providers/imap.rb', line 218

def find_messages(options=nil)
  client { |imap| imap.sort(['DATE'], search_keys(options), 'UTF-8') }
end

#message_keyObject

IMAP message id for the email that contains the selected data to process



192
193
194
195
196
# File 'lib/stockboy/providers/imap.rb', line 192

def message_key
  return @message_key if @message_key
  message_ids = find_messages(default_search_options)
  @message_key = pick_from(message_ids) unless message_ids.empty?
end

#search_keys(options = nil) ⇒ Array

Normalize a hash of search options into an array of IMAP search keys

Parameters:

  • options (Hash) (defaults to: nil)

    If none are given, the configured options are used

Returns:

  • (Array)


227
228
229
230
231
232
# File 'lib/stockboy/providers/imap.rb', line 227

def search_keys(options=nil)
  case options
  when Array, String then options
  else SearchOptions.new(options || default_search_options).to_imap
  end
end