ruby-gmail 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/History.txt +20 -7
- data/Manifest.txt +1 -1
- data/README.markdown +106 -0
- data/Rakefile +2 -1
- data/lib/gmail.rb +24 -6
- data/lib/gmail/mailbox.rb +42 -7
- data/lib/gmail/message.rb +16 -1
- data/lib/mime/entity.rb +6 -5
- data/lib/mime/message.rb +9 -0
- data/lib/smtp_tls.rb +4 -4
- metadata +9 -8
- metadata.gz.sig +0 -0
- data/README.txt +0 -85
data.tar.gz.sig
CHANGED
Binary file
|
data/History.txt
CHANGED
@@ -1,8 +1,21 @@
|
|
1
|
-
=== 0.0.
|
1
|
+
=== 0.0.4 / 2009-11-30
|
2
2
|
|
3
|
-
*
|
3
|
+
* 4 minor enhancement
|
4
4
|
|
5
|
-
*
|
5
|
+
* Added label creation (thanks to Justin Perkins / http://github.com/justinperkins)
|
6
|
+
* Made the gem login automatically when first needed
|
7
|
+
* Added an optional block on the Gmail.new object that will login and logout for you.
|
8
|
+
* Added several search options (thanks to Mikkel Malmberg / http://github.com/mikker)
|
9
|
+
|
10
|
+
=== 0.0.3 / 2009-11-19
|
11
|
+
|
12
|
+
* 1 bugfix
|
13
|
+
|
14
|
+
* Fixed MIME::Message#content= for messages without an encoding
|
15
|
+
|
16
|
+
* 1 minor enhancement
|
17
|
+
|
18
|
+
* Added Gmail#new_message
|
6
19
|
|
7
20
|
=== 0.0.2 / 2009-11-18
|
8
21
|
|
@@ -10,9 +23,9 @@
|
|
10
23
|
|
11
24
|
* Made all of the examples in the README possible.
|
12
25
|
|
13
|
-
=== 0.0.
|
26
|
+
=== 0.0.1 / 2009-11-18
|
14
27
|
|
15
|
-
* 1
|
28
|
+
* 1 major enhancement
|
29
|
+
|
30
|
+
* Birthday!
|
16
31
|
|
17
|
-
* Fixed MIME::Message#content= for messages without an encoding
|
18
|
-
* Added Gmail#new_message
|
data/Manifest.txt
CHANGED
data/README.markdown
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
# ruby-gmail
|
2
|
+
|
3
|
+
* Homepage: [http://dcparker.github.com/ruby-gmail/](http://dcparker.github.com/ruby-gmail/)
|
4
|
+
* Code: [http://github.com/dcparker/ruby-gmail](http://github.com/dcparker/ruby-gmail)
|
5
|
+
* Gem: [http://gemcutter.org/gems/ruby-gmail](http://gemcutter.org/gems/ruby-gmail)
|
6
|
+
|
7
|
+
## Author(s)
|
8
|
+
|
9
|
+
* Daniel Parker of BehindLogic.com
|
10
|
+
|
11
|
+
Extra thanks for specific feature contributions from:
|
12
|
+
|
13
|
+
* [Justin Perkins](http://github.com/justinperkins)
|
14
|
+
* [Mikkel Malmberg](http://github.com/mikker)
|
15
|
+
|
16
|
+
|
17
|
+
## Description
|
18
|
+
|
19
|
+
A Rubyesque interface to Gmail, with all the tools you'll need. Search, read and send multipart emails; archive, mark as read/unread, delete emails; and manage labels.
|
20
|
+
|
21
|
+
## Features
|
22
|
+
|
23
|
+
* Search emails
|
24
|
+
* Read emails (handles attachments)
|
25
|
+
* Emails: Label, archive, delete, mark as read/unread/spam
|
26
|
+
* Create and delete labels
|
27
|
+
* Create and send multipart email messages in plaintext and/or html, with inline images and attachments
|
28
|
+
* Utilizes Gmail's IMAP & SMTP, MIME-type detection and parses and generates MIME properly.
|
29
|
+
|
30
|
+
## Problems:
|
31
|
+
|
32
|
+
* May not correctly read malformed MIME messages. This could possibly be corrected by having IMAP parse the MIME structure.
|
33
|
+
* Cannot grab the plain or html message without also grabbing attachments. It might be nice to lazy-[down]load attachments.
|
34
|
+
|
35
|
+
## Example Code:
|
36
|
+
|
37
|
+
require 'gmail'
|
38
|
+
gmail = Gmail.new(username, password) do |g|
|
39
|
+
read_count = g.inbox.count(:read) # => .count take the same arguments as .emails
|
40
|
+
unread = g.inbox.emails(:unread)
|
41
|
+
unread[0].archive!
|
42
|
+
unread[1].delete!
|
43
|
+
unread[2].move_to('FunStuff') # => labels and removes from inbox
|
44
|
+
unread[3].message # => a MIME::Message, parsed from the email body
|
45
|
+
unread[3].mark(:read)
|
46
|
+
unread[3].message.attachments.length
|
47
|
+
unread[4].label('FunStuff') # => Just adds the label 'FunStuff'
|
48
|
+
unread[4].message.save_attachments_to('path/to/save/into')
|
49
|
+
unread[5].message.attachments[0].save_to_file('path/to/save/into')
|
50
|
+
unread[6].mark(:spam)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Optionally use a block like above to have the gem automatically login and logout,
|
54
|
+
# or just use it without a block after creating the object like below, and it will
|
55
|
+
# automatically logout at_exit. The block method is recommended in order to limit
|
56
|
+
# your signed-in session.
|
57
|
+
|
58
|
+
older = gmail.inbox.emails(:after => '2009-03-04', :before => '2009-03-15')
|
59
|
+
todays_date = Time.parse(Time.now.strftime('%Y-%m-%d'))
|
60
|
+
yesterday = gmail.inbox.emails(:after => (todays_date - 24*60*60), :before => todays_date)
|
61
|
+
todays_unread = gmail.inbox.emails(:unread, :after => todays_date)
|
62
|
+
|
63
|
+
new_email = MIME::Message.generate
|
64
|
+
new_email.to "email@example.com"
|
65
|
+
new_email.subject "Having fun in Puerto Rico!"
|
66
|
+
plain, html = new_email.generate_multipart('text/plain', 'text/html')
|
67
|
+
plain.content = "Text of plain message."
|
68
|
+
html.content = "<p>Text of <em>html</em> message.</p>"
|
69
|
+
new_email.attach_file('some_image.dmg')
|
70
|
+
gmail.send_email(new_email)
|
71
|
+
|
72
|
+
## Requirements
|
73
|
+
|
74
|
+
* ruby
|
75
|
+
* net/smtp
|
76
|
+
* net/imap
|
77
|
+
* shared-mime-info rubygem
|
78
|
+
|
79
|
+
## Install
|
80
|
+
|
81
|
+
sudo gem install ruby-gmail -s http://gemcutter.org
|
82
|
+
|
83
|
+
## License
|
84
|
+
|
85
|
+
(The MIT License)
|
86
|
+
|
87
|
+
Copyright (c) 2009 BehindLogic
|
88
|
+
|
89
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
90
|
+
a copy of this software and associated documentation files (the
|
91
|
+
'Software'), to deal in the Software without restriction, including
|
92
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
93
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
94
|
+
permit persons to whom the Software is furnished to do so, subject to
|
95
|
+
the following conditions:
|
96
|
+
|
97
|
+
The above copyright notice and this permission notice shall be
|
98
|
+
included in all copies or substantial portions of the Software.
|
99
|
+
|
100
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
101
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
102
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
103
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
104
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
105
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
106
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
CHANGED
@@ -6,6 +6,7 @@ require 'hoe'
|
|
6
6
|
Hoe.spec 'ruby-gmail' do
|
7
7
|
developer 'Daniel Parker', 'gems@behindlogic.com'
|
8
8
|
extra_deps << ['shared-mime-info', '>= 0']
|
9
|
+
self.readme_file = 'README.markdown'
|
9
10
|
self.url = "http://dcparker.github.com/ruby-gmail"
|
10
|
-
self.post_install_message = "
|
11
|
+
self.post_install_message = "\n\033[34mIf ruby-gmail saves you TWO hours of work, want to compensate me for, like, a half-hour?\nSupport me in making new and better gems:\033[0m \033[31;4mhttp://pledgie.com/campaigns/7087\033[0m\n\n"
|
11
12
|
end
|
data/lib/gmail.rb
CHANGED
@@ -3,12 +3,13 @@ require 'net/smtp'
|
|
3
3
|
require 'smtp_tls'
|
4
4
|
|
5
5
|
class Gmail
|
6
|
-
VERSION = '0.0.
|
6
|
+
VERSION = '0.0.4'
|
7
7
|
|
8
|
-
|
8
|
+
class NoLabel < RuntimeError; end
|
9
9
|
|
10
10
|
def initialize(username, password)
|
11
11
|
# This is to hide the username and password, not like it REALLY needs hiding, but ... you know.
|
12
|
+
# Could be helpful when demoing the gem in irb, these bits won't show up that way.
|
12
13
|
meta = class << self
|
13
14
|
class << self
|
14
15
|
attr_accessor :username, :password
|
@@ -18,8 +19,11 @@ class Gmail
|
|
18
19
|
meta.username = username =~ /@/ ? username : username + '@gmail.com'
|
19
20
|
meta.password = password
|
20
21
|
@imap = Net::IMAP.new('imap.gmail.com',993,true)
|
21
|
-
|
22
|
-
|
22
|
+
if block_given?
|
23
|
+
@connected = true if @imap.login(username, password)
|
24
|
+
yield self
|
25
|
+
logout
|
26
|
+
end
|
23
27
|
end
|
24
28
|
|
25
29
|
# Accessors for IMAP things
|
@@ -31,27 +35,41 @@ class Gmail
|
|
31
35
|
def inbox
|
32
36
|
mailbox('inbox')
|
33
37
|
end
|
38
|
+
# Accessor for @imap, but ensures that it's logged in first.
|
39
|
+
def imap
|
40
|
+
if !@connected
|
41
|
+
meta = class << self; self end
|
42
|
+
@connected = true if @imap.login(meta.username, meta.password)
|
43
|
+
at_exit { logout if @connected } # Set up auto-logout for later.
|
44
|
+
end
|
45
|
+
@imap
|
46
|
+
end
|
34
47
|
# Log out of gmail
|
35
48
|
def logout
|
36
49
|
@connected = false if @imap.logout
|
37
50
|
end
|
38
51
|
|
52
|
+
def create_label(name)
|
53
|
+
imap.create(name)
|
54
|
+
end
|
55
|
+
|
39
56
|
def in_mailbox(mailbox, &block)
|
40
57
|
raise ArgumentError, "Must provide a code block" unless block_given?
|
41
58
|
mailbox_stack << mailbox
|
42
59
|
unless @selected == mailbox.name
|
43
|
-
|
60
|
+
imap.select(mailbox.name)
|
44
61
|
@selected = mailbox.name
|
45
62
|
end
|
46
63
|
value = block.arity == 1 ? block.call(mailbox) : block.call
|
47
64
|
mailbox_stack.pop
|
48
65
|
# Select previously selected mailbox if there is one
|
49
66
|
if mailbox_stack.last
|
50
|
-
|
67
|
+
imap.select(mailbox_stack.last.name)
|
51
68
|
@selected = mailbox.name
|
52
69
|
end
|
53
70
|
return value
|
54
71
|
end
|
72
|
+
alias :in_label :in_mailbox
|
55
73
|
|
56
74
|
def open_smtp(&block)
|
57
75
|
raise ArgumentError, "This method is to be used with a block." unless block_given?
|
data/lib/gmail/mailbox.rb
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'time'
|
3
|
+
class Object
|
4
|
+
def to_imap_date
|
5
|
+
Date.parse(to_s).strftime("%d-%B-%Y")
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
1
9
|
class Gmail
|
2
10
|
class Mailbox
|
3
11
|
attr_reader :name
|
@@ -17,18 +25,45 @@ class Gmail
|
|
17
25
|
|
18
26
|
# Method: emails
|
19
27
|
# Args: [ :all | :unread | :read ]
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
28
|
+
# Opts: {:since => Date.new}
|
29
|
+
def emails(key_or_opts = :all, opts={})
|
30
|
+
if key_or_opts.is_a?(Hash) && opts.empty?
|
31
|
+
search = ['ALL']
|
32
|
+
opts = key_or_opts
|
33
|
+
elsif key_or_opts.is_a?(Symbol) && opts.is_a?(Hash)
|
34
|
+
aliases = {
|
35
|
+
:all => ['ALL'],
|
36
|
+
:unread => ['UNSEEN'],
|
37
|
+
:read => ['SEEN']
|
38
|
+
}
|
39
|
+
search = aliases[key_or_opts]
|
40
|
+
elsif key_or_opts.is_a?(Array) && opts.empty?
|
41
|
+
search = key_or_opts
|
42
|
+
else
|
43
|
+
raise ArgumentError, "Couldn't make sense of arguments to #emails - should be an optional hash of options preceded by an optional read-status bit; OR simply an array of parameters to pass directly to the IMAP uid_search call."
|
44
|
+
end
|
45
|
+
if !opts.empty?
|
46
|
+
# Support for several search macros
|
47
|
+
# :before => Date, :on => Date, :since => Date, :from => String, :to => String
|
48
|
+
search.concat ['SINCE', opts[:after].to_imap_date] if opts[:after]
|
49
|
+
search.concat ['BEFORE', opts[:before].to_imap_date] if opts[:before]
|
50
|
+
search.concat ['ON', opts[:on].to_imap_date] if opts[:on]
|
51
|
+
search.concat ['FROM', opts[:from]] if opts[:from]
|
52
|
+
search.concat ['TO', opts[:to]] if opts[:to]
|
53
|
+
end
|
54
|
+
|
26
55
|
# puts "Gathering #{(aliases[key] || key).inspect} messages for mailbox '#{name}'..."
|
27
56
|
@gmail.in_mailbox(self) do
|
28
|
-
@gmail.imap.uid_search(
|
57
|
+
@gmail.imap.uid_search(search).collect { |uid| messages[uid] ||= Message.new(@gmail, self, uid) }
|
29
58
|
end
|
30
59
|
end
|
31
60
|
|
61
|
+
# This is a convenience method that really probably shouldn't need to exist, but it does make code more readable
|
62
|
+
# if seriously all you want is the count of messages.
|
63
|
+
def count(*args)
|
64
|
+
emails(*args).length
|
65
|
+
end
|
66
|
+
|
32
67
|
def messages
|
33
68
|
@messages ||= {}
|
34
69
|
end
|
data/lib/gmail/message.rb
CHANGED
@@ -64,7 +64,22 @@ class Gmail
|
|
64
64
|
end
|
65
65
|
def label(name)
|
66
66
|
@gmail.in_mailbox(@mailbox) do
|
67
|
-
|
67
|
+
begin
|
68
|
+
@gmail.imap.uid_copy(uid, name)
|
69
|
+
rescue Net::IMAP::NoResponseError
|
70
|
+
raise Gmail::NoLabel, "No label `#{name}' exists!"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
def label!(name)
|
75
|
+
@gmail.in_mailbox(@mailbox) do
|
76
|
+
begin
|
77
|
+
@gmail.imap.uid_copy(uid, name)
|
78
|
+
rescue Net::IMAP::NoResponseError
|
79
|
+
# need to create the label first
|
80
|
+
@gmail.create_label(name)
|
81
|
+
retry
|
82
|
+
end
|
68
83
|
end
|
69
84
|
end
|
70
85
|
# We're not sure of any 'labels' except the 'mailbox' we're in at the moment.
|
data/lib/mime/entity.rb
CHANGED
@@ -89,11 +89,12 @@ module MIME
|
|
89
89
|
end
|
90
90
|
end
|
91
91
|
def attachment?
|
92
|
-
headers['content-disposition'] =~ /^attachment(?=;|$)/
|
92
|
+
headers['content-disposition'] =~ /^attachment(?=;|$)/ || headers['content-disposition'] =~ /^form-data;.* filename=[\"\']?[^\"\']+[\"\']?/
|
93
93
|
end
|
94
|
-
|
94
|
+
alias :file? :attachment?
|
95
|
+
def part_filename
|
95
96
|
# Content-Disposition: attachment; filename="summary.txt"
|
96
|
-
if headers['content-disposition'] =~
|
97
|
+
if headers['content-disposition'] =~ /; filename=[\"\']?([^\"\']+)/
|
97
98
|
$1
|
98
99
|
end
|
99
100
|
end
|
@@ -120,8 +121,8 @@ module MIME
|
|
120
121
|
|
121
122
|
def save_to_file(path=nil)
|
122
123
|
filename = path if path && !File.exists?(path) # If path doesn't exist, assume it's a filename
|
123
|
-
filename ||= path + '/' +
|
124
|
-
filename ||= (attachment? ?
|
124
|
+
filename ||= path + '/' + part_filename if path && attachment? # If path does exist, and we're saving an attachment, use the attachment filename
|
125
|
+
filename ||= (attachment? ? part_filename : path) # If there is no path and we're saving an attachment, use the attachment filename; otherwise use path (whether it is present or not)
|
125
126
|
filename ||= '.' # No path supplied, and not saving an attachment. We'll just save it in the current directory.
|
126
127
|
if File.directory?(filename)
|
127
128
|
i = 0
|
data/lib/mime/message.rb
CHANGED
@@ -28,6 +28,15 @@ module MIME
|
|
28
28
|
find_parts(:content_disposition => 'attachment')
|
29
29
|
end
|
30
30
|
|
31
|
+
def text
|
32
|
+
part = find_part(:content_type => 'text/plain')
|
33
|
+
part.content if part
|
34
|
+
end
|
35
|
+
def html
|
36
|
+
part = find_part(:content_type => 'text/html')
|
37
|
+
part.content if part
|
38
|
+
end
|
39
|
+
|
31
40
|
def save_attachments_to(path=nil)
|
32
41
|
attachments.each {|a| a.save_to_file(path) }
|
33
42
|
end
|
data/lib/smtp_tls.rb
CHANGED
@@ -15,13 +15,13 @@ Net::SMTP.class_eval do
|
|
15
15
|
start_method = use_tls ? :do_tls_start : :do_start
|
16
16
|
if block_given?
|
17
17
|
begin
|
18
|
-
send
|
18
|
+
send(start_method, helo, user, secret, authtype)
|
19
19
|
return yield(self)
|
20
20
|
ensure
|
21
21
|
do_finish
|
22
22
|
end
|
23
23
|
else
|
24
|
-
send
|
24
|
+
send(start_method, helo, user, secret, authtype)
|
25
25
|
return self
|
26
26
|
end
|
27
27
|
end
|
@@ -31,9 +31,9 @@ Net::SMTP.class_eval do
|
|
31
31
|
def do_tls_start(helodomain, user, secret, authtype)
|
32
32
|
raise IOError, 'SMTP session already started' if @started
|
33
33
|
if RUBY_VERSION == '1.8.6'
|
34
|
-
check_auth_args
|
34
|
+
check_auth_args(user, secret, authtype) if user or secret
|
35
35
|
else
|
36
|
-
check_auth_args
|
36
|
+
check_auth_args(user, secret) if user or secret
|
37
37
|
end
|
38
38
|
|
39
39
|
sock = timeout(@open_timeout) { TCPSocket.open(@address, @port) }
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-gmail
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Parker
|
@@ -30,7 +30,7 @@ cert_chain:
|
|
30
30
|
teST6sOe8lUhZQ==
|
31
31
|
-----END CERTIFICATE-----
|
32
32
|
|
33
|
-
date: 2009-
|
33
|
+
date: 2009-12-10 00:00:00 -05:00
|
34
34
|
default_executable:
|
35
35
|
dependencies:
|
36
36
|
- !ruby/object:Gem::Dependency
|
@@ -53,7 +53,7 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 2.3.3
|
55
55
|
version:
|
56
|
-
description: A Rubyesque interface to Gmail
|
56
|
+
description: A Rubyesque interface to Gmail, with all the tools you'll need. Search, read and send multipart emails; archive, mark as read/unread, delete emails; and manage labels.
|
57
57
|
email:
|
58
58
|
- gems@behindlogic.com
|
59
59
|
executables: []
|
@@ -63,7 +63,6 @@ extensions: []
|
|
63
63
|
extra_rdoc_files:
|
64
64
|
- History.txt
|
65
65
|
- Manifest.txt
|
66
|
-
- README.txt
|
67
66
|
files:
|
68
67
|
- .autotest
|
69
68
|
- History.txt
|
@@ -77,15 +76,17 @@ files:
|
|
77
76
|
- lib/smtp_tls.rb
|
78
77
|
- Manifest.txt
|
79
78
|
- Rakefile
|
80
|
-
- README.
|
79
|
+
- README.markdown
|
81
80
|
has_rdoc: true
|
82
81
|
homepage: http://dcparker.github.com/ruby-gmail
|
83
82
|
licenses: []
|
84
83
|
|
85
|
-
post_install_message: "
|
84
|
+
post_install_message: "\n\
|
85
|
+
\e[34mIf ruby-gmail saves you TWO hours of work, want to compensate me for, like, a half-hour?\n\
|
86
|
+
Support me in making new and better gems:\e[0m \e[31;4mhttp://pledgie.com/campaigns/7087\e[0m\n\n"
|
86
87
|
rdoc_options:
|
87
88
|
- --main
|
88
|
-
- README.
|
89
|
+
- README.markdown
|
89
90
|
require_paths:
|
90
91
|
- lib
|
91
92
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -106,6 +107,6 @@ rubyforge_project: ruby-gmail
|
|
106
107
|
rubygems_version: 1.3.5
|
107
108
|
signing_key:
|
108
109
|
specification_version: 3
|
109
|
-
summary: A Rubyesque interface to Gmail
|
110
|
+
summary: A Rubyesque interface to Gmail, with all the tools you'll need
|
110
111
|
test_files: []
|
111
112
|
|
metadata.gz.sig
CHANGED
Binary file
|
data/README.txt
DELETED
@@ -1,85 +0,0 @@
|
|
1
|
-
= ruby-gmail
|
2
|
-
|
3
|
-
* Homepage: http://dcparker.github.com/ruby-gmail/
|
4
|
-
* Code: http://github.com/dcparker/ruby-gmail
|
5
|
-
|
6
|
-
|
7
|
-
== DESCRIPTION:
|
8
|
-
|
9
|
-
A Rubyesque interface to Gmail. Connect to Gmail via IMAP and manipulate emails and labels. Send email with your Gmail account via SMTP. Includes full support for parsing and generating MIME messages.
|
10
|
-
|
11
|
-
== FEATURES:
|
12
|
-
|
13
|
-
* Read emails via IMAP
|
14
|
-
* Full MIME parsing ability, with understanding of attachments
|
15
|
-
* Create, rename, and delete labels
|
16
|
-
* Label, archive, delete, mark as read/unread/spam
|
17
|
-
* Send emails via SMTP
|
18
|
-
* Full ability to generate MIME messages including inline images and attachments
|
19
|
-
|
20
|
-
== PROBLEMS:
|
21
|
-
|
22
|
-
* May not correctly read malformed MIME messages. This could possibly be corrected by having IMAP parse the MIME structure.
|
23
|
-
* Cannot grab the plain or html message without also grabbing attachments. It might be nice to lazy-[down]load attachments.
|
24
|
-
|
25
|
-
== SYNOPSIS:
|
26
|
-
|
27
|
-
require 'gmail'
|
28
|
-
gmail = Gmail.new(username, password)
|
29
|
-
gmail.inbox.count # => {:read => 41, :unread => 2}
|
30
|
-
unread = gmail.inbox.emails(:unread)
|
31
|
-
unread[0].archive!
|
32
|
-
unread[1].delete!
|
33
|
-
unread[2].move_to('FunStuff') # => Labels 'FunStuff' and removes from inbox
|
34
|
-
unread[3].message # => a MIME::Message, parsed from the email body
|
35
|
-
unread[3].mark(:read)
|
36
|
-
unread[3].message.attachments.length
|
37
|
-
unread[4].label('FunStuff') # => Just adds the label 'FunStuff'
|
38
|
-
unread[4].message.save_attachments_to('path/to/save/into')
|
39
|
-
unread[5].message.attachments[0].save_to_file('path/to/save/into')
|
40
|
-
unread[6].mark(:spam)
|
41
|
-
|
42
|
-
new_email = MIME::Message.generate
|
43
|
-
new_email.to "email@example.com"
|
44
|
-
new_email.subject "Having fun in Puerto Rico!"
|
45
|
-
plain, html = new_email.generate_multipart('text/plain', 'text/html')
|
46
|
-
plain.content = "Text of plain message."
|
47
|
-
html.content = "<p>Text of <em>html</em> message.</p>"
|
48
|
-
new_email.attach_file('some_image.dmg')
|
49
|
-
gmail.send_email(new_email)
|
50
|
-
|
51
|
-
== REQUIREMENTS:
|
52
|
-
|
53
|
-
* ruby
|
54
|
-
* net/smtp
|
55
|
-
* net/imap
|
56
|
-
* gem shared-mime-info
|
57
|
-
|
58
|
-
== INSTALL:
|
59
|
-
|
60
|
-
* [sudo] gem install ruby-gmail -s http://gemcutter.org
|
61
|
-
|
62
|
-
== LICENSE:
|
63
|
-
|
64
|
-
(The MIT License)
|
65
|
-
|
66
|
-
Copyright (c) 2009 BehindLogic.com
|
67
|
-
|
68
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
69
|
-
a copy of this software and associated documentation files (the
|
70
|
-
'Software'), to deal in the Software without restriction, including
|
71
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
72
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
73
|
-
permit persons to whom the Software is furnished to do so, subject to
|
74
|
-
the following conditions:
|
75
|
-
|
76
|
-
The above copyright notice and this permission notice shall be
|
77
|
-
included in all copies or substantial portions of the Software.
|
78
|
-
|
79
|
-
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
80
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
81
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
82
|
-
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
83
|
-
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
84
|
-
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
85
|
-
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|