foco-contacts 1.2.18

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,45 @@
1
+ require 'gdata'
2
+
3
+ class Contacts
4
+ class Gmail < Base
5
+
6
+ DETECTED_DOMAINS = [ /gmail.com/i, /googlemail.com/i ]
7
+ CONTACTS_SCOPE = 'http://www.google.com/m8/feeds/'
8
+ CONTACTS_FEED = CONTACTS_SCOPE + 'contacts/default/full/?max-results=1000'
9
+
10
+ def contacts
11
+ return @contacts if @contacts
12
+ end
13
+
14
+ def real_connect
15
+ @client = GData::Client::Contacts.new
16
+ @client.clientlogin(@login, @password, @captcha_token, @captcha_response)
17
+
18
+ feed = @client.get(CONTACTS_FEED).to_xml
19
+
20
+ @contacts = feed.elements.to_a('entry').collect do |entry|
21
+ title, email = entry.elements['title'].text, nil
22
+ primary_email = nil
23
+
24
+ entry.elements.each('gd:email') do |e|
25
+ if e.attribute('primary')
26
+ primary_email = e.attribute('address').value
27
+ else
28
+ email = e.attribute('address').value
29
+ end
30
+ end
31
+
32
+ email = primary_email unless primary_email.nil?
33
+
34
+ [title, email] unless email.nil?
35
+ end
36
+ @contacts.compact!
37
+ rescue GData::Client::AuthorizationError => e
38
+ # raise AuthenticationError, "Username or password are incorrect"
39
+ end
40
+
41
+ private
42
+
43
+ TYPES[:gmail] = Gmail
44
+ end
45
+ end
@@ -0,0 +1,63 @@
1
+ class Contacts
2
+ class Gmx < Base
3
+ DETECTED_DOMAINS = [ /gmx.de/i, /gmx.at/i, /gmx.ch/i, /gmx.net/i ]
4
+ LOGIN_URL = "https://service.gmx.net/de/cgi/login"
5
+ ADDRESS_BOOK_URL = "https://service.gmx.net/de/cgi/g.fcgi/addressbook/cab?cc=subnavi_adressbuch&sid="
6
+ EXPORT_URL = "https://adressbuch.gmx.net/exportcontacts"
7
+
8
+ attr_accessor :cookies, :sid
9
+
10
+ def real_connect
11
+
12
+ postdata = "AREA=1&EXT=redirect&EXT2=&dlevel=c&id=%s&p=%s&uinguserid=__uuid__" % [
13
+ CGI.escape(login),
14
+ CGI.escape(password)
15
+ ]
16
+
17
+ data, resp, self.cookies, forward = post(LOGIN_URL, postdata, "")
18
+
19
+ if data.index("lose/password")
20
+ raise AuthenticationError, "Username and password do not match"
21
+ elsif !forward.nil? && forward.index("login-failed")
22
+ raise AuthenticationError, "Username and password do not match"
23
+ elsif cookies == "" or data == ""
24
+ raise ConnectionError, PROTOCOL_ERROR
25
+ end
26
+
27
+ data, resp, self.cookies, forward = get(forward, self.cookies)
28
+
29
+ self.sid = data.match(/sid=([a-z0-9\.]+)/)[1]
30
+ end
31
+
32
+ def contacts
33
+ data, resp, cookies, forward = get(ADDRESS_BOOK_URL + self.sid, self.cookies)
34
+ data, resp, cookies, forward = get(forward, self.cookies)
35
+
36
+ session = forward.match(/session=([^&]+)/)[1]
37
+
38
+ postdata = "language=eng&raw_format=csv_Outlook2003&what=PERSON&session=" + session
39
+
40
+ data, resp, cookies, forward = post(EXPORT_URL, postdata, self.cookies)
41
+
42
+ @contacts = []
43
+
44
+ CSV.parse(data) do |row|
45
+ @contacts << ["#{row[2]} #{row[0]}", row[9]] unless header_row?(row)
46
+ end
47
+
48
+ @contacts
49
+ end
50
+
51
+ def skip_gzip?
52
+ false
53
+ end
54
+
55
+ private
56
+
57
+ def header_row?(row)
58
+ row[0] == 'Last Name'
59
+ end
60
+ end
61
+
62
+ TYPES[:gmx] = Gmx
63
+ end
@@ -0,0 +1,92 @@
1
+ require 'csv'
2
+ require 'rubygems'
3
+ require 'nokogiri'
4
+
5
+ class Contacts
6
+ class Hotmail < Base
7
+ DETECTED_DOMAINS = [ /hotmail/i, /live/i, /msn/i, /chaishop/i ]
8
+ URL = "https://login.live.com/login.srf?id=2"
9
+ CONTACT_LIST_URL = "https://mail.live.com/mail/GetContacts.aspx"
10
+ PROTOCOL_ERROR = "Hotmail has changed its protocols, please upgrade this library first. If that does not work, report this error at http://rubyforge.org/forum/?group_id=2693"
11
+ PWDPAD = "IfYouAreReadingThisYouHaveTooMuchFreeTime"
12
+
13
+ def real_connect
14
+
15
+ data, resp, cookies, forward = get(URL)
16
+ old_url = URL
17
+ until forward.nil?
18
+ data, resp, cookies, forward, old_url = get(forward, cookies, old_url) + [forward]
19
+ end
20
+
21
+ postdata = "PPSX=%s&PwdPad=%s&login=%s&passwd=%s&LoginOptions=2&PPFT=%s" % [
22
+ CGI.escape(data.split("><").grep(/PPSX/).first[/=\S+$/][2..-3]),
23
+ PWDPAD[0...(PWDPAD.length-@password.length)],
24
+ CGI.escape(login),
25
+ CGI.escape(password),
26
+ CGI.escape(data.split("><").grep(/PPFT/).first[/=\S+$/][2..-3])
27
+ ]
28
+
29
+ form_url = data.split("><").grep(/form/).first.split[5][8..-2]
30
+ data, resp, cookies, forward = post(form_url, postdata, cookies)
31
+
32
+ old_url = form_url
33
+ until cookies =~ /; PPAuth=/ || forward.nil?
34
+ data, resp, cookies, forward, old_url = get(forward, cookies, old_url) + [forward]
35
+ end
36
+
37
+ if data.index("The e-mail address or password is incorrect")
38
+ # raise AuthenticationError, "Username and password do not match"
39
+ elsif data != ""
40
+ # raise AuthenticationError, "Required field must not be blank"
41
+ elsif cookies == ""
42
+ # raise ConnectionError, PROTOCOL_ERROR
43
+ end
44
+
45
+ data, resp, cookies, forward = get("http://mail.live.com/mail", cookies)
46
+ until forward.nil?
47
+ data, resp, cookies, forward, old_url = get(forward, cookies, old_url) + [forward]
48
+ end
49
+
50
+
51
+ @domain = URI.parse(old_url).host
52
+ @cookies = cookies
53
+ rescue AuthenticationError => m
54
+ if @attempt == 1
55
+ retry
56
+ else
57
+ # raise m
58
+ end
59
+ end
60
+
61
+ def contacts(options = {})
62
+ if @contacts.nil? && connected?
63
+ url = URI.parse(contact_list_url)
64
+ data, resp, cookies, forward = get(get_contact_list_url, @cookies )
65
+
66
+
67
+ data.force_encoding('ISO-8859-1')
68
+
69
+ @contacts = CSV.parse(data, {:headers => true, :col_sep => data[7]}).map do |row|
70
+ name = ""
71
+ name = row["First Name"] if !row["First Name"].nil?
72
+ name << " #{row["Last Name"]}" if !row["Last Name"].nil?
73
+ [name, row["E-mail Address"] || ""]
74
+ end
75
+ else
76
+ @contacts || []
77
+ end
78
+ end
79
+
80
+ private
81
+
82
+ TYPES[:hotmail] = Hotmail
83
+
84
+ # the contacts url is dynamic
85
+ # luckily it tells us where to find it
86
+ def get_contact_list_url
87
+ data = get(CONTACT_LIST_URL, @cookies)[0]
88
+ html_doc = Nokogiri::HTML(data)
89
+ html_doc.xpath("//a")[0]["href"]
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,90 @@
1
+ class Contacts
2
+ class InboxLt < Base
3
+ DETECTED_DOMAINS = [ /inbox\.lt/i ]
4
+ URL = "http://www.inbox.lt/?language=lt"
5
+ LOGIN_URL = "https://login.inbox.lt/redirect.php"
6
+ ADDRESS_BOOK_URL = "http://mail.inbox.lt/horde/turba/?char=&sort=name&page=%d"
7
+ PROTOCOL_ERROR = "inbox.lt has changed its protocols"
8
+
9
+ attr_accessor :cookies
10
+
11
+ def real_connect
12
+ data, resp, self.cookies, forward = get(URL, "")
13
+
14
+ doc = Nokogiri(data)
15
+
16
+ salt_el = doc.at('input[name=salt]')
17
+
18
+ if salt_el.nil?
19
+ raise ConnectionError, PROTOCOL_ERROR
20
+ end
21
+
22
+ salt = salt_el['value']
23
+
24
+ postdata = "language=lt&passhash=&salt=%s&redirect_url=%s&redirect_vars=imapuser,usessl&imapuser=%s&pass=%s&usessl=1" % [
25
+ CGI.escape(salt),
26
+ CGI.escape('http://www.inbox.lt/index.php?actionID=imp_login'),
27
+ CGI.escape(username),
28
+ CGI.escape(password)
29
+ ]
30
+
31
+ data, resp, self.cookies, forward = post(LOGIN_URL, postdata, "")
32
+
33
+ if forward.nil? || !forward.match("logged_in=1")
34
+ raise AuthenticationError, "Username and password do not match"
35
+ end
36
+
37
+ until forward.nil?
38
+ data, resp, self.cookies, forward = get(forward, self.cookies)
39
+ end
40
+ end
41
+
42
+ def contacts
43
+ @contacts = []
44
+ page = 0
45
+
46
+ until page.nil?
47
+ url = ADDRESS_BOOK_URL % page
48
+
49
+ data, resp, self.cookies, forward = get(url, self.cookies)
50
+
51
+ doc = Nokogiri(data)
52
+
53
+ (doc/"form#contactsForm table table[1] tr").each do |tr|
54
+ name_td = tr.at('td[2]')
55
+ email_td = tr.at('td[3]')
56
+
57
+ next if name_td.nil? || email_td.nil?
58
+
59
+ name = name_td.text.strip
60
+ email = email_td.text.strip
61
+
62
+ next unless email.match('@')
63
+
64
+ @contacts << [ name, email ]
65
+ end
66
+
67
+ page+= 1
68
+ page = nil unless data.match("&page=#{page}")
69
+ end
70
+
71
+ @contacts
72
+ end
73
+
74
+ def skip_gzip?
75
+ false
76
+ end
77
+
78
+ private
79
+
80
+ def username
81
+ @login.split('@').first
82
+ end
83
+
84
+ def domain
85
+ @login.split('@').last
86
+ end
87
+ end
88
+
89
+ TYPES[:inbox_lt] = InboxLt
90
+ end
@@ -0,0 +1,16 @@
1
+ if !Object.const_defined?('ActiveSupport')
2
+ require 'json'
3
+ end
4
+
5
+ class Contacts
6
+ def self.parse_json( string )
7
+ if Object.const_defined?('ActiveSupport') and
8
+ ActiveSupport.const_defined?('JSON')
9
+ ActiveSupport::JSON.decode( string )
10
+ elsif Object.const_defined?('JSON')
11
+ JSON.parse( string )
12
+ else
13
+ raise 'Contacts requires JSON or Rails (with ActiveSupport::JSON)'
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,69 @@
1
+ require 'csv'
2
+
3
+ class Contacts
4
+ class Mailru < Base
5
+ DETECTED_DOMAINS = [ /list\.ru/i, /inbox\.ru/i, /bk\.ru/i, /mail\.ru/i ]
6
+ LOGIN_URL = "https://auth.mail.ru/cgi-bin/auth"
7
+ ADDRESS_BOOK_URL = "http://e.mail.ru/cgi-bin/abexport/addressbook.csv"
8
+
9
+ attr_accessor :cookies
10
+
11
+ def real_connect
12
+ username = login
13
+
14
+ postdata = "Login=%s&Domain=%s&Password=%s" % [
15
+ CGI.escape(username),
16
+ CGI.escape(domain_param(username)),
17
+ CGI.escape(password)
18
+ ]
19
+
20
+ data, resp, self.cookies, forward = post(LOGIN_URL, postdata, "")
21
+
22
+ if data.index("fail=1")
23
+ raise AuthenticationError, "Username and password do not match"
24
+ elsif cookies == "" or data == ""
25
+ raise ConnectionError, PROTOCOL_ERROR
26
+ end
27
+
28
+ data, resp, cookies, forward = get(login_token_link(data), login_cookies.join(';'))
29
+ end
30
+
31
+ def contacts
32
+ postdata = "confirm=1&abtype=6"
33
+ data, resp, cookies, forward = post(ADDRESS_BOOK_URL, postdata, login_cookies.join(';'))
34
+
35
+ @contacts = []
36
+ CSV.parse(data) do |row|
37
+ @contacts << [row[0], row[4]] unless header_row?(row)
38
+ end
39
+
40
+ @contacts
41
+ end
42
+
43
+ def skip_gzip?
44
+ true
45
+ end
46
+
47
+ private
48
+ def login_token_link(data)
49
+ data.match(/url=(.+)\">/)[1]
50
+ end
51
+
52
+ def login_cookies
53
+ self.cookies.split(';').collect{|c| c if (c.include?('t=') or c.include?('Mpop='))}.compact.collect{|c| c.strip}
54
+ end
55
+
56
+ def header_row?(row)
57
+ row[0] == 'AB-Name'
58
+ end
59
+
60
+ def domain_param(login)
61
+ login.include?('@') ?
62
+ login.match(/.+@(.+)/)[1] :
63
+ 'mail.ru'
64
+ end
65
+
66
+ end
67
+
68
+ TYPES[:mailru] = Mailru
69
+ end
@@ -0,0 +1,78 @@
1
+ class Contacts
2
+ class Onelt < Base
3
+ DETECTED_DOMAINS = [ /one\.lt/i ]
4
+ LOGIN_URL = "http://w33.one.lt/logonSubsite.do?subsite=pastas"
5
+ EMAIL_URL = "http://email.one.lt/"
6
+ ADDRESS_BOOK_URL = "http://w33.one.lt/resinRedir.do?pane=email"
7
+ PROTOCOL_ERROR = "One.lt has changed its protocols, please upgrade this library first. If that does not work, report this error at http://rubyforge.org/forum/?group_id=2693"
8
+
9
+ attr_accessor :cookies
10
+
11
+ def real_connect
12
+ data, resp, self.cookies, forward = get(LOGIN_URL)
13
+
14
+ postdata = "username=%s&password=%s&subsite=pastas" % [
15
+ CGI.escape(username),
16
+ CGI.escape(password)
17
+ ]
18
+
19
+ data, resp, self.cookies, forward, old_url = post(LOGIN_URL, postdata, self.cookies)
20
+
21
+ if data.index("f-login")
22
+ raise AuthenticationError, "Username and password do not match"
23
+ elsif !forward.nil? && forward.match('brutecheck')
24
+ raise AuthenticationError, "Got captcha"
25
+ elsif forward.nil? || !forward.match('tkn')
26
+ raise ConnectionError, PROTOCOL_ERROR
27
+ end
28
+ end
29
+
30
+ def contacts
31
+ data, resp, self.cookies, forward = get(ADDRESS_BOOK_URL, self.cookies)
32
+
33
+ doc = Nokogiri(data)
34
+ int = nil
35
+
36
+ (doc/"input[name=int]").each do |input|
37
+ int = input['value']
38
+ end
39
+
40
+ postdata = "action=LoginUser&pane=contacts&int=#{int}"
41
+ data, resp, self.cookies, forward = post(EMAIL_URL, postdata, self.cookies)
42
+
43
+ contacts = []
44
+ page = 1
45
+
46
+ until page.nil?
47
+ url = "http://email.one.lt/index.html?pane=contacts&page-number=%d" % page
48
+
49
+ data, resp, self.cookies, forward = get(url, self.cookies)
50
+
51
+ doc = Nokogiri(data)
52
+
53
+ (doc/'form[name=contacts_items]//table[2]//tr[class=whiteBg]').each do |tr|
54
+ name = tr.at('td[2]').text.strip
55
+ email = tr.at('td[4]').text.strip
56
+
57
+ next if email.empty?
58
+
59
+ contacts << [ name, email ]
60
+ end
61
+
62
+ page+= 1
63
+ page = nil unless data.match("&page-number=#{page}")
64
+ end
65
+
66
+ contacts
67
+ end
68
+
69
+ private
70
+
71
+ def username
72
+ login.split('@').first
73
+ end
74
+
75
+ end
76
+
77
+ TYPES[:onelt] = Onelt
78
+ end