foco-contacts 1.2.18

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