aol.rb
5.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
class Hash
def to_query_string
u = ERB::Util.method(:u)
map { |k, v|
u.call(k) + "=" + u.call(v)
}.join("&")
end
end
class Contacts
class Aol < Base
URL = "http://www.aol.com/"
LOGIN_URL = "https://my.screenname.aol.com/_cqr/login/login.psp"
LOGIN_REFERER_URL = "http://webmail.aol.com/"
LOGIN_REFERER_PATH = "sitedomain=sns.webmail.aol.com&lang=en&locale=us&authLev=0&uitype=mini&loginId=&redirType=js&xchk=false"
AOL_NUM = "29970-343" # this seems to change each time they change the protocol
CONTACT_LIST_URL = "http://webmail.aol.com/#{AOL_NUM}/aim-2/en-us/Lite/ContactList.aspx?folder=Inbox&showUserFolders=False"
CONTACT_LIST_CSV_URL = "http://webmail.aol.com/#{AOL_NUM}/aim-2/en-us/Lite/ABExport.aspx?command=all"
PROTOCOL_ERROR = "AOL has changed its protocols, please upgrade this library first. If that does not work, dive into the code and submit a patch at http://github.com/cardmagic/contacts"
def real_connect
postdata = {
"loginId" => login,
"password" => password,
"rememberMe" => "on",
"_sns_fg_color_" => "",
"_sns_err_color_" => "",
"_sns_link_color_" => "",
"_sns_width_" => "",
"_sns_height_" => "",
"offerId" => "mail-second-en-us",
"_sns_bg_color_" => "",
"sitedomain" => "sns.webmail.aol.com",
"regPromoCode" => "",
"mcState" => "initialized",
"uitype" => "std",
"siteId" => "",
"lang" => "en",
"locale" => "us",
"authLev" => "0",
"siteState" => "",
"isSiteStateEncoded" => "false",
"use_aam" => "0",
"seamless" => "novl",
"aolsubmit" => CGI.escape("Sign In"),
"idType" => "SN",
"usrd" => "",
"doSSL" => "",
"redirType" => "",
"xchk" => "false"
}
# Get this cookie and stick it in the form to confirm to Aol that your cookies work
data, resp, cookies, forward = get(URL)
postdata["stips"] = cookie_hash_from_string(cookies)["stips"]
postdata["tst"] = cookie_hash_from_string(cookies)["tst"]
data, resp, cookies, forward, old_url = get(LOGIN_REFERER_URL, cookies) + [URL]
until forward.nil?
data, resp, cookies, forward, old_url = get(forward, cookies, old_url) + [forward]
end
data, resp, cookies, forward, old_url = get("#{LOGIN_URL}?#{LOGIN_REFERER_PATH}", cookies) + [LOGIN_REFERER_URL]
until forward.nil?
data, resp, cookies, forward, old_url = get(forward, cookies, old_url) + [forward]
end
doc = Nokogiri::HTML.fragment data
doc.css('input').each do |input|
postdata["usrd"] = input["value"] if input["name"] == "usrd"
end
# parse data for <input name="usrd" value="2726212" type="hidden"> and add it to the postdata
postdata["SNS_SC"] = cookie_hash_from_string(cookies)["SNS_SC"]
postdata["SNS_LDC"] = cookie_hash_from_string(cookies)["SNS_LDC"]
postdata["LTState"] = cookie_hash_from_string(cookies)["LTState"]
# raise data.inspect
data, resp, cookies, forward, old_url = post(LOGIN_URL, postdata.to_query_string, cookies, LOGIN_REFERER_URL) + [LOGIN_REFERER_URL]
until forward.nil?
data, resp, cookies, forward, old_url = get(forward, cookies, old_url) + [forward]
end
if data.index("Invalid Screen Name or Password.")
raise AuthenticationError, "Username and password do not match"
elsif data.index("Required field must not be blank")
raise AuthenticationError, "Login and password must not be blank"
elsif data.index("errormsg_0_logincaptcha")
raise AuthenticationError, "Captcha error"
elsif data.index("Invalid request")
raise ConnectionError, PROTOCOL_ERROR
elsif cookies == ""
raise ConnectionError, PROTOCOL_ERROR
end
@cookies = cookies
end
def contacts
postdata = {
"file" => 'contacts',
"fileType" => 'csv'
}
return @contacts if @contacts
if connected?
data, resp, cookies, forward, old_url = get(CONTACT_LIST_URL, @cookies, CONTACT_LIST_URL) + [CONTACT_LIST_URL]
until forward.nil?
data, resp, cookies, forward, old_url = get(forward, cookies, old_url) + [forward]
end
if resp.code_type != Net::HTTPOK
raise ConnectionError, self.class.const_get(:PROTOCOL_ERROR)
end
# parse data and grab <input name="user" value="8QzMPIAKs2" type="hidden">
doc = Nokogiri::HTML.fragment data
doc.css('input').each do |input|
postdata["user"] = input["value"] if input["name"] == "user"
end
data, resp, cookies, forward, old_url = get(CONTACT_LIST_CSV_URL, @cookies, CONTACT_LIST_URL) + [CONTACT_LIST_URL]
if forward.nil?
parse data
else
raise AuthenticationError, "Account cancelled"
end
end
end
private
def parse(data, options={})
data = CSV.parse(data)
col_names = data.shift
@contacts = data.map do |person|
["#{person[0]} #{person[1]}", person[4]] unless person[4].empty?
end.compact
end
end
TYPES[:aol] = Aol
end