yahoo.rb
2.92 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
require 'csv'
class Contacts
class Yahoo < Base
URL = "http://mail.yahoo.com/"
LOGIN_URL = "https://login.yahoo.com/config/login"
ADDRESS_BOOK_URL = "http://address.mail.yahoo.com/?1&VPC=import_export"
CONTACT_LIST_URL = "http://address.yahoo.com/index.php?VPC=import_export&A=B&submit[action_export_yahoo]=Export%20Now"
PROTOCOL_ERROR = "Yahoo 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 = ".tries=2&.src=ym&.md5=&.hash=&.js=&.last=&promo=&.intl=us&.bypass="
postdata += "&.partner=&.u=4eo6isd23l8r3&.v=0&.challenge=gsMsEcoZP7km3N3NeI4mX"
postdata += "kGB7zMV&.yplus=&.emailCode=&pkg=&stepid=&.ev=&hasMsgr=1&.chkP=Y&."
postdata += "done=#{CGI.escape(URL)}&login=#{CGI.escape(login)}&passwd=#{CGI.escape(password)}"
data, resp, cookies, forward = post(LOGIN_URL, postdata)
if data.index("Invalid ID or password") || data.index("This ID is not yet taken")
raise AuthenticationError, "Username and password do not match"
elsif data.index("Sign in") && data.index("to Yahoo!")
raise AuthenticationError, "Required field must not be blank"
elsif !data.match(/uncompressed\/chunked/)
raise ConnectionError, PROTOCOL_ERROR
elsif cookies == ""
raise ConnectionError, PROTOCOL_ERROR
end
data, resp, cookies, forward = get(forward, cookies, LOGIN_URL)
if resp.code_type != Net::HTTPOK
raise ConnectionError, PROTOCOL_ERROR
end
@cookies = cookies
end
def contacts
return @contacts if @contacts
if connected?
# first, get the addressbook site with the new crumb parameter
url = URI.parse(address_book_url)
http = open_http(url)
resp, data = http.get("#{url.path}?#{url.query}",
"Cookie" => @cookies
)
if resp.code_type != Net::HTTPOK
raise ConnectionError, self.class.const_get(:PROTOCOL_ERROR)
end
crumb = data.to_s[/id="crumb2" value="(.*?)"/][19...-1]
# now proceed with the new ".crumb" parameter to get the csv data
url = URI.parse("#{contact_list_url}&.crumb=#{crumb}")
http = open_http(url)
resp, data = http.get("#{url.path}?#{url.query}",
"Cookie" => @cookies
)
if resp.code_type != Net::HTTPOK
raise ConnectionError, self.class.const_get(:PROTOCOL_ERROR)
end
parse data
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[2]].delete_if{|i|i.empty?}.join(" "), person[4]] unless person[4].empty?
end.compact
end
end
TYPES[:yahoo] = Yahoo
end