forked from cardmagic/contacts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
aol.rb
154 lines (130 loc) · 5.58 KB
/
aol.rb
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
148
149
150
151
152
153
154
class Contacts
require 'hpricot'
require 'csv'
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
if login.strip =~ /^(.+)@aol\.com$/ # strip off the @aol.com for AOL logins
login = $1
end
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 = Hpricot(data)
(doc/:input).each do |input|
postdata["usrd"] = input.attributes["value"] if input.attributes["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, h_to_query_string(postdata), 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 Username or Password. Please try again.")
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 = Hpricot(data)
(doc/:input).each do |input|
postdata["user"] = input.attributes["value"] if input.attributes["name"] == "user"
end
data, resp, cookies, forward, old_url = get(CONTACT_LIST_CSV_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 data.include?("error.gif")
raise AuthenticationError, "Account invalid"
end
parse data
end
end
private
def parse(data, options={})
data = CSV::Reader.parse(data)
col_names = data.shift
@contacts = data.map do |person|
["#{person[0]} #{person[1]}", person[4]] if person[4] && !person[4].empty?
end.compact
end
def h_to_query_string(hash)
u = ERB::Util.method(:u)
hash.map { |k, v|
u.call(k) + "=" + u.call(v)
}.join("&")
end
end
TYPES[:aol] = Aol
end