blackbook 1.0.0
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/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
|
+
---------------------------------
|