email-spy 0.0.3
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.
- 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:
|