contacts_cn 1.2.6 → 1.2.7

Sign up to get free protection for your applications and to get access to all the features.
data/lib/contacts/aol.rb CHANGED
@@ -7,11 +7,11 @@ class Contacts
7
7
  LOGIN_REFERER_URL = "http://webmail.aol.com/"
8
8
  LOGIN_REFERER_PATH = "sitedomain=sns.webmail.aol.com&lang=en&locale=us&authLev=0&uitype=mini&loginId=&redirType=js&xchk=false"
9
9
  AOL_NUM = "29970-343" # this seems to change each time they change the protocol
10
-
10
+
11
11
  CONTACT_LIST_URL = "http://webmail.aol.com/#{AOL_NUM}/aim-2/en-us/Lite/ContactList.aspx?folder=Inbox&showUserFolders=False"
12
12
  CONTACT_LIST_CSV_URL = "http://webmail.aol.com/#{AOL_NUM}/aim-2/en-us/Lite/ABExport.aspx?command=all"
13
13
  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"
14
-
14
+
15
15
  def real_connect
16
16
  if login.strip =~ /^(.+)@aol\.com$/ # strip off the @aol.com for AOL logins
17
17
  login = $1
@@ -47,39 +47,39 @@ class Contacts
47
47
  "redirType" => "",
48
48
  "xchk" => "false"
49
49
  }
50
-
50
+
51
51
  # Get this cookie and stick it in the form to confirm to Aol that your cookies work
52
52
  data, resp, cookies, forward = get(URL)
53
53
  postdata["stips"] = cookie_hash_from_string(cookies)["stips"]
54
54
  postdata["tst"] = cookie_hash_from_string(cookies)["tst"]
55
-
55
+
56
56
  data, resp, cookies, forward, old_url = get(LOGIN_REFERER_URL, cookies) + [URL]
57
57
  until forward.nil?
58
58
  data, resp, cookies, forward, old_url = get(forward, cookies, old_url) + [forward]
59
59
  end
60
-
60
+
61
61
  data, resp, cookies, forward, old_url = get("#{LOGIN_URL}?#{LOGIN_REFERER_PATH}", cookies) + [LOGIN_REFERER_URL]
62
62
  until forward.nil?
63
63
  data, resp, cookies, forward, old_url = get(forward, cookies, old_url) + [forward]
64
64
  end
65
-
65
+
66
66
  doc = Hpricot(data)
67
67
  (doc/:input).each do |input|
68
68
  postdata["usrd"] = input.attributes["value"] if input.attributes["name"] == "usrd"
69
69
  end
70
70
  # parse data for <input name="usrd" value="2726212" type="hidden"> and add it to the postdata
71
-
71
+
72
72
  postdata["SNS_SC"] = cookie_hash_from_string(cookies)["SNS_SC"]
73
73
  postdata["SNS_LDC"] = cookie_hash_from_string(cookies)["SNS_LDC"]
74
74
  postdata["LTState"] = cookie_hash_from_string(cookies)["LTState"]
75
75
  # raise data.inspect
76
-
76
+
77
77
  data, resp, cookies, forward, old_url = post(LOGIN_URL, h_to_query_string(postdata), cookies, LOGIN_REFERER_URL) + [LOGIN_REFERER_URL]
78
-
78
+
79
79
  until forward.nil?
80
80
  data, resp, cookies, forward, old_url = get(forward, cookies, old_url) + [forward]
81
81
  end
82
-
82
+
83
83
  if data.index("Invalid Username or Password. Please try again.")
84
84
  raise AuthenticationError, "Username and password do not match"
85
85
  elsif data.index("Required field must not be blank")
@@ -91,57 +91,57 @@ class Contacts
91
91
  elsif cookies == ""
92
92
  raise ConnectionError, PROTOCOL_ERROR
93
93
  end
94
-
94
+
95
95
  @cookies = cookies
96
96
  end
97
-
97
+
98
98
  def contacts
99
99
  postdata = {
100
100
  "file" => 'contacts',
101
101
  "fileType" => 'csv'
102
102
  }
103
-
103
+
104
104
  return @contacts if @contacts
105
105
  if connected?
106
106
  data, resp, cookies, forward, old_url = get(CONTACT_LIST_URL, @cookies, CONTACT_LIST_URL) + [CONTACT_LIST_URL]
107
-
107
+
108
108
  until forward.nil?
109
109
  data, resp, cookies, forward, old_url = get(forward, cookies, old_url) + [forward]
110
110
  end
111
-
111
+
112
112
  if resp.code_type != Net::HTTPOK
113
113
  raise ConnectionError, self.class.const_get(:PROTOCOL_ERROR)
114
114
  end
115
-
115
+
116
116
  # parse data and grab <input name="user" value="8QzMPIAKs2" type="hidden">
117
117
  doc = Hpricot(data)
118
118
  (doc/:input).each do |input|
119
119
  postdata["user"] = input.attributes["value"] if input.attributes["name"] == "user"
120
120
  end
121
-
121
+
122
122
  data, resp, cookies, forward, old_url = get(CONTACT_LIST_CSV_URL, @cookies, CONTACT_LIST_URL) + [CONTACT_LIST_URL]
123
-
123
+
124
124
  until forward.nil?
125
125
  data, resp, cookies, forward, old_url = get(forward, cookies, old_url) + [forward]
126
126
  end
127
-
127
+
128
128
  if data.include?("error.gif")
129
129
  raise AuthenticationError, "Account invalid"
130
130
  end
131
-
131
+
132
132
  parse data
133
133
  end
134
134
  end
135
- private
136
-
135
+ private
136
+
137
137
  def parse(data, options={})
138
138
  data = CSV::Reader.parse(data)
139
139
  col_names = data.shift
140
140
  @contacts = data.map do |person|
141
141
  ["#{person[0]} #{person[1]}", person[4]] if person[4] && !person[4].empty?
142
142
  end.compact
143
- end
144
-
143
+ end
144
+
145
145
  def h_to_query_string(hash)
