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
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'fastercsv'
|
2
|
+
|
3
|
+
##
|
4
|
+
# Imports contacts from a CSV file
|
5
|
+
|
6
|
+
class Blackbook::Importer::Csv < Blackbook::Importer::Base
|
7
|
+
|
8
|
+
DEFAULT_COLUMNS = [:name,:email,:misc]
|
9
|
+
|
10
|
+
##
|
11
|
+
# Matches this importer to a file that contains CSV values
|
12
|
+
|
13
|
+
def =~(options)
|
14
|
+
options && options[:file].respond_to?(:open) ? true : false
|
15
|
+
end
|
16
|
+
|
17
|
+
##
|
18
|
+
# fetch_contacts! implementation for this importer
|
19
|
+
|
20
|
+
def fetch_contacts!
|
21
|
+
lines = IO.readlines(options[:file].path)
|
22
|
+
columns = to_columns(lines.first)
|
23
|
+
lines.shift if columns.first == :name
|
24
|
+
columns = DEFAULT_COLUMNS.dup unless columns.first == :name
|
25
|
+
|
26
|
+
contacts = Array.new
|
27
|
+
lines.each do |l|
|
28
|
+
vals = l.split(',')
|
29
|
+
next if vals.empty?
|
30
|
+
contacts << to_hash(columns, vals)
|
31
|
+
end
|
32
|
+
|
33
|
+
contacts
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_hash(cols, vals) # :nodoc:
|
37
|
+
h = Hash.new
|
38
|
+
cols.each do |c|
|
39
|
+
h[c] = (c == cols.last) ? vals.join(',') : vals.shift
|
40
|
+
end
|
41
|
+
h
|
42
|
+
end
|
43
|
+
|
44
|
+
def to_columns(line) # :nodoc:
|
45
|
+
columns = Array.new
|
46
|
+
tags = line.split(',')
|
47
|
+
# deal with "Name,E-mail..." oddity up front
|
48
|
+
if tags.first =~ /^name$/i
|
49
|
+
tags.shift
|
50
|
+
columns << :name
|
51
|
+
if tags.first =~ /^e.?mail/i # E-mail or Email
|
52
|
+
tags.shift
|
53
|
+
columns << :email
|
54
|
+
end
|
55
|
+
end
|
56
|
+
tags.each{|v| columns << v.strip.to_sym}
|
57
|
+
columns
|
58
|
+
end
|
59
|
+
|
60
|
+
Blackbook.register(:csv, self)
|
61
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'blackbook/importer/page_scraper'
|
2
|
+
|
3
|
+
##
|
4
|
+
# Imports contacts from GMail
|
5
|
+
|
6
|
+
class Blackbook::Importer::Gmail < Blackbook::Importer::PageScraper
|
7
|
+
|
8
|
+
##
|
9
|
+
# Matches this importer to an user's name/address
|
10
|
+
|
11
|
+
def =~(options = {})
|
12
|
+
options && options[:username] =~ /@gmail.com$/i ? true : false
|
13
|
+
end
|
14
|
+
|
15
|
+
##
|
16
|
+
# login to gmail
|
17
|
+
|
18
|
+
def login
|
19
|
+
page = agent.get('http://mail.google.com/')
|
20
|
+
form = page.forms.first
|
21
|
+
form.Email = options[:username]
|
22
|
+
form.Passwd = options[:password]
|
23
|
+
page = agent.submit(form,form.buttons.first)
|
24
|
+
|
25
|
+
raise( Blackbook::BadCredentialsError, "That username and password was not accepted. Please check them and try again." ) if page.body =~ /Username and password do not match/
|
26
|
+
|
27
|
+
url = page.search('//meta').first.attributes['content'].split('URL=').last rescue nil
|
28
|
+
page = agent.get url
|
29
|
+
end
|
30
|
+
|
31
|
+
##
|
32
|
+
# prepare this importer
|
33
|
+
|
34
|
+
def prepare
|
35
|
+
login
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# scrape gmail contacts for this importer
|
40
|
+
|
41
|
+
def scrape_contacts
|
42
|
+
unless agent.cookies.find{|c| c.name == 'GAUSR' &&
|
43
|
+
c.value == "mail:#{options[:username]}"}
|
44
|
+
raise( Blackbook::BadCredentialsError, "Must be authenticated to access contacts." )
|
45
|
+
end
|
46
|
+
|
47
|
+
page = agent.get('http://mail.google.com/mail/h/?v=cl&pnl=a')
|
48
|
+
contact_rows = page.search("input[@name='c']/../..")
|
49
|
+
contact_rows.collect do |row|
|
50
|
+
columns = row/"td"
|
51
|
+
{
|
52
|
+
:name => ( columns[1] / "b" ).inner_html, # name
|
53
|
+
:email => columns[2].inner_html.gsub( /(\n| )/, '' ) # email
|
54
|
+
}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
Blackbook.register(:gmail, self)
|
59
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'blackbook/importer/page_scraper'
|
2
|
+
require 'cgi'
|
3
|
+
|
4
|
+
##
|
5
|
+
# imports contacts for MSN/Hotmail
|
6
|
+
class Blackbook::Importer::Hotmail < Blackbook::Importer::PageScraper
|
7
|
+
|
8
|
+
DOMAINS = { "compaq.net" => "https://msnia.login.live.com/ppsecure/post.srf",
|
9
|
+
"hotmail.co.jp" => "https://login.live.com/ppsecure/post.srf",
|
10
|
+
"hotmail.co.uk" => "https://login.live.com/ppsecure/post.srf",
|
11
|
+
"hotmail.com" => "https://login.live.com/ppsecure/post.srf",
|
12
|
+
"hotmail.de" => "https://login.live.com/ppsecure/post.srf",
|
13
|
+
"hotmail.fr" => "https://login.live.com/ppsecure/post.srf",
|
14
|
+
"hotmail.it" => "https://login.live.com/ppsecure/post.srf",
|
15
|
+
"messengeruser.com" => "https://login.live.com/ppsecure/post.srf",
|
16
|
+
"msn.com" => "https://msnia.login.live.com/ppsecure/post.srf",
|
17
|
+
"passport.com" => "https://login.live.com/ppsecure/post.srf",
|
18
|
+
"webtv.net" => "https://login.live.com/ppsecure/post.srf" }
|
19
|
+
|
20
|
+
##
|
21
|
+
# Matches this importer to an user's name/address
|
22
|
+
|
23
|
+
def =~(options)
|
24
|
+
return false unless options && options[:username]
|
25
|
+
domain = username_domain(options[:username].downcase)
|
26
|
+
!domain.blank? && DOMAINS.keys.include?( domain ) ? true : false
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# Login procedure
|
31
|
+
# 1. Go to login form
|
32
|
+
# 2. Set login and passwd
|
33
|
+
# 3. Set PwdPad to IfYouAreReadingThisYouHaveTooMuchFreeTime minus however many characters are in passwd (so if passwd
|
34
|
+
# was 8 chars, you'd chop 8 chars of the end of IfYouAreReadingThisYouHaveTooMuchFreeTime - giving you IfYouAreReadingThisYouHaveTooMuch)
|
35
|
+
# 4. Set the action to the appropriate URL for the username's domain
|
36
|
+
# 5. Get the query string to append to the new action
|
37
|
+
# 5. Submit the form and parse the url from the resulting page's javascript
|
38
|
+
# 6. Go to that url
|
39
|
+
|
40
|
+
def login
|
41
|
+
page = agent.get('http://login.live.com/login.srf?id=2')
|
42
|
+
form = page.forms.first
|
43
|
+
form.login = options[:username]
|
44
|
+
form.passwd = options[:password]
|
45
|
+
form.PwdPad = ( "IfYouAreReadingThisYouHaveTooMuchFreeTime"[0..(-1 - options[:password].to_s.size )])
|
46
|
+
query_string = page.body.scan(/g_QS="([^"]+)/).first.first rescue nil
|
47
|
+
form.action = login_url + "?#{query_string.to_s}"
|
48
|
+
page = agent.submit(form)
|
49
|
+
|
50
|
+
# Check for login success
|
51
|
+
if page.body =~ /The e-mail address or password is incorrect/ ||
|
52
|
+
page.body =~ /Sign in failed\./
|
53
|
+
raise( Blackbook::BadCredentialsError,
|
54
|
+
"That username and password was not accepted. Please check them and try again." )
|
55
|
+
end
|
56
|
+
|
57
|
+
page = agent.get( page.body.scan(/http\:\/\/[^"]+/).first )
|
58
|
+
end
|
59
|
+
|
60
|
+
##
|
61
|
+
# prepare this importer
|
62
|
+
|
63
|
+
def prepare
|
64
|
+
login
|
65
|
+
end
|
66
|
+
|
67
|
+
##
|
68
|
+
# Scrape contacts for Hotmail
|
69
|
+
# Seems like a POST to directly fetch CSV contacts from options.aspx?subsection=26&n=
|
70
|
+
# raises an end of file error in Net::HTTP via Mechanize.
|
71
|
+
# Seems like Hotmail addresses are now hosted on Windows Live.
|
72
|
+
|
73
|
+
def scrape_contacts
|
74
|
+
unless agent.cookies.find{|c| c.name == 'MSPPre' && c.value == options[:username]}
|
75
|
+
raise( Blackbook::BadCredentialsError, "Must be authenticated to access contacts." )
|
76
|
+
end
|
77
|
+
|
78
|
+
page = agent.get('PrintShell.aspx?type=contact')
|
79
|
+
rows = page.search("//div[@class='ContactsPrintPane cPrintContact BorderTop']")
|
80
|
+
rows.collect do |row|
|
81
|
+
name = row.search("//div[@class='cDisplayName']").first.innerText.strip
|
82
|
+
name = name[0,(name.size-3)] # char 142 is last char of clean text
|
83
|
+
|
84
|
+
vals = {}
|
85
|
+
row.search("/table/tr").each do |pair|
|
86
|
+
key = pair.search("/td[@class='TextAlignRight Label']").first.innerText.strip
|
87
|
+
val = pair.search("/td[@class='Value']").first.innerText.strip
|
88
|
+
vals[key.to_sym] = val
|
89
|
+
end
|
90
|
+
vals[:name] = name
|
91
|
+
vals[:email] = (vals['Personal e-mail'.to_sym] || vals['Work e-mail'.to_sym]).split(' ').first rescue ''
|
92
|
+
vals
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
##
|
97
|
+
# lookup for the login service that should be used based on the user's
|
98
|
+
# address
|
99
|
+
|
100
|
+
def login_url
|
101
|
+
DOMAINS[username_domain] || DOMAINS['hotmail.com']
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
##
|
106
|
+
# normalizes the host for the page that is currently being "viewed" by the
|
107
|
+
# Mechanize agent
|
108
|
+
|
109
|
+
def current_host
|
110
|
+
return nil unless agent && agent.current_page
|
111
|
+
uri = agent.current_page.uri
|
112
|
+
"#{uri.scheme}://#{uri.host}"
|
113
|
+
end
|
114
|
+
|
115
|
+
##
|
116
|
+
# determines the domain for the user
|
117
|
+
|
118
|
+
def username_domain(username = nil)
|
119
|
+
username ||= options[:username] if options
|
120
|
+
return unless username
|
121
|
+
username.to_s.split('@').last
|
122
|
+
end
|
123
|
+
|
124
|
+
Blackbook.register(:hotmail, self)
|
125
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
gem 'mechanize', '>= 0.7.0'
|
3
|
+
require 'mechanize'
|
4
|
+
require 'generator' # for SyncEnumerator
|
5
|
+
|
6
|
+
# Patch Mechanize's broken html unescaping Mechanize 0.6.11
|
7
|
+
class WWW::Mechanize
|
8
|
+
def to_absolute_uri(url, cur_page=current_page())
|
9
|
+
unless url.is_a? URI
|
10
|
+
url = url.to_s.strip
|
11
|
+
url = URI.parse(
|
12
|
+
self.class.html_unescape(
|
13
|
+
SyncEnumerator.new(
|
14
|
+
url.split(/%[0-9A-Fa-f]{2}/), url.scan(/%[0-9A-Fa-f]{2}/)
|
15
|
+
).map { |x,y|
|
16
|
+
"#{URI.escape(x||'')}#{y}"
|
17
|
+
}.join('').gsub(/%23/, '#')
|
18
|
+
)
|
19
|
+
)
|
20
|
+
# Mechanize here uses #zip to combine the two arrays, which will ignore
|
21
|
+
# excessive elements of the second array (the one which is passed as an
|
22
|
+
# argument). That means if the URL ends with more than one already escaped
|
23
|
+
# character, then only the first one will be restored into the resulting
|
24
|
+
# URL.
|
25
|
+
end
|
26
|
+
|
27
|
+
# construct an absolute uri
|
28
|
+
if url.relative?
|
29
|
+
raise 'no history. please specify an absolute URL' unless cur_page.uri
|
30
|
+
url = cur_page.uri + url
|
31
|
+
# Strip initial "/.." bits from the path
|
32
|
+
url.path.sub!(/^(\/\.\.)+(?=\/)/, '')
|
33
|
+
end
|
34
|
+
|
35
|
+
return url
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# A base class for importers that scrape their contacts from web services
|
41
|
+
|
42
|
+
class Blackbook::Importer::PageScraper < Blackbook::Importer::Base
|
43
|
+
|
44
|
+
attr_accessor :agent
|
45
|
+
|
46
|
+
##
|
47
|
+
# creates the Mechanize agent used to do the scraping and sets a nice
|
48
|
+
# user agent header for good net educate
|
49
|
+
|
50
|
+
def create_agent
|
51
|
+
self.agent = WWW::Mechanize.new
|
52
|
+
agent.user_agent = "Mozilla/4.0 (compatible; Blackbook #{Blackbook::VERSION})"
|
53
|
+
agent.keep_alive = false
|
54
|
+
agent
|
55
|
+
end
|
56
|
+
|
57
|
+
##
|
58
|
+
# Page scrapers will follow a fairly simple pattern of instantiating the
|
59
|
+
# agent, prepping for the scrape and then the actual scrape process
|
60
|
+
|
61
|
+
def fetch_contacts!
|
62
|
+
create_agent
|
63
|
+
prepare
|
64
|
+
scrape_contacts
|
65
|
+
end
|
66
|
+
|
67
|
+
##
|
68
|
+
# Providers will often require you to login or otherwise prepare to actual
|
69
|
+
# scrape the contacts
|
70
|
+
|
71
|
+
def prepare; end # stub
|
72
|
+
|
73
|
+
##
|
74
|
+
# Some providers have a single page you can scrape from (like Gmail's HTML
|
75
|
+
# Contacts page) while others might require you to navigate several pages,
|
76
|
+
# scraping as you go.
|
77
|
+
|
78
|
+
def scrape_contacts; end # stub
|
79
|
+
|
80
|
+
##
|
81
|
+
# helper to strip html from text
|
82
|
+
|
83
|
+
def strip_html( html )
|
84
|
+
html.gsub(/<\/?[^>]*>/, '')
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'blackbook/importer/page_scraper'
|
2
|
+
require 'fastercsv'
|
3
|
+
|
4
|
+
##
|
5
|
+
# contacts importer for Yahoo!
|
6
|
+
|
7
|
+
class Blackbook::Importer::Yahoo < Blackbook::Importer::PageScraper
|
8
|
+
|
9
|
+
##
|
10
|
+
# Matches this importer to an user's name/address
|
11
|
+
|
12
|
+
def =~(options = {})
|
13
|
+
options && options[:username] =~ /@yahoo.com$/i ? true : false
|
14
|
+
end
|
15
|
+
|
16
|
+
##
|
17
|
+
# login for Yahoo!
|
18
|
+
|
19
|
+
def login
|
20
|
+
page = agent.get('https://login.yahoo.com/config/login_verify2?')
|
21
|
+
form = page.forms.first
|
22
|
+
form.login = options[:username].split("@").first
|
23
|
+
form.passwd = options[:password]
|
24
|
+
page = agent.submit(form, form.buttons.first)
|
25
|
+
|
26
|
+
# Check for login success
|
27
|
+
raise( Blackbook::BadCredentialsError, "That username and password was not accepted. Please check them and try again." ) if page.body =~ /Invalid ID or password./
|
28
|
+
true
|
29
|
+
end
|
30
|
+
|
31
|
+
##
|
32
|
+
# prepare the importer
|
33
|
+
|
34
|
+
def prepare
|
35
|
+
login
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# scrape yahoo contacts
|
40
|
+
|
41
|
+
def scrape_contacts
|
42
|
+
page = agent.get("http://address.yahoo.com/?1=&VPC=import_export")
|
43
|
+
if page.body =~ /To access Yahoo! Address Book\.\.\..*Sign in./m
|
44
|
+
raise( Blackbook::BadCredentialsError, "Must be authenticated to access contacts." )
|
45
|
+
end
|
46
|
+
form = page.forms.last
|
47
|
+
csv = agent.submit(form, form.buttons[2]) # third button is Yahoo-format CSV
|
48
|
+
|
49
|
+
contact_rows = FasterCSV.parse(csv.body)
|
50
|
+
labels = contact_rows.shift # TODO: Actually use the labels to find the indexes of the data we want
|
51
|
+
contact_rows.collect do |row|
|
52
|
+
next if !row[7].blank? && options[:username] =~ /^#{row[7]}/ # Don't collect self
|
53
|
+
{
|
54
|
+
:name => "#{row[0]} #{row[2]}".to_s,
|
55
|
+
:email => (row[4] || "#{row[7]}@yahoo.com") # email is a field in the data, but will be blank for Yahoo users so we create their email address
|
56
|
+
}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
Blackbook.register(:yahoo, self)
|
61
|
+
end
|
@@ -0,0 +1,565 @@
|
|
1
|
+
---------------------------------
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
|
6
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xml:lang="en" lang="en">
|
7
|
+
<head>
|
8
|
+
<title>Free email address from AOL Mail</title>
|
9
|
+
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8"/>
|
10
|
+
<meta name="keywords" content="AOL Mail free web reliable easy IMAP inbox email industry leading antivirus virus spam protection antispam storage pictures photo calendar address calendar personal domain name Blackberry Treo Motorola Q Outlook Thunderbird buddy list access anywhere everywhere on the go personal domain drag and drop blog integration keyword search easy to use"/>
|
11
|
+
<meta name="description" content="Get a free email address from AOL now! You no longer need to be an AOL member to take advantage of great AOL Mail features such as industry-leading spam and virus protection, anytime-access on your mobile device, flexibility to work with other email clients using IMAP and more."/>
|
12
|
+
<link rel="stylesheet" type="text/css" media="screen" href="https://s.aolcdn.com/art/registration/snslanding_css.css"/>
|
13
|
+
<script language="javascript" type="text/javascript" src="https://s.aolcdn.com/art/registration/snslanding_js.js"><!--....--></script>
|
14
|
+
<link rel="stylesheet" type="text/css" media="screen" href="https://s.aolcdn.com/art/landing_pages/snslanding10_id1686.css"/>
|
15
|
+
|
16
|
+
<LINK href="https://sns-static.aolcdn.com/sns/3.5r2/style/snsMiniStyles.css" rel="stylesheet" type="text/css">
|
17
|
+
<style type="text/css">
|
18
|
+
#sns_MainContentDiv, #sns_MainContentDiv #snsLoginRow,#sns_LoginTitleBar,.sns_noTabs, #sns_NewLoginModule, #sns_LoginContentDiv,.sns_LoginTabs .selected,#sns_LoginTitleBar { color: #000000;background-color: #FFFFFF; }
|
19
|
+
#sns_Module #sns_MainContentDiv, #sns_Footer #sPipe, .sns_HeadlineBold, #sns_MainContentDiv label, #sns_MainContentDiv .sns_FieldLabel { color: #000000 }
|
20
|
+
#sns_TitleBar { background-color: #3333CC;border:1px solid #3333CC }
|
21
|
+
#sns_Module .sLnkSm, #sns_Module .sLnkMd, #sns_Module .sLnkLg, #sns_NewLoginModule .sLnkMd, #sns_NewLoginModule a{ color: #3333CC; }
|
22
|
+
#sns_MainContentDiv .sns_Text3, #sns_MainContentDiv td.sns_Text3 { color: #3399FF }
|
23
|
+
#sns_NewLoginModule {background-color:#FFFFFF; border:1px solid #3333CC; }
|
24
|
+
</style>
|
25
|
+
</head>
|
26
|
+
<body>
|
27
|
+
<div class="port_land">
|
28
|
+
<div class="lands">
|
29
|
+
<div id="othercontent">
|
30
|
+
<div class="aol_hatcontainer">
|
31
|
+
<script type="text/javascript">
|
32
|
+
//Overwrite Hat 2.0 min-width
|
33
|
+
var _aol_hat_commonstyle_ = '#aol_hat2 {min-width:100% !important; _width:100% !important;}';
|
34
|
+
var _sns_use_ssl_ = '1';
|
35
|
+
</script>
|
36
|
+
<script type="text/javascript" src="https://secure.aolhat.com/hat2/webmail_cayman2/jswrite.js"><!--hat jswrite is being included--></script>
|
37
|
+
</div>
|
38
|
+
<div class="brand">
|
39
|
+
<h1>
|
40
|
+
<img src="https://s.aolcdn.com/art/landing_pages/cayman_branding.gif" width="169" height="45" alt="FREE AOL Webmail" title="FREE AOL Webmail" border="0"/>
|
41
|
+
</h1>
|
42
|
+
<div class="logTrouble">
|
43
|
+
<a href="http://help.channels.aol.com/topic.adp?topicId=ART_219191&ncid=AOLCMP00300000000128">Trouble Logging In?</a>
|
44
|
+
</div>
|
45
|
+
<div id="webBeacon" style="display:none;"><!--....--></div>
|
46
|
+
<script type="text/javascript">loc=document.getElementById('webBeacon');wBeacon = document.createElement("img");wBeacon.setAttribute('src', 'https://s.aolcdn.com/websuitebeacon/aol/en-us/BeaconLandingPage.html');wBeacon.style.height='1px';wBeacon.style.width='1px';loc.appendChild(wBeacon);</script>
|
47
|
+
<!--...--> </div>
|
48
|
+
</div>
|
49
|
+
<div class="landslt">
|
50
|
+
<div class="prim_promo">
|
51
|
+
<div class="contCopyTop"><!--....--></div>
|
52
|
+
<div class="contCopy">
|
53
|
+
<h2>Get your FREE email account<br/>
|
54
|
+
with unlimited storage! </h2>
|
55
|
+
<h3>Try FREE AOL Mail and we'll transfer your messages<br/>
|
56
|
+
and address book from your old email account automatically. </h3>
|
57
|
+
<h4>AOL Easy Transfer makes switching your email a snap.</h4>
|
58
|
+
<a class="buttonGet" href="https://new.aol.com/freeaolweb?promocode=824087&promocode2=806077&ncid=AOLCMP00300000000126">Get FREE AOL Mail</a>
|
59
|
+
<ul>
|
60
|
+
<li>Automatically copies your address book</li>
|
61
|
+
<li>Notifies all your friends of your new email address</li>
|
62
|
+
<li>Forwards emails sent to your old email address</li>
|
63
|
+
<li>Copies all your emails, attachments, even your folders</li>
|
64
|
+
</ul>
|
65
|
+
<a class="linkEasy" href="https://secure5.trueswitch.com/aolweb/?ncid=AOLCMP00300000000129">Transfer My Emails and Address Book Now</a>
|
66
|
+
<a class="linkLearnMore" href="http://discover.aol.com/memed/webmail/">Learn More</a>
|
67
|
+
<div class="clearme"><!--....--></div>
|
68
|
+
</div>
|
69
|
+
<div class="contCopyBot"><!--....--></div>
|
70
|
+
<div class="sellBlockLeft">
|
71
|
+
<p>Rather have a personalized email address that totally expresses who you are, like Emily@Wild4music.com?<strong>It's FREE.</strong>
|
72
|
+
<a class="sblButton" href="http://domains.aol.com?ncid=AOLCMP00300000000130">Find a Personalized Address</a>
|
73
|
+
</p>
|
74
|
+
<img src="https://s.aolcdn.com/art/landing_pages/bl_promo" width="59" height="60" alt="find a personalized address" title="find a personalized address"/>
|
75
|
+
<a class="sblLearnLink" href="http://discover.aol.com/memed/webmail/myeaddress.adp">Learn More</a>
|
76
|
+
</div>
|
77
|
+
<div class="sellBlockRight">
|
78
|
+
<h5>AIM<sup>®</sup>
|
79
|
+
. Mail. Content. All in one window - New AOL Mail! </h5>
|
80
|
+
<img src="https://s.aolcdn.com/art/landing_pages/br_promo" width="158" height="83" alt="AOL Mail screen shot" title="AOL Mail screen shot"/>
|
81
|
+
<p>View all your messages on one page - check out new AOL Mail now.</p>
|
82
|
+
<a href="http://o.aolcdn.com/cdn.webmail.aol.com/mailtour/aol/en-us/index-noNav.htm?ncid=AOLCMP00300000000131">Take the Tour</a>
|
83
|
+
</div>
|
84
|
+
</div>
|
85
|
+
</div>
|
86
|
+
<div class="landsrt">
|
87
|
+
<div class="login">
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
|
92
|
+
|
93
|
+
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
|
100
|
+
|
101
|
+
|
102
|
+
|
103
|
+
|
104
|
+
|
105
|
+
|
106
|
+
|
107
|
+
|
108
|
+
|
109
|
+
|
110
|
+
|
111
|
+
|
112
|
+
|
113
|
+
|
114
|
+
|
115
|
+
|
116
|
+
|
117
|
+
|
118
|
+
|
119
|
+
|
120
|
+
|
121
|
+
|
122
|
+
|
123
|
+
|
124
|
+
|
125
|
+
|
126
|
+
|
127
|
+
|
128
|
+
|
129
|
+
|
130
|
+
|
131
|
+
<SCRIPT LANGUAGE="JavaScript" SRC="https://sns-static.aolcdn.com/sns/3.5r2/js/mainValidations.js"></SCRIPT>
|
132
|
+
|
133
|
+
<script language="javascript" type="text/javascript">
|
134
|
+
prereqchecks('/badbrowser.psp?source=login&null');
|
135
|
+
</script>
|
136
|
+
|
137
|
+
|
138
|
+
<div id="sns_miniUiWidget" >
|
139
|
+
<div id="snsHelpBlk">
|
140
|
+
<span class="hdrText">Sign In</span>
|
141
|
+
|
142
|
+
<a id="snsHelpLnk" href="javascript:snsInfoPopUp(1,'https://my.screenname.aol.com/_cqr/help/infoPopUp.jsp?help=1')" alt="Help" tabindex="5">Help</a>
|
143
|
+
|
144
|
+
</div>
|
145
|
+
|
146
|
+
|
147
|
+
|
148
|
+
|
149
|
+
|
150
|
+
|
151
|
+
|
152
|
+
|
153
|
+
|
154
|
+
|
155
|
+
|
156
|
+
|
157
|
+
|
158
|
+
|
159
|
+
|
160
|
+
|
161
|
+
|
162
|
+
|
163
|
+
|
164
|
+
|
165
|
+
|
166
|
+
|
167
|
+
|
168
|
+
|
169
|
+
|
170
|
+
|
171
|
+
|
172
|
+
|
173
|
+
|
174
|
+
|
175
|
+
|
176
|
+
|
177
|
+
|
178
|
+
|
179
|
+
|
180
|
+
|
181
|
+
|
182
|
+
|
183
|
+
|
184
|
+
|
185
|
+
|
186
|
+
|
187
|
+
|
188
|
+
|
189
|
+
|
190
|
+
|
191
|
+
|
192
|
+
|
193
|
+
|
194
|
+
|
195
|
+
|
196
|
+
|
197
|
+
|
198
|
+
|
199
|
+
|
200
|
+
|
201
|
+
|
202
|
+
|
203
|
+
|
204
|
+
|
205
|
+
|
206
|
+
|
207
|
+
|
208
|
+
|
209
|
+
|
210
|
+
|
211
|
+
|
212
|
+
|
213
|
+
|
214
|
+
|
215
|
+
|
216
|
+
|
217
|
+
|
218
|
+
|
219
|
+
|
220
|
+
|
221
|
+
|
222
|
+
|
223
|
+
|
224
|
+
|
225
|
+
|
226
|
+
|
227
|
+
|
228
|
+
|
229
|
+
|
230
|
+
|
231
|
+
|
232
|
+
|
233
|
+
|
234
|
+
|
235
|
+
|
236
|
+
|
237
|
+
|
238
|
+
<SCRIPT type="text/JavaScript" language="JavaScript">
|
239
|
+
|
240
|
+
|
241
|
+
|
242
|
+
|
243
|
+
function validateAolTab(loginForm){
|
244
|
+
var pwderr = new Array(4);
|
245
|
+
pwderr[RetVal.EMPTY_ERR]="You must enter a value for Password.";
|
246
|
+
pwderr[RetVal.MIN_ERR]="Password you entered is too short.";
|
247
|
+
pwderr[RetVal.MAX_ERR]="Password must not be longer than 16 characters.";
|
248
|
+
pwderr[RetVal.INVALID_ERR]="Password you entered is invalid. A Valid password should contain 6-16 letters or numbers.";
|
249
|
+
var result;
|
250
|
+
var loginId = loginForm.loginId;
|
251
|
+
stripOffAOLDomains(loginId);
|
252
|
+
if((/@/).test(loginId.value)) {
|
253
|
+
var err = new Array(4);
|
254
|
+
err[RetVal.EMPTY_ERR]="You must enter a value for E-mail Address.";
|
255
|
+
err[RetVal.MIN_ERR]="E-mail Address you entered is too short.";
|
256
|
+
err[RetVal.MAX_ERR]="E-mail Address must not be longer than 97 characters.";
|
257
|
+
err[RetVal.INVALID_ERR]="E-mail Address you entered is invalid. A valid E-mail address should look like: joe@aol.com. Please be sure that the E-mail Address doesn't contain any spaces.";
|
258
|
+
}
|
259
|
+
else {
|
260
|
+
var err = new Array(5);
|
261
|
+
err[RetVal.EMPTY_ERR]="You must enter a value for Screen Name.";
|
262
|
+
err[RetVal.MIN_ERR]="ScreenName you entered is too short.";
|
263
|
+
err[RetVal.MAX_ERR]="ScreenName must not be longer than 16 characters.";
|
264
|
+
err[RetVal.INVALID_ERR]="ScreenName you entered is invalid. A valid Screen Name consists of 3-16 characters and can contain letters, numbers, spaces, and must start with a letter (e.g., johndoe123). Please re-type your Screen Name.";
|
265
|
+
err[RetVal.ICQ_INVALID_ERR]="The ICQ UIN you entered is invalid. A valid ICQ UIN consists of 5-10 digits. Please re-type your ICQ UIN.";
|
266
|
+
}
|
267
|
+
|
268
|
+
result=snsCheckSignInForm(loginForm,err,pwderr);
|
269
|
+
return result;
|
270
|
+
}
|
271
|
+
|
272
|
+
|
273
|
+
function validateIcqTab(loginForm){
|
274
|
+
var pwderr = new Array(4);
|
275
|
+
pwderr[RetVal.EMPTY_ERR]="You must enter a value for Password.";
|
276
|
+
pwderr[RetVal.MIN_ERR]="Password you entered is too short.";
|
277
|
+
pwderr[RetVal.MAX_ERR]="Password must not be longer than 16 characters.";
|
278
|
+
pwderr[RetVal.INVALID_ERR]="Password you entered is invalid. A Valid password should contain 6-16 letters or numbers.";
|
279
|
+
var result;
|
280
|
+
var loginId = loginForm.loginId;
|
281
|
+
if((/@/).test(loginId.value)) {
|
282
|
+
var err = new Array(3);
|
283
|
+
err[RetVal.EMPTY_ERR]="Please enter an ICQ UIN or ICQ email alias";
|
284
|
+
err[RetVal.MIN_ERR]="ICQ e-mail alias you entered is invalid. A valid E-mail address should look like:joe@aol.com.";
|
285
|
+
err[RetVal.MAX_ERR]="E-mail Address must not be longer than 97 characters.";
|
286
|
+
err[RetVal.INVALID_ERR]="ICQ e-mail alias you entered is invalid. A valid E-mail address should look like:joe@aol.com.";
|
287
|
+
}
|
288
|
+
else {
|
289
|
+
var err = new Array(4);
|
290
|
+
err[RetVal.EMPTY_ERR]="Please enter an ICQ UIN or ICQ email alias";
|
291
|
+
err[RetVal.MIN_ERR]="An ICQ UIN is at least 5 numeric digits ";
|
292
|
+
err[RetVal.MAX_ERR]="ICQ UIN must not be more than 10 numeric digits";
|
293
|
+
err[RetVal.INVALID_ERR]="The ICQ UIN you entered is invalid. A valid ICQ UIN consists of 5-10 digits. Please re-type your ICQ UIN.";
|
294
|
+
}
|
295
|
+
|
296
|
+
result=checkIcqForm(loginForm,err,pwderr);
|
297
|
+
return result;
|
298
|
+
}
|
299
|
+
|
300
|
+
|
301
|
+
|
302
|
+
|
303
|
+
|
304
|
+
|
305
|
+
|
306
|
+
|
307
|
+
|
308
|
+
|
309
|
+
|
310
|
+
|
311
|
+
|
312
|
+
|
313
|
+
|
314
|
+
|
315
|
+
|
316
|
+
|
317
|
+
|
318
|
+
|
319
|
+
|
320
|
+
|
321
|
+
|
322
|
+
</SCRIPT>
|
323
|
+
|
324
|
+
|
325
|
+
<div id="SLT" class="snslogintypes snslogintypes_content">
|
326
|
+
|
327
|
+
|
328
|
+
<div class="sns_noTabs"></div>
|
329
|
+
|
330
|
+
|
331
|
+
|
332
|
+
|
333
|
+
|
334
|
+
|
335
|
+
|
336
|
+
|
337
|
+
|
338
|
+
|
339
|
+
|
340
|
+
|
341
|
+
|
342
|
+
|
343
|
+
|
344
|
+
|
345
|
+
|
346
|
+
|
347
|
+
|
348
|
+
|
349
|
+
|
350
|
+
|
351
|
+
|
352
|
+
|
353
|
+
|
354
|
+
|
355
|
+
|
356
|
+
|
357
|
+
|
358
|
+
|
359
|
+
|
360
|
+
|
361
|
+
|
362
|
+
|
363
|
+
|
364
|
+
|
365
|
+
|
366
|
+
|
367
|
+
|
368
|
+
|
369
|
+
|
370
|
+
|
371
|
+
|
372
|
+
|
373
|
+
|
374
|
+
|
375
|
+
|
376
|
+
|
377
|
+
|
378
|
+
|
379
|
+
|
380
|
+
|
381
|
+
|
382
|
+
|
383
|
+
|
384
|
+
|
385
|
+
|
386
|
+
<div class="content" id="SLT.1">
|
387
|
+
<div id="sns_LoginAol">
|
388
|
+
<form name="AOLLoginForm" method="POST" action="https://my.screenname.aol.com/_cqr/login/login.psp" onsubmit="return validateAolTab(this);">
|
389
|
+
<input type="hidden" name="sitedomain" value="sns.webmail.aol.com">
|
390
|
+
<input type="hidden" name="siteId" value="">
|
391
|
+
<input type="hidden" name="lang" value="en">
|
392
|
+
<input type="hidden" name="locale" value="us">
|
393
|
+
<input type="hidden" name="authLev" value="2">
|
394
|
+
<input type="hidden" name="siteState" value="ver%3A2%7Cac%3AWS%7Cat%3ASNS%7Cld%3Awebmail.aol.com%7Cuv%3AAOL%7Clc%3Aen-us">
|
395
|
+
<input type="hidden" name="isSiteStateEncoded" value="true">
|
396
|
+
<input type="hidden" name="mcState" value="initialized">
|
397
|
+
<input type="hidden" name="uitype" value="std">
|
398
|
+
<input type="hidden" name="use_aam" value="0">
|
399
|
+
<input type="hidden" name="_sns_fg_color_" value="">
|
400
|
+
<input type="hidden" name="_sns_err_color_" value="">
|
401
|
+
<input type="hidden" name="_sns_link_color_" value="">
|
402
|
+
<input type="hidden" name="_sns_width_" value="">
|
403
|
+
<input type="hidden" name="_sns_height_" value="">
|
404
|
+
<input type="hidden" name="_sns_bg_color_" value="">
|
405
|
+
<input type="hidden" name="offerId" value="">
|
406
|
+
<input type="hidden" name="seamless" value="novl">
|
407
|
+
<input type="hidden" name="regPromoCode" value="">
|
408
|
+
<input type="hidden" name="idType" value="SN">
|
409
|
+
|
410
|
+
|
411
|
+
<input type="hidden" name="usrd" value="9604003">
|
412
|
+
|
413
|
+
|
414
|
+
|
415
|
+
|
416
|
+
|
417
|
+
|
418
|
+
|
419
|
+
|
420
|
+
|
421
|
+
|
422
|
+
|
423
|
+
<div id="snsmPswdRetry" class="snsmErrorText">
|
424
|
+
|
425
|
+
|
426
|
+
|
427
|
+
Invalid Screen Name or Password. Please try again.
|
428
|
+
|
429
|
+
|
430
|
+
</div>
|
431
|
+
|
432
|
+
|
433
|
+
|
434
|
+
|
435
|
+
|
436
|
+
|
437
|
+
|
438
|
+
|
439
|
+
<label for="lgnId1" id="lgnId1lbl">Screen Name or E-mail:</label>
|
440
|
+
|
441
|
+
|
442
|
+
|
443
|
+
<input type="text" name="loginId" maxlength="97" size="25" tabindex="1" value="mondragonmichael" id="lgnId1" class="inputBox">
|
444
|
+
|
445
|
+
|
446
|
+
|
447
|
+
|
448
|
+
|
449
|
+
|
450
|
+
<div id="snsmCreateAcctLnk"></div>
|
451
|
+
|
452
|
+
|
453
|
+
|
454
|
+
<label for="pwdId" alt="enter AOL password" id="pwdId1lbl">Password:</label>
|
455
|
+
<input type="password" name="password" maxlength="23" size="25" tabindex="2" value="" id="pwdId1" class="inputBox" alt="enter AOL password">
|
456
|
+
|
457
|
+
<a href="https://account.login.aol.com/opr/_cqr/opr/opr.psp?sitedomain=sns.webmail.aol.com&authLev=2&siteState=ver%3A2%7Cac%3AWS%7Cat%3ASNS%7Cld%3Awebmail.aol.com%7Cuv%3AAOL%7Clc%3Aen-us&lang=en&locale=us&seamless=novl" id="forgotpswdLnk" target="_top" class="snsmTinyText" tabindex="7" >Forgot Password</a>
|
458
|
+
|
459
|
+
|
460
|
+
|
461
|
+
<div id="rmbrBlk">
|
462
|
+
<input type="hidden" name="rememberMe" value="off">
|
463
|
+
</div>
|
464
|
+
|
465
|
+
|
466
|
+
<div class="alignBtnRt" id="sbmtAol">
|
467
|
+
<input type="submit" id="submitAol" value="Sign In" class="artzBtn def" tabindex="3" alt="Sign In" title="Sign In" />
|
468
|
+
</div>
|
469
|
+
|
470
|
+
|
471
|
+
</form>
|
472
|
+
</div>
|
473
|
+
</div>
|
474
|
+
|
475
|
+
|
476
|
+
|
477
|
+
|
478
|
+
|
479
|
+
|
480
|
+
|
481
|
+
|
482
|
+
|
483
|
+
|
484
|
+
|
485
|
+
|
486
|
+
|
487
|
+
<div style="display:none;">none</div>
|
488
|
+
|
489
|
+
<script type="text/Javascript">
|
490
|
+
_sns_p("SLT.1").style.display="block";
|
491
|
+
|
492
|
+
|
493
|
+
|
494
|
+
|
495
|
+
if( document.getElementById("pwdId1")){document.getElementById("pwdId1").focus();}
|
496
|
+
|
497
|
+
|
498
|
+
|
499
|
+
|
500
|
+
|
501
|
+
|
502
|
+
|
503
|
+
|
504
|
+
</script>
|
505
|
+
|
506
|
+
</div> <!-- end SLT -->
|
507
|
+
|
508
|
+
|
509
|
+
|
510
|
+
|
511
|
+
|
512
|
+
</div>
|
513
|
+
<script type="text/javascript">
|
514
|
+
<!--
|
515
|
+
var s_account="aolsnssignin,aolsvc";
|
516
|
+
//-->
|
517
|
+
</script>
|
518
|
+
<script type="text/javascript" src="https://sns-static.aolcdn.com/omni/H.8/omniunih.js"></script>
|
519
|
+
<script type="text/javascript">
|
520
|
+
<!--
|
521
|
+
s_265.linkInternalFilters="javascript:,aol.com";
|
522
|
+
s_265.server="my.screenname.aol.com";
|
523
|
+
s_265.pfxID="sso";
|
524
|
+
s_265.pageName="sso : login";
|
525
|
+
s_265.channel="us.snssignin";
|
526
|
+
s_265.prop1='ssologin';
|
527
|
+
s_265.prop12="/snsUiDriver.jsp";
|
528
|
+
s_265.prop15="bW9uZHJhZ29ubWljaGFlbA%3D%3D";
|
529
|
+
s_265.prop16="sns.webmail.aol.com";
|
530
|
+
s_265.prop17="lp";
|
531
|
+
s_265.prop18="2";
|
532
|
+
s_265.prop19="wa3";
|
533
|
+
s_265.prop20="en-us";
|
534
|
+
s_265.prop21="AOLPortal";
|
535
|
+
s_265.prop22=".aol.com";
|
536
|
+
var s_code=s_265.t();
|
537
|
+
if(s_code)document.write(s_code);
|
538
|
+
//-->
|
539
|
+
</script>
|
540
|
+
</div>
|
541
|
+
<div class="addl_promo">
|
542
|
+
<script type="text/javascript">r1=Math.round(Math.random()*1000000)//;</script>
|
543
|
+
<script type="text/javascript">document.write('<script type="text/javascript" src="https://eatps.web.aol.com:9001/open_web_adhoc?subtype=6915amp;r1='+r1+'">');document.write ('</scr'+'ipt>');</script>
|
544
|
+
</div>
|
545
|
+
</div>
|
546
|
+
</div>
|
547
|
+
<div class="footer">
|
548
|
+
<style type="text/css">#footerlinks{position:relative;display:block;font:10px arial,sans serif;color:#959494;margin:px 0px 0px 0px;}#footerlinks a, #footerlinks a:visited { color:#959494; text-decoration:none;}#footerlinks a:hover { text-decoration:underline; }</style>
|
549
|
+
<div id="footerlinks">
|
550
|
+
<a href="http://www.corp.aol.com/">AOL LLC.</a>
|
551
|
+
| <a href="http://downloads.channel.aol.com/windowsproducts">Download AOL</a>
|
552
|
+
| <a href="http://corp.aol.com/accessibility/">Accessibility Policy</a>
|
553
|
+
| <a href="http://www.aol.com/aolnetwork/terms_use.html">Terms of Use</a>
|
554
|
+
| <a href="http://www.aol.com/aolnetwork/aol_pp.html">Privacy Policy</a>
|
555
|
+
| <a href="http://www.aol.com/aolnetwork/trademarks.html">Trademarks</a>
|
556
|
+
| <a href="http://postmaster.aol.com/guidelines/bulk_email.html">Email Policy</a>
|
557
|
+
| <a href="http://advisor.aol.com/">Advertise With Us</a>
|
558
|
+
<br/>
|
559
|
+
Copyright 2007 AOL LLC. All Rights Reserved </div>
|
560
|
+
</div>
|
561
|
+
</div>
|
562
|
+
</body>
|
563
|
+
</html>
|
564
|
+
|
565
|
+
---------------------------------
|