email-spy 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +21 -0
- data/.rspec +1 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +49 -0
- data/LICENSE +22 -0
- data/README.md +21 -0
- data/Rakefile +2 -0
- data/email-spy.gemspec +27 -0
- data/lib/email-spy.rb +38 -0
- data/lib/email-spy/126.rb +60 -0
- data/lib/email-spy/contact.rb +3 -0
- data/lib/email-spy/email_types.rb +3 -0
- data/lib/email-spy/errors.rb +22 -0
- data/lib/email-spy/gmail.rb +26 -0
- data/lib/email-spy/hotmail.rb +35 -0
- data/lib/email-spy/version.rb +3 -0
- data/lib/email-spy/yahoo.rb +55 -0
- data/spec/126_spec.rb +6 -0
- data/spec/email-spy_spec.rb +21 -0
- data/spec/gmail_spec.rb +6 -0
- data/spec/hotmail_spec.rb +6 -0
- data/spec/spec_helper.rb +31 -0
- data/spec/yahoo_spec.rb +6 -0
- metadata +130 -0
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
email-spy (0.0.2)
|
5
|
+
gdata_19 (~> 1.1.5)
|
6
|
+
httpclient (~> 2.2.5)
|
7
|
+
mechanize (~> 2.5.1)
|
8
|
+
nokogiri (~> 1.5.0)
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: http://ruby.taobao.org/
|
12
|
+
specs:
|
13
|
+
diff-lcs (1.1.3)
|
14
|
+
domain_name (0.5.3)
|
15
|
+
unf (~> 0.0.3)
|
16
|
+
gdata_19 (1.1.5)
|
17
|
+
httpclient (2.2.5)
|
18
|
+
mechanize (2.5.1)
|
19
|
+
domain_name (~> 0.5, >= 0.5.1)
|
20
|
+
mime-types (~> 1.17, >= 1.17.2)
|
21
|
+
net-http-digest_auth (~> 1.1, >= 1.1.1)
|
22
|
+
net-http-persistent (~> 2.5, >= 2.5.2)
|
23
|
+
nokogiri (~> 1.4)
|
24
|
+
ntlm-http (~> 0.1, >= 0.1.1)
|
25
|
+
webrobots (~> 0.0, >= 0.0.9)
|
26
|
+
mime-types (1.17.2)
|
27
|
+
net-http-digest_auth (1.2.1)
|
28
|
+
net-http-persistent (2.7)
|
29
|
+
nokogiri (1.5.5)
|
30
|
+
ntlm-http (0.1.1)
|
31
|
+
rspec (2.11.0)
|
32
|
+
rspec-core (~> 2.11.0)
|
33
|
+
rspec-expectations (~> 2.11.0)
|
34
|
+
rspec-mocks (~> 2.11.0)
|
35
|
+
rspec-core (2.11.1)
|
36
|
+
rspec-expectations (2.11.2)
|
37
|
+
diff-lcs (~> 1.1.3)
|
38
|
+
rspec-mocks (2.11.1)
|
39
|
+
unf (0.0.5)
|
40
|
+
unf_ext
|
41
|
+
unf_ext (0.0.5)
|
42
|
+
webrobots (0.0.13)
|
43
|
+
|
44
|
+
PLATFORMS
|
45
|
+
ruby
|
46
|
+
|
47
|
+
DEPENDENCIES
|
48
|
+
email-spy!
|
49
|
+
rspec (~> 2.11.0)
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 wade
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
email-spy
|
2
|
+
=========
|
3
|
+
|
4
|
+
|
5
|
+
Usage
|
6
|
+
-----
|
7
|
+
|
8
|
+
```ruby
|
9
|
+
contacts = EmailSpy.fetch(account, password, emailtype)
|
10
|
+
contacts.each do |contact|
|
11
|
+
puts "name: #{contact.name}, email: #{contact.email}"
|
12
|
+
end
|
13
|
+
```
|
14
|
+
|
15
|
+
Current Supported Email Type
|
16
|
+
--------------------------
|
17
|
+
|
18
|
+
+ gmail
|
19
|
+
+ hotmail
|
20
|
+
+ 126
|
21
|
+
+ yahoo
|
data/Rakefile
ADDED
data/email-spy.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/email-spy/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = 'email-spy'
|
6
|
+
s.version = EmailSpy::VERSION
|
7
|
+
s.date = '2012-07-30'
|
8
|
+
s.summary = ""
|
9
|
+
s.description = "Retrieves contact list of email"
|
10
|
+
s.authors = ["Wade Xing"]
|
11
|
+
s.email = ['iamxingxing@gmail.com']
|
12
|
+
s.files = `git ls-files`.split($\)
|
13
|
+
|
14
|
+
s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
15
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
16
|
+
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
|
19
|
+
s.homepage = 'https://github.com/xingxing/email-spy'
|
20
|
+
|
21
|
+
s.add_runtime_dependency "httpclient", "~> 2.2.5"
|
22
|
+
s.add_runtime_dependency 'nokogiri', "~> 1.5.0"
|
23
|
+
s.add_runtime_dependency 'gdata_19', "~> 1.1.5"
|
24
|
+
s.add_runtime_dependency 'mechanize', "~> 2.5.1"
|
25
|
+
|
26
|
+
s.add_development_dependency 'rspec', "~> 2.11.0"
|
27
|
+
end
|
data/lib/email-spy.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bundler/setup'
|
4
|
+
require "nokogiri"
|
5
|
+
require 'gdata'
|
6
|
+
|
7
|
+
require 'iconv'
|
8
|
+
require "mechanize"
|
9
|
+
require "csv"
|
10
|
+
require "json"
|
11
|
+
|
12
|
+
require 'email-spy/contact'
|
13
|
+
require 'email-spy/email_types'
|
14
|
+
require 'email-spy/version'
|
15
|
+
require 'email-spy/errors'
|
16
|
+
|
17
|
+
require 'email-spy/gmail'
|
18
|
+
require "email-spy/hotmail"
|
19
|
+
require "email-spy/126"
|
20
|
+
require "email-spy/yahoo"
|
21
|
+
|
22
|
+
module EmailSpy
|
23
|
+
# 获取 联系人集合
|
24
|
+
# @param [String] 邀请人电邮地址
|
25
|
+
# @param [String] 邀请人电邮密码
|
26
|
+
# @param [String] 邮件类型
|
27
|
+
# @param [Array<EmailSay::Contact>] 联系人集合
|
28
|
+
def self.fetch invitor_email_address,invitor_email_password,email_type
|
29
|
+
self.const_get(operating_klass_name email_type).fetch invitor_email_address,invitor_email_password
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def self.operating_klass_name email_type
|
35
|
+
key = email_type.to_s.downcase
|
36
|
+
EMAIL_TYPE[key] or raise EmailTypeNotFound
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module EmailSpy
|
3
|
+
class OneTowSix
|
4
|
+
|
5
|
+
# 登录页
|
6
|
+
LANDING_PAGE_URL = 'http://mail.126.com'
|
7
|
+
|
8
|
+
# 联系人 URL 模板
|
9
|
+
Contacts_URL = "http://tg1a64.mail.126.com/jy3/address/addrlist.jsp?sid=%s"
|
10
|
+
|
11
|
+
def self.fetch invitor_email_address,invitor_email_password
|
12
|
+
self.new(invitor_email_address,invitor_email_password).contacts
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
def initialize invitor_email_address,invitor_email_password
|
17
|
+
@invitor_email_address = invitor_email_address
|
18
|
+
@invitor_email_password = invitor_email_password
|
19
|
+
@agent = Mechanize.new
|
20
|
+
end
|
21
|
+
|
22
|
+
# 通讯录联系人
|
23
|
+
# @return [Array<EmailSpy::Contract>]
|
24
|
+
def contacts
|
25
|
+
body = @agent.get(Contacts_URL % sid).body
|
26
|
+
contacts = []
|
27
|
+
|
28
|
+
Nokogiri::HTML(body).xpath(".//*[@id='addrstable']/tbody[1]/tr").each do |tr|
|
29
|
+
contacts << Contact.new(tr.css(".Ibx_Td_addrName a").text,
|
30
|
+
tr.css(".Ibx_Td_addrEmail a").text)
|
31
|
+
end
|
32
|
+
|
33
|
+
contacts
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
# 登录
|
39
|
+
# @return [String] SID
|
40
|
+
def sid
|
41
|
+
page = @agent.get(LANDING_PAGE_URL)
|
42
|
+
login_form = page.forms[0]
|
43
|
+
login_form.action= 'http://reg.163.com/login.jsp'
|
44
|
+
login_form.add_field!('type',1)
|
45
|
+
login_form.add_field!('product','mail126')
|
46
|
+
login_form.add_field!('url' ,URI.encode("http://entry.mail.126.com/cgi/ntesdoor?hid=10010102&lightweight=1&language=0&style=3"))
|
47
|
+
login_form.username ,login_form.password = @invitor_email_address,@invitor_email_password
|
48
|
+
page = login_form.submit(login_form.buttons.first)
|
49
|
+
page1 = login_form.click_button
|
50
|
+
page2 = page1.links[0].click
|
51
|
+
|
52
|
+
page3 = @agent.get('http://entry.mail.126.com/cgi/ntesdoor?verifycookie=1&lightweight=1&style=-1')
|
53
|
+
page3.uri.to_s.scan(/sid=(\S+)/).first[0]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
EMAIL_TYPE['126'] = "OneTowSix"
|
60
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module EmailSpy
|
2
|
+
class EmailSypError < StandardError
|
3
|
+
end
|
4
|
+
|
5
|
+
class AuthenticationError < EmailSypError
|
6
|
+
def initialize(msg = "Email address or password are incorrect")
|
7
|
+
super(msg)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class ConnectionError < EmailSypError
|
12
|
+
def initialize(msg = "Check your network connection")
|
13
|
+
super(msg)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class EmailTypeNotFound < EmailSypError
|
18
|
+
def initialize(msg = "Does not support this message type")
|
19
|
+
super(msg)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module EmailSpy
|
2
|
+
class Gmail
|
3
|
+
|
4
|
+
Contacts_API_URL = "http://www.google.com/m8/feeds/contacts/default/full"
|
5
|
+
|
6
|
+
def self.fetch invitor_email_address,invitor_email_password
|
7
|
+
client = GData::Client::Contacts.new
|
8
|
+
client.clientlogin(invitor_email_address, invitor_email_password)
|
9
|
+
response = client.get(Contacts_API_URL).to_xml
|
10
|
+
|
11
|
+
response.elements.to_a('entry').map do |entry|
|
12
|
+
title, email = entry.elements['title'].text, nil
|
13
|
+
entry.elements.each('gd:email') do |e|
|
14
|
+
email = e.attribute('address').value if e.attribute('primary')
|
15
|
+
end
|
16
|
+
Contact.new(title,email) unless email.nil?
|
17
|
+
end.compact
|
18
|
+
rescue GData::Client::AuthorizationError => e
|
19
|
+
raise AuthenticationError
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
EMAIL_TYPE['gmail'] = "Gmail"
|
26
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module EmailSpy
|
3
|
+
class Hotmail
|
4
|
+
# 登录页 地址
|
5
|
+
LANDING_PAGE_URL = 'https://login.live.com/login.srf?id=2'
|
6
|
+
|
7
|
+
# 用户名密码错误提示
|
8
|
+
Login_Error_Message = "That password is incorrect. Be sure you're using the password for your Microsoft account."
|
9
|
+
|
10
|
+
Contacts_URL = "http://co108w.col108.mail.live.com/mail/GetContacts.aspx"
|
11
|
+
|
12
|
+
def self.fetch invitor_email_address,invitor_email_password
|
13
|
+
agent = Mechanize.new
|
14
|
+
agent.verify_mode=OpenSSL::SSL::VERIFY_NONE
|
15
|
+
page = agent.get(LANDING_PAGE_URL)
|
16
|
+
login_form = page.forms[0]
|
17
|
+
login_form.login ,login_form.passwd = invitor_email_address,invitor_email_password
|
18
|
+
page = login_form.submit
|
19
|
+
raise AuthenticationError if page.body.include? Login_Error_Message
|
20
|
+
body = agent.get(Contacts_URL).body
|
21
|
+
|
22
|
+
contacts = []
|
23
|
+
|
24
|
+
CSV.parse(body,headers: :first_row).each do |record|
|
25
|
+
contacts << Contact.new("#{record['Last Name']} #{record['First Name']}",record['E-mail Address'])
|
26
|
+
end
|
27
|
+
|
28
|
+
contacts.compact
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
EMAIL_TYPE['hotmail'] = "Hotmail"
|
35
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module EmailSpy
|
2
|
+
class Yahoo
|
3
|
+
|
4
|
+
LANDING_PAGE_URL = 'https://login.yahoo.com/config/login'
|
5
|
+
|
6
|
+
CONTACTS_URL = "http://address.mail.yahoo.com/?.rand=430244936"
|
7
|
+
|
8
|
+
def self.fetch invitor_email_address,invitor_email_password
|
9
|
+
self.new(invitor_email_address,invitor_email_password).contacts
|
10
|
+
rescue SocketError => e
|
11
|
+
raise ConnectionError
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize invitor_email_address,invitor_email_password
|
15
|
+
@invitor_email_address = invitor_email_address
|
16
|
+
@invitor_email_password = invitor_email_password
|
17
|
+
@agent = Mechanize.new
|
18
|
+
@agent.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
19
|
+
end
|
20
|
+
|
21
|
+
def contacts
|
22
|
+
login
|
23
|
+
contacts = []
|
24
|
+
contacts_json.each do |contact|
|
25
|
+
contacts << Contact.new(contact['contactName'],contact['email'])
|
26
|
+
end
|
27
|
+
|
28
|
+
contacts
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def login
|
35
|
+
page = @agent.get(LANDING_PAGE_URL)
|
36
|
+
login_form = page.forms[0]
|
37
|
+
login_form.login = @invitor_email_address
|
38
|
+
login_form.passwd = @invitor_email_password
|
39
|
+
page = login_form.submit
|
40
|
+
raise AuthenticationError if page.body.index("Invalid ID or passowrd") or page.body.index("This ID is not yet taken")
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
def contacts_json
|
45
|
+
contacts_list_source = @agent.get(CONTACTS_URL).body
|
46
|
+
contacts_json = contacts_list_source.scan(/InitialContacts\s*=([^;]*);/m)[0][0].to_s
|
47
|
+
JSON.load(contacts_json).flatten
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
EMAIL_TYPE['yahoo'] = "Yahoo"
|
55
|
+
end
|
data/spec/126_spec.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe "EmailSpy" do
|
5
|
+
|
6
|
+
let(:email){ 'iamxingxing@gmail.com' }
|
7
|
+
let(:pwd){ 'password' }
|
8
|
+
|
9
|
+
describe ".fetch" do
|
10
|
+
it "should invoke operating class .fech " do
|
11
|
+
EmailSpy::Gmail.should_receive(:fetch).with(email,pwd)
|
12
|
+
EmailSpy.fetch(email,pwd,"gmail")
|
13
|
+
end
|
14
|
+
|
15
|
+
context "when email type not found" do
|
16
|
+
it "should raise A EmailTypeNotFound" do
|
17
|
+
lambda { EmailSpy.fetch(email,pwd,"whatever") }.should raise_error(EmailSpy::EmailTypeNotFound)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/spec/gmail_spec.rb
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
$:.unshift File.expand_path('../../lib', __FILE__)
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'bundler/setup'
|
6
|
+
|
7
|
+
require 'email-spy'
|
8
|
+
|
9
|
+
shared_examples_for "fetch A contact list" do |email_type|
|
10
|
+
let(:expected_result) do
|
11
|
+
YAML::load(File.read(File.expand_path("spec/fixture/#{email_type}.yml")))
|
12
|
+
end
|
13
|
+
|
14
|
+
before(:all) do
|
15
|
+
@contacts = EmailSpy.fetch(expected_result["invitor email"], expected_result["invitor password"], email_type)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should return expected contact info" do
|
19
|
+
@contacts.find do |contact|
|
20
|
+
contact.name == expected_result['contact']['name'] and contact.email == expected_result['contact']['email']
|
21
|
+
end.should_not == nil
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should return expected length" do
|
25
|
+
@contacts.should have(expected_result['contacts count']).items
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should not include the invitor's email" do
|
29
|
+
@contacts.map{|c| c.email }.should_not include expected_result['invitor_email']
|
30
|
+
end
|
31
|
+
end
|
data/spec/yahoo_spec.rb
ADDED
metadata
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: email-spy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Wade Xing
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-30 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: httpclient
|
16
|
+
requirement: &70298431184880 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 2.2.5
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70298431184880
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: nokogiri
|
27
|
+
requirement: &70298431184380 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.5.0
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70298431184380
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: gdata_19
|
38
|
+
requirement: &70298431183920 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 1.1.5
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70298431183920
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: mechanize
|
49
|
+
requirement: &70298431183400 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 2.5.1
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70298431183400
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: rspec
|
60
|
+
requirement: &70298431182860 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ~>
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: 2.11.0
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70298431182860
|
69
|
+
description: Retrieves contact list of email
|
70
|
+
email:
|
71
|
+
- iamxingxing@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- .gitignore
|
77
|
+
- .rspec
|
78
|
+
- Gemfile
|
79
|
+
- Gemfile.lock
|
80
|
+
- LICENSE
|
81
|
+
- README.md
|
82
|
+
- Rakefile
|
83
|
+
- email-spy.gemspec
|
84
|
+
- lib/email-spy.rb
|
85
|
+
- lib/email-spy/126.rb
|
86
|
+
- lib/email-spy/contact.rb
|
87
|
+
- lib/email-spy/email_types.rb
|
88
|
+
- lib/email-spy/errors.rb
|
89
|
+
- lib/email-spy/gmail.rb
|
90
|
+
- lib/email-spy/hotmail.rb
|
91
|
+
- lib/email-spy/version.rb
|
92
|
+
- lib/email-spy/yahoo.rb
|
93
|
+
- spec/126_spec.rb
|
94
|
+
- spec/email-spy_spec.rb
|
95
|
+
- spec/gmail_spec.rb
|
96
|
+
- spec/hotmail_spec.rb
|
97
|
+
- spec/spec_helper.rb
|
98
|
+
- spec/yahoo_spec.rb
|
99
|
+
homepage: https://github.com/xingxing/email-spy
|
100
|
+
licenses: []
|
101
|
+
post_install_message:
|
102
|
+
rdoc_options: []
|
103
|
+
require_paths:
|
104
|
+
- lib
|
105
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - ! '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
|
+
none: false
|
113
|
+
requirements:
|
114
|
+
- - ! '>='
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
requirements: []
|
118
|
+
rubyforge_project:
|
119
|
+
rubygems_version: 1.8.17
|
120
|
+
signing_key:
|
121
|
+
specification_version: 3
|
122
|
+
summary: ''
|
123
|
+
test_files:
|
124
|
+
- spec/126_spec.rb
|
125
|
+
- spec/email-spy_spec.rb
|
126
|
+
- spec/gmail_spec.rb
|
127
|
+
- spec/hotmail_spec.rb
|
128
|
+
- spec/spec_helper.rb
|
129
|
+
- spec/yahoo_spec.rb
|
130
|
+
has_rdoc:
|