Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.rvmrc
.DS_Store
pkg/*
test/accounts.yml
Expand Down
2 changes: 2 additions & 0 deletions lib/contacts.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@
require 'plaxo'
require 'aol'
require 'mailru'
require 'gmx'
require 'webde'
65 changes: 65 additions & 0 deletions lib/contacts/gmx.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
class Contacts
class Gmx < Base
LOGIN_URL = 'https://service.gmx.net/de/cgi/login'
JUMP_URL = 'https://uas2.uilogin.de/intern/jump' #used for unified address service auth
MAIL_FOLDER_URL = 'http://service.gmx.net/de/cgi/g.fcgi/mail/index'
MAIL_FOLDER_PARAMS = "folder=%s&allfolders=false&first=%s&CUSTOMERNO=%s&t=%s"

def real_connect
postdata = "AREA=1&id=%s&p=%s" % [
CGI.escape(login),
CGI.escape(password)
]

data, resp, @cookies, forward = post(LOGIN_URL, postdata)

if data.include?("/lose/password") || data.include?("login-failed")
raise AuthenticationError, "Username and password do not match"
end

@customerno = forward.match(/CUSTOMERNO=(\d+)/)[1]
@t = forward.match(/t=([^&]+)/)[1]
end

def contacts
@contacts = {}

if connected?
folders.each do |folder|
contacts_for_folder(folder)
end
end

@contacts.to_a
end

private

def scan_contacts(html)
html.scan(/"\"?([\w\.\s-]+)\"?\s&lt;([\w\.-]+@[\w\.-]+\.\w+)(?:&gt;)?"/) do |match|
@contacts[match[0]] = match[1]
end
end

def contacts_for_folder(folder)
count = 0
while count < 100 do
data, resp, cookies, forward = get MAIL_FOLDER_URL + "?" + MAIL_FOLDER_PARAMS % [
folder,
count,
@customerno,
@t
], @cookies
scan_contacts(data)
count += 10
end
end

def folders
%w(inbox sent)
end

end

TYPES[:gmx] = Gmx
end
2 changes: 1 addition & 1 deletion lib/contacts/hotmail.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def contacts(options = {})
# Grab info
case c_info[1]
when "e" # Email
build_contacts.last[1] = row.match(/#{email_match_text_beginning}(.*)#{email_match_text_end}/)[1]
build_contacts.last[1] = CGI.unescape(row.match(/#{email_match_text_beginning}([^&]*)#{email_match_text_end}/)[1])
when "dn" # Name
build_contacts.last[0] = row.match(/<a[^>]*>(.+)<\/a>/)[1]
end
Expand Down
71 changes: 71 additions & 0 deletions lib/contacts/webde.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
require "iconv"

class Contacts
class Webde < Base
LOGIN_URL = "https://login.web.de/intern/login/"
JUMP_URL = "https://uas2.uilogin.de/intern/jump/"
ADDRESSBOOK_URL = "https://adressbuch.web.de/exportcontacts"

def real_connect
postdata = "service=freemail&server=%s&password=%s&username=%s" % [
CGI.escape('https://freemail.web.de'),
CGI.escape(password),
CGI.escape(login)
]

# send login
data, resp, cookies, forward = post(LOGIN_URL, postdata)

if forward.include?("logonfailed")
raise AuthenticationError, "Username and password do not match"
end

# request session from login service
data, resp, cookies, forward = get forward

# start mail app session
data, resp, cookies, forward = get forward

@si = forward.match(/si=([^&]+)/)[1]
end

def connected?
@si && @si.length > 0
end

def contacts
connect_to_addressbook
@contacts = []
if @sessionid
CSV.parse(get_entries_from_addressbook) do |row|
@contacts << [latin1_to_utf8("#{row[2]} #{row[0]}"), latin1_to_utf8(row[9])] unless header_row?(row)
end
end

@contacts
end

private

def latin1_to_utf8(string)
Iconv.conv("utf-8", "ISO-8859-1", string)
end

def header_row?(row)
row[0] == 'Nachname'
end

def connect_to_addressbook
data, resp, cookies, forward = get JUMP_URL + "?serviceID=comsaddressbook-live.webde&session=#{@si}&server=https://freemailng2901.web.de&partnerdata="
@sessionid = forward.match(/session=([^&]+)/)[1]
end

def get_entries_from_addressbook
postdata = "language=de&raw_format=csv_Outlook2003&session=#{@sessionid}&what=PERSON"
data, resp, cookies, forward = post ADDRESSBOOK_URL, postdata
data
end
end

TYPES[:webde] = Webde
end
39 changes: 39 additions & 0 deletions test/unit/gmx_contact_importer_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
dir = File.dirname(__FILE__)
require "#{dir}/../test_helper"
require 'contacts'

class GmxContactImporterTest < ContactImporterTestCase
def setup
super
@account = TestAccounts[:gmx]
end

def test_successful_login
assert Contacts.new(:gmx, @account.username, @account.password).connected?
end

def test_importer_fails_with_invalid_password
assert_raise(Contacts::AuthenticationError) do
Contacts.new(:gmx, @account.username, "wrong_password")
end
end

def test_importer_fails_with_blank_password
assert_raise(Contacts::AuthenticationError) do
Contacts.new(:gmx, @account.username, "")
end
end

def test_importer_fails_with_blank_username
assert_raise(Contacts::AuthenticationError) do
Contacts.new(:gmx, "", @account.password)
end
end

def test_fetch_contacts
contacts = Contacts.new(:gmx, @account.username, @account.password).contacts
@account.contacts.each do |contact|
assert contacts.include?(contact), "Could not find: #{contact.inspect} in #{contacts.inspect}"
end
end
end
39 changes: 39 additions & 0 deletions test/unit/webde_contact_importer_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
dir = File.dirname(__FILE__)
require "#{dir}/../test_helper"
require 'contacts'

class WebdeContactImporterTest < ContactImporterTestCase
def setup
super
@account = TestAccounts[:webde]
end

def test_successful_login
assert Contacts.new(:webde, @account.username, @account.password).connected?
end

def test_importer_fails_with_invalid_password
assert_raise(Contacts::AuthenticationError) do
Contacts.new(:webde, @account.username, "wrong_password")
end
end

def test_importer_fails_with_blank_password
assert_raise(Contacts::AuthenticationError) do
Contacts.new(:webde, @account.username, "")
end
end

def test_importer_fails_with_blank_username
assert_raise(Contacts::AuthenticationError) do
Contacts.new(:webde, "", @account.password)
end
end

def test_fetch_contacts
contacts = Contacts.new(:webde, @account.username, @account.password).contacts
@account.contacts.each do |contact|
assert contacts.include?(contact), "Could not find: #{contact.inspect} in #{contacts.inspect}"
end
end
end