ppl 1.23.0 → 1.24.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +6 -0
  3. data/features/email.feature +38 -1
  4. data/features/phone.feature +21 -0
  5. data/features/step_definitions/ppl_steps.rb +31 -1
  6. data/lib/ppl/adapter/vcard/greencard.rb +8 -2
  7. data/lib/ppl/application/bootstrap.rb +14 -0
  8. data/lib/ppl/command/email.rb +58 -4
  9. data/lib/ppl/command/mutt.rb +2 -2
  10. data/lib/ppl/command/phone.rb +46 -31
  11. data/lib/ppl/entity/email_address.rb +13 -0
  12. data/lib/ppl/entity/phone_number.rb +2 -0
  13. data/lib/ppl/format/address_book/email_addresses.rb +4 -1
  14. data/lib/ppl/format/address_book/mutt_query.rb +1 -1
  15. data/lib/ppl/format/address_book/one_line.rb +10 -1
  16. data/lib/ppl/format/contact/email_addresses.rb +7 -17
  17. data/lib/ppl/format/contact/full.rb +27 -8
  18. data/lib/ppl/format/contact/phone_number.rb +6 -1
  19. data/lib/ppl/format/table.rb +2 -2
  20. data/lib/ppl/service/email_address.rb +37 -0
  21. data/lib/ppl/service/phone_number.rb +40 -0
  22. data/lib/ppl.rb +8 -1
  23. data/ppl.gemspec +2 -2
  24. data/spec/ppl/adapter/vcard/greencard_spec.rb +40 -2
  25. data/spec/ppl/command/email_spec.rb +58 -0
  26. data/spec/ppl/command/mutt_spec.rb +10 -10
  27. data/spec/ppl/command/phone_spec.rb +30 -26
  28. data/spec/ppl/entity/email_address_spec.rb +28 -0
  29. data/spec/ppl/entity/phone_number_spec.rb +6 -0
  30. data/spec/ppl/format/address_book/email_addresses_spec.rb +1 -1
  31. data/spec/ppl/format/address_book/mutt_query_spec.rb +2 -2
  32. data/spec/ppl/format/address_book/one_line_spec.rb +11 -1
  33. data/spec/ppl/format/contact/email_addresses_spec.rb +27 -13
  34. data/spec/ppl/format/contact/full_spec.rb +25 -13
  35. data/spec/ppl/format/contact/phone_number_spec.rb +13 -1
  36. data/spec/ppl/service/email_address_spec.rb +73 -0
  37. data/spec/ppl/service/phone_number_spec.rb +75 -0
  38. metadata +8 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6c8a86000f8071b266624cd2cb96c4ea0da0294a
4
- data.tar.gz: f0a2f09b185c73029847e11b010cc81f5fe97d7d
3
+ metadata.gz: 2f33a5e4b27cd115dbac2ce3532e4fc81e93635e
4
+ data.tar.gz: 1eef11f3f8784fa687c211b9343fe45e914c2cb2
5
5
  SHA512:
6
- metadata.gz: eb44a9bf6207db1a1073b47f2e7fe22787b4f05e9d04987faabc473de6372ee35db3ae04c3b5bffa85817b4bd5fe8b5c060ce071faa231dbba14dc7752dae5f1
7
- data.tar.gz: 487f408c4610193bbb135d0016cee82555ab0445b64645da7c072eb351d1ea32084173886eaecf44e41a9563f4276865f843348fe4ecce614a082daa619a29a8
6
+ metadata.gz: 19c1da0a40163b4e3b37f9ae01ef70b590b312b2dc381cdb5ba35f776261f85fda799736c0e5d0694a4f7d67e3a85f232f7ab961b95f8a2e15fd3f1f72e1ffe1
7
+ data.tar.gz: 4798e2a97cdb5daf366d821e8b736d187798ef238a00329aae88d66149379cfad1207d98c8bf4f432099e4756617802c61a307458518876340dfbc386ace4973
data/Rakefile CHANGED
@@ -40,3 +40,9 @@ task :enable_config do
40
40
  end
41
41
  end
42
42
 
