blackbook 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +18 -0
- data/Manifest.txt +55 -0
- data/README.txt +71 -0
- data/Rakefile +38 -0
- data/init.rb +1 -0
- data/lib/blackbook.rb +80 -0
- data/lib/blackbook/exporter/base.rb +16 -0
- data/lib/blackbook/exporter/vcf.rb +45 -0
- data/lib/blackbook/exporter/xml.rb +28 -0
- data/lib/blackbook/importer/aol.rb +74 -0
- data/lib/blackbook/importer/base.rb +39 -0
- data/lib/blackbook/importer/csv.rb +61 -0
- data/lib/blackbook/importer/gmail.rb +59 -0
- data/lib/blackbook/importer/hotmail.rb +125 -0
- data/lib/blackbook/importer/page_scraper.rb +86 -0
- data/lib/blackbook/importer/yahoo.rb +61 -0
- data/test/fixtures/aol_bad_login_response_stage_3.html +565 -0
- data/test/fixtures/aol_contacts.html +90 -0
- data/test/fixtures/aol_login_response_stage_1.html +158 -0
- data/test/fixtures/aol_login_response_stage_2.html +559 -0
- data/test/fixtures/aol_login_response_stage_3.html +61 -0
- data/test/fixtures/aol_login_response_stage_4.html +48 -0
- data/test/fixtures/aol_login_response_stage_5.html +404 -0
- data/test/fixtures/gmail.csv +3 -0
- data/test/fixtures/gmail_bad_login_response_stage_2.html +560 -0
- data/test/fixtures/gmail_contacts.html +228 -0
- data/test/fixtures/gmail_login_response_stage_1.html +556 -0
- data/test/fixtures/gmail_login_response_stage_2.html +1 -0
- data/test/fixtures/gmail_login_response_stage_3.html +249 -0
- data/test/fixtures/hotmail_bad_login_response_stage_2.html +31 -0
- data/test/fixtures/hotmail_contacts.html +132 -0
- data/test/fixtures/hotmail_login_response_stage_1.html +31 -0
- data/test/fixtures/hotmail_login_response_stage_2.html +1 -0
- data/test/fixtures/hotmail_login_response_stage_3.html +380 -0
- data/test/fixtures/yahoo_bad_login_response_stage_2.html +443 -0
- data/test/fixtures/yahoo_contacts.csv +3 -0
- data/test/fixtures/yahoo_contacts_not_logged_in.html +432 -0
- data/test/fixtures/yahoo_contacts_stage_1.html +399 -0
- data/test/fixtures/yahoo_login_response_stage_1.html +433 -0
- data/test/fixtures/yahoo_login_response_stage_2.html +16 -0
- data/test/scripts/live_test.rb +25 -0
- data/test/test_blackbook.rb +60 -0
- data/test/test_blackbook_exporter_base.rb +16 -0
- data/test/test_blackbook_exporter_vcf.rb +52 -0
- data/test/test_blackbook_exporter_xml.rb +16 -0
- data/test/test_blackbook_importer_aol.rb +107 -0
- data/test/test_blackbook_importer_base.rb +24 -0
- data/test/test_blackbook_importer_csv.rb +60 -0
- data/test/test_blackbook_importer_gmail.rb +96 -0
- data/test/test_blackbook_importer_hotmail.rb +143 -0
- data/test/test_blackbook_importer_page_scraper.rb +51 -0
- data/test/test_blackbook_importer_yahoo.rb +97 -0
- data/test/test_helper.rb +47 -0
- data/vendor/plugins/blackbook/lib/autotest/blackbook.rb +27 -0
- data/vendor/plugins/blackbook/lib/autotest/discover.rb +3 -0
- metadata +147 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
History.txt
|
2
|
+
Manifest.txt
|
3
|
+
README.txt
|
4
|
+
Rakefile
|
5
|
+
init.rb
|
6
|
+
lib/blackbook.rb
|
7
|
+
lib/blackbook/exporter/base.rb
|
8
|
+
lib/blackbook/exporter/vcf.rb
|
9
|
+
lib/blackbook/exporter/xml.rb
|
10
|
+
lib/blackbook/importer/aol.rb
|
11
|
+
lib/blackbook/importer/base.rb
|
12
|
+
lib/blackbook/importer/csv.rb
|
13
|
+
lib/blackbook/importer/gmail.rb
|
14
|
+
lib/blackbook/importer/hotmail.rb
|
15
|
+
lib/blackbook/importer/page_scraper.rb
|
16
|
+
lib/blackbook/importer/yahoo.rb
|
17
|
+
test/fixtures/aol_bad_login_response_stage_3.html
|
18
|
+
test/fixtures/aol_contacts.html
|
19
|
+
test/fixtures/aol_login_response_stage_1.html
|
20
|
+
test/fixtures/aol_login_response_stage_2.html
|
21
|
+
test/fixtures/aol_login_response_stage_3.html
|
22
|
+
test/fixtures/aol_login_response_stage_4.html
|
23
|
+
test/fixtures/aol_login_response_stage_5.html
|
24
|
+
test/fixtures/gmail.csv
|
25
|
+
test/fixtures/gmail_bad_login_response_stage_2.html
|
26
|
+
test/fixtures/gmail_contacts.html
|
27
|
+
test/fixtures/gmail_login_response_stage_1.html
|
28
|
+
test/fixtures/gmail_login_response_stage_2.html
|
29
|
+
test/fixtures/gmail_login_response_stage_3.html
|
30
|
+
test/fixtures/hotmail_bad_login_response_stage_2.html
|
31
|
+
test/fixtures/hotmail_contacts.html
|
32
|
+
test/fixtures/hotmail_login_response_stage_1.html
|
33
|
+
test/fixtures/hotmail_login_response_stage_2.html
|
34
|
+
test/fixtures/hotmail_login_response_stage_3.html
|
35
|
+
test/fixtures/yahoo_bad_login_response_stage_2.html
|
36
|
+
test/fixtures/yahoo_contacts.csv
|
37
|
+
test/fixtures/yahoo_contacts_not_logged_in.html
|
38
|
+
test/fixtures/yahoo_contacts_stage_1.html
|
39
|
+
test/fixtures/yahoo_login_response_stage_1.html
|
40
|
+
test/fixtures/yahoo_login_response_stage_2.html
|
41
|
+
test/scripts/live_test.rb
|
42
|
+
test/test_blackbook.rb
|
43
|
+
test/test_blackbook_exporter_base.rb
|
44
|
+
test/test_blackbook_exporter_vcf.rb
|
45
|
+
test/test_blackbook_exporter_xml.rb
|
46
|
+
test/test_blackbook_importer_aol.rb
|
47
|
+
test/test_blackbook_importer_base.rb
|
48
|
+
test/test_blackbook_importer_csv.rb
|
49
|
+
test/test_blackbook_importer_gmail.rb
|
50
|
+
test/test_blackbook_importer_hotmail.rb
|
51
|
+
test/test_blackbook_importer_page_scraper.rb
|
52
|
+
test/test_blackbook_importer_yahoo.rb
|
53
|
+
test/test_helper.rb
|
54
|
+
vendor/plugins/blackbook/lib/autotest/blackbook.rb
|
55
|
+
vendor/plugins/blackbook/lib/autotest/discover.rb
|
data/README.txt
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
Blackbook
|
2
|
+
http://rubyforge.org/projects/contentfree/
|
3
|
+
|
4
|
+
== DESCRIPTION:
|
5
|
+
|
6
|
+
Blackbook automates the nitty-gritty of importing contacts from various services and files and exporting them as VCard, XML, or simple Hash. Utilize those contacts from services like AOL, GMail, Yahoo Mail, Hotmail or CSV to help your social networking site become GIGANTIC overnight! You'll be able to get big and sell for millions before anyone figures out it's just like every other social network.
|
7
|
+
|
8
|
+
== FEATURES/PROBLEMS:
|
9
|
+
|
10
|
+
The current list of supported services and file types:
|
11
|
+
|
12
|
+
Import:
|
13
|
+
* AOL
|
14
|
+
* CSV files
|
15
|
+
* Gmail
|
16
|
+
* Hotmail
|
17
|
+
* Yahoo! Mail
|
18
|
+
|
19
|
+
Export:
|
20
|
+
* Simple hash (default)
|
21
|
+
* Vcard
|
22
|
+
* XML
|
23
|
+
|
24
|
+
If you create an additional importer or exporter - or simply find a bug - please consider submitting it as a patch to the project so the community can all benefit from your hard work and ingenuity.
|
25
|
+
|
26
|
+
== SYNOPSIS:
|
27
|
+
|
28
|
+
# An example of fetching Gmail contacts - by default, returns an array of hashes with :name and :email
|
29
|
+
contacts = Blackbook.get :username => 'me@gmail.com', :password => 'whatever'
|
30
|
+
|
31
|
+
# or returning XML
|
32
|
+
contacts = Blackbook.get :username => 'me@gmail.com', :password => 'whatever', :as => :xml
|
33
|
+
|
34
|
+
# or importing from a CSV file
|
35
|
+
contacts = Blackbook.get :csv, :file => #<File:/path/to/file.csv>
|
36
|
+
|
37
|
+
== REQUIREMENTS:
|
38
|
+
|
39
|
+
* Mechanize and its dependencies, for interacting with online providers
|
40
|
+
* Fastercsv for reading CSV, Mechanize >= 0.7.0 for page scraping
|
41
|
+
|
42
|
+
== INSTALL:
|
43
|
+
|
44
|
+
* sudo gem install blackbook
|
45
|
+
|
46
|
+
== THANKS:
|
47
|
+
|
48
|
+
Big thanks to Marton Fabo for figuring out why Mechanize couldn't log in to AOL.
|
49
|
+
|
50
|
+
== LICENSE:
|
51
|
+
|
52
|
+
Copyright (c) 2007, Contentfree
|
53
|
+
|
54
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
55
|
+
a copy of this software and associated documentation files (the
|
56
|
+
'Software'), to deal in the Software without restriction, including
|
57
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
58
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
59
|
+
permit persons to whom the Software is furnished to do so, subject to
|
60
|
+
the following conditions:
|
61
|
+
|
62
|
+
The above copyright notice and this permission notice shall be
|
63
|
+
included in all copies or substantial portions of the Software.
|
64
|
+
|
65
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
66
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
67
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
68
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
69
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
70
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
71
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'hoe'
|
5
|
+
$LOAD_PATH.unshift 'lib'
|
6
|
+
require 'blackbook'
|
7
|
+
|
8
|
+
begin
|
9
|
+
require 'rcov/rcovtask'
|
10
|
+
rescue LoadError
|
11
|
+
end
|
12
|
+
|
13
|
+
Hoe.new('blackbook', Blackbook::VERSION) do |p|
|
14
|
+
p.rubyforge_name = 'contentfree'
|
15
|
+
p.author = 'Contentfree'
|
16
|
+
p.email = 'dave.myron@contentfree.com'
|
17
|
+
p.summary = 'Blackbook handles the nitty-gritty of importing contacts from various service providers and contact lists and exporting them in a useful format.'
|
18
|
+
p.description = p.paragraphs_of('README.txt', 1).join("\n\n")
|
19
|
+
p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
|
20
|
+
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
|
21
|
+
p.extra_deps << [ "mechanize", ">= 0.7.0" ]
|
22
|
+
p.extra_deps << [ "fastercsv", ">= 1.2.0" ]
|
23
|
+
p.clean_globs << 'coverage'
|
24
|
+
p.clean_globs << 'pkg'
|
25
|
+
p.clean_globs << 'doc'
|
26
|
+
p.clean_globs << 'ri'
|
27
|
+
end
|
28
|
+
|
29
|
+
task :release_and_publish => [:release, :publish_docs]
|
30
|
+
|
31
|
+
begin
|
32
|
+
Rcov::RcovTask.new do |t|
|
33
|
+
t.test_files = FileList['test/test*.rb']
|
34
|
+
t.verbose = true
|
35
|
+
#t.rcov_opts << "--exclude rcov.rb,hpricot.rb,hpricot/.*\.rb"
|
36
|
+
end
|
37
|
+
rescue NameError
|
38
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'blackbook'
|
data/lib/blackbook.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
$:.unshift File.expand_path(File.join(File.dirname(__FILE__)))
|
2
|
+
require 'singleton'
|
3
|
+
require 'rubygems'
|
4
|
+
|
5
|
+
class Blackbook
|
6
|
+
include ::Singleton
|
7
|
+
VERSION = '1.0.0'
|
8
|
+
|
9
|
+
class BlackbookError < ::StandardError; end
|
10
|
+
class BadCredentialsError < BlackbookError; end
|
11
|
+
|
12
|
+
attr_accessor :importers
|
13
|
+
attr_accessor :exporters
|
14
|
+
|
15
|
+
def self.get( *args )
|
16
|
+
instance.get( *args )
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.register(name, adapter_class)
|
20
|
+
case adapter = adapter_class.new
|
21
|
+
when Importer::Base
|
22
|
+
instance.importers[name.to_sym] = adapter
|
23
|
+
when Exporter::Base
|
24
|
+
instance.exporters[name.to_sym] = adapter
|
25
|
+
else
|
26
|
+
raise ArgumentError, "Unknown adapter"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Sends the vcards from the import to whatever is handling the export
|
31
|
+
def export( importer, exporter, options )
|
32
|
+
exporter.export importer.import( options )
|
33
|
+
end
|
34
|
+
|
35
|
+
# Searches registered importers for one that will handle the given options
|
36
|
+
def find_importer( options )
|
37
|
+
importers.each{ |key, importer| return importer if importer =~ options }
|
38
|
+
nil
|
39
|
+
end
|
40
|
+
|
41
|
+
# Fetches contacts from various services or filetypes. The default is to return an array
|
42
|
+
# of hashes - Blackbook's internal format
|
43
|
+
#
|
44
|
+
# Handles several different calls:
|
45
|
+
# get( :username => 'something@gmail.com', :password => 'whatever' )
|
46
|
+
# get( :as => :xml, :username => 'something@gmail.com', :password => 'whatever' )
|
47
|
+
# get( :csv, :file => #<File:/path/to/file.csv> )
|
48
|
+
def get( *args )
|
49
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
50
|
+
to_format = exporters[ options[:as] || :basic ]
|
51
|
+
source = (importers[args.first.to_sym] rescue nil) || find_importer(options)
|
52
|
+
|
53
|
+
raise ArgumentError, "Unknown exporter" unless to_format
|
54
|
+
raise ArgumentError, "Unknown source" unless source
|
55
|
+
|
56
|
+
export source, to_format, options
|
57
|
+
end
|
58
|
+
|
59
|
+
def initialize
|
60
|
+
self.importers = {}
|
61
|
+
self.exporters = {}
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Require all the importers/exporters
|
66
|
+
require 'blackbook/importer/base'
|
67
|
+
require 'blackbook/exporter/base'
|
68
|
+
Dir.glob(File.join(File.dirname(__FILE__), 'blackbook/importer/*.rb')).each {|f| require f }
|
69
|
+
Dir.glob(File.join(File.dirname(__FILE__), 'blackbook/exporter/*.rb')).each {|f| require f }
|
70
|
+
|
71
|
+
class String
|
72
|
+
alias :blank? :empty?
|
73
|
+
end
|
74
|
+
class NilClass
|
75
|
+
alias :blank? :nil?
|
76
|
+
end
|
77
|
+
class Array
|
78
|
+
alias :blank? :empty?
|
79
|
+
end
|
80
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
##
|
2
|
+
# base class for exporters of contact information
|
3
|
+
|
4
|
+
module Blackbook::Exporter
|
5
|
+
|
6
|
+
class Base
|
7
|
+
##
|
8
|
+
# Override this to convert +contacts+ (an array of hashes) to something more useful. Here, it
|
9
|
+
# just returns Blackbook's internal format
|
10
|
+
def export( contacts )
|
11
|
+
contacts
|
12
|
+
end
|
13
|
+
|
14
|
+
Blackbook.register :basic, self
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
##
|
2
|
+
# exports contacts in Vcard format
|
3
|
+
class Blackbook::Exporter::Vcf < Blackbook::Exporter::Base
|
4
|
+
|
5
|
+
##
|
6
|
+
# representation of a vcard
|
7
|
+
|
8
|
+
class Vcard
|
9
|
+
|
10
|
+
attr_accessor :first, :last, :email
|
11
|
+
|
12
|
+
##
|
13
|
+
# initialize dynamically sets the attributes passed in as accessible
|
14
|
+
# attribute on its object
|
15
|
+
|
16
|
+
def initialize( attributes = {} )
|
17
|
+
attributes.each{ |name,value| self.send("#{name}=", value) rescue next }
|
18
|
+
end
|
19
|
+
|
20
|
+
##
|
21
|
+
# text representation of this vcard
|
22
|
+
def to_s
|
23
|
+
<<-EOVC
|
24
|
+
BEGIN:VCARD
|
25
|
+
N:#{last};#{first}
|
26
|
+
EMAIL:#{email}
|
27
|
+
END:VCARD
|
28
|
+
EOVC
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# exports contacts as Vcards
|
34
|
+
|
35
|
+
def export( contacts = [] )
|
36
|
+
return if contacts.blank?
|
37
|
+
|
38
|
+
contacts.uniq.compact.collect do |contact|
|
39
|
+
first_name, last_name = contact[:name].split(' ', 2)
|
40
|
+
Vcard.new( :first => first_name.to_s, :last => last_name.to_s, :email => contact[:email])
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
Blackbook.register(:vcf, self)
|
45
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rexml/document'
|
2
|
+
|
3
|
+
##
|
4
|
+
# exports contacts in xml format
|
5
|
+
|
6
|
+
class Blackbook::Exporter::Xml < Blackbook::Exporter::Base
|
7
|
+
|
8
|
+
##
|
9
|
+
# contacts are an array of hashes that are contacts and returns xml
|
10
|
+
|
11
|
+
def export( contacts )
|
12
|
+
doc = REXML::Document.new
|
13
|
+
doc << REXML::XMLDecl.new
|
14
|
+
|
15
|
+
root = doc.add_element 'contacts'
|
16
|
+
contacts.each do |contact|
|
17
|
+
el = root.add_element 'contact'
|
18
|
+
name = el.add_element 'name'
|
19
|
+
name.text = contact[:name]
|
20
|
+
|
21
|
+
el.add_element('email').text = contact[:email]
|
22
|
+
end
|
23
|
+
|
24
|
+
doc.to_s
|
25
|
+
end
|
26
|
+
|
27
|
+
Blackbook.register(:xml, self)
|
28
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'blackbook/importer/page_scraper'
|
2
|
+
|
3
|
+
##
|
4
|
+
# Imports contacts from AOL
|
5
|
+
|
6
|
+
class Blackbook::Importer::Aol < Blackbook::Importer::PageScraper
|
7
|
+
|
8
|
+
##
|
9
|
+
# Matches this importer to an user's name/address
|
10
|
+
|
11
|
+
def =~( options )
|
12
|
+
options && options[:username] =~ /@(aol|aim)\.com$/i ? true : false
|
13
|
+
end
|
14
|
+
|
15
|
+
##
|
16
|
+
# Login process:
|
17
|
+
# - Get mail.aol.com which redirects to a page containing a javascript redirect
|
18
|
+
# - Get the URL that the javascript is supposed to redirect you to
|
19
|
+
# - Fill out and submit the login form
|
20
|
+
# - Get the URL from *another* javascript redirect
|
21
|
+
|
22
|
+
def login
|
23
|
+
page = agent.get( 'http://webmail.aol.com/' )
|
24
|
+
|
25
|
+
form = page.forms.name('AOLLoginForm').first
|
26
|
+
form.loginId = options[:username].split('@').first # Drop the domain
|
27
|
+
form.password = options[:password]
|
28
|
+
page = agent.submit(form, form.buttons.first)
|
29
|
+
|
30
|
+
raise( Blackbook::BadCredentialsError, "That username and password was not accepted. Please check them and try again." ) if page.body =~ /Invalid Screen Name or Password. Please try again./
|
31
|
+
|
32
|
+
# aol bumps to a wait page while logging in. if we can't scrape out the js then its a bad login
|
33
|
+
wait_url = page.body.scan(/onLoad="checkError[^\)]+/).first.scan(/'([^']+)'/).last.first
|
34
|
+
page = agent.get wait_url
|
35
|
+
# aol generates the URL below from some JS magic in the wait_url page
|
36
|
+
agent.get 'http://webmail.aol.com/31361/aol/en-us/Suite.aspx'
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# must login to prepare
|
41
|
+
|
42
|
+
def prepare
|
43
|
+
login
|
44
|
+
end
|
45
|
+
|
46
|
+
##
|
47
|
+
# The url to scrape contacts from has to be put together from the Auth cookie
|
48
|
+
# and a known uri that hosts their contact service. An array of hashes with
|
49
|
+
# :name and :email keys is returned.
|
50
|
+
|
51
|
+
def scrape_contacts
|
52
|
+
unless auth_cookie = agent.cookies.find{|c| c.name =~ /^Auth/}
|
53
|
+
raise( Blackbook::BadCredentialsError, "Must be authenticated to access contacts." )
|
54
|
+
end
|
55
|
+
|
56
|
+
# Get user id from cookies
|
57
|
+
user_id = auth_cookie.value.scan(/&uid:([^&]+)&/).first.first
|
58
|
+
|
59
|
+
# Get contacts print page
|
60
|
+
page = agent.get "http://webmail.aol.com/aim/en-us/Lite/addresslist-print.aspx?command=all&sort=FirstLastNick&sortDir=Ascending&nameFormat=FirstLastNick&user=#{user_id}"
|
61
|
+
|
62
|
+
# Grab all the contacts
|
63
|
+
names = page.body.scan( /<span class="fullName">([^<]+)<\/span>/ ).flatten
|
64
|
+
emails = page.body.scan( /<span>Email 1:<\/span> <span>([^<]+)<\/span>/ ).flatten
|
65
|
+
(0...[names.size,emails.size].max).collect do |i|
|
66
|
+
{
|
67
|
+
:name => names[i],
|
68
|
+
:email => emails[i]
|
69
|
+
}
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
Blackbook.register :aol, self
|
74
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#
|
2
|
+
# Provides a base template for interface and behavior of contact importers
|
3
|
+
|
4
|
+
module Blackbook::Importer
|
5
|
+
class Base
|
6
|
+
attr_accessor :options
|
7
|
+
|
8
|
+
##
|
9
|
+
# Should return true or false/nil depending on whether the +options+ given
|
10
|
+
# can be handled by this importer
|
11
|
+
|
12
|
+
def =~( options ); end # stub
|
13
|
+
|
14
|
+
##
|
15
|
+
# Does the work of extracting contacts. Returns an Array of Arrays
|
16
|
+
# containing the name and email as the first and second elements. Of
|
17
|
+
# course, you can override this behavior to meet the needs of a
|
18
|
+
# particular service.
|
19
|
+
|
20
|
+
def fetch_contacts!; end # stub
|
21
|
+
|
22
|
+
##
|
23
|
+
# Imports the contacts using the given +options+. Returns an array of
|
24
|
+
# hashes in the internal format (a hash with at least :name and :email
|
25
|
+
# values).
|
26
|
+
|
27
|
+
def import(options = {})
|
28
|
+
self.options = options
|
29
|
+
fetch_contacts!
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# Name of the importer service.
|
34
|
+
|
35
|
+
def service_name
|
36
|
+
self.class.name.split("::").last
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|