146
146
  u = ERB::Util.method(:u)
147
147
  hash.map { |k, v|
@@ -149,6 +149,6 @@ class Contacts
149
149
  }.join("&")
150
150
  end
151
151
  end
152
-
152
+
153
153
  TYPES[:aol] = Aol
154
- end
154
+ end
data/lib/contacts/base.rb CHANGED
@@ -9,7 +9,7 @@ require "erb"
9
9
 
10
10
  class Contacts
11
11
  TYPES = {}
12
- VERSION = "1.2.6"
12
+ VERSION = "1.2.7"
13
13
 
14
14
  class Base
15
15
  def initialize(login, password, options={})
@@ -36,7 +36,7 @@ class Contacts
36
36
  url = URI.parse(contact_list_url)
37
37
  http = open_http(url)
38
38
  resp, data = http.get("#{url.path}?#{url.query}",
39
- "Cookie" => @cookies
39
+ "Cookie" => @cookies
40
40
  )
41
41
 
42
42
  if resp.code_type != Net::HTTPOK
@@ -74,7 +74,7 @@ class Contacts
74
74
  @password
75
75
  end
76
76
 
77
- private
77
+ private
78
78
 
79
79
  def domain
80
80
  @d ||= self.class.const_get(:DOMAIN) rescue nil
@@ -142,19 +142,19 @@ class Contacts
142
142
  url = URI.parse(url)
143
143
  http = open_http(url)
144
144
  resp, data = http.post(url.path, postdata,
145
- "User-Agent" => "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0",
146
- "Accept-Encoding" => "gzip",
147
- "Cookie" => cookies,
148
- "Referer" => referer,
149
- "Content-Type" => 'application/x-www-form-urlencoded'
145
+ "User-Agent" => "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0",
146
+ "Accept-Encoding" => "gzip",
147
+ "Cookie" => cookies,
148
+ "Referer" => referer,
149
+ "Content-Type" => 'application/x-www-form-urlencoded'
150
150
  )
151
151
  data = uncompress(resp, data)
152
152
  cookies = parse_cookies(resp.response['set-cookie'], cookies)
153
153
  forward = resp.response['Location']
154
154
  forward ||= (data =~ /<meta.*?url='([^']+)'/ ? CGI.unescapeHTML($1) : nil)
155
- if (not forward.nil?) && URI.parse(forward).host.nil?
156
- forward = url.scheme.to_s + "://" + url.host.to_s + forward
157
- end
155
+ if (not forward.nil?) && URI.parse(forward).host.nil?
156
+ forward = url.scheme.to_s + "://" + url.host.to_s + forward
157
+ end
158
158
  return data, resp, cookies, forward
159
159
  end
160
160
 
@@ -162,17 +162,17 @@ class Contacts
162
162
  url = URI.parse(url)
163
163
  http = open_http(url)
164
164
  resp, data = http.get("#{url.path}?#{url.query}",
165
- "User-Agent" => "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0",
166
- "Accept-Encoding" => "gzip",
167
- "Cookie" => cookies,
168
- "Referer" => referer
165
+ "User-Agent" => "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0",
166
+ "Accept-Encoding" => "gzip",
167
+ "Cookie" => cookies,
168
+ "Referer" => referer
169
169
  )
170
170
  data = uncompress(resp, data)
171
171
  cookies = parse_cookies(resp.response['set-cookie'], cookies)
172
172
  forward = resp.response['Location']
173
- if (not forward.nil?) && URI.parse(forward).host.nil?
174
- forward = url.scheme.to_s + "://" + url.host.to_s + forward
175
- end
173
+ if (not forward.nil?) && URI.parse(forward).host.nil?
174
+ forward = url.scheme.to_s + "://" + url.host.to_s + forward
175
+ end
176
176
  return data, resp, cookies, forward
177
177
  end
178
178
 
@@ -183,8 +183,8 @@ class Contacts
183
183
  data = gz.read
184
184
  gz.close
185
185
  resp.response['content-encoding'] = nil
186
- # FIXME: Not sure what Hotmail was feeding me with their 'deflate',
187
- # but the headers definitely were not right
186
+ # FIXME: Not sure what Hotmail was feeding me with their 'deflate',
187
+ # but the headers definitely were not right
188
188
  when 'deflate'
189
189
  data = Zlib::Inflate.inflate(data)
190
190
  resp.response['content-encoding'] = nil
@@ -2,20 +2,20 @@ require 'gdata'
2
2
 
3
3
  class Contacts
4
4
  class Gmail < Base
5
-
5
+
6
6
  CONTACTS_SCOPE = 'http://www.google.com/m8/feeds/'
7
7
  CONTACTS_FEED = CONTACTS_SCOPE + 'contacts/default/full/?max-results=1000'
8
-
8
+
9
9
  def contacts
10
10
  return @contacts if @contacts
11
11
  end
12
-
12
+
13
13
  def real_connect
14
14
  @client = GData::Client::Contacts.new
15
15
  @client.clientlogin(@login, @password, @captcha_token, @captcha_response)
16
-
16
+
17
17
  feed = @client.get(CONTACTS_FEED).to_xml
18
-
18
+
19
19
  @contacts = feed.elements.to_a('entry').collect do |entry|
20
20
  title, email = entry.elements['title'].text, nil
21
21
  entry.elements.each('gd:email') do |e|
@@ -27,9 +27,9 @@ class Contacts
27
27
  rescue GData::Client::AuthorizationError => e
28
28
  raise AuthenticationError, "Username or password are incorrect"
29
29
  end
30
-
30
+
31
31
  private
32
-
32
+
33
33
  TYPES[:gmail] = Gmail
34
34
  end
35
- end
35
+ end
@@ -79,7 +79,7 @@ class Contacts
79
79
  email_match_text_end = Regexp.escape("&amp;")
80
80
 