43
+ task :feature, :feature_name do |task, params|
44
+ Rake::Task["disable_config"].invoke
45
+ system "bundle exec cucumber features/#{params[:feature_name]}.feature"
46
+ Rake::Task["enable_config"].invoke
47
+ end
48
+
@@ -1,6 +1,13 @@
1
1
 
2
2
  Feature: ppl email
3
3
 
4
+ Scenario: Add a preferred email address to a contact
5
+ Given I am in an address book with a blank contact called bob
6
+ And I run "ppl email bob --preferred bob@example.org"
7
+ Then it should succeed
8
+ And bob should have 1 email address
9
+ And the 1st email address should be "* bob@example.org"
10
+
4
11
  Scenario: Add an email address to a contact
5
12
  Given I am in an address book with a blank contact called bob
6
13
  And I run "ppl email bob bob@example.org"
@@ -8,9 +15,39 @@ Feature: ppl email
8
15
  And bob should have 1 email address
9
16
  And the 1st email address should be "bob@example.org"
10
17
 
11
- Scenario: Remove an email address from a contact
18
+ Scenario: Add a second email address to a contact
19
+ Given I am in the same address book as before
20
+ And I run "ppl email bob rob@testing.com"
21
+ Then it should succeed
22
+ And bob should have 2 email addresses
23
+ And the 1st email address should be "bob@example.org"
24
+ And the 2nd email address should be "rob@testing.com"
25
+
26
+ Scenario: Set an existing email address as the preferred address
27
+ Given I am in the same address book as before
28
+ And I run "ppl email bob --preferred rob@testing.com"
29
+ Then it should succeed
30
+ And bob should have 2 email addresses
31
+ And "rob@testing.com" should be the favourite email address
32
+
33
+ Scenario: Choose a different preferred email address
34
+ Given I am in the same address book as before
35
+ And I run "ppl email bob --preferred bob@example.org"
36
+ Then it should succeed
37
+ And bob should have 2 email addresses
38
+ And "bob@example.org" should be the favourite email address
39
+
40
+ Scenario: Remove the preferred flag from an email address
41
+ Given I am in the same address book as before
42
+ And I run "ppl email bob --not-preferred bob@example.org"
43
+ Then it should succeed
44
+ And bob should have 2 email addresses
45
+ And there should be no favourite email address
46
+
47
+ Scenario: Remove email addresses from a contact
12
48
  Given I am in the same address book as before
13
49
  And I run "ppl email bob --delete bob@example.org"
50
+ And I run "ppl email bob --d rob@testing.com"
14
51
  Then it should succeed
15
52
  And bob should have 0 email addresses
16
53
 
@@ -1,6 +1,13 @@
1
1
 
2
2
  Feature: ppl phone
3
3
 
4
+ Scenario: Add a preferred phone number with a type
5
+ Given I am in an address book with a blank contact called bob
6
+ And I run "ppl phone bob 123 --type cell --preferred"
7
+ Then it should succeed
8
+ And bob should have 1 phone number
9
+ And the 1st phone number should be "* 123 (cell)"
10
+
4
11
  Scenario: Add a phone number to a contact
5
12
  Given I am in an address book with a blank contact called bob
6
13
  And I run "ppl phone bob 01234567890"
@@ -22,6 +29,20 @@ Feature: ppl phone
22
29
  And bob should have 1 phone number
23
30
  And the 1st phone number should be "01234567890"
24
31
 
32
+ Scenario: Set an existing phone number as the preferred number
33
+ Given I am in the same address book as before
34
+ And I run "ppl phone bob 01234567890 --preferred"
35
+ Then it should succeed
36
+ And bob should have 1 phone number
37
+ And "01234567890" should be the preferred phone number
38
+
39
+ Scenario: Remove the preferred flag from a phone number
40
+ Given I am in the same address book as before
41
+ And I run "ppl phone bob -P 01234567890"
42
+ Then it should succeed
43
+ And bob should have 1 phone number
44
+ And there should be no preferred phone number
45
+
25
46
  Scenario: Remove a phone number from a contact
26
47
  Given I am in the same address book as before
27
48
  And I run "ppl phone bob --delete 01234567890"
