watirmark_email 1.3.1
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.
- checksums.yaml +7 -0
- data/lib/watirmark_email.rb +10 -0
- data/lib/watirmark_email/email_base.rb +142 -0
- data/lib/watirmark_email/email_collection.rb +62 -0
- data/lib/watirmark_email/gmail.rb +94 -0
- data/lib/watirmark_email/qamail.rb +158 -0
- data/lib/watirmark_email/version.rb +7 -0
- data/spec/get_emails_spec.rb +41 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/watirmark_email_gmail_spec.rb +66 -0
- data/spec/watirmark_email_qamail_spec.rb +48 -0
- metadata +57 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: bb366bfcf3fab9ccfcc228545902f2c27b6b95e6
|
|
4
|
+
data.tar.gz: 25d666f434e75c7e26454177a529c38bb90b3c76
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 25ea7b742c9c6d989d5cdcf7b76991113d04d1d09c701af78f9d85cbd1d94e59bd307cadeb842a3bcc444c2560271ac2e0065e1399c0ed2c6b9009ba718b6984
|
|
7
|
+
data.tar.gz: 7e32bea10309b1bb6d4103851da24ab1b71d9c7bf1e3c75828c626c721760beeff6a45dbd2db5587ed567632f060a48c3b6cf7887ab1b54316fce1995b754ffc
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
module WatirmarkEmail
|
|
2
|
+
class BaseController
|
|
3
|
+
# Connects using the credentials supplied on initialize, returns the IMAP object. Most of the time, if all you want
|
|
4
|
+
# is an email, you won't need to use this method as get_email_text handles connect for you.
|
|
5
|
+
def connect
|
|
6
|
+
imap = Net::IMAP.new(@url, @port, @ssl)
|
|
7
|
+
imap.login(@email, @password)
|
|
8
|
+
imap.select(@inbox)
|
|
9
|
+
imap
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# This is a test method to disconnect from the server. get_email_text handles disconnect for you.
|
|
13
|
+
def disconnect(imap)
|
|
14
|
+
return true if imap.disconnected?
|
|
15
|
+
imap.logout
|
|
16
|
+
imap.disconnect
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# This is a test method to copy an email to the inbox
|
|
20
|
+
def copy(search_array, destination_folder=@inbox)
|
|
21
|
+
begin
|
|
22
|
+
@log.debug("copying to #{destination_folder}")
|
|
23
|
+
imap = connect
|
|
24
|
+
email_id = imap.search(search_array).last
|
|
25
|
+
email_uid = imap.fetch(email_id, 'UID').last.attr['UID']
|
|
26
|
+
raise "Original message not found to copy!" unless email_uid
|
|
27
|
+
imap.uid_copy(email_uid, destination_folder)
|
|
28
|
+
ensure
|
|
29
|
+
disconnect(imap)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def get_email_text(search_array, timeout=600, delete=true, since_sec=3600)
|
|
34
|
+
# Trying super ugly workaraound for the gmail 'Too many simlutaneous connections' error.
|
|
35
|
+
# Just trying to login to gmail and if it fails try to wait until other connections
|
|
36
|
+
# are closed and try again.
|
|
37
|
+
email_text = nil
|
|
38
|
+
email_subject = nil
|
|
39
|
+
email_uid = nil
|
|
40
|
+
|
|
41
|
+
::Timeout.timeout(timeout) do
|
|
42
|
+
@log.debug("start Timeout block for #{timeout} seconds")
|
|
43
|
+
loop do
|
|
44
|
+
begin
|
|
45
|
+
imap = connect
|
|
46
|
+
msgs = imap.search(search_array)
|
|
47
|
+
if (msgs && msgs.length > 0)
|
|
48
|
+
email_id = msgs.last
|
|
49
|
+
email_uid = imap.fetch(email_id, 'UID').last.attr['UID']
|
|
50
|
+
email_text = imap.uid_fetch(email_uid, 'BODY[TEXT]').last.attr['BODY[TEXT]']
|
|
51
|
+
envelope = imap.uid_fetch(email_uid, 'ENVELOPE').last.attr['ENVELOPE']
|
|
52
|
+
email_subject = envelope.subject
|
|
53
|
+
end
|
|
54
|
+
rescue => e
|
|
55
|
+
@log.info("Error connecting to IMAP: #{e.message}")
|
|
56
|
+
ensure
|
|
57
|
+
if (delete && email_uid)
|
|
58
|
+
@log.info("Deleting the email message #{email_subject}")
|
|
59
|
+
delete(email_uid, imap)
|
|
60
|
+
end
|
|
61
|
+
disconnect(imap) unless imap.nil? # because sometimes the timeout happens before imap is defined
|
|
62
|
+
end
|
|
63
|
+
break if email_text
|
|
64
|
+
@log.debug("Couldn't find email yet ... trying again")
|
|
65
|
+
sleep 10
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
email_text
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def get_email_replyto(search_array, timeout=600, delete=true)
|
|
72
|
+
envelope = nil
|
|
73
|
+
email_uid = nil
|
|
74
|
+
|
|
75
|
+
::Timeout.timeout(timeout) do
|
|
76
|
+
@log.debug("start Timeout block for #{timeout} seconds")
|
|
77
|
+
loop do
|
|
78
|
+
begin
|
|
79
|
+
imap = connect
|
|
80
|
+
msgs = imap.search(search_array)
|
|
81
|
+
if (msgs && msgs.length > 0)
|
|
82
|
+
email_id = msgs.last
|
|
83
|
+
email_uid = imap.fetch(email_id, 'UID').last.attr['UID']
|
|
84
|
+
envelope = imap.uid_fetch(email_uid, 'ENVELOPE').last.attr['ENVELOPE']
|
|
85
|
+
end
|
|
86
|
+
rescue => e
|
|
87
|
+
@log.info("Error connecting to IMAP: #{e.message}")
|
|
88
|
+
ensure
|
|
89
|
+
if (delete && email_uid)
|
|
90
|
+
delete(email_uid, imap)
|
|
91
|
+
end
|
|
92
|
+
disconnect(imap) unless imap.nil? # because sometimes the timeout happens before imap is defined
|
|
93
|
+
end
|
|
94
|
+
break if envelope
|
|
95
|
+
@log.debug("Couldn't find email yet ... trying again")
|
|
96
|
+
sleep 10
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
"#{envelope.reply_to[0].name} <#{envelope.reply_to[0].mailbox}@#{envelope.reply_to[0].host}>"
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
#returns the name of the email attachment
|
|
103
|
+
#returns nil if there is no attachment
|
|
104
|
+
def get_email_attachment(search_array, timeout=600)
|
|
105
|
+
attachment = nil
|
|
106
|
+
finished = false
|
|
107
|
+
::Timeout.timeout(timeout) do
|
|
108
|
+
@log.debug("start Timeout block for #{timeout} seconds")
|
|
109
|
+
loop do
|
|
110
|
+
begin
|
|
111
|
+
imap = connect
|
|
112
|
+
msgs = imap.search(search_array)
|
|
113
|
+
if (msgs && msgs.length > 0)
|
|
114
|
+
msgs.each do |msgID|
|
|
115
|
+
msg = imap.fetch(msgID, ["ENVELOPE", "UID", "BODY"])[0]
|
|
116
|
+
body = msg.attr["BODY"]
|
|
117
|
+
attachment = body.parts[1].param['NAME']
|
|
118
|
+
finished = true
|
|
119
|
+
#TODO read text of .pdf file
|
|
120
|
+
#grab attachment file
|
|
121
|
+
#attachment_file = imap.fetch(msgID, "BODY[#{2}]")[0].attr["BODY[#{2}]"]
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
rescue => e
|
|
125
|
+
@log.info("Error connecting to IMAP: #{e.message}")
|
|
126
|
+
ensure
|
|
127
|
+
disconnect(imap) unless imap.nil? # because sometimes the timeout happens before imap is defined
|
|
128
|
+
end
|
|
129
|
+
break if finished
|
|
130
|
+
@log.debug("Couldn't find email yet ... trying again")
|
|
131
|
+
sleep 10
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
attachment
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
module WatirmarkEmail
|
|
2
|
+
class Email
|
|
3
|
+
attr_accessor :date, :subject, :to, :from, :message_id, :body_text, :body_raw, :uid
|
|
4
|
+
|
|
5
|
+
def initialize(envelope, body_text, body_raw, uid)
|
|
6
|
+
@to = []
|
|
7
|
+
@date = envelope.date
|
|
8
|
+
@subject = envelope.subject
|
|
9
|
+
envelope.to.each do |recipient|
|
|
10
|
+
@to << "#{recipient.mailbox}@#{recipient.host}"
|
|
11
|
+
end
|
|
12
|
+
@from = "#{envelope.from.first.mailbox}@#{envelope.from.first.host}"
|
|
13
|
+
@message_id = envelope.message_id
|
|
14
|
+
@body_text = body_text
|
|
15
|
+
@body_raw = body_raw
|
|
16
|
+
@uid = uid
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def <=> (other)
|
|
20
|
+
date <=> other.date
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
class EmailCollection
|
|
25
|
+
include Enumerable
|
|
26
|
+
|
|
27
|
+
def initialize
|
|
28
|
+
@emails = []
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def each(&block)
|
|
32
|
+
@emails.each(&block)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def empty?
|
|
36
|
+
@emails.empty?
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def [](x)
|
|
40
|
+
@emails[x]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def length
|
|
44
|
+
@emails.length
|
|
45
|
+
end
|
|
46
|
+
alias :size :length
|
|
47
|
+
|
|
48
|
+
def add_emails(email_info)
|
|
49
|
+
#should be an array of Net::IMAP::FetchData or a single class
|
|
50
|
+
email_info = [email_info] unless email_info.is_a?(Array)
|
|
51
|
+
email_info.each do |email|
|
|
52
|
+
envelope = email.attr["ENVELOPE"]
|
|
53
|
+
body_text = email.attr["BODY[TEXT]"]
|
|
54
|
+
body_raw = email.attr["BODY[]"]
|
|
55
|
+
uid = email.attr["UID"]
|
|
56
|
+
@emails << Email.new(envelope, body_text, body_raw, uid)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
module WatirmarkEmail
|
|
2
|
+
class Gmail < BaseController
|
|
3
|
+
attr_accessor :inbox
|
|
4
|
+
URL = "imap.gmail.com"
|
|
5
|
+
PORT = 993
|
|
6
|
+
MAILBOX_INBOX = "INBOX"
|
|
7
|
+
MAILBOX_TRASH = "[Gmail]/Trash"
|
|
8
|
+
MAILBOX_ALL = "[Gmail]/All Mail"
|
|
9
|
+
|
|
10
|
+
# Constructor for this class.
|
|
11
|
+
# This will initialize all variables according to the type email service this is using.
|
|
12
|
+
def initialize(email, password, logLevel = ::Logger::INFO)
|
|
13
|
+
@email = email
|
|
14
|
+
@password = password
|
|
15
|
+
@log = ::Logger.new STDOUT
|
|
16
|
+
@log.level = logLevel
|
|
17
|
+
@url = URL
|
|
18
|
+
@port = PORT
|
|
19
|
+
@inbox = MAILBOX_INBOX
|
|
20
|
+
@trash = MAILBOX_TRASH
|
|
21
|
+
@ssl = true # port 993
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def delete(email_uid, imap)
|
|
25
|
+
imap.uid_copy(email_uid, @trash)
|
|
26
|
+
imap.uid_store(email_uid, "+FLAGS", [:Deleted])
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# This keeps polling the email inbox until a message is found with the given
|
|
31
|
+
# parameters (based on net::IMAP search) or the timeout is reached. This also
|
|
32
|
+
# deletes the email from the inbox if the delete flag is set to true.
|
|
33
|
+
# Returns the email text.
|
|
34
|
+
#
|
|
35
|
+
# search_array is an array of strings that need to be formatted according to the following convention from Net::IMAP.
|
|
36
|
+
# These strings will be used to send a SEARCH command to search the mailbox for messages that match the given
|
|
37
|
+
# searching criteria:
|
|
38
|
+
# BEFORE <date>: messages with an internal date strictly before <date>. The date argument has a format similar
|
|
39
|
+
# to 8-Aug-2002.
|
|
40
|
+
# BODY <string>: messages that contain <string> within their body.
|
|
41
|
+
# CC <string>: messages containing <string> in their CC field.
|
|
42
|
+
# FROM <string>: messages that contain <string> in their FROM field.
|
|
43
|
+
# NEW: messages with the Recent, but not the Seen, flag set.
|
|
44
|
+
# NOT <search-key>: negate the following search key.
|
|
45
|
+
# OR <search-key> <search-key>: "or" two search keys together.
|
|
46
|
+
# ON <date>: messages with an internal date exactly equal to <date>, which has a format similar to 8-Aug-2002.
|
|
47
|
+
# SINCE <date>: messages with an internal date on or after <date>.
|
|
48
|
+
# SUBJECT <string>: messages with <string> in their subject.
|
|
49
|
+
# TO <string>: messages with <string> in their TO field.
|
|
50
|
+
#
|
|
51
|
+
# For example:
|
|
52
|
+
# get_email_text(["SUBJECT", "hello", "NOT", "NEW"])
|
|
53
|
+
# => finds emails with the subject "hello" which are not "NEW" (see definition of NEW)
|
|
54
|
+
#
|
|
55
|
+
# See also: http://tools.ietf.org/html/rfc3501#section-6.4.4
|
|
56
|
+
#
|
|
57
|
+
def get_email_text(search_array, timeout=600, delete=true, since_sec=3600)
|
|
58
|
+
# Only look for emails that have come in since the last hour
|
|
59
|
+
since = Time.now - since_sec
|
|
60
|
+
imap_search_terms = search_array.dup.push("SINCE", since.strftime('%d-%b-%Y'))
|
|
61
|
+
@log.debug("Searching for email with query: #{imap_search_terms}")
|
|
62
|
+
|
|
63
|
+
super imap_search_terms, timeout, delete, since_sec
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def send_email(to, opts={})
|
|
67
|
+
opts[:from] ||= 'qa@convio.com'
|
|
68
|
+
opts[:from_alias] ||= 'Watirmark Email'
|
|
69
|
+
opts[:subject] ||= "test"
|
|
70
|
+
opts[:body] ||= "Watirmark Email test message"
|
|
71
|
+
|
|
72
|
+
smtp = Net::SMTP.new 'smtp.gmail.com', 587
|
|
73
|
+
smtp.enable_starttls
|
|
74
|
+
|
|
75
|
+
msg = <<END_OF_MESSAGE
|
|
76
|
+
From: #{opts[:from_alias]} <#{opts[:from]}>
|
|
77
|
+
To: <#{to}>
|
|
78
|
+
Subject: #{opts[:subject]}
|
|
79
|
+
|
|
80
|
+
#{opts[:body]}
|
|
81
|
+
END_OF_MESSAGE
|
|
82
|
+
|
|
83
|
+
response = smtp.start('smtp.gmail.com', @email, @password, :plain) do |smpt|
|
|
84
|
+
smtp.send_message msg, opts[:from], to
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
if response && response.status == "250"
|
|
88
|
+
return true
|
|
89
|
+
else
|
|
90
|
+
return false
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
module WatirmarkEmail
|
|
2
|
+
class QAMail < BaseController
|
|
3
|
+
URL = "qasendmail.conviocloud.com"
|
|
4
|
+
PORT = 143
|
|
5
|
+
MAILBOX_INBOX = "Inbox"
|
|
6
|
+
|
|
7
|
+
# Constructor for this class.
|
|
8
|
+
# This will initialize all variables according to the type email service this is using.
|
|
9
|
+
def initialize(account, password=nil, logLevel = ::Logger::INFO)
|
|
10
|
+
@email = account
|
|
11
|
+
@password = password || account
|
|
12
|
+
@log = ::Logger.new STDOUT
|
|
13
|
+
@log.level = logLevel
|
|
14
|
+
@url = URL
|
|
15
|
+
@port = PORT
|
|
16
|
+
@inbox = MAILBOX_INBOX
|
|
17
|
+
@ssl = false # port 143
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def delete(email_uid, imap)
|
|
21
|
+
imap.uid_store(email_uid, "+FLAGS", [:Deleted])
|
|
22
|
+
imap.expunge
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# used for testing
|
|
26
|
+
def delete_emails(search_terms, timeout = 60)
|
|
27
|
+
uid_list = find_email_uids(search_terms, timeout)
|
|
28
|
+
imap = connect
|
|
29
|
+
uid_list.each do |uid|
|
|
30
|
+
imap.uid_store(uid, "+FLAGS", [:Deleted])
|
|
31
|
+
end
|
|
32
|
+
imap.expunge
|
|
33
|
+
disconnect imap
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# This keeps polling the email inbox until a message is found with the given
|
|
37
|
+
# parameters (based on net::IMAP search) or the timeout is reached. This also
|
|
38
|
+
# deletes the email from the inbox if the delete flag is set to true.
|
|
39
|
+
# Returns the email text.
|
|
40
|
+
#
|
|
41
|
+
# search_array is an array of strings that need to be formatted according to the following convention from Net::IMAP.
|
|
42
|
+
# These strings will be used to send a SEARCH command to search the mailbox for messages that match the given
|
|
43
|
+
# searching criteria:
|
|
44
|
+
# BEFORE <date>: messages with an internal date strictly before <date>. The date argument has a format similar
|
|
45
|
+
# to 8-Aug-2002.
|
|
46
|
+
# BODY <string>: messages that contain <string> within their body.
|
|
47
|
+
# CC <string>: messages containing <string> in their CC field.
|
|
48
|
+
# FROM <string>: messages that contain <string> in their FROM field.
|
|
49
|
+
# NEW: messages with the Recent, but not the Seen, flag set.
|
|
50
|
+
# NOT <search-key>: negate the following search key.
|
|
51
|
+
# OR <search-key> <search-key>: "or" two search keys together.
|
|
52
|
+
# ON <date>: messages with an internal date exactly equal to <date>, which has a format similar to 8-Aug-2002.
|
|
53
|
+
# SINCE <date>: messages with an internal date on or after <date>.
|
|
54
|
+
# SUBJECT <string>: messages with <string> in their subject.
|
|
55
|
+
# TO <string>: messages with <string> in their TO field.
|
|
56
|
+
#
|
|
57
|
+
# For example:
|
|
58
|
+
# get_email_text(["SUBJECT", "hello", "NOT", "NEW"])
|
|
59
|
+
# => finds emails with the subject "hello" which are not "NEW" (see definition of NEW)
|
|
60
|
+
#
|
|
61
|
+
# See also: http://tools.ietf.org/html/rfc3501#section-6.4.4
|
|
62
|
+
#
|
|
63
|
+
def get_email_text(search_array, timeout=600, delete=true)
|
|
64
|
+
@log.debug("Searching for email with query: #{search_array}")
|
|
65
|
+
|
|
66
|
+
super search_array, timeout, delete
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def get_email_replyto(search_array, timeout=600, delete=true)
|
|
70
|
+
@log.debug("Searching for email with query: #{search_array}")
|
|
71
|
+
|
|
72
|
+
super search_array, timeout, delete
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def get_email_attachment(search_arry, timeout=600)
|
|
76
|
+
@log.debug("Searching for email attachment with query: #{search_arry}")
|
|
77
|
+
|
|
78
|
+
super search_arry, timeout
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def send_email(to, opts={})
|
|
82
|
+
opts[:server] ||= 'qasendmail.conviocloud.com'
|
|
83
|
+
opts[:from] ||= 'qa@convio.com'
|
|
84
|
+
opts[:from_alias] ||= 'Watirmark Email'
|
|
85
|
+
opts[:subject] ||= "test"
|
|
86
|
+
opts[:body] ||= "Watirmark Email test message"
|
|
87
|
+
|
|
88
|
+
msg = <<END_OF_MESSAGE
|
|
89
|
+
From: #{opts[:from_alias]} <#{opts[:from]}>
|
|
90
|
+
To: <#{to}>
|
|
91
|
+
Subject: #{opts[:subject]}
|
|
92
|
+
|
|
93
|
+
#{opts[:body]}
|
|
94
|
+
END_OF_MESSAGE
|
|
95
|
+
|
|
96
|
+
response = Net::SMTP.start(opts[:server]) do |smtp|
|
|
97
|
+
smtp.send_message msg, opts[:from], to
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
if response && response.status == "250"
|
|
101
|
+
return true
|
|
102
|
+
else
|
|
103
|
+
return false
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def find_emails(search_terms, timeout = 60)
|
|
108
|
+
uids = find_email_uids(search_terms, timeout)
|
|
109
|
+
emails = WatirmarkEmail::EmailCollection.new
|
|
110
|
+
|
|
111
|
+
::Timeout.timeout(timeout) do
|
|
112
|
+
@log.debug("start Timeout block for #{timeout} seconds")
|
|
113
|
+
loop do
|
|
114
|
+
begin
|
|
115
|
+
imap = connect
|
|
116
|
+
fetchdata = imap.uid_fetch(uids, ["ENVELOPE", "BODY[TEXT]", "BODY[]", "UID"])
|
|
117
|
+
emails.add_emails(fetchdata)
|
|
118
|
+
rescue => e
|
|
119
|
+
@log.info("#{e.class}: #{e.message}")
|
|
120
|
+
ensure
|
|
121
|
+
disconnect(imap) unless imap.nil? # because sometimes the timeout happens before imap is defined
|
|
122
|
+
end
|
|
123
|
+
break unless emails.empty?
|
|
124
|
+
@log.debug("Couldn't find email yet ... trying again")
|
|
125
|
+
sleep 10
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
emails
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def find_email_uids(search_terms, timeout = 60)
|
|
132
|
+
email_uids = []
|
|
133
|
+
|
|
134
|
+
::Timeout.timeout(timeout) do
|
|
135
|
+
@log.debug("start Timeout block for #{timeout} seconds")
|
|
136
|
+
loop do
|
|
137
|
+
begin
|
|
138
|
+
imap = connect
|
|
139
|
+
msgs = imap.search(search_terms)
|
|
140
|
+
@log.debug("found message numbers: #{msgs}")
|
|
141
|
+
if (msgs && msgs.length > 0)
|
|
142
|
+
email_uids = msgs.inject([]) { |email_uids, email_id| email_uids << imap.fetch(email_id, 'UID').last.attr['UID'] }
|
|
143
|
+
end
|
|
144
|
+
rescue => e
|
|
145
|
+
@log.info("Error connecting to IMAP: #{e.message}")
|
|
146
|
+
ensure
|
|
147
|
+
disconnect(imap) unless imap.nil? # because sometimes the timeout happens before imap is defined
|
|
148
|
+
end
|
|
149
|
+
break unless email_uids.empty?
|
|
150
|
+
@log.debug("Couldn't find email yet ... trying again")
|
|
151
|
+
sleep 10
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
@log.debug("found UIDS: #{email_uids}}")
|
|
155
|
+
email_uids
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "Get Emails" do
|
|
4
|
+
before(:all) do
|
|
5
|
+
username = CREDENTIALS['qamail']['username']
|
|
6
|
+
password = CREDENTIALS['qamail']['password']
|
|
7
|
+
send_to = CREDENTIALS['qamail']['send_to']
|
|
8
|
+
@subject = "Multiple Email Test #{Time.now.strftime "%Y%m%d%H%M%S"}"
|
|
9
|
+
@search_terms = ['SUBJECT', "Multiple Email Test"]
|
|
10
|
+
@e = WatirmarkEmail::QAMail.new(username, password, ::Logger::DEBUG)
|
|
11
|
+
1.upto(5) do |x|
|
|
12
|
+
@e.send_email(send_to, :subject => "#{@subject} - message #{x}", :body => "#{@subject} - message #{x}")
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
after(:all) do
|
|
17
|
+
@e.delete_emails @search_terms
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "should find 5 emails when searching by subject \"Multiple Email Test\"" do
|
|
21
|
+
emails = @e.find_emails(@search_terms)
|
|
22
|
+
emails.length.should == 5
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "when searching by subject \"Multiple Email Test\", each found email should have a subject and a body with an incrementing number" do
|
|
26
|
+
emails = @e.find_emails(@search_terms)
|
|
27
|
+
0.upto(4).each do |x|
|
|
28
|
+
emails[x].subject.should == "#{@subject} - message #{x + 1}"
|
|
29
|
+
emails[x].body_text.should =~ /#{@subject} - message #{x + 1}/
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "when searching by subject \"Multiple Email Test\", mapping the subjects to an array returns an array of length 5" do
|
|
34
|
+
expected_subject_array = ["#{@subject} - message 1",
|
|
35
|
+
"#{@subject} - message 2",
|
|
36
|
+
"#{@subject} - message 3",
|
|
37
|
+
"#{@subject} - message 4",
|
|
38
|
+
"#{@subject} - message 5"]
|
|
39
|
+
@e.find_emails(@search_terms).map { |email| email.subject }.sort.should == expected_subject_array
|
|
40
|
+
end
|
|
41
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require 'rspec'
|
|
2
|
+
require 'yaml'
|
|
3
|
+
require 'watirmark_email'
|
|
4
|
+
|
|
5
|
+
# this file contains credentials to gmail and IMAP servers in a simple hash expressed in YAML and looks like:
|
|
6
|
+
#---
|
|
7
|
+
#qamail:
|
|
8
|
+
# username: <supply your own>
|
|
9
|
+
# password: <not telling>
|
|
10
|
+
# send_to: <email address on your IMAP server, needed here because we all know how to get to gmail>
|
|
11
|
+
#gmail:
|
|
12
|
+
# username: <supply your own>
|
|
13
|
+
# password: <not telling>
|
|
14
|
+
CREDENTIALS = YAML.load_file(File.join(File.dirname(__FILE__), "email_server_credentials.yaml"))
|
|
15
|
+
|
|
16
|
+
alias :context :describe
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
context 'WatirmarkEmail::Gmail' do
|
|
4
|
+
|
|
5
|
+
before :all do
|
|
6
|
+
STDOUT.sync = true
|
|
7
|
+
@username = CREDENTIALS['gmail']['username']
|
|
8
|
+
@password = CREDENTIALS['gmail']['password']
|
|
9
|
+
@test_message = ['SUBJECT', 'UNIT TEST MESSAGE', 'BODY', "unit_test_message_id"]
|
|
10
|
+
@does_not_exist_test_message = ['SUBJECT', "MISSING"]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
specify 'initialize email connection to gmail.com' do
|
|
14
|
+
e = WatirmarkEmail::Gmail.new(@username, @password)
|
|
15
|
+
e.should_not be_nil
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
specify 'should timeout when the email does not exist' do
|
|
19
|
+
e = WatirmarkEmail::Gmail.new(@username, @password, Logger::DEBUG)
|
|
20
|
+
lambda {
|
|
21
|
+
txt = e.get_email_text(@does_not_exist_test_message, 15, false)
|
|
22
|
+
}.should raise_error Timeout::Error
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
specify 'should send an email to gmail' do
|
|
26
|
+
e = WatirmarkEmail::Gmail.new(@username, @password, Logger::DEBUG)
|
|
27
|
+
e.send_email(@username, :subject => 'UNIT TEST MESSAGE', :body => "unit_test_message_id").should be_true
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
specify 'copy the test email to the UnitTest folder' do
|
|
31
|
+
e = WatirmarkEmail::Gmail.new(@username, @password, Logger::DEBUG)
|
|
32
|
+
e.copy(@test_message, 'UnitTest')
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
specify 'verify test email exists in the UnitTest folder' do
|
|
36
|
+
e = WatirmarkEmail::Gmail.new(@username, @password, Logger::DEBUG)
|
|
37
|
+
e.inbox = 'UnitTest'
|
|
38
|
+
txt = e.get_email_text(@test_message, 60, false)
|
|
39
|
+
txt.should be_a(String)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
specify 'copy the test email from the UnitTest folder to the inbox' do
|
|
43
|
+
e = WatirmarkEmail::Gmail.new(@username, @password, Logger::DEBUG)
|
|
44
|
+
e.inbox = 'UnitTest'
|
|
45
|
+
e.copy(@test_message, WatirmarkEmail::Gmail::MAILBOX_INBOX)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
specify 'should return body text from an email in the inbox' do
|
|
49
|
+
e = WatirmarkEmail::Gmail.new(@username, @password, Logger::DEBUG)
|
|
50
|
+
txt = e.get_email_text(@test_message, 60, false)
|
|
51
|
+
txt.should be_a(String)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
specify 'delete flag should remove the email from the inbox' do
|
|
55
|
+
e = WatirmarkEmail::Gmail.new(@username, @password, Logger::DEBUG)
|
|
56
|
+
txt = e.get_email_text(@test_message, 60, true)
|
|
57
|
+
txt.should be_a(String)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
specify 'should not see the email now that it is deleted' do
|
|
61
|
+
e = WatirmarkEmail::Gmail.new(@username, @password, Logger::DEBUG)
|
|
62
|
+
lambda {
|
|
63
|
+
txt = e.get_email_text(@test_message, 15, false)
|
|
64
|
+
}.should raise_error Timeout::Error
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "WatirmarkEmail::QAMail" do
|
|
4
|
+
|
|
5
|
+
before(:all) do
|
|
6
|
+
@username = CREDENTIALS['qamail']['username']
|
|
7
|
+
@password = CREDENTIALS['qamail']['password']
|
|
8
|
+
@send_to = CREDENTIALS['qamail']['send_to']
|
|
9
|
+
@search_terms = ['BODY', "Watirmark"]
|
|
10
|
+
@not_present_search_terms = ['SUBJECT', "MISSING"]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "should return an instance of itself when started" do
|
|
14
|
+
e = WatirmarkEmail::QAMail.new(@username, @password)
|
|
15
|
+
e.class.should == WatirmarkEmail::QAMail
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "should be able to connect to the qamail server successfullly" do
|
|
19
|
+
e = WatirmarkEmail::QAMail.new(@username, @password)
|
|
20
|
+
imap = e.connect
|
|
21
|
+
imap.should_not be_disconnected # cause imap has no "connected" method
|
|
22
|
+
e.disconnect(imap).should be_nil
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'should send an email to qamail' do
|
|
26
|
+
e = WatirmarkEmail::QAMail.new(@username, @password)
|
|
27
|
+
e.send_email(@send_to, :subject => 'UNIT TEST MESSAGE', :body => "Watirmark Email test message").should be_true
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "should get a sample email with 'Watirmark Email test message' in the body of the email" do
|
|
31
|
+
e = WatirmarkEmail::QAMail.new(@username, @password)
|
|
32
|
+
email_body_text = e.get_email_text(@search_terms, 30, false)
|
|
33
|
+
email_body_text.should match(/Watirmark Email test message/)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
specify "should timeout when the email does not exist" do
|
|
37
|
+
e = WatirmarkEmail::QAMail.new(@username, @password, Logger::DEBUG)
|
|
38
|
+
lambda {
|
|
39
|
+
txt = e.get_email_text(@not_present_search_terms, 15, false)
|
|
40
|
+
}.should raise_error Timeout::Error
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "should delete a sample email with 'Watirmark Email test message' in the body of the email" do
|
|
44
|
+
e = WatirmarkEmail::QAMail.new(@username, @password)
|
|
45
|
+
email_body_text = e.get_email_text(@search_terms, 30, true)
|
|
46
|
+
email_body_text.should match(/Watirmark Email test message/)
|
|
47
|
+
end
|
|
48
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: watirmark_email
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.3.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Alan Baird
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2015-10-01 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: watirmark_email lets you get email from both GMAIL and generic IMAP servers
|
|
14
|
+
email: abaird@convio.com
|
|
15
|
+
executables: []
|
|
16
|
+
extensions: []
|
|
17
|
+
extra_rdoc_files: []
|
|
18
|
+
files:
|
|
19
|
+
- lib/watirmark_email.rb
|
|
20
|
+
- lib/watirmark_email/email_base.rb
|
|
21
|
+
- lib/watirmark_email/email_collection.rb
|
|
22
|
+
- lib/watirmark_email/gmail.rb
|
|
23
|
+
- lib/watirmark_email/qamail.rb
|
|
24
|
+
- lib/watirmark_email/version.rb
|
|
25
|
+
- spec/get_emails_spec.rb
|
|
26
|
+
- spec/spec_helper.rb
|
|
27
|
+
- spec/watirmark_email_gmail_spec.rb
|
|
28
|
+
- spec/watirmark_email_qamail_spec.rb
|
|
29
|
+
homepage: http://github.com/convio/watirmark_email
|
|
30
|
+
licenses: []
|
|
31
|
+
metadata: {}
|
|
32
|
+
post_install_message:
|
|
33
|
+
rdoc_options: []
|
|
34
|
+
require_paths:
|
|
35
|
+
- lib
|
|
36
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - '>='
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
41
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
42
|
+
requirements:
|
|
43
|
+
- - '>='
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '0'
|
|
46
|
+
requirements: []
|
|
47
|
+
rubyforge_project:
|
|
48
|
+
rubygems_version: 2.4.8
|
|
49
|
+
signing_key:
|
|
50
|
+
specification_version: 4
|
|
51
|
+
summary: watirmark_email-1.3.1
|
|
52
|
+
test_files:
|
|
53
|
+
- spec/get_emails_spec.rb
|
|
54
|
+
- spec/spec_helper.rb
|
|
55
|
+
- spec/watirmark_email_gmail_spec.rb
|
|
56
|
+
- spec/watirmark_email_qamail_spec.rb
|
|
57
|
+
has_rdoc:
|