81
81
  raw_html = resp.body.split("
82
- ").grep(/(?:e|dn)lk[0-9]+/)
82
+ ").grep(/(?:e|dn)lk[0-9]+/)
83
83
  raw_html.inject(-1) do |memo, row|
84
84
  c_info = row.match(/(e|dn)lk([0-9])+/)
85
85
 
@@ -88,10 +88,10 @@ class Contacts
88
88
 
89
89
  # Grab info
90
90
  case c_info[1]
91
- when "e" # Email
92
- build_contacts.last[1] = row.match(/#{email_match_text_beginning}(.*)#{email_match_text_end}/)[1]
93
- when "dn" # Name
94
- build_contacts.last[0] = row.match(/<a[^>]*>(.+)<\/a>/)[1]
91
+ when "e" # Email
92
+ build_contacts.last[1] = row.match(/#{email_match_text_beginning}(.*)#{email_match_text_end}/)[1]
93
+ when "dn" # Name
94
+ build_contacts.last[0] = row.match(/<a[^>]*>(.+)<\/a>/)[1]
95
95
  end
96
96
 
97
97
  # Set memo to contact id
@@ -5,7 +5,7 @@ end
5
5
  class Contacts
6
6
  def self.parse_json( string )
7
7
  if Object.const_defined?('ActiveSupport') and
8
- ActiveSupport.const_defined?('JSON')
8
+ ActiveSupport.const_defined?('JSON')
9
9
  ActiveSupport::JSON.decode( string )
10
10
  elsif Object.const_defined?('JSON')
11
11
  JSON.parse( string )
@@ -1,116 +1,116 @@
1
1
  class Contacts
2
2
  class NetEase < Base
3
- URL = "http://www.163.com"
3
+ URL = "http://www.163.com"
4
4
  LOGIN_URL = "https://reg.163.com/logins.jsp"
5
5
  LoginData = {
6
- :url2 => {
7
- :wy163 => 'http://mail.163.com/errorpage/err_163.htm',
8
- :wy126 => 'http://mail.126.com/errorpage/err_126.htm',
9
- :yeah => 'http://mail.yeah.net/errorpage/err_yeah.htm'
10
- },
11
- :url => {
12
- :wy163 => 'http://entry.mail.163.com/coremail/fcg/ntesdoor2?lightweight=1&verifycookie=1&language=-1&style=-1&username=%s',
13
- :wy126 => 'http://entry.mail.126.com/cgi/ntesdoor?hid=10010102&lightweight=1&verifycookie=1&language=0&style=-1&username=%s',
14
- :yeah => 'http://entry.mail.yeah.net/cgi/ntesdoor?lightweight=1&verifycookie=1&style=-1&username=%s'
15
- },
16
- :product => {
17
- :wy163 => 'mail163',
18
- :wy126 => 'mail126',
19
- :yeah => 'mailyeah'
20
- }
6
+ :url2 => {
7
+ :wy163 => 'http://mail.163.com/errorpage/err_163.htm',
8
+ :wy126 => 'http://mail.126.com/errorpage/err_126.htm',
9
+ :yeah => 'http://mail.yeah.net/errorpage/err_yeah.htm'
10
+ },
11
+ :url => {
12
+ :wy163 => 'http://entry.mail.163.com/coremail/fcg/ntesdoor2?lightweight=1&verifycookie=1&language=-1&style=-1&username=%s',
13
+ :wy126 => 'http://entry.mail.126.com/cgi/ntesdoor?hid=10010102&lightweight=1&verifycookie=1&language=0&style=-1&username=%s',
14
+ :yeah => 'http://entry.mail.yeah.net/cgi/ntesdoor?lightweight=1&verifycookie=1&style=-1&username=%s'
15
+ },
16
+ :product => {
17
+ :wy163 => 'mail163',
18
+ :wy126 => 'mail126',
19
+ :yeah => 'mailyeah'
20
+ }
21
21
  }
22
22
  ENTER_MAIL_URL = {
23
- :wy163 => "http://entry.mail.163.com/coremail/fcg/ntesdoor2?lightweight=1&verifycookie=1&language=-1&style=-1&username=%s",
24
- :wy126 => "http://entry.mail.126.com/cgi/ntesdoor?hid=10010102&lightweight=1&verifycookie=1&language=0&style=-1&username=%s",
25
- :yeah => "http://entry.mail.yeah.net/cgi/ntesdoor?lightweight=1&verifycookie=1&style=-1&username=%s"
23
+ :wy163 => "http://entry.mail.163.com/coremail/fcg/ntesdoor2?lightweight=1&verifycookie=1&language=-1&style=-1&username=%s",
24
+ :wy126 => "http://entry.mail.126.com/cgi/ntesdoor?hid=10010102&lightweight=1&verifycookie=1&language=0&style=-1&username=%s",
25
+ :yeah => "http://entry.mail.yeah.net/cgi/ntesdoor?lightweight=1&verifycookie=1&style=-1&username=%s"
26
26
  }
27
27
 
28
- CONTACT_LIST_URL = "%ss?sid=%s&func=global:sequential"
29
- PROTOCOL_ERROR = "netease has changed its protocols, please upgrade this library first. you can also contact kamechb@gmail.com"
28
+ CONTACT_LIST_URL = "%ss?sid=%s&func=global:sequential"
29
+ PROTOCOL_ERROR = "netease has changed its protocols, please upgrade this library first. you can also contact kamechb@gmail.com"
30
30
 
31
31
  def initialize(login, password, options={})
32
- @mail_type = get_mail_type(login)
33
- super(login,password,options)
32
+ @mail_type = get_mail_type(login)
33
+ super(login,password,options)
34
34
  end
35
35
 
36
36
  def real_connect
37
- login_for_cookies
38
- enter_mail_server
37
+ login_for_cookies
38
+ enter_mail_server
39
39
  end
40
40
 
41
41
  def contacts
42
- return @contacts if @contacts
42
+ return @contacts if @contacts
43
43
  if connected?
44
- url = URI.parse(CONTACT_LIST_URL % [@mail_server,@sid])
45
- http = open_http(url)
46
- postdata = '<?xml version="1.0"?><object><array name="items"><object><string name="func">pab:searchContacts</string><object name="var"><array name="order"><object><string name="field">FN</string><boolean name="ignoreCase">true</boolean></object></array></object></object><object><string name="func">user:getSignatures</string></object><object><string name="func">pab:getAllGroups</string></object></array></object>'
47
- set_header = {"Cookie" => @cookies,'Accept' => 'text/javascript','Content-Type' => 'application/xml; charset=UTF-8'}
48
- resp, data = http.post("#{url.path}?#{url.query}",postdata,set_header)
49
- if resp.code_type != Net::HTTPOK
44
+ url = URI.parse(CONTACT_LIST_URL % [@mail_server,@sid])
45
+ http = open_http(url)
46
+ postdata = '<?xml version="1.0"?><object><array name="items"><object><string name="func">pab:searchContacts</string><object name="var"><array name="order"><object><string name="field">FN</string><boolean name="ignoreCase">true</boolean></object></array></object></object><object><string name="func">user:getSignatures</string></object><object><string name="func">pab:getAllGroups</string></object></array></object>'
47
+ set_header = {"Cookie" => @cookies,'Accept' => 'text/javascript','Content-Type' => 'application/xml; charset=UTF-8'}
48
+ resp, data = http.post("#{url.path}?#{url.query}",postdata,set_header)
49
+ if resp.code_type != Net::HTTPOK
50
50
  raise ConnectionError, self.class.const_get(:PROTOCOL_ERROR)
51
51
  end
52
- parse(data)
52
+ parse(data)
53
53
  end
54
54
  end
55
55
 
56
56
  private
57
57
 
58
58
  def get_mail_type(username)
59
- if username.include?("@126.com")
60
- :wy126
61
- elsif username.include?("@163.com")
62
- :wy163
63
- elsif username.include?("@yeah.net")
64
- :yeah
65
- else
66
- raise MailServerError, "there are only three mail servers that 126.com, 163.com and yeah.net. please add domain after username"
67
- end
59
+ if username.include?("@126.com")
60
+ :wy126
61
+ elsif username.include?("@163.com")
62
+ :wy163
63
+ elsif username.include?("@yeah.net")
64
+ :yeah
65
+ else
66
+ raise MailServerError, "there are only three mail servers that 126.com, 163.com and yeah.net. please add domain after username"
67
+ end
68
68
  end
69
69
 
70
70
  def parse(data)
71
- json_data = Contacts.parse_json(data)
72
- json_data['var'][0]['var'].map{|contactor|
73
- [contactor['FN'],contactor['EMAIL;PREF']]
74
- }
71
+ json_data = Contacts.parse_json(data)
72
+ json_data['var'][0]['var'].map{|contactor|
73
+ [contactor['FN'],contactor['EMAIL;PREF']]
74
+ }
75
75
  end
76
76
 
77
77
  def login_for_cookies
78
- data = {
79
- :type => '1',
80
- :url => LoginData[:url][@mail_type],
81
- :username => @login,
82
- :password => @password,
83
- :selType => '-1',
84
- :remUser => '1',
85
- :secure => 'on',
86
- :verifycookie => '1',
87
- :style => '-1',
88
- :product => LoginData[:product][@mail_type],
89
- :savelogin => '',
90
- :url2 => LoginData[:url2][@mail_type]
78
+ data = {
79
+ :type => '1',
80
+ :url => LoginData[:url][@mail_type],
81
+ :username => @login,
82
+ :password => @password,
83
+ :selType => '-1',
84
+ :remUser => '1',
85
+ :secure => 'on',
86
+ :verifycookie => '1',
87
+ :style => '-1',
88
+ :product => LoginData[:product][@mail_type],
89
+ :savelogin => '',
90
+ :url2 => LoginData[:url2][@mail_type]
91
91
  }
92
92
  postdata = data.to_query_string
93
93
  #login and get cookie
94
94
  data, resp, cookies, forward = post(LOGIN_URL,postdata)
95
95
  @cookies = cookies
96
96
  if data.index(LoginData[:url2][@mail_type])
97
- raise AuthenticationError, "Username or password error"
97
+ raise AuthenticationError, "Username or password error"
98
98
  end
99
99
  end
100
100
 
101
101
  def enter_mail_server
102
- #get mail server and sid
103
- enter_mail_url = ENTER_MAIL_URL[@mail_type] % @login
104
- data, resp, cookies, forward = get(enter_mail_url,@cookies)
105
- location = resp['Location']
106
- data_reg = /<a.*?(http.*?)main.jsp\?sid=(.*?)\">/
107
- location_reg = /(http.*?)main.jsp\?sid=(.*)/
108
- unless data.match(data_reg) || location.match(location_reg)
109
- raise ConnectionError, self.class.const_get(:PROTOCOL_ERROR)
110
- end
111
- @cookies = cookies
112
- @mail_server = $1
113
- @sid = $2
102
+ #get mail server and sid
103
+ enter_mail_url = ENTER_MAIL_URL[@mail_type] % @login
104
+ data, resp, cookies, forward = get(enter_mail_url,@cookies)
105
+ location = resp['Location']
106
+ data_reg = /<a.*?(http.*?)main.jsp\?sid=(.*?)\">/
107
+ location_reg = /(http.*?)main.jsp\?sid=(.*)/
108
+ unless data.match(data_reg) || location.match(location_reg)
109
+ raise ConnectionError, self.class.const_get(:PROTOCOL_ERROR)
110
+ end
111
+ @cookies = cookies
112
+ @mail_server = $1
113
+ @sid = $2
114
114
  end
115
115
  TYPES[:net_ease] = NetEase
116
116
  end
@@ -7,28 +7,28 @@ class Contacts
7
7
  ADDRESS_BOOK_URL = "http://www.plaxo.com/po3/?module=ab&operation=viewFull&mode=normal"
8
8
  CONTACT_LIST_URL = "http://www.plaxo.com/axis/soap/contact?_action=getContacts&_format=xml"
9
9
  PROTOCOL_ERROR = "Plaxo 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"
10
-
10
+
11
11
  def real_connect
12
-
12
+
13
13
  end # real_connect
14
-
14
+
15
15
  def contacts
16
16
  getdata = "&authInfo.authByEmail.email=%s" % CGI.escape(login)
17
17
  getdata += "&authInfo.authByEmail.password=%s" % CGI.escape(password)
18
18
  data, resp, cookies, forward = get(CONTACT_LIST_URL + getdata)
19
-
19
+
20
20
  if resp.code_type != Net::HTTPOK
21
21
  raise ConnectionError, PROTOCOL_ERROR
22
22
  end
23
-
23
+
24
24
  parse data
25
25
  end # contacts
26
-
27
- private
26
+
27
+ private
28
28
  def parse(data, options={})
29
29
  doc = REXML::Document.new(data)
30
30
  code = doc.elements['//response/code'].text
31
-
31
+
32
32
  if code == '401'
33
33
  raise AuthenticationError, "Username and password do not match"
34
34
  elsif code == '200'
@@ -50,13 +50,13 @@ class Contacts
50
50
  else
51
51
  raise ConnectionError, PROTOCOL_ERROR
52
52
  end
53
-
53
+
54
54
  end # parse
55
55
 
56
56
  end # Plaxo
57
-
57
+
58
58
  TYPES[:plaxo] = Plaxo
59
-
59
+
60
60
  end # Contacts
61
61
 
62
62
 
@@ -96,7 +96,7 @@ Success
96
96
  <message>OK</message>
97
97
  <userId>77311236242</userId>
98
98
  </response>
99
-
99
+
100
100
  <contacts>
101
101
 
102
102
  <contact>
@@ -109,7 +109,7 @@ Success
109
109
  <email1>joeblow1@mailinator.com</email1>
110
110
  <folderId>5291351</folderId>
111
111
  </contact>
112
-
112
+
113
113
  <contact>
114
114
  <itemId>61313159</itemId>
115
115
  <displayName>Joe Blow2</displayName>
@@ -120,11 +120,11 @@ Success
120
120
  <email1>joeblow2@mailinator.com</email1>
121
121
  <folderId>5291351</folderId>
122
122
  </contact>
123
-
123
+
124
124
  </contacts>
125
-
125
+
126
126
  <totalCount>2</totalCount>
127
127
  <editCounter>3</editCounter>
128
-
128
+
129
129
  </ns1:GetContactsResponse>
130
- =end
130
+ =end
data/lib/contacts/sina.rb CHANGED
@@ -1,35 +1,35 @@
1
1
  class Contacts
2
2
  class Sina < Base
3
- URL = "http://mail.sina.com.cn"
3
+ URL = "http://mail.sina.com.cn"
4
4
  LOGIN_URL = {
5
- :sina_cn => "https://mail.sina.com.cn/cgi-bin/cnlogin.php",
6
- :sina_com => "https://mail.sina.com.cn/cgi-bin/login.php"
5
+ :sina_cn => "https://mail.sina.com.cn/cgi-bin/cnlogin.php",
6
+ :sina_com => "https://mail.sina.com.cn/cgi-bin/login.php"
7
7
  }
8
- LOGIN_COOKIE = {
9
- :sina_cn => "sina_cn_mail_id=nonobo_t; sina_cn_mail_recid=true",
10
- :sina_com => "sina_free_mail_id=fangs2; sina_free_mail_recid=true; sina_free_mail_ltype=uid; sina_vip_mail_recid=false"
11
- }
12
- DOMAIN = {
13
- :sina_cn => 'sina.cn',
14
- :sina_com => 'sina.com'
15
- }
16
- PROTOCOL_ERROR = "sina has changed its protocols, please upgrade this library first. you can also contact kamechb@gmail.com"
8
+ LOGIN_COOKIE = {
9
+ :sina_cn => "sina_cn_mail_id=nonobo_t; sina_cn_mail_recid=true",
10
+ :sina_com => "sina_free_mail_id=fangs2; sina_free_mail_recid=true; sina_free_mail_ltype=uid; sina_vip_mail_recid=false"
11
+ }
12
+ DOMAIN = {
13
+ :sina_cn => 'sina.cn',
14
+ :sina_com => 'sina.com'
15
+ }
16
+ PROTOCOL_ERROR = "sina has changed its protocols, please upgrade this library first. you can also contact kamechb@gmail.com"
17
17
 
18
18
  def initialize(login, password, options={})
19
- @mail_type = get_mail_type(login)
20
- super(login,password,options)
19
+ @mail_type = get_mail_type(login)
20
+ super(login,password,options)
21
21
  end
22
22
 
23
23
  def real_connect
24
- login_for_cookies
25
- redirect_for_location
24
+ login_for_cookies
25
+ redirect_for_location
26
26
  end
27
27
 
28
28
  def contacts
29
- return @contacts if @contacts
29
+ return @contacts if @contacts
30
30
  if connected?
31
- data, resp, cookies, forward = get(@mail_url,@cookies)
32
- if resp.code_type != Net::HTTPOK
31
+ data, resp, cookies, forward = get(@mail_url,@cookies)
32
+ if resp.code_type != Net::HTTPOK
33
33
  raise ConnectionError, self.class.const_get(:PROTOCOL_ERROR)
34
34
  end
35
35
  parse(data)
@@ -39,50 +39,51 @@ class Contacts
39
39
  private
40
40
 
41
41
  def get_mail_type(username)
42
- if username.include?("@sina.com")
43
- :sina_com
44
- elsif username.include?("@sina.cn")
45
- :sina_cn
46
- else
47
- raise MailServerError, "there are only two mail servers that sina.com and sina.cn. please add domain after username"
48
- end
42
+ if username.include?("@sina.com")
43
+ :sina_com
44
+ elsif username.include?("@sina.cn")
45
+ :sina_cn
46
+ else
47
+ raise MailServerError, "there are only two mail servers that sina.com and sina.cn. please add domain after username"
48
+ end
49
49
  end
50
50
 
51
51
  def parse(data)
52
- data =~ /conf.*?contacts:.*?(\{.*?\}),\s*groups:/m
53
- contacts = $1.gsub("&quot;",'')
54
- contacts = ActiveSupport::JSON.decode(contacts)
55
- contacts['contact'].map{|contactor|
56
- [contactor['name'],contactor['email']]
57
- }
52
+ #data =~ /conf.*?contacts:.*?(\{.*?\}),\s*groups:/m
53
+ data =~ /conf.*?contacts.*?(\{.*\}).*?groups/m
54
+ contacts = $1.gsub("&quot;",'')
55
+ contacts = ActiveSupport::JSON.decode(contacts)
56
+ contacts['contact'].map{|contactor|
57
+ [contactor['name'],contactor['email']]
58
+ }
58
59
  end
59
60
 
60
61
  def login_for_cookies
61
- data = {
62
- :domain => DOMAIN[@mail_type],
63
- :logintype => 'uid',
64
- :u => @login,
65
- :psw => @password,
66
- :savelogin => 'on',
67
- :sshchk => 'on',
68
- :ssl => 'on'
69
- }
70
- data, resp, cookies, forward = post(LOGIN_URL[@mail_type],data.to_query_string,LOGIN_COOKIE[@mail_type])
71
- login_faile_flag = %r{form.*?action.*?http.*?mail.sina.com.cn/cgi-bin/.*?login.php}m
72
- if data.match(login_faile_flag)
73
- raise AuthenticationError, "Username or password error"
74
- end
75
- data.match(/URL=(http:\/\/.*?)'>/)
76
- @redirect_url = $1
77
- @mail_server = @redirect_url.match(/(http:\/\/.*\..*?)\//)
78
- @cookies = cookies
62
+ data = {
63
+ :domain => DOMAIN[@mail_type],
64
+ :logintype => 'uid',
65
+ :u => @login,
66
+ :psw => @password,
67
+ :savelogin => 'on',
68
+ :sshchk => 'on',
69
+ :ssl => 'on'
70
+ }
71
+ data, resp, cookies, forward = post(LOGIN_URL[@mail_type],data.to_query_string,LOGIN_COOKIE[@mail_type])
72
+ login_faile_flag = %r{form.*?action.*?http.*?mail.sina.com.cn/cgi-bin/.*?login.php}m
73
+ if data.match(login_faile_flag)
74
+ raise AuthenticationError, "Username or password error"
75
+ end
76
+ data.match(/URL=(http:\/\/.*?)'>/)
77
+ @redirect_url = $1
78
+ @mail_server = @redirect_url.match(/(http:\/\/.*\..*?)\//)
79
+ @cookies = cookies
79
80
  end
80
81
 
81
82
  def redirect_for_location
82
- data, resp, cookies, forward = get(@redirect_url,@cookies)
83
- location = resp['Location']
84
- @mail_url = location.index("http://") ? location : "#{@mail_server}#{location}"
85
- @cookies = cookies
83
+ data, resp, cookies, forward = get(@redirect_url,@cookies)
84
+ location = resp['Location']
85
+ @mail_url = location.index("http://") ? location : "#{@mail_server}#{location}"
86
+ @cookies = cookies
86
87
  end
87
88
 
88
89
  TYPES[:sina] = Sina
data/lib/contacts/sohu.rb CHANGED
@@ -1,21 +1,21 @@
1
1
  class Contacts
2
2
  class Sohu < Base
3
- URL = "http://mail.sohu.com"
4
- DOMAIN = "sohu.com"
3
+ URL = "http://mail.sohu.com"
4
+ DOMAIN = "sohu.com"
5
5
  LOGIN_URL = "https://passport.sohu.com/sso/login.jsp"
6
6
  LOGIN_COOKIE = "IPLOC=CN3301; SUV=1008301317090277"
7
- MAIL_URL = "http://mail.sohu.com/bapp/81/main"
8
- PROTOCOL_ERROR = "sohu has changed its protocols, please upgrade this library first. you can also contact kamechb@gmail.com"
7
+ MAIL_URL = "http://mail.sohu.com/bapp/81/main"
8
+ PROTOCOL_ERROR = "sohu has changed its protocols, please upgrade this library first. you can also contact kamechb@gmail.com"
9
9
 
10
10
  def real_connect
11
- login_for_cookies
11
+ login_for_cookies
12
12
  end
13
13
 
14
14
  def contacts
15
- return @contacts if @contacts
15
+ return @contacts if @contacts
16
16
  if connected?
17
- data, resp, cookies, forward = get(MAIL_URL,@cookies)
18
- if resp.code_type != Net::HTTPOK
17
+ data, resp, cookies, forward = get(MAIL_URL,@cookies)
18
+ if resp.code_type != Net::HTTPOK
19
19
  raise ConnectionError, self.class.const_get(:PROTOCOL_ERROR)
20
20
  end
21
21
  parse(data)
@@ -26,32 +26,32 @@ class Contacts
26
26
 
27
27
 
28
28
  def parse(data)
29
- data.match(/ADDRESSES.*?'(\{.*?\})';/m)
30
- contacts = ActiveSupport::JSON.decode($1)
31
- contacts['contact'].map{|contactor|
32
- [contactor['nickname'],contactor['email']]
33
- }
29
+ data.match(/ADDRESSES.*?'(\{.*?\})';/m)
30
+ contacts = ActiveSupport::JSON.decode($1)
31
+ contacts['contact'].map{|contactor|
32
+ [contactor['nickname'],contactor['email']]
33
+ }
34
34
  end
35
35
 
36
- def login_for_cookies
37
- data = {
38
- :userid => @login,
39
- :password => @password,
40
- :appid => '1000',
41
- :persistentcookie => '0',
42
- :s => '1283173792650',
43
- :b => '2',
44
- :w => '1280',
45
- :pwdtype => '0',
46
- :v => '26'
47
- }
48
- data, resp, cookies, forward = get("#{LOGIN_URL}?#{data.to_query_string}",LOGIN_COOKIE)
49
- login_faile_flag = %r{login_status.*?error}
50
- if data.match(login_faile_flag)
51
- raise AuthenticationError, "Username or password error"
52
- end
53
- @cookies = cookies
54
- end
36
+ def login_for_cookies
37
+ data = {
38
+ :userid => @login,
39
+ :password => @password,
40
+ :appid => '1000',
41
+ :persistentcookie => '0',
42
+ :s => '1283173792650',
43
+ :b => '2',
44
+ :w => '1280',
45
+ :pwdtype => '0',
46
+ :v => '26'
47
+ }
48
+ data, resp, cookies, forward = get("#{LOGIN_URL}?#{data.to_query_string}",LOGIN_COOKIE)
49
+ login_faile_flag = %r{login_status.*?error}
50
+ if data.match(login_faile_flag)
51
+ raise AuthenticationError, "Username or password error"
52
+ end
53
+ @cookies = cookies
54
+ end
55
55
 
56
56
  TYPES[:sohu] = Sohu
57
57
  end
@@ -5,15 +5,15 @@ class Contacts
5
5
  ADDRESS_BOOK_URL = "http://address.mail.yahoo.com/?.rand=430244936"
6
6
  CONTACT_LIST_URL = "http://address.mail.yahoo.com/?_src=&_crumb=crumb&sortfield=3&bucket=1&scroll=1&VPC=social_list&.r=time"
7
7
  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"
8
-
9
- def real_connect
8
+
9
+ def real_connect
10
10
  postdata = ".tries=2&.src=ym&.md5=&.hash=&.js=&.last=&promo=&.intl=us&.bypass="
11
11
  postdata += "&.partner=&.u=4eo6isd23l8r3&.v=0&.challenge=gsMsEcoZP7km3N3NeI4mX"
12
12
  postdata += "kGB7zMV&.yplus=&.emailCode=&pkg=&stepid=&.ev=&hasMsgr=1&.chkP=Y&."
13
13
  postdata += "done=#{CGI.escape(URL)}&login=#{CGI.escape(login)}&passwd=#{CGI.escape(password)}"
14
-
14
+
15
15
  data, resp, cookies, forward = post(LOGIN_URL, postdata)
16
-
16
+
17
17
  if data.index("Invalid ID or password") || data.index("This ID is not yet taken")
18
18
  raise AuthenticationError, "Username and password do not match"
19
19
  elsif data.index("Sign in") && data.index("to Yahoo!")
@@ -23,24 +23,24 @@ class Contacts
23
23
  elsif cookies == ""
24
24
  raise ConnectionError, PROTOCOL_ERROR
25
25
  end
26
-
26
+
27
27
  data, resp, cookies, forward = get(forward, cookies, LOGIN_URL)
28
-
28
+
29
29
  if resp.code_type != Net::HTTPOK
30
30
  raise ConnectionError, PROTOCOL_ERROR
31
31
  end
32
-
32
+
33
33
  @cookies = cookies
34
34
  end
35
-
36
- def contacts
35
+
36
+ def contacts
37
37
  return @contacts if @contacts
38
38
  if connected?
39
39
  # first, get the addressbook site with the new crumb parameter
40
40
  url = URI.parse(address_book_url)
41
41
  http = open_http(url)
42
42
  resp, data = http.get("#{url.path}?#{url.query}",
43
- "Cookie" => @cookies
43
+ "Cookie" => @cookies
44
44
  )
45
45
 
46
46
  if resp.code_type != Net::HTTPOK
@@ -53,15 +53,15 @@ class Contacts
53
53
  url = URI.parse(contact_list_url.sub("_crumb=crumb","_crumb=#{crumb}").sub("time", Time.now.to_f.to_s.sub(".","")[0...-2]))
54
54
  http = open_http(url)
55
55
  resp, more_data = http.get("#{url.path}?#{url.query}",
56
- "Cookie" => @cookies,
57
- "X-Requested-With" => "XMLHttpRequest",
58
- "Referer" => address_book_url
56
+ "Cookie" => @cookies,
57
+ "X-Requested-With" => "XMLHttpRequest",
58
+ "Referer" => address_book_url
59
59
  )
60
60
 
61
61
  if resp.code_type != Net::HTTPOK
62
- raise ConnectionError, self.class.const_get(:PROTOCOL_ERROR)
62
+ raise ConnectionError, self.class.const_get(:PROTOCOL_ERROR)
63
63
  end
64
-
64
+
65
65
  if more_data =~ /"TotalABContacts":(\d+)/
66
66
  total = $1.to_i
67
67
  ((total / 50.0).ceil).times do |i|
@@ -69,25 +69,25 @@ class Contacts
69
69
  url = URI.parse(contact_list_url.sub("bucket=1","bucket=#{i}").sub("_crumb=crumb","_crumb=#{crumb}").sub("time", Time.now.to_f.to_s.sub(".","")[0...-2]))
70
70
  http = open_http(url)
71
71
  resp, more_data = http.get("#{url.path}?#{url.query}",
72
- "Cookie" => @cookies,
73
- "X-Requested-With" => "XMLHttpRequest",
74
- "Referer" => address_book_url
72
+ "Cookie" => @cookies,
73
+ "X-Requested-With" => "XMLHttpRequest",
74
+ "Referer" => address_book_url
75
75
  )
76
76
 
77
77
  if resp.code_type != Net::HTTPOK
78
- raise ConnectionError, self.class.const_get(:PROTOCOL_ERROR)
78
+ raise ConnectionError, self.class.const_get(:PROTOCOL_ERROR)
79
79
  end
80
80
 
81
81
  parse more_data
82
82
  end
83
83
  end
84
-
84
+
85
85
  @contacts
86
86
  end
87
87
  end
88
88
 
89
- private
90
-
89
+ private
90
+
91
91
  def parse(data, options={})
92
92
  @contacts ||= []
93
93
  @contacts += Contacts.parse_json(data)["response"]["ResultSet"]["Contacts"].to_a.select{|contact|!contact["email"].to_s.empty?}.map do |contact|
@@ -96,8 +96,8 @@ class Contacts
96
96
  end if data =~ /^\{"response":/
97
97
  @contacts
98
98
  end
99
-
99
+
100
100
  end
101
101
 
102
102
  TYPES[:yahoo] = Yahoo
103
- end
103
+ end
data/lib/contacts_cn.rb CHANGED
@@ -2,7 +2,7 @@ $:.unshift(File.dirname(__FILE__)+"/contacts/")
2
2
 
3
3
  require 'rubygems'
4
4
  unless Object.const_defined?('ActiveSupport')
5
- require 'activesupport'
5
+ require 'activesupport'
6
6
  end
7
7
  require 'base'
8
8
  require 'gmail'
@@ -1,5 +1,5 @@
1
- dir = File.dirname(__FILE__)
2
- require "#{dir}/../test_helper"
1
+ dir = File.dirname(__FILE__)
2
+ require "#{dir}/../test_helper"
3
3
  require 'contacts'
4
4
  class NetEaseContactImporterTest < ContactImporterTestCase
5
5
  def setup
@@ -1,5 +1,5 @@
1
- dir = File.dirname(__FILE__)
2
- require "#{dir}/../test_helper"
1
+ dir = File.dirname(__FILE__)
2
+ require "#{dir}/../test_helper"
3
3
  require 'contacts'
4
4
  class SinaContactImporterTest < ContactImporterTestCase
5
5
  def setup
@@ -4,20 +4,20 @@ require "#{dir}/../test_helper"
4
4
  class TestAccountsTest < ContactImporterTestCase
5
5
  def test_test_accounts_loads_data_from_example_accounts_file
6
6
  account = TestAccounts.load(File.dirname(__FILE__) + "/../example_accounts.yml")[:gmail]
7
-
7
+
8
8
  assert_equal :gmail, account.type
9
9
  assert_equal "<changeme>", account.username
10
10
  assert_equal "<changeme>", account.password
11
11
  assert_equal [["FirstName1 LastName1", "firstname1@example.com"], ["FirstName2 LastName2", "firstname2@example.com"]], account.contacts
12
12
  end
13
-
13
+
14
14
  def test_test_accounts_blows_up_if_file_doesnt_exist
15
15
  assert_raise(RuntimeError) do
16
16
  TestAccounts.load("file_that_does_not_exist.yml")
17
17
  end
18
18
  end
19
-
19
+
20
20
  def test_we_can_load_from_account_file
21
21
  assert_not_nil TestAccounts[:gmail].username
22
22
  end
23
- end
23
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: contacts_cn
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
5
- prerelease: false
4
+ hash: 17
5
+ prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 2
9
- - 6
10
- version: 1.2.6
9
+ - 7
10
+ version: 1.2.7
11
11
  platform: ruby
12
12
  authors:
13
13
  - Lucas Carlson
@@ -16,7 +16,7 @@ autorequire: contacts
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-03-03 00:00:00 +08:00
19
+ date: 2011-12-19 00:00:00 +08:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -62,32 +62,32 @@ extensions: []
62
62
  extra_rdoc_files: []
63
63
 
64
64
  files:
65
- - lib/contacts/yahoo.rb
66
- - lib/contacts/hash_ext.rb
65
+ - lib/contacts_cn.rb
66
+ - lib/contacts/base.rb
67
+ - lib/contacts/json_picker.rb
68
+ - lib/contacts/gmail.rb
67
69
  - lib/contacts/sina.rb
68
70
  - lib/contacts/plaxo.rb
69
- - lib/contacts/aol.rb
70
- - lib/contacts/gmail.rb
71
- - lib/contacts/base.rb
72
71
  - lib/contacts/net_ease.rb
72
+ - lib/contacts/aol.rb
73
+ - lib/contacts/hash_ext.rb
73
74
  - lib/contacts/hotmail.rb
74
- - lib/contacts/json_picker.rb
75
+ - lib/contacts/yahoo.rb
75
76
  - lib/contacts/sohu.rb
76
- - lib/contacts_cn.rb
77
- - test/example_accounts.yml
78
77
  - test/test_helper.rb
79
- - test/test_suite.rb
80
- - test/unit/hotmail_contact_importer_test.rb
78
+ - test/unit/gmail_contact_importer_test.rb
81
79
  - test/unit/aol_contact_importer_test.rb
82
- - test/unit/sina_contact_importer_test.rb
83
- - test/unit/test_accounts_test.rb
84
80
  - test/unit/sohu_contact_importer_test.rb
85
81
  - test/unit/net_ease_contact_importer_test.rb
82
+ - test/unit/sina_contact_importer_test.rb
86
83
  - test/unit/yahoo_csv_contact_importer_test.rb
87
- - test/unit/gmail_contact_importer_test.rb
84
+ - test/unit/hotmail_contact_importer_test.rb
85
+ - test/unit/test_accounts_test.rb
86
+ - test/example_accounts.yml
87
+ - test/test_suite.rb
88
+ - README
88
89
  - Rakefile
89
90
  - LICENSE
90
- - README
91
91
  - examples/grab_contacts.rb
92
92
  has_rdoc: true
93
93
  homepage: http://rubyforge.org/projects/contacts
@@ -119,7 +119,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
119
119
  requirements:
120
120
  - A json parser, the gdata ruby gem
121
121
  rubyforge_project:
122
- rubygems_version: 1.3.7
122
+ rubygems_version: 1.6.2
123
123
  signing_key:
124
124
  specification_version: 3
125
125
  summary: A universal interface to grab contact list information from various providers including Yahoo, AOL, Gmail, Hotmail, 126, 163, Yeah, Sohu, Sina and Plaxo.It is extended from contacts gem.