@@ -60,7 +60,7 @@ And /^its name should be "([^"]+)"$/ do |name|
60
60
  end
61
61
 
62
62
  Then(/^the (\d+).. email address should be "([^"]+)"$/) do |nth, address|
63
- @email_addresses[nth.to_i - 1].should eq address
63
+ @email_addresses[nth.to_i - 1].strip.should eq address
64
64
  end
65
65
 
66
66
  Then /^running "ppl ([^"]+)" should output (\d+) lines?$/ do |command, lines|
@@ -88,6 +88,36 @@ Then(/^the (\d+).. URL should be "([^"]+)"$/) do |nth, url|
88
88
  @urls[nth.to_i - 1].should eq url
89
89
  end
90
90
 
91
+ And /^"([^"]+)" should be the favourite email address$/ do |email_address|
92
+ @email_addresses.should include "* #{email_address}"
93
+ @email_addresses.each do |line|
94
+ if line.include? "*"
95
+ line.should eq "* #{email_address}"
96
+ end
97
+ end
98
+ end
99
+
100
+ And /^"([^"]+)" should be the preferred phone number$/ do |phone_number|
101
+ @phone_numbers.should include "* #{phone_number}"
102
+ @phone_numbers.each do |line|
103
+ if line.include? "*"
104
+ line.should eq "* #{phone_number}"
105
+ end
106
+ end
107
+ end
108
+
109
+ And /^there should be no favourite email address$/ do
110
+ @email_addresses.each do |line|
111
+ line.should_not include "*"
112
+ end
113
+ end
114
+
115
+ And /^there should be no preferred phone number$/ do
116
+ @phone_numbers.each do |line|
117
+ line.should_not include "*"
118
+ end
119
+ end
120
+
91
121
  Then /^(bob)'s birthday should be "([^"]+)"$/ do |id, birthday|
92
122
  ppl("bday #{id}").should eq birthday
93
123
  end
@@ -58,7 +58,9 @@ class Ppl::Adapter::Vcard::GreenCard
58
58
 
59
59
  def encode_email_addresses(contact, vcard_maker)
60
60
  contact.email_addresses.each do |email_address|
61
- vcard_maker.add_email(email_address)
61
+ vcard_maker.add_email(email_address.address) do |vcard_email|
62
+ vcard_email.preferred = email_address.preferred
63
+ end
62
64
  end
63
65
  end
64
66
 
@@ -66,6 +68,7 @@ class Ppl::Adapter::Vcard::GreenCard
66
68
  contact.phone_numbers.each do |phone_number|
67
69
  vcard_maker.add_tel(phone_number.number) do |tel|
68
70
  tel.location = phone_number.type
71
+ tel.preferred = phone_number.preferred
69
72
  end
70
73
  end
71
74
  end
@@ -117,7 +120,9 @@ class Ppl::Adapter::Vcard::GreenCard
117
120
 
118
121
  def decode_email_addresses(vcard, contact)
119
122
  vcard.emails.each do |email|
120
- contact.email_addresses.push(email.to_s)
123
+ email_address = Ppl::Entity::EmailAddress.new(email.to_s)
124
+ email_address.preferred = email.preferred
125
+ contact.email_addresses << email_address
121
126
  end
122
127
  end
123
128
 
@@ -137,6 +142,7 @@ class Ppl::Adapter::Vcard::GreenCard
137
142
  phone_number = Ppl::Entity::PhoneNumber.new
138
143
  phone_number.number = tel.to_s
139
144
  phone_number.type = (tel.location | tel.nonstandard).join
145
+ phone_number.preferred = tel.preferred
140
146
  contact.phone_numbers << phone_number
141
147
  end
142
148
  end
@@ -37,6 +37,7 @@ class Ppl::Application::Bootstrap
37
37
 
38
38
  register :command_email do
39
39
  email = Ppl::Command::Email.new
40
+ email.email_service = email_service
40
41
  email.storage = storage_adapter
41
42
  email.list_format = format_address_book_email_addresses
42
43
  email.show_format = format_contact_email_addresses
@@ -101,6 +102,7 @@ class Ppl::Application::Bootstrap
101
102
 
