address_book 0.1 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -2,3 +2,4 @@
2
2
  .bundle
3
3
  Gemfile.lock
4
4
  pkg/*
5
+ .rvmrc
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Igor Sidorov
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,38 @@
1
+ == AddressBook
2
+
3
+ Exports your contact address books from various email providers.
4
+
5
+ AddressBook is designed to provide simple and clean interface to various email providers address books. Only Mail.ru, Yandex, Rambler and Gmail are availible currently, but new services can be added easily.
6
+
7
+ == Installation and Usage
8
+
9
+ The gem can be installed in the usual way:
10
+
11
+ gem install address_book
12
+
13
+ Or added to your Gemfile if you use Bundler (I hope you do):
14
+
15
+ gem "address_book"
16
+
17
+ To export your address book, simply call AddressBook.export() with email credentials:
18
+
19
+ AddressBook.export "test@gmail.com", "password"
20
+ # => [["name1", "email1@example.com"], ["name2", "email2@test.com"]]
21
+
22
+ AddressBook will try to determine email provider using domain name from provided email address and return array of names and emails of your contacts. If no provider is registered for given email, it will raise AddressBook::ServiceNotFound exception.
23
+
24
+ == Background
25
+
26
+ This gem is heavily inspired and based on the great Contacts[https://github.com/cardmagic/contacts] gem. In fact at first I wanted just to fork it and add needed providers. I gave up this idea, because (imho) gems should perform only one task (but do it well of course) -- export contact lists in our case. It shouldn't bother with handling HTTP connections, sessions, cookies etc. Other gems (Patron[https://github.com/toland/patron] is cool) can do it instead of me.
27
+
28
+ The gem shouldn't leave the task of specifying provider to user -- it should guess the provider itself. I didn't like how guessing is implemented in Contacts. In fact sending your valuable email credentials to all known providers looks like a serious security breach to me. AddressBook sends credentials to only one guessed provider and raises exception if it cannot guess.
29
+
30
+ Another thing is testing -- I didn't like the idea that user has to fill in testing accounts information just to see if she didn't break anything in the existing code. What if she made a typo in her password? Test will fail instead of pass and pass instead of fail. The gem should be supplied with prerecorded correct service answers (VCR[https://github.com/myronmarston/vcr] is great for this task).
31
+
32
+ == Contributing
33
+
34
+ Pull requests are greatly welcome. Before submitting a pull request, please make sure that your changes are well tested (with latest Ruby 1.8.x and 1.9.x versions if possible).
35
+
36
+ == License
37
+
38
+ AddressBook is released under the MIT License.
@@ -17,6 +17,10 @@ Gem::Specification.new do |s|
17
17
  s.add_dependency "nokogiri"
18
18
  s.add_dependency "patron"
19
19
 
20
+ s.add_development_dependency "rspec"
21
+ s.add_development_dependency "vcr"
22
+ s.add_development_dependency "webmock"
23
+
20
24
  s.files = `git ls-files`.split("\n")
21
25
  s.require_paths = ["lib"]
22
26
  end
@@ -1,7 +1,6 @@
1
1
  $:.unshift File.dirname(__FILE__) + "/address_book/"
2
2
 
3
3
  require "base.rb"
4
- require "error.rb"
5
4
  require "mailru.rb"
6
5
  require "rambler.rb"
7
6
  require "yandex.rb"
@@ -2,26 +2,29 @@ require "patron"
2
2
  require "nokogiri"
3
3
 
4
4
  class AddressBook
5
- @@domains = {}
5
+ class << self
6
+ attr_accessor :domains
6
7
 
7
- def self.register_service(domains, klass)
8
- Array(domains).each do |domain|
9
- @@domains[domain] = klass
8
+ def register_service(list, klass)
9
+ self.domains ||= {}
10
+ Array(list).each do |domain|
11
+ self.domains[domain] = klass
12
+ end
10
13
  end
11
- end
12
14
 
13
- def self.export(login, password)
14
- domain = extract_domain login
15
- klass = @@domains[domain]
16
- if klass
17
- klass.new(login, password).contacts
18
- else
19
- raise ServiceNotFound, "No service registered for #{domain.inspect} domain"
15
+ def extract_domain(login)
16
+ login.split("@").last
20
17
  end
21
- end
22
18
 
23
- def self.extract_domain(login)
24
- login.split("@").last
19
+ def export(login, password)
20
+ domain = extract_domain login
21
+ service = domains[domain]
22
+ if service
23
+ service.new(login, password).contacts
24
+ else
25
+ raise ServiceNotFound, "No service registered for #{domain.inspect} domain"
26
+ end
27
+ end
25
28
  end
26
29
 
27
30
  class Base
@@ -31,4 +34,10 @@ class AddressBook
31
34
  @session ||= Patron::Session.new.handle_cookies
32
35
  end
33
36
  end
37
+
38
+ class ServiceNotFound < StandardError
39
+ end
40
+
41
+ class AuthenticationError < StandardError
42
+ end
34
43
  end
@@ -1,3 +1,3 @@
1
1
  class AddressBook
2
- VERSION = "0.1"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -0,0 +1,72 @@
1
+ require "spec_helper"
2
+
3
+ describe AddressBook do
4
+ let(:accounts) { YAML.load(File.open("./spec/fixtures/accounts.yml")) }
5
+
6
+ %w(yandex mailru rambler gmail).each do |service|
7
+ context service.capitalize do
8
+ let(:account) { accounts[service] }
9
+
10
+ use_vcr_cassette service
11
+
12
+ context "with invalid credentials" do
13
+ it "should raise AuthenticationError" do
14
+ expect { AddressBook.export(account[:login], nil) }.to raise_error AddressBook::AuthenticationError
15
+ end
16
+ end
17
+
18
+ context "with valid credentials" do
19
+ it "should fetch address book" do
20
+ AddressBook.export(account[:login], account[:password]).each do |contact|
21
+ account[:contacts][contact[1]].should == contact[0]
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ describe ".register_service" do
29
+ subject { AddressBook.domains }
30
+
31
+ context "given array of domains" do
32
+ it "associates all domains with given class" do
33
+ AddressBook.register_service [:domain1, :domain2], String
34
+ should include :domain1 => String, :domain2 => String
35
+ end
36
+ end
37
+
38
+ context "given one domain" do
39
+ it "associates that domain with given class" do
40
+ AddressBook.register_service :domain, String
41
+ should include :domain => String
42
+ end
43
+ end
44
+ end
45
+
46
+ describe ".extract_domain" do
47
+ it "returns the domain part of email" do
48
+ AddressBook.extract_domain("igor.cug@gmail.com").should == "gmail.com"
49
+ end
50
+ end
51
+
52
+ describe ".export" do
53
+ context "when called for valid service" do
54
+ it "should export user contacts from this service" do
55
+ foo = double()
56
+
57
+ AddressBook.register_service "foo", foo
58
+
59
+ foo.should_receive(:new).and_return foo
60
+ foo.should_receive(:contacts).and_return foo
61
+
62
+ AddressBook.export("test@foo", nil).should == foo
63
+ end
64
+ end
65
+
66
+ context "when called for invalid service" do
67
+ it "should raise ServiceNotFound" do
68
+ expect { AddressBook.export("foobar", nil) }.to raise_error AddressBook::ServiceNotFound
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,24 @@
1
+ yandex:
2
+ :login: test@yandex.ru
3
+ :password: 123123
4
+ :contacts:
5
+ test1@yandex.ru: John Doe
6
+ test2@yandex.ru: Judy Doe
7
+ mailru:
8
+ :login: test@mail.ru
9
+ :password: 123123
10
+ :contacts:
11
+ test1@mail.ru: John Doe
12
+ test2@mail.ru: Judy Doe
13
+ rambler:
14
+ :login: test@rambler.ru
15
+ :password: 123123
16
+ :contacts:
17
+ test1@rambler.ru: John Doe
18
+ test2@rambler.ru: Judy Doe
19
+ gmail:
20
+ :login: test@gmail.com
21
+ :password: 123123
22
+ :contacts:
23
+ test1@gmail.com: John Doe
24
+ test2@gmail.com: Judy Doe
@@ -0,0 +1,61 @@
1
+ ---
2
+ - !ruby/struct:VCR::HTTPInteraction
3
+ request: !ruby/struct:VCR::Request
4
+ method: :post
5
+ uri: https://www.google.com:443/accounts/ClientLogin
6
+ body: accountType=HOSTED_OR_GOOGLE&Email=test%40gmail.com&service=cp&source=GoogleDataRubyUtil-AnonymousApp
7
+ headers:
8
+ response: !ruby/struct:VCR::Response
9
+ status: !ruby/struct:VCR::ResponseStatus
10
+ code: 403
11
+ message: Forbidden
12
+ headers:
13
+ body: |
14
+ Error=BadAuthentication
15
+
16
+ http_version: "1.1"
17
+ - !ruby/struct:VCR::HTTPInteraction
18
+ request: !ruby/struct:VCR::Request
19
+ method: :post
20
+ uri: https://www.google.com:443/accounts/ClientLogin
21
+ body: accountType=HOSTED_OR_GOOGLE&Email=test%40gmail.com&Passwd=123123&service=cp&source=GoogleDataRubyUtil-AnonymousApp
22
+ response: !ruby/struct:VCR::Response
23
+ status: !ruby/struct:VCR::ResponseStatus
24
+ code: 200
25
+ message: OK
26
+ body: |
27
+ SID=DQAAAKgAAABwV6Qd_vrMOi-86IdAnEhSFVj4bHXwd6HIlrWn15mSSXzTm_hDfu5Bfc3rFQHZ1TZ_tCotFayq7T2_tjZ-6Y-KGdjrI8fWgxSDLwd4lxnoJNNa1o-1Qexa-Dkugw2NGQzs2dksLN3MtIquM6qKKGi5eU-XtoMhZuCO0ONOHcbXee2BzddIfyFLU3KLequHnalvEimYwzcXan_e_rpq-LQSMNqGq7pjcFpe8PrUClZPEQ
28
+ LSID=DQAAAKsAAADkbdCaqEb7sGI_UfyrmbHqt31rPnF1B_2WGFszNhjVT4bnxes3vVPZlxFnMgLdq3NXDoTt7uMCjpC5XwCflHUf36MMy4EoLmlomOU0JQwkOOZYiPrO9eIXDxPpravJlyp4L7DwQlICsCNDnq7NAB9qmPwy_DbJYOeoS2bhHOPkJcV6odXe6M1G3k24ingUZz3_ok6sq2HhFOmXVdP1F50cAPbB-J9j2XfrHp1pWdKHiA
29
+ Auth=DQAAAKsAAADkbdCaqEb7sGI_UfyrmbHqt31rPnF1B_2WGFszNhjVT4bnxes3vVPZlxFnMgLdq3NGEhR1RON3lVO5-hHhHVxMiw-X1-s2YOujC22Lp0AL6Q5pxx55ICMEKMwkAyb4Z95HRyBUCMb3IZk1Qy6H2fFiGubRmK-pFAeJIr5XhSYQ2eXiCq2jMc2RbZ4BX_O03AgFpZHmNueux0x98yjS9zFlijSXoD6NMSheE1Tc9jDWBQ
30
+
31
+ http_version: "1.1"
32
+ - !ruby/struct:VCR::HTTPInteraction
33
+ request: !ruby/struct:VCR::Request
34
+ method: :get
35
+ uri: http://www.google.com:80/m8/feeds/contacts/default/full/?max-results=1000
36
+ body:
37
+ headers:
38
+ user-agent:
39
+ - GoogleDataRubyUtil-AnonymousApp
40
+ gdata-version:
41
+ - "2"
42
+ content-type:
43
+ - application/atom+xml
44
+ authorization:
45
+ - GoogleLogin auth=DQAAAKsAAADkbdCaqEb7sGI_UfyrmbHqt31rPnF1B_2WGFszNhjVT4bnxes3vVPZlxFnMgLdq3NGEhR1RON3lVO5-hHhHVxMiw-X1-s2YOujC22Lp0AL6Q5pxx55ICMEKMwkAyb4Z95HRyBUCMb3IZk1Qy6H2fFiGubRmK-pFAeJIr5XhSYQ2eXiCq2jMc2RbZ4BX_O03AgFpZHmNueux0x98yjS9zFlijSXoD6NMSheE1Tc9jDWBQ
46
+ response: !ruby/struct:VCR::Response
47
+ status: !ruby/struct:VCR::ResponseStatus
48
+ code: 200
49
+ message: OK
50
+ body: |-
51
+ <?xml version='1.0' encoding='UTF-8'?>
52
+ <feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearch/1.1/' xmlns:gContact='http://schemas.google.com/contact/2008' xmlns:batch='http://schemas.google.com/gdata/batch' xmlns:gd='http://schemas.google.com/g/2005' gd:etag=''>
53
+ <entry>
54
+ <title>John Doe</title>
55
+ <gd:email address="test1@gmail.com" />
56
+ </entry>
57
+ <entry>
58
+ <title>Judy Doe</title>
59
+ <gd:email address="test2@gmail.com" />
60
+ </entry>
61
+ </feed>
@@ -0,0 +1,44 @@
1
+ ---
2
+ - !ruby/struct:VCR::HTTPInteraction
3
+ request: !ruby/struct:VCR::Request
4
+ method: :post
5
+ uri: https://auth.mail.ru:443/cgi-bin/auth
6
+ body: Login=test%40mail.ru&Domain=mail.ru&Password=
7
+ headers:
8
+ response: !ruby/struct:VCR::Response
9
+ status: !ruby/struct:VCR::ResponseStatus
10
+ code: 200
11
+ message: OK
12
+ headers:
13
+ body: fail=1
14
+ http_version:
15
+ - !ruby/struct:VCR::HTTPInteraction
16
+ request: !ruby/struct:VCR::Request
17
+ method: :post
18
+ uri: https://auth.mail.ru:443/cgi-bin/auth
19
+ body: Login=test%40mail.ru&Domain=mail.ru&Password=123123
20
+ headers:
21
+ response: !ruby/struct:VCR::Response
22
+ status: !ruby/struct:VCR::ResponseStatus
23
+ code: 200
24
+ message: OK
25
+ headers:
26
+ body: okay
27
+ http_version:
28
+ - !ruby/struct:VCR::HTTPInteraction
29
+ request: !ruby/struct:VCR::Request
30
+ method: :post
31
+ uri: http://e.mail.ru:80/cgi-bin/abexport/addressbook.csv
32
+ body: confirm=1&abtype=6
33
+ headers:
34
+ response: !ruby/struct:VCR::Response
35
+ status: !ruby/struct:VCR::ResponseStatus
36
+ code: 200
37
+ message: OK
38
+ headers:
39
+ body: |
40
+ AB-Name,AB-Name1,AB-Name2,AB-Name3,AB-Email1,AB-Email2,AB-Email3,AB-Phones,AB-WWW,AB-Address,AB-Org,AB-Notes,AB-BY,AB-BM,AB-BD,AB-XTRA
41
+ John Doe,,,,test1@mail.ru,,,,,,,,,,,
42
+ Judy Doe,,,,test2@mail.ru,,,,,,,,,,,
43
+
44
+ http_version:
@@ -0,0 +1,52 @@
1
+ ---
2
+ - !ruby/struct:VCR::HTTPInteraction
3
+ request: !ruby/struct:VCR::Request
4
+ method: :post
5
+ uri: http://id.rambler.ru:80/script/auth.cgi
6
+ body: login=test%40rambler.ru&domain=rambler.ru&passw=
7
+ headers:
8
+ response: !ruby/struct:VCR::Response
9
+ status: !ruby/struct:VCR::ResponseStatus
10
+ code: 200
11
+ message: OK
12
+ headers:
13
+ body: errorbox
14
+ http_version:
15
+ - !ruby/struct:VCR::HTTPInteraction
16
+ request: !ruby/struct:VCR::Request
17
+ method: :post
18
+ uri: http://id.rambler.ru:80/script/auth.cgi
19
+ body: login=test%40rambler.ru&domain=rambler.ru&passw=123123
20
+ headers:
21
+ response: !ruby/struct:VCR::Response
22
+ status: !ruby/struct:VCR::ResponseStatus
23
+ code: 200
24
+ message: OK
25
+ headers:
26
+ body: okay
27
+ http_version:
28
+ - !ruby/struct:VCR::HTTPInteraction
29
+ request: !ruby/struct:VCR::Request
30
+ method: :get
31
+ uri: http://mail.rambler.ru/mail/contacts.cgi
32
+ body:
33
+ headers:
34
+ response: !ruby/struct:VCR::Response
35
+ status: !ruby/struct:VCR::ResponseStatus
36
+ code: 200
37
+ message: OK
38
+ headers:
39
+ body: |-
40
+ <div id="mailbox-list">
41
+ <tbody>
42
+ <tr>
43
+ <div class="mtbox-name">John Doe</div>
44
+ <div class="mtbox-email">test1@rambler.ru</div>
45
+ </tr>
46
+ <tr>
47
+ <div class="mtbox-name">Judy Doe</div>
48
+ <div class="mtbox-email">test2@rambler.ru</div>
49
+ </tr>
50
+ </tbody>
51
+ </div>
52
+ http_version:
@@ -0,0 +1,50 @@
1
+ ---
2
+ - !ruby/struct:VCR::HTTPInteraction
3
+ request: !ruby/struct:VCR::Request
4
+ method: :post
5
+ uri: http://passport.yandex.ru:80/passport?mode=auth
6
+ body: login=test%40yandex.ru&passwd=
7
+ response: !ruby/struct:VCR::Response
8
+ status: !ruby/struct:VCR::ResponseStatus
9
+ code: 200
10
+ message: OK
11
+ body: b-login-error
12
+ - !ruby/struct:VCR::HTTPInteraction
13
+ request: !ruby/struct:VCR::Request
14
+ method: :post
15
+ uri: http://passport.yandex.ru:80/passport?mode=auth
16
+ body: login=test%40yandex.ru&passwd=123123
17
+ response: !ruby/struct:VCR::Response
18
+ status: !ruby/struct:VCR::ResponseStatus
19
+ code: 200
20
+ message: OK
21
+ body: okay
22
+ - !ruby/struct:VCR::HTTPInteraction
23
+ request: !ruby/struct:VCR::Request
24
+ method: :post
25
+ uri: https://mail.yandex.ru:443/neo2/handlers/handlers.jsx
26
+ body: _handlers=abook-contacts&all=yes
27
+ response: !ruby/struct:VCR::Response
28
+ status: !ruby/struct:VCR::ResponseStatus
29
+ code: 200
30
+ message: OK
31
+ body: |-
32
+ <handlers>
33
+ <handler name="abook-contacts" gid="0" key="_handler=abook-contacts&amp;amp;all=yes">
34
+ <abook-contacts>
35
+ <contacts>
36
+ <pager count="2"/>
37
+ <contact mcid="2">
38
+ <name first="John" last="Doe"/>
39
+ <email cid="0" rec_id="4">test1@yandex.ru</email>
40
+ </contact>
41
+ <contact mcid="1">
42
+ <name first="Judy" last="Doe"/>
43
+ <email cid="1" rec_id="2">test2@yandex.ru</email>
44
+ </contact>
45
+ </contacts>
46
+ </abook-contacts>
47
+ </handler>
48
+ <login>test</login>
49
+ <actual-version>3.3.11</actual-version>
50
+ </handlers>
@@ -0,0 +1,19 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
2
+
3
+ require "rubygems"
4
+ require "bundler"
5
+
6
+ Bundler.require
7
+
8
+ require "vcr"
9
+ require "address_book"
10
+
11
+ VCR.config do |config|
12
+ config.cassette_library_dir = "spec/fixtures"
13
+ config.stub_with :webmock
14
+ config.default_cassette_options = { :record => :new_episodes, :match_requests_on => [:uri, :method, :body] }
15
+ end
16
+
17
+ RSpec.configure do |c|
18
+ c.extend VCR::RSpec::Macros
19
+ end
metadata CHANGED
@@ -1,104 +1,153 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: address_book
3
- version: !ruby/object:Gem::Version
4
- version: '0.1'
3
+ version: !ruby/object:Gem::Version
5
4
  prerelease:
5
+ version: 0.1.1
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Igor Sidorov
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-06-28 00:00:00.000000000 +04:00
12
+
13
+ date: 2011-06-30 00:00:00 +04:00
13
14
  default_executable:
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
16
17
  name: gdata
17
- requirement: &77369070 !ruby/object:Gem::Requirement
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
18
20
  none: false
19
- requirements:
20
- - - ! '>='
21
- - !ruby/object:Gem::Version
22
- version: '0'
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "0"
23
25
  type: :runtime
24
- prerelease: false
25
- version_requirements: *77369070
26
- - !ruby/object:Gem::Dependency
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
27
28
  name: gdata19
28
- requirement: &77368860 !ruby/object:Gem::Requirement
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
29
31
  none: false
30
- requirements:
31
- - - ! '>='
32
- - !ruby/object:Gem::Version
33
- version: '0'
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: "0"
34
36
  type: :runtime
35
- prerelease: false
36
- version_requirements: *77368860
37
- - !ruby/object:Gem::Dependency
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
38
39
  name: nokogiri
39
- requirement: &77368650 !ruby/object:Gem::Requirement
40
+ prerelease: false
41
+ requirement: &id003 !ruby/object:Gem::Requirement
40
42
  none: false
41
- requirements:
42
- - - ! '>='
43
- - !ruby/object:Gem::Version
44
- version: '0'
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
45
47
  type: :runtime
46
- prerelease: false
47
- version_requirements: *77368650
48
- - !ruby/object:Gem::Dependency
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
49
50
  name: patron
50
- requirement: &77368440 !ruby/object:Gem::Requirement
51
+ prerelease: false
52
+ requirement: &id004 !ruby/object:Gem::Requirement
51
53
  none: false
52
- requirements:
53
- - - ! '>='
54
- - !ruby/object:Gem::Version
55
- version: '0'
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
56
58
  type: :runtime
59
+ version_requirements: *id004
60
+ - !ruby/object:Gem::Dependency
61
+ name: rspec
62
+ prerelease: false
63
+ requirement: &id005 !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: "0"
69
+ type: :development
70
+ version_requirements: *id005
71
+ - !ruby/object:Gem::Dependency
72
+ name: vcr
57
73
  prerelease: false
58
- version_requirements: *77368440
59
- description: Exports address books from various e-mail services (Gmail, Mail.ru, Yandex,
60
- Rambler)
61
- email:
74
+ requirement: &id006 !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: "0"
80
+ type: :development
81
+ version_requirements: *id006
82
+ - !ruby/object:Gem::Dependency
83
+ name: webmock
84
+ prerelease: false
85
+ requirement: &id007 !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: "0"
91
+ type: :development
92
+ version_requirements: *id007
93
+ description: Exports address books from various e-mail services (Gmail, Mail.ru, Yandex, Rambler)
94
+ email:
62
95
  - igor.cug@gmail.com
63
96
  executables: []
97
+
64
98
  extensions: []
99
+
65
100
  extra_rdoc_files: []
66
- files:
101
+
102
+ files:
67
103
  - .gitignore
104
+ - .rspec
68
105
  - Gemfile
106
+ - LICENSE
107
+ - README.rdoc
69
108
  - Rakefile
70
109
  - address_book.gemspec
71
110
  - lib/address_book.rb
72
111
  - lib/address_book/base.rb
73
- - lib/address_book/error.rb
74
112
  - lib/address_book/gmail.rb
75
113
  - lib/address_book/mailru.rb
76
114
  - lib/address_book/rambler.rb
77
115
  - lib/address_book/version.rb
78
116
  - lib/address_book/yandex.rb
117
+ - spec/address_book_spec.rb
118
+ - spec/fixtures/accounts.yml
119
+ - spec/fixtures/gmail.yml
120
+ - spec/fixtures/mailru.yml
121
+ - spec/fixtures/rambler.yml
122
+ - spec/fixtures/yandex.yml
123
+ - spec/spec_helper.rb
79
124
  has_rdoc: true
80
125
  homepage: https://github.com/binarycode/address_book
81
126
  licenses: []
127
+
82
128
  post_install_message:
83
129
  rdoc_options: []
84
- require_paths:
130
+
131
+ require_paths:
85
132
  - lib
86
- required_ruby_version: !ruby/object:Gem::Requirement
133
+ required_ruby_version: !ruby/object:Gem::Requirement
87
134
  none: false
88
- requirements:
89
- - - ! '>='
90
- - !ruby/object:Gem::Version
91
- version: '0'
92
- required_rubygems_version: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: "0"
139
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
140
  none: false
94
- requirements:
95
- - - ! '>='
96
- - !ruby/object:Gem::Version
97
- version: '0'
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: "0"
98
145
  requirements: []
146
+
99
147
  rubyforge_project:
100
148
  rubygems_version: 1.6.2
101
149
  signing_key:
102
150
  specification_version: 3
103
151
  summary: Address book export
104
152
  test_files: []
153
+
@@ -1,7 +0,0 @@
1
- class AddressBook
2
- class ServiceNotFound < StandardError
3
- end
4
-
5
- class AuthenticationError < StandardError
6
- end
7
- end