animoto_gmail 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Manifest +7 -0
- data/README +50 -0
- data/Rakefile +12 -0
- data/animoto_gmail.gemspec +40 -0
- data/lib/gmail.rb +91 -0
- data/test/gmail_test.rb +28 -0
- data/test/test_helper.rb +2 -0
- metadata +97 -0
data/Manifest
ADDED
data/README
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
ABOUT
|
2
|
+
-----
|
3
|
+
This Ruby gem wraps around Net::IMAP and TMail to provide GMail functionality.
|
4
|
+
|
5
|
+
AUTHOR
|
6
|
+
------
|
7
|
+
Animoto.com
|
8
|
+
|
9
|
+
INSTALL
|
10
|
+
-------
|
11
|
+
|
12
|
+
This gem is hosted on gemcutter.org. You must install the gemcutter gem and add it as a repository.
|
13
|
+
sudo gem install gemcutter
|
14
|
+
gem tumble
|
15
|
+
|
16
|
+
USAGE
|
17
|
+
-----
|
18
|
+
|
19
|
+
gem 'animoto_gmail', :lib => "gmail"
|
20
|
+
require 'gmail'
|
21
|
+
|
22
|
+
Animoto::GMail.logger = Logger.new(STDOUT)
|
23
|
+
gmail = Animoto::GMail.new(EMAIL, PASSWORD)
|
24
|
+
conditions = {:subject => SUBJECT, :since => "1-Dec-2009", :before => "2-Dec-2009"}
|
25
|
+
messages = gmail.search(:conditions => conditions, :full_message => true, :limit => 10)
|
26
|
+
puts "MESSAGE COUNT #{messages.size}"
|
27
|
+
messages.each { |m|
|
28
|
+
# DO WHAT YOU GOTTA DO
|
29
|
+
}
|
30
|
+
|
31
|
+
Please review IMAP RFC for parameters for searching.
|
32
|
+
http://ruby-doc.org/stdlib/libdoc/net/imap/rdoc/classes/Net/IMAP.html#M000738
|
33
|
+
|
34
|
+
:limit is an optional argument to limit the number of fetches done on subsequent calls to retrieve the email body. Without this argument, every message from the search will be fetched.
|
35
|
+
|
36
|
+
TESTING
|
37
|
+
-------
|
38
|
+
Tests can be executed via:
|
39
|
+
|
40
|
+
rake test
|
41
|
+
|
42
|
+
There is a simple test. To test yourself, please enable INTEGRATION and add your gmail email and password to the test file.
|
43
|
+
|
44
|
+
VERSION HISTORY
|
45
|
+
---------------
|
46
|
+
.0.0.1 - Initial gem-ification process of original code.
|
47
|
+
|
48
|
+
TO DO
|
49
|
+
-----
|
50
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'echoe'
|
4
|
+
|
5
|
+
Echoe.new('animoto_gmail', '0.0.1') do |p|
|
6
|
+
p.description = "Ruby Gmail Client over IMAP."
|
7
|
+
p.url = "http://animoto.com"
|
8
|
+
p.author = "Animoto"
|
9
|
+
p.email = "theteam@animoto.com"
|
10
|
+
p.ignore_pattern = ["tmp/*", "script/*"]
|
11
|
+
p.runtime_dependencies = ["tmail", "activesupport", "logging"]
|
12
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{animoto_gmail}
|
5
|
+
s.version = "0.0.1"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Animoto"]
|
9
|
+
s.date = %q{2009-12-02}
|
10
|
+
s.description = %q{Ruby Gmail Client over IMAP.}
|
11
|
+
s.email = %q{theteam@animoto.com}
|
12
|
+
s.extra_rdoc_files = ["README", "lib/gmail.rb"]
|
13
|
+
s.files = ["Manifest", "README", "Rakefile", "animoto_gmail.gemspec", "lib/gmail.rb", "test/gmail_test.rb", "test/test_helper.rb"]
|
14
|
+
s.homepage = %q{http://animoto.com}
|
15
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Animoto_gmail", "--main", "README"]
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
s.rubyforge_project = %q{animoto_gmail}
|
18
|
+
s.rubygems_version = %q{1.3.5}
|
19
|
+
s.summary = %q{Ruby Gmail Client over IMAP.}
|
20
|
+
s.test_files = ["test/gmail_test.rb", "test/test_helper.rb"]
|
21
|
+
|
22
|
+
if s.respond_to? :specification_version then
|
23
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
24
|
+
s.specification_version = 3
|
25
|
+
|
26
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
27
|
+
s.add_runtime_dependency(%q<tmail>, [">= 0"])
|
28
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 0"])
|
29
|
+
s.add_runtime_dependency(%q<logging>, [">= 0"])
|
30
|
+
else
|
31
|
+
s.add_dependency(%q<tmail>, [">= 0"])
|
32
|
+
s.add_dependency(%q<activesupport>, [">= 0"])
|
33
|
+
s.add_dependency(%q<logging>, [">= 0"])
|
34
|
+
end
|
35
|
+
else
|
36
|
+
s.add_dependency(%q<tmail>, [">= 0"])
|
37
|
+
s.add_dependency(%q<activesupport>, [">= 0"])
|
38
|
+
s.add_dependency(%q<logging>, [">= 0"])
|
39
|
+
end
|
40
|
+
end
|
data/lib/gmail.rb
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'net/imap' #ruby imap connector
|
3
|
+
require 'tmail' #ruby email parser
|
4
|
+
require 'activesupport' #for cattr_accessor
|
5
|
+
|
6
|
+
# Animoto::GMail
|
7
|
+
# Search for messages in a gmail account using the IMAP interface
|
8
|
+
#
|
9
|
+
# To initialize:
|
10
|
+
# theguys = Animoto::GMail.new('theguys@animoto.com', 'theguys_password')
|
11
|
+
#
|
12
|
+
# To search:
|
13
|
+
# conditions = { :subject => 'Animoto for Education Application',
|
14
|
+
# :since => Time.now.utc - 1.day }
|
15
|
+
# msgs = theguys.search( :conditions => conditions, :full_message => true )
|
16
|
+
|
17
|
+
module Animoto
|
18
|
+
class GMail
|
19
|
+
cattr_accessor :logger
|
20
|
+
attr_accessor :imap
|
21
|
+
|
22
|
+
def logger
|
23
|
+
self.class.logger
|
24
|
+
end
|
25
|
+
|
26
|
+
# connects to gmail server and selects the global mailbox
|
27
|
+
def initialize(login, password, mailbox = "[Gmail]/All Mail")
|
28
|
+
@messages = []
|
29
|
+
@messages_mutex = Mutex.new
|
30
|
+
|
31
|
+
# connect to gmail server
|
32
|
+
@imap = Net::IMAP.new('imap.gmail.com', 993, true)
|
33
|
+
@imap.login(login, password)
|
34
|
+
|
35
|
+
# select the mailbox with "all" messages
|
36
|
+
@imap.select(mailbox) # tag to select
|
37
|
+
end
|
38
|
+
|
39
|
+
# clean interface for searching an imap mailbox
|
40
|
+
# accepts a conditions hash with search options
|
41
|
+
def search(options)
|
42
|
+
conditions = options.delete(:conditions) || {}
|
43
|
+
mailbox = conditions.delete(:label)
|
44
|
+
@imap.select( mailbox ) if mailbox
|
45
|
+
|
46
|
+
# allow user to pass in custom clause
|
47
|
+
custom = conditions.delete(:custom) || []
|
48
|
+
|
49
|
+
# validate search flags
|
50
|
+
# http://tools.ietf.org/html/rfc3501#section-6.4.4
|
51
|
+
valid_flags = %w(before body cc from label new not or on since subject to)
|
52
|
+
if bad_flag = conditions.keys.detect{ |flag| !valid_flags.include?(flag.to_s) }
|
53
|
+
raise ArgumentError, "Invalid search flag '#{bad_flag}'"
|
54
|
+
end
|
55
|
+
|
56
|
+
# imap requires search params to be in a flattened array
|
57
|
+
# e.g. ['TO', 'stevie@animoto.com', 'BEFORE', Time.now]
|
58
|
+
keys = [ *conditions.map{|k,v| [k.to_s.upcase, v] }.flatten ] + custom
|
59
|
+
logger.info { "Executing IMAP search with #{keys.join(',')}" }
|
60
|
+
msg_ids = @imap.search(keys)
|
61
|
+
msg_ids = msg_ids[0, options[:limit].to_i] unless options[:limit].nil?
|
62
|
+
retrieve_messages(msg_ids, !!options[:full_message])
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
# retrieve all messages
|
68
|
+
# will return TMail::Mail objects for full messages,
|
69
|
+
# and Net::IMAP::Envelope objects for headers only
|
70
|
+
def retrieve_messages(msg_ids, full_message = false)
|
71
|
+
if full_message
|
72
|
+
raw_msgs = @imap.fetch(msg_ids, 'RFC822')
|
73
|
+
messages = raw_msgs.map { |msg|
|
74
|
+
TMail::Mail.parse(msg.attr['RFC822'])
|
75
|
+
}
|
76
|
+
else
|
77
|
+
raw_msgs = @imap.fetch(msg_ids, 'ENVELOPE')
|
78
|
+
messages = raw_msgs.map{ |msg| msg.attr['ENVELOPE'] }
|
79
|
+
end
|
80
|
+
messages
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# helper extension for getting email address
|
87
|
+
class Net::IMAP::Address
|
88
|
+
def email
|
89
|
+
"#{mailbox}@#{host}"
|
90
|
+
end
|
91
|
+
end
|
data/test/gmail_test.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'gmail'
|
3
|
+
require 'gmail_util'
|
4
|
+
|
5
|
+
class GMailTest < Test::Unit::TestCase
|
6
|
+
EMAIL = "PUT YOUR GMAIL EMAIL HERE"
|
7
|
+
PASSWORD = "PUT YOUR GMAIL PASSWORD HERE"
|
8
|
+
INTEGRATION = false
|
9
|
+
|
10
|
+
def test_gmail_search
|
11
|
+
return if !INTEGRATION
|
12
|
+
Animoto::GMail.logger = Logger.new(STDOUT)
|
13
|
+
gmail = Animoto::GMail.new(EMAIL, PASSWORD)
|
14
|
+
conditions = {:subject => "Contact [Account Inquiry] from Debora Daniel"}
|
15
|
+
messages = gmail.search(:conditions => conditions, :full_message => true, :limit => 1)
|
16
|
+
assert_not_nil messages
|
17
|
+
assert_equal messages.size, 1
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_gmail_search_2
|
21
|
+
return if !INTEGRATION
|
22
|
+
Animoto::GMail.logger = Logger.new(STDOUT)
|
23
|
+
gmail = Animoto::GMail.new(EMAIL, PASSWORD)
|
24
|
+
conditions = {:subject => "Returned mail: see transcript for details"}
|
25
|
+
messages = gmail.search(:conditions => conditions, :full_message => true, :limit => 100)
|
26
|
+
assert_not_nil messages
|
27
|
+
end
|
28
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: animoto_gmail
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Animoto
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-12-02 00:00:00 -05:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: tmail
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: activesupport
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: logging
|
37
|
+
type: :runtime
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: "0"
|
44
|
+
version:
|
45
|
+
description: Ruby Gmail Client over IMAP.
|
46
|
+
email: theteam@animoto.com
|
47
|
+
executables: []
|
48
|
+
|
49
|
+
extensions: []
|
50
|
+
|
51
|
+
extra_rdoc_files:
|
52
|
+
- README
|
53
|
+
- lib/gmail.rb
|
54
|
+
files:
|
55
|
+
- Manifest
|
56
|
+
- README
|
57
|
+
- Rakefile
|
58
|
+
- animoto_gmail.gemspec
|
59
|
+
- lib/gmail.rb
|
60
|
+
- test/gmail_test.rb
|
61
|
+
- test/test_helper.rb
|
62
|
+
has_rdoc: true
|
63
|
+
homepage: http://animoto.com
|
64
|
+
licenses: []
|
65
|
+
|
66
|
+
post_install_message:
|
67
|
+
rdoc_options:
|
68
|
+
- --line-numbers
|
69
|
+
- --inline-source
|
70
|
+
- --title
|
71
|
+
- Animoto_gmail
|
72
|
+
- --main
|
73
|
+
- README
|
74
|
+
require_paths:
|
75
|
+
- lib
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: "0"
|
81
|
+
version:
|
82
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: "1.2"
|
87
|
+
version:
|
88
|
+
requirements: []
|
89
|
+
|
90
|
+
rubyforge_project: animoto_gmail
|
91
|
+
rubygems_version: 1.3.5
|
92
|
+
signing_key:
|
93
|
+
specification_version: 3
|
94
|
+
summary: Ruby Gmail Client over IMAP.
|
95
|
+
test_files:
|
96
|
+
- test/gmail_test.rb
|
97
|
+
- test/test_helper.rb
|