102
103
  register :command_phone do
103
104
  phone = Ppl::Command::Phone.new
105
+ phone.phone_service = phone_service
104
106
  phone.storage = storage_adapter
105
107
  phone.list_format = format_address_book_phone_numbers
106
108
  phone.show_format = format_contact_phone_numbers
@@ -349,5 +351,17 @@ class Ppl::Application::Bootstrap
349
351
  Ppl::Adapter::EmailScraper::Mail.new
350
352
  end
351
353
 
354
+ register :email_service do
355
+ email_service = Ppl::Service::EmailAddress.new
356
+ email_service.storage = storage_adapter
357
+ email_service
358
+ end
359
+
360
+ register :phone_service do
361
+ phone_service = Ppl::Service::PhoneNumber.new
362
+ phone_service.storage = storage_adapter
363
+ phone_service
364
+ end
365
+
352
366
  end
353
367
 
@@ -1,18 +1,72 @@
1
1
 
2
- class Ppl::Command::Email < Ppl::Command::Attribute
2
+ class Ppl::Command::Email < Ppl::Application::Command
3
3
 
4
4
  name "email"
5
5
  description "Show or change a contact's email address"
6
6
 
7
- def initialize
8
- @attribute = :email_addresses
9
- end
7
+ attr_writer :email_service
8
+ attr_writer :list_format
9
+ attr_writer :show_format
10
10
 
11
11
  def options(parser, options)
12
12
  parser.banner = "usage: ppl email <contact> [<email-address>]"
13
13
  parser.on("-d", "--delete", "delete email address") do
14
14
  options[:delete] = true
15
15
  end
16
+ parser.on("-p", "--preferred", "mark address as preferred") do
17
+ options[:preferred] = true
18
+ end
19
+ parser.on("-P", "--not-preferred", "mark address as not preferred") do
20
+ options[:preferred] = false
21
+ end
22
+ end
23
+
24
+ def execute(input, output)
25
+ action = determine_action(input)
26
+ send(action, input, output)
27
+ true
28
+ end
29
+
30
+ private
31
+
32
+ def determine_action(input)
33
+ if input.arguments.length < 1
34
+ :list_address_book_email_addresses
35
+ elsif input.arguments.length < 2
36
+ :show_contact_email_addresses
37
+ elsif input.options[:delete]
38
+ :remove_email_address_from_contact
39
+ else
40
+ :update_contact_email_addresses
41
+ end
42
+ end
43
+
44
+ def list_address_book_email_addresses(input, output)
45
+ address_book = @storage.load_address_book
46
+ output.line(@list_format.process(address_book))
47
+ end
48
+
49
+ def show_contact_email_addresses(input, output)
50
+ contact = @storage.require_contact(input.arguments[0])
51
+ output.line(@show_format.process(contact))
52
+ end
53
+
54
+ def remove_email_address_from_contact(input, output)
55
+ contact = @storage.require_contact(input.arguments[0])
56
+ @email_service.remove(contact, input.arguments[1])
57
+ end
58
+
59
+ def update_contact_email_addresses(input, output)
60
+ contact = @storage.require_contact(input.arguments[0])
61
+ if new_email_address?(contact, input.arguments[1])
62
+ @email_service.add(contact, input.arguments[1], input.options)
63
+ else
64
+ @email_service.update(contact, input.arguments[1], input.options)
65
+ end
66
+ end
67
+
68
+ def new_email_address?(contact, email_address)
69
+ (contact.email_addresses.select { |ea| ea.address == email_address }).empty?
16
70
  end
17
71
 
18
72
  end
@@ -62,9 +62,9 @@ class Ppl::Command::Mutt < Ppl::Application::Command
62
62
  def match_by_email_address(contact, query)
63
63
  matches = contact.email_addresses.select do |email_address|
64
64
  if @options[:ignore_case]
65
- email_address.downcase.include? query.downcase
65
+ email_address.address.downcase.include? query.downcase
66
66
  else
67
- email_address.include? query
67
+ email_address.address.include? query
68
68
  end
69
69
  end
70
70
  if matches.length > 0
@@ -1,61 +1,76 @@
1
1
 
