contacts 1.0.6 → 1.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -30,8 +30,13 @@ Notice there are three ways to use this library so that you can limit the use as
30
30
 
31
31
  See the examples/ directory.
32
32
 
33
- == Authors
33
+ == Authors
34
+
34
35
  * Lucas Carlson from MOG (mailto:lucas@rufy.com) - http://mog.com
35
36
 
37
+ == Contributors
38
+
39
+ * Britt Selvitelle from Twitter (mailto:anotherbritt@gmail.com) - http://twitter.com
40
+
36
41
  This library is released under the terms of the BSD.
37
42
 
data/lib/contacts/base.rb CHANGED
@@ -8,7 +8,7 @@ require "thread"
8
8
 
9
9
  class Contacts
10
10
  TYPES = {}
11
- VERSION = "1.0.6"
11
+ VERSION = "1.0.7"
12
12
 
13
13
  class Base
14
14
  def initialize(login, password)
@@ -27,7 +27,7 @@ class Contacts
27
27
  @cookies && !@cookies.empty?
28
28
  end
29
29
 
30
- def contacts
30
+ def contacts(options = {})
31
31
  return @contacts if @contacts
32
32
  if connected?
33
33
  url = URI.parse(contact_list_url)
@@ -40,7 +40,7 @@ class Contacts
40
40
  raise ConnectionError, self.class.const_get(:PROTOCOL_ERROR)
41
41
  end
42
42
 
43
- parse data
43
+ parse(data, options)
44
44
  end
45
45
  end
46
46
 
@@ -5,19 +5,19 @@ class Contacts
5
5
  URL = "https://mail.google.com/mail/"
6
6
  LOGIN_URL = "https://www.google.com/accounts/ServiceLoginAuth"
7
7
  LOGIN_REFERER_URL = "https://www.google.com/accounts/ServiceLogin?service=mail&passive=true&rm=false&continue=http%3A%2F%2Fmail.google.com%2Fmail%3Fui%3Dhtml%26zy%3Dl&ltmpl=yj_blanco&ltmplcache=2&hl=en"
8
- CONTACT_LIST_URL = "https://mail.google.com/mail/?view=cl&search=contacts&pnl=a"
8
+ CONTACT_LIST_URL = "https://mail.google.com/mail/contacts/data/contacts?thumb=true&show=ALL&enums=true&psort=Name&max=10000&out=js&rf=&jsx=true"
9
9
  PROTOCOL_ERROR = "Gmail has changed its protocols, please upgrade this library first. If that does not work, contact lucas@rufy.com with this error"
10
10
 
11
11
  def real_connect
12
12
  postdata = "ltmpl=yj_blanco"
13
- postdata += "&continue=#{CGI.escape(URL)}"
13
+ postdata += "&continue=%s" % CGI.escape(URL)
14
14
  postdata += "&ltmplcache=2"
15
15
  postdata += "&service=mail"
16
16
  postdata += "&rm=false"
17
17
  postdata += "&ltmpl=yj_blanco"
18
18
  postdata += "&hl=en"
19
- postdata += "&Email=#{CGI.escape(login)}"
20
- postdata += "&Passwd=#{CGI.escape(password)}"
19
+ postdata += "&Email=%s" % CGI.escape(login)
20
+ postdata += "&Passwd=%s" % CGI.escape(password)
21
21
  postdata += "&rmShown=1"
22
22
  postdata += "&null=Sign+in"
23
23
 
@@ -41,41 +41,34 @@ class Contacts
41
41
  raise ConnectionError, PROTOCOL_ERROR
42
42
  end
43
43
 
44
- until forward.nil?
45
- data, resp, cookies, forward, old_url = get(forward, cookies, old_url) + [forward]
46
- end
47
44
  cookies = remove_cookie("LSID", cookies)
48
45
  cookies = remove_cookie("GV", cookies)
49
-
50
- if resp.code_type != Net::HTTPOK
51
- raise ConnectionError, PROTOCOL_ERROR
52
- end
53
-
46
+
54
47
  @cookies = cookies
55
48
  end
56
49
 
57
50
  private
58
51
 
