contacts_cn 1.2.6 → 1.2.7

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/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.