2
- class Ppl::Command::Phone < Ppl::Command::Attribute
2
+ class Ppl::Command::Phone < Ppl::Application::Command
3
3
 
4
4
  name "phone"
5
5
  description "List, show or change phone numbers"
6
6
 
7
- def initialize
8
- @attribute = :phone_numbers
9
- end
7
+ attr_writer :phone_service
8
+ attr_writer :list_format
9
+ attr_writer :show_format
10
10
 
11
11
  def options(parser, options)
12
12
  parser.banner = "usage: ppl phone <contact> [<number>]"
13
13
  parser.on("-d", "--delete", "delete phone number") do
14
14
  options[:delete] = true
15
15
  end
16
- parser.on("-t", "--type <type>") do |type|
16
+ parser.on("-t", "--type <type>", "set the phone number's type") do |type|
17
17
  options[:type] = type
18
18
  end
19
+ parser.on("-p", "--preferred", "mark phone number as preferred") do
20
+ options[:preferred] = true
21
+ end
22
+ parser.on("-P", "--not-preferred", "mark phone number as not preferred") do
23
+ options[:preferred] = false
24
+ end
25
+ end
26
+
27
+ def execute(input, output)
28
+ action = determine_action(input)
29
+ send(action, input, output)
30
+ true
19
31
  end
20
32
 
21
- def add_attribute(input, output)
22
- contact = @storage.require_contact(input.arguments.shift)
23
- if new_number?(contact, input.arguments[0])
24
- add_new_number(contact, input)
33
+ private
34
+
35
+ def determine_action(input)
36
+ if input.arguments.length < 1
37
+ :list_address_book_phone_numbers
38
+ elsif input.arguments.length < 2
39
+ :show_contact_phone_numbers
40
+ elsif input.options[:delete]
41
+ :remove_phone_number_from_contact
25
42
  else
26
- update_existing_number(contact, input)
43
+ :update_contact_phone_numbers
27
44
  end
28
- @storage.save_contact(contact)
29
- true
30
45
  end
31
46
 
32
- def remove_attribute(input, output)
33
- contact = @storage.require_contact(input.arguments[0])
34
- contact.phone_numbers.select! { |pn| pn.number != input.arguments[1] }
35
- @storage.save_contact(contact)
47
+ def list_address_book_phone_numbers(input, output)
48
+ address_book = @storage.load_address_book
49
+ output.line(@list_format.process(address_book))
36
50
  end
37
51
 
38
- def new_number?(contact, input_number)
39
- matching_numbers = contact.phone_numbers.select do |pn|
40
- pn.number == input_number
41
- end
42
- matching_numbers.length < 1
52
+ def show_contact_phone_numbers(input, output)
53
+ contact = @storage.require_contact(input.arguments[0])
54
+ output.line(@show_format.process(contact))
43
55
  end
44
56
 
45
- def add_new_number(contact, input)
46
- phone_number = Ppl::Entity::PhoneNumber.new
47
- phone_number.number = input.arguments[0]
48
- phone_number.type = input.options[:type]
49
- contact.phone_numbers << phone_number
57
+ def remove_phone_number_from_contact(input, output)
58
+ contact = @storage.require_contact(input.arguments[0])
59
+ @phone_service.remove(contact, input.arguments[1])
50
60
  end
51
61
 
52
- def update_existing_number(contact, input)
53
- contact.phone_numbers.each do |pn|
54
- if pn.number == input.arguments[0]
55
- pn.type = input.options[:type]
56
- end
62
+ def update_contact_phone_numbers(input, output)
63
+ contact = @storage.require_contact(input.arguments[0])
64
+ if new_phone_number?(contact, input.arguments[1])
65
+ @phone_service.add(contact, input.arguments[1], input.options)
66
+ else
67
+ @phone_service.update(contact, input.arguments[1], input.options)
57
68
  end
58
69
  end
59
70
 
71
+ def new_phone_number?(contact, number)
72
+ (contact.phone_numbers.select { |pn| pn.number == number }).empty?
73
+ end
74
+
60
75
  end
61
76
 
