outlook_importer 0.1.0
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/README.md +42 -0
- data/Rakefile +54 -0
- data/VERSION +1 -0
- data/outlook_importer.gemspec +55 -0
- data/outlook_importer.rb +71 -0
- data/test/livemail_de.csv +2 -0
- data/test/outlook_2007_de.csv +3 -0
- data/test/outlook_importer_test.rb +40 -0
- data/test/test_helper.rb +2 -0
- metadata +107 -0
data/README.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Outlook CSV Importer
|
|
2
|
+
|
|
3
|
+
Can read csv contacts files exported by Outlook > 2000 and Windows Live Mail and return the contacts as a nested array.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
# USAGE
|
|
7
|
+
|
|
8
|
+
Initialize the importer with a lookup table that specifies which strings in the csv headers match either firstname, lastname and email or name and email.
|
|
9
|
+
|
|
10
|
+
lookup_table = {
|
|
11
|
+
:name => 'Name',
|
|
12
|
+
:email => 'E-Mail-Adresse'
|
|
13
|
+
}
|
|
14
|
+
importer = OutlookImporter.new(lookup_table)
|
|
15
|
+
|
|
16
|
+
After initialization let the importer read a file and you can access you contacts via the contacts method.
|
|
17
|
+
|
|
18
|
+
importer.read('example.csv')
|
|
19
|
+
importer.contacts # => [["Robin Example", "robin@example.de"]]
|
|
20
|
+
|
|
21
|
+
For further reference please see the outlook importer test in this project.
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# CREDITS
|
|
25
|
+
* Payango GmbH for allowing us to open source this lib.
|
|
26
|
+
* Robin Mehner for sharing the Outlook CSV test files.
|
|
27
|
+
* Frank Prößdorf
|
|
28
|
+
* Thilo Utke
|
|
29
|
+
|
|
30
|
+
# LICENSE
|
|
31
|
+
|
|
32
|
+
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
|
33
|
+
Version 2, December 2004
|
|
34
|
+
|
|
35
|
+
Copyright (C) 2004 Sam Hocevar
|
|
36
|
+
14 rue de Plaisance, 75014 Paris, France
|
|
37
|
+
Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long as the name is changed.
|
|
38
|
+
|
|
39
|
+
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
|
40
|
+
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
|
41
|
+
|
|
42
|
+
0. You just DO WHAT THE FUCK YOU WANT TO.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'rake'
|
|
3
|
+
|
|
4
|
+
begin
|
|
5
|
+
require 'jeweler'
|
|
6
|
+
Jeweler::Tasks.new do |gem|
|
|
7
|
+
gem.name = "outlook_importer"
|
|
8
|
+
gem.summary = "Simple importer for outlook and alike csv files"
|
|
9
|
+
gem.description = "Nothing more to say"
|
|
10
|
+
gem.email = "dont@bother.me"
|
|
11
|
+
gem.homepage = "http://github.com/thilo/outlook_importer"
|
|
12
|
+
gem.authors = ["Frank Prößdorf, Thilo Utke"]
|
|
13
|
+
gem.add_dependency "fastercsv", ">= 1.5.0"
|
|
14
|
+
gem.add_development_dependency "test-unit", ">= 1.2.3"
|
|
15
|
+
gem.has_rdoc = false
|
|
16
|
+
end
|
|
17
|
+
Jeweler::GemcutterTasks.new
|
|
18
|
+
rescue LoadError
|
|
19
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
require 'rake/testtask'
|
|
23
|
+
Rake::TestTask.new(:test) do |test|
|
|
24
|
+
test.libs << 'lib' << 'test'
|
|
25
|
+
test.pattern = 'test/**/test_*.rb'
|
|
26
|
+
test.verbose = true
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
begin
|
|
30
|
+
require 'rcov/rcovtask'
|
|
31
|
+
Rcov::RcovTask.new do |test|
|
|
32
|
+
test.libs << 'test'
|
|
33
|
+
test.pattern = 'test/**/test_*.rb'
|
|
34
|
+
test.verbose = true
|
|
35
|
+
end
|
|
36
|
+
rescue LoadError
|
|
37
|
+
task :rcov do
|
|
38
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
task :test => :check_dependencies
|
|
43
|
+
|
|
44
|
+
task :default => :test
|
|
45
|
+
|
|
46
|
+
require 'rake/rdoctask'
|
|
47
|
+
Rake::RDocTask.new do |rdoc|
|
|
48
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
|
49
|
+
|
|
50
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
51
|
+
rdoc.title = "outlook_importer #{version}"
|
|
52
|
+
rdoc.rdoc_files.include('README*')
|
|
53
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
54
|
+
end
|
data/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.1.0
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Generated by jeweler
|
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
|
4
|
+
# -*- encoding: utf-8 -*-
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |s|
|
|
7
|
+
s.name = %q{outlook_importer}
|
|
8
|
+
s.version = "0.1.0"
|
|
9
|
+
|
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
|
+
s.authors = ["Frank Pr\303\266\303\237dorf, Thilo Utke"]
|
|
12
|
+
s.date = %q{2010-10-25}
|
|
13
|
+
s.description = %q{Nothing more to say}
|
|
14
|
+
s.email = %q{dont@bother.me}
|
|
15
|
+
s.extra_rdoc_files = [
|
|
16
|
+
"README.md"
|
|
17
|
+
]
|
|
18
|
+
s.files = [
|
|
19
|
+
"README.md",
|
|
20
|
+
"Rakefile",
|
|
21
|
+
"VERSION",
|
|
22
|
+
"outlook_importer.gemspec",
|
|
23
|
+
"outlook_importer.rb",
|
|
24
|
+
"test/livemail_de.csv",
|
|
25
|
+
"test/outlook_2007_de.csv",
|
|
26
|
+
"test/outlook_importer_test.rb",
|
|
27
|
+
"test/test_helper.rb"
|
|
28
|
+
]
|
|
29
|
+
s.homepage = %q{http://github.com/thilo/outlook_importer}
|
|
30
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
|
31
|
+
s.require_paths = ["lib"]
|
|
32
|
+
s.rubygems_version = %q{1.3.7}
|
|
33
|
+
s.summary = %q{Simple importer for outlook and alike csv files}
|
|
34
|
+
s.test_files = [
|
|
35
|
+
"test/outlook_importer_test.rb",
|
|
36
|
+
"test/test_helper.rb"
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
if s.respond_to? :specification_version then
|
|
40
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
|
41
|
+
s.specification_version = 3
|
|
42
|
+
|
|
43
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
|
44
|
+
s.add_runtime_dependency(%q<fastercsv>, [">= 1.5.0"])
|
|
45
|
+
s.add_development_dependency(%q<test-unit>, [">= 1.2.3"])
|
|
46
|
+
else
|
|
47
|
+
s.add_dependency(%q<fastercsv>, [">= 1.5.0"])
|
|
48
|
+
s.add_dependency(%q<test-unit>, [">= 1.2.3"])
|
|
49
|
+
end
|
|
50
|
+
else
|
|
51
|
+
s.add_dependency(%q<fastercsv>, [">= 1.5.0"])
|
|
52
|
+
s.add_dependency(%q<test-unit>, [">= 1.2.3"])
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
data/outlook_importer.rb
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'fastercsv'
|
|
3
|
+
|
|
4
|
+
class OutlookImporter
|
|
5
|
+
def initialize(mapping)
|
|
6
|
+
@mapping = mapping.invert
|
|
7
|
+
raise ArgumentError unless valid_arguments?
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def read(file_path)
|
|
11
|
+
separator = File.new(file_path).gets.match(/([,;])[^,;]+\n/)[1]
|
|
12
|
+
@csv = FasterCSV.read(file_path, :headers => true, :col_sep => separator)
|
|
13
|
+
assign_header_columns(@csv.headers)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def assign_header_columns(headers)
|
|
17
|
+
@header_column_indices = {}
|
|
18
|
+
@mapping.keys.each do |key|
|
|
19
|
+
@header_column_indices[@mapping[key]] = headers.index(key)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def contacts
|
|
24
|
+
_contacts = []
|
|
25
|
+
@csv.each do |row|
|
|
26
|
+
_contacts << contact_entry(row)
|
|
27
|
+
end
|
|
28
|
+
_contacts
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def contact_entry(row)
|
|
32
|
+
[
|
|
33
|
+
contact_entry_name(row),
|
|
34
|
+
row[@header_column_indices[:email]]
|
|
35
|
+
]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def contact_entry_name(row)
|
|
39
|
+
if joined_arguments?
|
|
40
|
+
row[@header_column_indices[:name]]
|
|
41
|
+
else
|
|
42
|
+
"#{row[@header_column_indices[:firstname]]} #{row[@header_column_indices[:lastname]]}"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def valid_arguments?
|
|
47
|
+
required_values_present? && required_keys_present?
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def required_values_present?
|
|
51
|
+
required_keys_split_up - @mapping.values == [] ||
|
|
52
|
+
required_keys_joined - @mapping.values == []
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def required_keys_present?
|
|
56
|
+
values = @mapping.keys
|
|
57
|
+
values.select{|val| val && val.length > 0}.length == values.length
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def required_keys_split_up
|
|
61
|
+
[:firstname, :lastname, :email]
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def required_keys_joined
|
|
65
|
+
[:name, :email]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def joined_arguments?
|
|
69
|
+
@joined_arguments ||= @header_column_indices.include?(:name)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
Name;E-Mail-Adresse;Straße (privat);Ort (privat);Postleitzahl (privat);Bundesland (privat);Land/Region (privat);Telefon (privat);Straße (geschäftlich);Ort (geschäftlich);Postleitzahl (geschäftlich);Bundesland (geschäftlich);Land/Region (geschäftlich);Telefon (geschäftlich);Firma;Position
|
|
2
|
+
Robin Example;robin@example.de;;;;;;+49 160 00000000000;;;;;;;Coding Robin;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"Anrede","Vorname","Weitere Vornamen","Nachname","Suffix","Firma","Abteilung","Position","Straße geschäftlich","Straße geschäftlich 2","Straße geschäftlich 3","Ort geschäftlich","Region geschäftlich","Postleitzahl geschäftlich","Land/Region geschäftlich","Straße privat","Straße privat 2","Straße privat 3","Ort privat","Bundesland/Kanton privat","Postleitzahl privat","Land/Region privat","Weitere Straße","Weitere Straße 2","Weitere Straße 3","Weiterer Ort","Weiteres/r Bundesland/Kanton","Weitere Postleitzahl","Weiteres/e Land/Region","Telefon Assistent","Fax geschäftlich","Telefon geschäftlich","Telefon geschäftlich 2","Rückmeldung","Autotelefon","Telefon Firma","Fax privat","Telefon privat","Telefon privat 2","ISDN","Mobiltelefon","Weiteres Fax","Weiteres Telefon","Pager","Haupttelefon","Mobiltelefon 2","Telefon für Hörbehinderte","Telex","Abrechnungsinformation","Benutzer 1","Benutzer 2","Benutzer 3","Benutzer 4","Beruf","Büro","E-Mail-Adresse","E-Mail-Typ","E-Mail: Angezeigter Name","E-Mail 2: Adresse","E-Mail 2: Typ","E-Mail 2: Angezeigter Name","E-Mail 3: Adresse","E-Mail 3: Typ","E-Mail 3: Angezeigter Name","Empfohlen von","Geburtstag","Geschlecht","Hobby","Initialen","Internet-Frei/Gebucht","Jahrestag","Kategorien","Kinder","Konto","Name Assistent","Name des/der Vorgesetzten","Notizen","Organisationsnr.","Ort","Partner","Postfach geschäftlich","Postfach privat","Priorität","Privat","Regierungsnr.","Reisekilometer","Sprache","Stichwörter","Vertraulichkeit","Verzeichnisserver","Webseite","Weiteres Postfach"
|
|
2
|
+
"","Robin","","Example","","Coding Robin","","","Teststr. 23",,,"Berlin","","13355","Deutschland",,,,,,,,,,,,,,,,,"+49 1600000",,,,,,,,,,,,,,,,,,,,,,,,"robin@example.de","SMTP","Robin Example (robin@example.com)",,,,,,,,"0.0.00","Keine Angabe",,"R.M.",,"0.0.00",,,"",,,"
|
|
3
|
+
",,"",,,,"Normal","Aus",,,"","","Normal",,"http://example.de"
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
|
2
|
+
|
|
3
|
+
class OutlookImporterTest < Test::Unit::TestCase
|
|
4
|
+
def test_read_outlook_contacts
|
|
5
|
+
lookup_table = {
|
|
6
|
+
:firstname => 'Vorname',
|
|
7
|
+
:lastname => 'Nachname',
|
|
8
|
+
:email => 'E-Mail-Adresse'
|
|
9
|
+
}
|
|
10
|
+
importer = OutlookImporter.new(lookup_table)
|
|
11
|
+
importer.read('outlook_2007_de.csv')
|
|
12
|
+
|
|
13
|
+
assert_equal importer.contacts.first, ["Robin Example", "robin@example.de"]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def test_read_livemail_contacts
|
|
17
|
+
lookup_table = {
|
|
18
|
+
:name => 'Name',
|
|
19
|
+
:email => 'E-Mail-Adresse'
|
|
20
|
+
}
|
|
21
|
+
importer = OutlookImporter.new(lookup_table)
|
|
22
|
+
importer.read('livemail_de.csv')
|
|
23
|
+
|
|
24
|
+
assert_equal importer.contacts.first, ["Robin Example", "robin@example.de"]
|
|
25
|
+
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def test_initilize_raise_invalid_argument_error_if_lookup_not_satisfied
|
|
29
|
+
assert_raise ArgumentError do
|
|
30
|
+
importer = OutlookImporter.new(:firstname => '', :lastname => '', :email => '')
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def test_initialize_raises_invalid_argument_error_if_lookup_is_missing_a_value
|
|
35
|
+
assert_raise ArgumentError do
|
|
36
|
+
lookup = {:firstname => 'Vorname', :lastname => 'Nachname'}
|
|
37
|
+
importer = OutlookImporter.new(lookup)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: outlook_importer
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
hash: 27
|
|
5
|
+
prerelease: false
|
|
6
|
+
segments:
|
|
7
|
+
- 0
|
|
8
|
+
- 1
|
|
9
|
+
- 0
|
|
10
|
+
version: 0.1.0
|
|
11
|
+
platform: ruby
|
|
12
|
+
authors:
|
|
13
|
+
- "Frank Pr\xC3\xB6\xC3\x9Fdorf, Thilo Utke"
|
|
14
|
+
autorequire:
|
|
15
|
+
bindir: bin
|
|
16
|
+
cert_chain: []
|
|
17
|
+
|
|
18
|
+
date: 2010-10-25 00:00:00 +02:00
|
|
19
|
+
default_executable:
|
|
20
|
+
dependencies:
|
|
21
|
+
- !ruby/object:Gem::Dependency
|
|
22
|
+
name: fastercsv
|
|
23
|
+
prerelease: false
|
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
26
|
+
requirements:
|
|
27
|
+
- - ">="
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
hash: 3
|
|
30
|
+
segments:
|
|
31
|
+
- 1
|
|
32
|
+
- 5
|
|
33
|
+
- 0
|
|
34
|
+
version: 1.5.0
|
|
35
|
+
type: :runtime
|
|
36
|
+
version_requirements: *id001
|
|
37
|
+
- !ruby/object:Gem::Dependency
|
|
38
|
+
name: test-unit
|
|
39
|
+
prerelease: false
|
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
|
41
|
+
none: false
|
|
42
|
+
requirements:
|
|
43
|
+
- - ">="
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
hash: 25
|
|
46
|
+
segments:
|
|
47
|
+
- 1
|
|
48
|
+
- 2
|
|
49
|
+
- 3
|
|
50
|
+
version: 1.2.3
|
|
51
|
+
type: :development
|
|
52
|
+
version_requirements: *id002
|
|
53
|
+
description: Nothing more to say
|
|
54
|
+
email: dont@bother.me
|
|
55
|
+
executables: []
|
|
56
|
+
|
|
57
|
+
extensions: []
|
|
58
|
+
|
|
59
|
+
extra_rdoc_files:
|
|
60
|
+
- README.md
|
|
61
|
+
files:
|
|
62
|
+
- README.md
|
|
63
|
+
- Rakefile
|
|
64
|
+
- VERSION
|
|
65
|
+
- outlook_importer.gemspec
|
|
66
|
+
- outlook_importer.rb
|
|
67
|
+
- test/livemail_de.csv
|
|
68
|
+
- test/outlook_2007_de.csv
|
|
69
|
+
- test/outlook_importer_test.rb
|
|
70
|
+
- test/test_helper.rb
|
|
71
|
+
has_rdoc: true
|
|
72
|
+
homepage: http://github.com/thilo/outlook_importer
|
|
73
|
+
licenses: []
|
|
74
|
+
|
|
75
|
+
post_install_message:
|
|
76
|
+
rdoc_options:
|
|
77
|
+
- --charset=UTF-8
|
|
78
|
+
require_paths:
|
|
79
|
+
- lib
|
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
81
|
+
none: false
|
|
82
|
+
requirements:
|
|
83
|
+
- - ">="
|
|
84
|
+
- !ruby/object:Gem::Version
|
|
85
|
+
hash: 3
|
|
86
|
+
segments:
|
|
87
|
+
- 0
|
|
88
|
+
version: "0"
|
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
90
|
+
none: false
|
|
91
|
+
requirements:
|
|
92
|
+
- - ">="
|
|
93
|
+
- !ruby/object:Gem::Version
|
|
94
|
+
hash: 3
|
|
95
|
+
segments:
|
|
96
|
+
- 0
|
|
97
|
+
version: "0"
|
|
98
|
+
requirements: []
|
|
99
|
+
|
|
100
|
+
rubyforge_project:
|
|
101
|
+
rubygems_version: 1.3.7
|
|
102
|
+
signing_key:
|
|
103
|
+
specification_version: 3
|
|
104
|
+
summary: Simple importer for outlook and alike csv files
|
|
105
|
+
test_files:
|
|
106
|
+
- test/outlook_importer_test.rb
|
|
107
|
+
- test/test_helper.rb
|