ppl 1.23.0 → 1.24.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.
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!