@@ -0,0 +1,13 @@
1
+
2
+ class Ppl::Entity::EmailAddress
3
+
4
+ attr_accessor :address
5
+ attr_accessor :preferred
6
+
7
+ def initialize(address = nil)
8
+ @address = address
9
+ @preferred = false
10
+ end
11
+
12
+ end
13
+
@@ -3,9 +3,11 @@ class Ppl::Entity::PhoneNumber
3
3
 
4
4
  attr_accessor :number
5
5
  attr_accessor :type
6
+ attr_accessor :preferred
6
7
 
7
8
  def initialize(number = nil, type = nil)
8
9
  @number = number
10
+ @preferred = false
9
11
  @type = type
10
12
  end
11
13
 
@@ -18,10 +18,13 @@ class Ppl::Format::AddressBook::EmailAddresses < Ppl::Format::AddressBook
18
18
  def add_row(contact)
19
19
  @table.add_row({
20
20
  :id => sprintf("%s:", contact.id),
21
- :email_addresses => contact.email_addresses.join(", "),
21
+ :email_addresses => stringify_email_addresses(contact.email_addresses),
22
22
  })
23
23
  end
24
24
 
25
+ def stringify_email_addresses(email_addresses)
26
+ email_addresses.map { |em| em.address }.join(", ")
27
+ end
25
28
 
26
29
  end
27
30
 
@@ -23,7 +23,7 @@ class Ppl::Format::AddressBook::MuttQuery < Ppl::Format::AddressBook
23
23
 
24
24
  def add_email_address(email_address, name)
25
25
  @table.add_row({
26
- :email => email_address,
26
+ :email => email_address.address,
27
27
  :name => name,
28
28
  })
29
29
  end
@@ -20,7 +20,7 @@ class Ppl::Format::AddressBook::OneLine < Ppl::Format::AddressBook
20
20
  email = nil
21
21
 
22
22
  if !contact.email_addresses.empty?
23
- email = sprintf("<%s>", contact.email_addresses.first)
23
+ email = sprintf("<%s>", choose_email_address(contact).address)
24
24
  end
25
25
 
26
26
  @table.add_row({
@@ -30,5 +30,14 @@ class Ppl::Format::AddressBook::OneLine < Ppl::Format::AddressBook
30
30
  })
31
31
  end
32
32
 
33
+ def choose_email_address(contact)
34
+ preferred = contact.email_addresses.find { |e| e.preferred }
35
+ if preferred.nil?
36
+ contact.email_addresses.first
37
+ else
38
+ preferred
39
+ end
40
+ end
41
+
33
42
  end
34
43
 
@@ -1,30 +1,20 @@
1
1
 
2
2
  class Ppl::Format::Contact::EmailAddresses < Ppl::Format::Contact
3
3
 
4
- attr_writer :color_adapter
5
- attr_writer :colors
4
+ attr_writer :table
6
5
 
7
6
  def initialize(colors={})
8
- @colors = colors
9
- @color_adapter = Ppl::Adapter::Color::Colored.new
7
+ @table = Ppl::Format::Table.new([:star, :email_addresses], colors)
10
8
  end
11
9
 
12
10
  def process(contact)
13
- lines = []
14
11
  contact.email_addresses.each do |email_address|
15
- lines.push email_address
16
- end
17
- colorize_output(lines.join("\n"))
18
- end
19
-
20
- private
21
-
22
- def colorize_output(string)
23
- if @colors["email_addresses"]
24
- @color_adapter.colorize(string, @colors["email_addresses"])
25
- else
26
- string
12
+ @table.add_row({
13
+ :star => email_address.preferred ? "*" : " ",
14
+ :email_addresses => email_address.address,
15
+ })
27
16
  end
17
+ @table.to_s
28
18
  end
29
19
 
30
20
  end
@@ -1,9 +1,13 @@
1
1
 
2
2
  class Ppl::Format::Contact::Full < Ppl::Format::Contact
3
3
 
4
+ attr_writer :email_address_format
5
+ attr_writer :phone_number_format
4
6
  attr_writer :postal_address_format
5
7
 
6
8
  def initialize