59
- def parse(data)
60
- data.gsub!("\n","")
61
- data.gsub!("D([", "\nD([")
62
- data.gsub!("]);", "]);\n")
63
- data.gsub!("u003d", "=")
64
- data.gsub!("u002f", "/")
52
+ def parse(data, options)
53
+ data.gsub!(/^while \(true\); &&&START&&&/, '')
54
+ data.gsub!(/ &&&END&&&$/, '')
55
+ @contacts = JSON.parse(data)['Body']['Contacts']
65
56
 
66
- parsed_data = []
67
- data.scan(%r{D\(\[(.*)\]\)}) do |match|
68
- parsed_data << JSON.parse("[#{match[0]}]") rescue next
69
- end
57
+ # Determine in which format to return the data.
70
58
 
71
- @contacts = parsed_data.select{|d| d[0] == "cl"}.inject([]) do |a,d|
72
- a.concat(d.inject([]) do |ar,dr|
73
- ar.concat(dr.is_a?(Array) && dr[4] && !dr[4].empty? ? [[dr[3],dr[4]]] : [])
74
- end)
59
+ # Return the full JSON Hash.
60
+ return @contacts if(options[:details])
61
+
62
+ # Default format.
63
+ # ['Name', 'Email1', 'Email2', ...]
64
+ @contacts = @contacts.map do |c|
65
+ name, emails = c.values_at "Name", "Emails"
66
+ emails = emails.first.values
67
+ [name, emails].flatten
75
68
  end
76
69
  end
77
70
 
78
71
  end
79
72
 
80
73
  TYPES[:gmail] = Gmail
81
- end
74
+ end
@@ -9,8 +9,6 @@ class Contacts
9
9
  MAX_HTTP_THREADS = 8
10
10
 
11
11
  def real_connect
12
- @use_new_contact_url = false
13
-
14
12
  data, resp, cookies, forward = get(URL)
15
13
 
16
14
  old_url = URL
@@ -18,10 +16,13 @@ class Contacts
18
16
  data, resp, cookies, forward, old_url = get(forward, cookies, old_url) + [forward]
19
17
  end
20
18
 
21
- postdata = "PPSX=#{CGI.escape(data.split("><").grep(/PPSX/).first[/=\S+$/][2..-3])}&"
22
- postdata += "PwdPad=#{PWDPAD[0...(PWDPAD.length-@password.length)]}&"
23
- postdata += "login=#{CGI.escape(login)}&passwd=#{CGI.escape(password)}&LoginOptions=2&"
24
- postdata += "PPFT=#{CGI.escape(data.split("><").grep(/PPFT/).first[/=\S+$/][2..-3])}"
19
+ postdata = "PPSX=%s&PwdPad=%s&login=%s&passwd=%s&LoginOptions=2&PPFT=%s" % [
20
+ CGI.escape(data.split("><").grep(/PPSX/).first[/=\S+$/][2..-3]),
21
+ PWDPAD[0...(PWDPAD.length-@password.length)],
22
+ CGI.escape(login),
23
+ CGI.escape(password),
24
+ CGI.escape(data.split("><").grep(/PPFT/).first[/=\S+$/][2..-3])
25
+ ]
25
26
 
26
27
  form_url = data.split("><").grep(/form/).first.split[5][8..-2]
27
28
  data, resp, cookies, forward = post(form_url, postdata, cookies)
@@ -38,27 +39,31 @@ class Contacts
38
39
  until forward.nil?
39
40
  data, resp, cookies, forward, old_url = get(forward, cookies, old_url) + [forward]
40
41
  end
41
-
42
- if resp.code_type != Net::HTTPOK
43
- raise ConnectionError, PROTOCOL_ERROR
44
- end
45
42
 
46
- forward = "http://www.hotmail.msn.com/cgi-bin/sbox"
43
+ =begin
44
+ if data =~ %r{action="(.*?)"}
45
+ forward = $1
46
+ puts forward
47
+ napexp = CGI.escape(data.to_s[/id="NAPExp" value="(.*?)"/][19...-1])
48
+ nap = CGI.escape(data.to_s[/id="NAP" value="(.*?)"/][16...-1])
49
+ anon = CGI.escape(data.to_s[/id="ANON" value="(.*?)"/][17...-1])
50
+ anonexp = CGI.escape(data.to_s[/id="ANONExp" value="(.*?)"/][20...-1])
51
+ t = CGI.escape(data.to_s[/id="t" value="(.*?)"/][14...-1])
52
+
53
+ postdata = "NAPExp=%s&NAP=%s&ANON=%s&ANONExp=%s&t=%s" % [ napexp, nap, anon, anonexp, t ]
54
+ puts postdata
55
+ data, resp, cookies, forward, old_url = post(forward, postdata, cookies, old_url) + [forward]
56
+ end
47
57
 