9
+ @email_address_format = Ppl::Format::Contact::EmailAddresses.new
10
+ @phone_number_format = Ppl::Format::Contact::PhoneNumber.new
7
11
  @postal_address_format = Ppl::Format::PostalAddress::OneLine.new
8
12
  end
9
13
 
@@ -37,12 +41,22 @@ class Ppl::Format::Contact::Full < Ppl::Format::Contact
37
41
  if !contact.name.nil?
38
42
  line += contact.name
39
43
  end
40
- if !contact.email_addresses.empty?
41
- line += " <#{contact.email_addresses.first}>"
44
+ email_address = choose_first_line_address(contact)
45
+ unless email_address.nil?
46
+ line += " <#{email_address.address}>"
42
47
  end
43
48
  return line
44
49
  end
45
50
 
51
+ def choose_first_line_address(contact)
52
+ preferred = contact.email_addresses.find { |e| e.preferred }
53
+ if preferred.nil?
54
+ contact.email_addresses.first
55
+ else
56
+ preferred
57
+ end
58
+ end
59
+
46
60
  def vitals(contact)
47
61
  vitals = []
48
62
  if !contact.birthday.nil?
@@ -60,16 +74,18 @@ class Ppl::Format::Contact::Full < Ppl::Format::Contact
60
74
  end
61
75
 
62
76
  def format_email_addresses(contact)
63
- push_list("Email Addresses", contact.email_addresses)
77
+ unless contact.email_addresses.empty?
78
+ @lines << ""
79
+ @lines << "Email Addresses:"
80
+ @lines << @email_address_format.process(contact)
81
+ end
64
82
  end
65
83
 
66
84
  def format_phone_numbers(contact)
67
85
  unless contact.phone_numbers.empty?
68
86
  @lines << ""
69
87
  @lines << "Phone Numbers"
70
- contact.phone_numbers.each do |pn|
71
- @lines << " #{pn.number}"
72
- end
88
+ @lines << @phone_number_format.process(contact)
73
89
  end
74
90
  end
75
91
 
@@ -86,12 +102,15 @@ class Ppl::Format::Contact::Full < Ppl::Format::Contact
86
102
  push_list("URLs", contact.urls)
87
103
  end
88
104
 
89
- def push_list(label, list)
105
+ def push_list(label, list, property = nil)
90
106
  return if list.empty?
91
107
  @lines.push("")
92
108
  @lines.push("#{label}:")
93
109
  if list.kind_of?(Array)
94
- list.each { |item| @lines.push(" #{item}") }
110
+ list.each do |item|
111
+ string = property.nil? ? item : item.send(property)
112
+ @lines << " #{string}"
113
+ end
95
114
  else
96
115
  @lines.push(" #{list}")
97
116
  end
@@ -4,7 +4,7 @@ class Ppl::Format::Contact::PhoneNumber < Ppl::Format::Contact
4
4
  attr_writer :table
5
5
 
6
6
  def initialize(colors={})
7
- @table = Ppl::Format::Table.new([:phone_numbers, :type], colors)
7
+ @table = Ppl::Format::Table.new([:star, :phone_numbers, :type], colors)
8
8
  end
9
9
 
10
10
  def process(contact)
@@ -16,11 +16,16 @@ class Ppl::Format::Contact::PhoneNumber < Ppl::Format::Contact
16
16
 
17
17
  def add_row(phone_number)
18
18
  @table.add_row({
19
+ :star => format_star(phone_number),
19
20
  :phone_numbers => phone_number.number,
20
21
  :type => format_type(phone_number.type),
21
22
  })
22
23
  end
23
24
 
25
+ def format_star(phone_number)
26
+ phone_number.preferred ? "*" : " "
27
+ end
28
+
24
29
  def format_type(type)
25
30
  unless type.nil? || type == ""
26
31
  "(#{type})"
@@ -34,8 +34,8 @@ class Ppl::Format::Table
34
34
 
35
35
  def to_s
36
36
  string = ""
37
- @rows.each { |row| string += format_row(row).strip + "\n" }
38
- string.strip
37
+ @rows.each { |row| string += format_row(row).rstrip + "\n" }
38
+ string.rstrip
39
39
  end
40
40
 
41
41
  def disable_colors!