48
58
  until forward.nil?
49
59
  data, resp, cookies, forward, old_url = get(forward, cookies, old_url) + [forward]
50
60
  end
61
+ =end
51
62
 
52
- if resp.code_type != Net::HTTPOK
53
- raise ConnectionError, PROTOCOL_ERROR
54
- elsif old_url.include?('login.live.com')
55
- data, resp, cookies, forward, old_url = get("http://mail.live.com/mail", cookies)
56
- data, resp, cookies, forward, old_url = get(forward, cookies)
57
- old_url = forward
58
- @use_new_contact_url = true
59
- end
63
+ data, resp, cookies, forward, old_url = get("http://mail.live.com/mail", cookies)
64
+ data, resp, cookies, forward, old_url = get(forward, cookies)
60
65
 
61
- @domain = URI.parse(old_url).host
66
+ @domain = URI.parse(forward).host
62
67
  @cookies = cookies
63
68
  rescue AuthenticationError => m
64
69
  if @attempt == 1
@@ -71,7 +76,7 @@ class Contacts
71
76
  private
72
77
 
73
78
  def contact_list_url
74
- (@use_new_contact_url ? NEW_CONTACT_LIST_URL : OLD_CONTACT_LIST_URL) % @domain
79
+ NEW_CONTACT_LIST_URL % @domain
75
80
  end
76
81
 
77
82
  def follow_email(data, id, contacts_slot)
@@ -93,48 +98,12 @@ class Contacts
93
98
  @contacts[contacts_slot][1] = e[1] if e[1].match(/@/)
94
99
  end
95
100
 
96
- def parse(data)
97
- if @use_new_contact_url
98
- data = CSV.parse(data)
99
- col_names = data.shift
100
- @contacts = data.map do |person|
101
- [[person[1], person[2], person[3]].delete_if{|i|i.nil?}.join(" "), person[46]] unless person[46].nil?
102
- end.compact
103
- else
104
- chunks = data.split('id="hotmail"')
105
- prev = chunks.delete_at(0)
106
-
107
- queue = Queue.new
108
- threads = []
109
- @contacts = []
110
- chunks.each do |chunk|
111
- name = chunk.split('return false;">')[1].split('</a>')[0] rescue nil
112
- email = chunk.split('return false;">')[2].split('</a>')[0] rescue nil
113
- unless email && email != "more"
114
- prev = chunk
115
- next
116
- end
117
- next_slot = @contacts.size
118
- @contacts[next_slot] = [name, email]
119
- if email.match(/\.\.\.$/)
120
- if m = prev.match(/\s+id="([A-Za-z0-9\-]+)"/)
121
- queue.push([m[1], next_slot])
122
- if threads.size < MAX_HTTP_THREADS
123
- threads.push(Thread.new {
124
- while x = queue.pop
125
- follow_email(data, *x)
126
- end
127
- })
128
- end
129
- end
130
- end
131
- prev = chunk
132
- end
133
-
134
- threads.each { queue.push(nil) }
135
- threads.each { |t| t.join }
136
- @contacts
137
- end
101
+ def parse(data, options={})
102
+ data = CSV.parse(data)
103
+ col_names = data.shift
104
+ @contacts = data.map do |person|
105
+ [[person[1], person[2], person[3]].delete_if{|i|i.nil?}.join(" "), person[46]] unless person[46].nil?
106
+ end.compact
138
107
  end
139
108
 
140
109
  end
@@ -68,7 +68,7 @@ class Contacts
68
68
 
69
69
  private
70
70
 
71
- def parse(data)
71
+ def parse(data, options={})
72
72
  data = CSV.parse(data)
73
73
  col_names = data.shift
74
74
  @contacts = data.map do |person|
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: contacts
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.0.6
7
- date: 2007-10-29 00:00:00 -07:00
6
+ version: 1.0.7
7
+ date: 2007-11-20 00:00:00 -08:00
8
8
  summary: Ridiculously easy contact list information from various providers including Yahoo, Gmail, and Hotmail
9
9
  require_paths:
10
10
  - lib