ppl 1.7.0 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/ppl.rb CHANGED
@@ -1,7 +1,7 @@
1
1
 
2
2
  module Ppl
3
3
 
4
- Version = "1.7.0"
4
+ Version = "1.8.0"
5
5
 
6
6
  module Adapter
7
7
  end
@@ -55,6 +55,7 @@ require "ppl/command/phone"
55
55
  require "ppl/command/mutt"
56
56
  require "ppl/command/post"
57
57
  require "ppl/command/shell"
58
+ require "ppl/command/url"
58
59
 
59
60
  require "ppl/entity/address_book"
60
61
  require "ppl/entity/contact"
@@ -72,6 +73,7 @@ require "ppl/format/address_book/one_line"
72
73
  require "ppl/format/address_book/organizations"
73
74
  require "ppl/format/address_book/phone_numbers"
74
75
  require "ppl/format/address_book/postal_addresses"
76
+ require "ppl/format/address_book/urls"
75
77
  require "ppl/format/contact"
76
78
  require "ppl/format/contact/birthday"
77
79
  require "ppl/format/contact/email_addresses"
@@ -80,6 +82,7 @@ require "ppl/format/contact/name"
80
82
  require "ppl/format/contact/organization"
81
83
  require "ppl/format/contact/phone_number"
82
84
  require "ppl/format/contact/postal_address"
85
+ require "ppl/format/contact/urls"
83
86
  require "ppl/format/postal_address"
84
87
  require "ppl/format/postal_address/one_line"
85
88
  require "ppl/format/table"
@@ -20,6 +20,7 @@ class Ppl::Adapter::Vcard::Vpim
20
20
  encode_phone_number(contact, maker)
21
21
  encode_organization(contact, maker)
22
22
  encode_postal_address(contact, maker)
23
+ encode_urls(contact, maker)
23
24
  end
24
25
  vcard.to_s
25
26
  end
@@ -33,6 +34,7 @@ class Ppl::Adapter::Vcard::Vpim
33
34
  decode_postal_address(vcard, contact)
34
35
  decode_organization(vcard, contact)
35
36
  decode_name(vcard, contact)
37
+ decode_urls(vcard, contact)
36
38
  return contact
37
39
  end
38
40
 
@@ -83,6 +85,10 @@ class Ppl::Adapter::Vcard::Vpim
83
85
  end
84
86
  end
85
87
 
88
+ def encode_urls(contact, vcard_maker)
89
+ contact.urls.each { |url| vcard_maker.add_url(url) }
90
+ end
91
+
86
92
  def decode_birthday(vcard, contact)
87
93
  contact.birthday = vcard.birthday unless vcard.birthday.nil?
88
94
  end
@@ -122,5 +128,9 @@ class Ppl::Adapter::Vcard::Vpim
122
128
  end
123
129
  end
124
130
 
131
+ def decode_urls(vcard, contact)
132
+ vcard.urls.each { |url| contact.urls.push(url.uri) }
133
+ end
134
+
125
135
  end
126
136
 
@@ -18,6 +18,7 @@ class Ppl::Application::Bootstrap
18
18
  Ppl::Command::Phone.new,
19
19
  Ppl::Command::Post.new,
20
20
  Ppl::Command::Shell.new,
21
+ Ppl::Command::Url.new,
21
22
  ]
22
23
  commands.each do |command|
23
24
  command.storage = storage_adapter
@@ -0,0 +1,82 @@
1
+
2
+ class Ppl::Command::Url < Ppl::Application::Command
3
+
4
+ name "url"
5
+ description "List, show or change URLs"
6
+
7
+ attr_writer :show_format
8
+ attr_writer :list_format
9
+
10
+ def initialize
11
+ @show_format = Ppl::Format::Contact::Urls.new
12
+ @list_format = Ppl::Format::AddressBook::Urls.new
13
+ end
14
+
15
+ def options(parser, options)
16
+ parser.banner = "usage: ppl url <contact> [<url>]"
17
+ parser.on("-d", "--delete", "delete url") do
18
+ options[:delete] = true
19
+ end
20
+ end
21
+
22
+ def execute(input, output)
23
+ action = determine_action(input)
24
+ send(action, input, output)
25
+ end
26
+
27
+
28
+ private
29
+
30
+ def determine_action(input)
31
+ if input.arguments[0].nil?
32
+ :list_urls
33
+ elsif input.arguments[1].nil?
34
+ :show_urls
35
+ elsif input.options[:delete]
36
+ :delete_url
37
+ else
38
+ :set_url
39
+ end
40
+ end
41
+
42
+ def list_urls(input, output)
43
+ address_book = @storage.load_address_book
44
+ url_list = @list_format.process(address_book)
45
+ output.line(url_list)
46
+ end
47
+
48
+ def show_urls(input, output)
49
+ contact = @storage.require_contact(input.arguments[0])
50
+ urls = @show_format.process(contact)
51
+ if urls != ""
52
+ output.line(urls)
53
+ true
54
+ else
55
+ false
56
+ end
57
+ end
58
+
59
+ def delete_url(input, output)
60
+ contact = @storage.require_contact(input.arguments[0])
61
+ old_url = input.arguments[1].dup
62
+ contact.urls.delete(old_url) do
63
+ message = sprintf("%s has no such url %s", contact.id, old_url)
64
+ raise Ppl::Error::IncorrectUsage, message
65
+ end
66
+ @storage.save_contact(contact)
67
+ end
68
+
69
+ def set_url(input, output)
70
+ contact = @storage.require_contact(input.arguments[0])
71
+ new_url = input.arguments[1].dup
72
+ if contact.urls.include?(new_url)
73
+ message = sprintf("%s already has url %s", contact.id, new_url)
74
+ raise Ppl::Error::IncorrectUsage, message
75
+ else
76
+ contact.urls.push(new_url)
77
+ end
78
+ @storage.save_contact(contact)
79
+ end
80
+
81
+ end
82
+
@@ -8,9 +8,11 @@ class Ppl::Entity::Contact
8
8
  attr_accessor :phone_number
9
9
  attr_accessor :organization
10
10
  attr_accessor :postal_address
11
+ attr_accessor :urls
11
12
 
12
13
  def initialize
13
14
  @email_addresses = []
15
+ @urls = []
14
16
  end
15
17
 
16
18
  def set_postal_address
@@ -0,0 +1,34 @@
1
+
2
+ class Ppl::Format::AddressBook::Urls < Ppl::Format::AddressBook
3
+
4
+ attr_writer :table
5
+
6
+ def initialize
7
+ @table = Ppl::Format::Table.new([:id, :urls])
8
+ end
9
+
10
+ def process(address_book)
11
+ address_book.each { |contact| add_row(contact) }
12
+ @table.to_s
13
+ end
14
+
15
+
16
+ private
17
+
18
+ def add_row(contact)
19
+ id = sprintf("%s:", contact.id)
20
+ urls = nil
21
+
22
+ if !contact.urls.empty?
23
+ urls = contact.urls.join(", ")
24
+ end
25
+
26
+ @table.add_row({
27
+ :id => id,
28
+ :urls => urls,
29
+ })
30
+ end
31
+
32
+
33
+ end
34
+
@@ -24,6 +24,7 @@ class Ppl::Format::Contact::Full < Ppl::Format::Contact
24
24
  format_email_addresses(contact)
25
25
  format_phone_numbers(contact)
26
26
  format_postal_addresses(contact)
27
+ format_urls(contact)
27
28
 
28
29
  return @lines.join("\n")
29
30
  end
@@ -80,5 +81,13 @@ class Ppl::Format::Contact::Full < Ppl::Format::Contact
80
81
  end
81
82
  end
82
83
 
84
+ def format_urls(contact)
85
+ if !contact.urls.empty?
86
+ @lines.push("")
87
+ @lines.push("URLs:")
88
+ contact.urls.each { |url| @lines.push(" " + url) }
89
+ end
90
+ end
91
+
83
92
  end
84
93
 
@@ -0,0 +1,13 @@
1
+
2
+ class Ppl::Format::Contact::Urls < Ppl::Format::Contact
3
+
4
+ def process(contact)
5
+ lines = []
6
+ contact.urls.each do |url|
7
+ lines.push url
8
+ end
9
+ lines.join("\n")
10
+ end
11
+
12
+ end
13
+
data/ppl.gemspec CHANGED
@@ -2,8 +2,8 @@
2
2
  Gem::Specification.new do |spec|
3
3
 
4
4
  spec.name = "ppl"
5
- spec.version = "1.7.0"
6
- spec.date = "2012-12-29"
5
+ spec.version = "1.8.0"
6
+ spec.date = "2013-01-05"
7
7
 
8
8
  spec.required_ruby_version = ">= 1.9.3"
9
9
 
@@ -68,6 +68,11 @@ describe Ppl::Adapter::Vcard::Vpim, "#encode" do
68
68
  @adapter.encode(@contact).should include("ADR:;;;;South West;;")
69
69
  end
70
70
 
71
+ it "should encode the contact's URL" do
72
+ @contact.urls.push "http://google.com"
73
+ @adapter.encode(@contact).should include("URL:http://google.com")
74
+ end
75
+
71
76
  end
72
77
 
73
78
 
@@ -220,5 +225,17 @@ describe Ppl::Adapter::Vcard::Vpim, "#decode" do
220
225
  contact.postal_address.country.should eq "UK"
221
226
  end
222
227
 
228
+ it "should decode the contact's URL" do
229
+ vcard = [
230
+ "BEGIN:VCARD",
231
+ "N:,test",
232
+ "VERSION:3.0",
233
+ "URL:http://google.com",
234
+ "END:VCARD",
235
+ ].join("\n")
236
+ contact = @adapter.decode(vcard)
237
+ contact.urls.first.should eq "http://google.com"
238
+ end
239
+
223
240
  end
224
241
 
@@ -78,6 +78,9 @@ describe Ppl::Application::Bootstrap do
78
78
  it "should contain the 'shell' command" do
79
79
  @bootstrap.command_suite.find_command("shell").should_not be nil
80
80
  end
81
+ it "should contain the 'url' command" do
82
+ @bootstrap.command_suite.find_command("url").should_not be nil
83
+ end
81
84
  end
82
85
 
83
86
  describe "#configuration" do
@@ -0,0 +1,91 @@
1
+
2
+ describe Ppl::Command::Url do
3
+
4
+ before(:each) do
5
+ @command = Ppl::Command::Url.new
6
+ @input = Ppl::Application::Input.new
7
+ @output = Ppl::Application::Output.new(nil, nil)
8
+ @contact = Ppl::Entity::Contact.new
9
+ @storage = double(Ppl::Adapter::Storage)
10
+
11
+ @list_format = double(Ppl::Format::Contact)
12
+ @show_format = double(Ppl::Format::Contact)
13
+
14
+ @command.storage = @storage
15
+ @command.show_format = @show_format
16
+ @command.list_format = @list_format
17
+ @contact.id = "jim"
18
+ end
19
+
20
+ describe "#name" do
21
+ it "should be 'url'" do
22
+ @command.name.should eq "url"
23
+ end
24
+ end
25
+
26
+ describe "#execute" do
27
+
28
+ it "should list all URLs if no contact ID is given" do
29
+ @storage.should_receive(:load_address_book).and_return(@address_book)
30
+ @list_format.should_receive(:process).and_return("all the URLs")
31
+ @output.should_receive(:line).with("all the URLs")
32
+ @input.arguments = []
33
+ @command.execute(@input, @output)
34
+ end
35
+
36
+ it "should show the current URLs if no new URL is given" do
37
+ @storage.should_receive(:require_contact).and_return(@contact)
38
+ @show_format.should_receive(:process).and_return("http://example.org/~jdoe")
39
+ @output.should_receive(:line).with("http://example.org/~jdoe")
40
+ @input.arguments = ["jim"]
41
+ @command.execute(@input, @output).should eq true
42
+ end
43
+
44
+ it "should not output anything if there's nothing to show" do
45
+ @storage.should_receive(:require_contact).and_return(@contact)
46
+ @show_format.should_receive(:process).and_return("")
47
+ @input.arguments = ["jim"]
48
+ @command.execute(@input, @output).should eq false
49
+ end
50
+
51
+ it "should delete the given URL from the contact if requested" do
52
+ @contact.urls.push("http://example.org/~jdoe")
53
+ @contact.urls.push("http://example.com/~jdoe")
54
+ @storage.should_receive(:require_contact).and_return(@contact)
55
+ @storage.should_receive(:save_contact) do |contact|
56
+ contact.urls.should eq ["http://example.com/~jdoe"]
57
+ end
58
+ @input.arguments = ["jim", "http://example.org/~jdoe"]
59
+ @input.options = { :delete => true }
60
+ @command.execute(@input, @output)
61
+ end
62
+
63
+ it "should raise an error when deleting a non-existent URL" do
64
+ @contact.urls.push("http://example.org/~jdoe")
65
+ @contact.urls.push("http://example.com/~jdoe")
66
+ @storage.should_receive(:require_contact).and_return(@contact)
67
+ @input.arguments = ["jim", "http://example.net/~jdoe"]
68
+ @input.options = { :delete => true }
69
+ expect{@command.execute(@input, nil)}.to raise_error(Ppl::Error::IncorrectUsage)
70
+ end
71
+
72
+ it "should add the given URL to the contact if it's new" do
73
+ @storage.should_receive(:require_contact).and_return(@contact)
74
+ @storage.should_receive(:save_contact) do |contact|
75
+ contact.urls.first.should eq "http://example.org/~jdoe"
76
+ end
77
+ @input.arguments = ["jim", "http://example.org/~jdoe"]
78
+ @command.execute(@input, @output)
79
+ end
80
+
81
+ it "should raise an error if the user is adding a duplicate address" do
82
+ @contact.urls.push "http://example.org/~jdoe"
83
+ @storage.should_receive(:require_contact).and_return(@contact)
84
+ @input.arguments = ["jim", "http://example.org/~jdoe"]
85
+ expect{@command.execute(@input, nil)}.to raise_error(Ppl::Error::IncorrectUsage)
86
+ end
87
+
88
+ end
89
+
90
+ end
91
+
@@ -46,5 +46,11 @@ describe Ppl::Entity::Contact do
46
46
  end
47
47
  end
48
48
 
49
+ describe "#urls" do
50
+ it "should return an array" do
51
+ @contact.urls.should be_a(Array)
52
+ end
53
+ end
54
+
49
55
  end
50
56
 
@@ -0,0 +1,38 @@
1
+
2
+ describe Ppl::Format::AddressBook::Urls do
3
+
4
+ before(:each) do
5
+ @format = Ppl::Format::AddressBook::Urls.new
6
+ @address_book = Ppl::Entity::AddressBook.new
7
+ @contact = Ppl::Entity::Contact.new
8
+ @table = double(Ppl::Format::Table)
9
+
10
+ @contact.id = "test"
11
+ @format.table = @table
12
+
13
+ @address_book.add_contact(@contact)
14
+ end
15
+
16
+ describe "#process" do
17
+
18
+ it "should at least show the contact's id" do
19
+ @table.should_receive(:add_row).with({
20
+ :id => "test:",
21
+ :urls => nil,
22
+ })
23
+ @format.process(@address_book)
24
+ end
25
+
26
+ it "should show a URL if it's available" do
27
+ @contact.urls.push "http://example.org/~jdoe"
28
+ @table.should_receive(:add_row).with({
29
+ :id => "test:",
30
+ :urls => "http://example.org/~jdoe",
31
+ })
32
+ @format.process(@address_book)
33
+ end
34
+
35
+ end
36
+
37
+ end
38
+
@@ -57,6 +57,11 @@ describe Ppl::Format::Contact::Full do
57
57
  @format.process(@contact)
58
58
  end
59
59
 
60
+ it "should show all their URLs" do
61
+ @contact.urls.push "http://example.org"
62
+ @format.process(@contact).should include "http://example.org"
63
+ end
64
+
60
65
  end
61
66
 
62
67
  end
@@ -0,0 +1,23 @@
1
+
2
+ describe Ppl::Format::Contact::Urls do
3
+
4
+ before(:each) do
5
+ @format = Ppl::Format::Contact::Urls.new
6
+ @contact = Ppl::Entity::Contact.new
7
+ end
8
+
9
+ describe "#process" do
10
+
11
+ it "should return an empty string if the contact lacks a URL" do
12
+ @format.process(Ppl::Entity::Contact.new).should eq ""
13
+ end
14
+
15
+ it "should return the contact's URL if one is set" do
16
+ @contact.urls.push "http://example.org/~jdoe"
17
+ @format.process(@contact).should eq "http://example.org/~jdoe"
18
+ end
19
+
20
+ end
21
+
22
+ end
23
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ppl
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.0
4
+ version: 1.8.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-29 00:00:00.000000000 Z
12
+ date: 2013-01-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: inifile
16
- requirement: &7003600 !ruby/object:Gem::Requirement
16
+ requirement: &20369960 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - =
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 2.0.2
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *7003600
24
+ version_requirements: *20369960
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rugged
27
- requirement: &7002340 !ruby/object:Gem::Requirement
27
+ requirement: &20352640 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - =
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 0.17.0.b6
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *7002340
35
+ version_requirements: *20352640
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: vpim
38
- requirement: &7001560 !ruby/object:Gem::Requirement
38
+ requirement: &20351880 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - =
@@ -43,7 +43,7 @@ dependencies:
43
43
  version: '0.695'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *7001560
46
+ version_requirements: *20351880
47
47
  description: CLI Address Book
48
48
  email: henry@henrysmith.org
49
49
  executables:
@@ -89,6 +89,7 @@ files:
89
89
  - lib/ppl/command/rm.rb
90
90
  - lib/ppl/command/shell.rb
91
91
  - lib/ppl/command/show.rb
92
+ - lib/ppl/command/url.rb
92
93
  - lib/ppl/entity/address_book.rb
93
94
  - lib/ppl/entity/contact.rb
94
95
  - lib/ppl/entity/postal_address.rb
@@ -103,6 +104,7 @@ files:
103
104
  - lib/ppl/format/address_book/organizations.rb
104
105
  - lib/ppl/format/address_book/phone_numbers.rb
105
106
  - lib/ppl/format/address_book/postal_addresses.rb
107
+ - lib/ppl/format/address_book/urls.rb
106
108
  - lib/ppl/format/contact.rb
107
109
  - lib/ppl/format/contact/birthday.rb
108
110
  - lib/ppl/format/contact/email_addresses.rb
@@ -111,6 +113,7 @@ files:
111
113
  - lib/ppl/format/contact/organization.rb
112
114
  - lib/ppl/format/contact/phone_number.rb
113
115
  - lib/ppl/format/contact/postal_address.rb
116
+ - lib/ppl/format/contact/urls.rb
114
117
  - lib/ppl/format/postal_address.rb
115
118
  - lib/ppl/format/postal_address/one_line.rb
116
119
  - lib/ppl/format/table.rb
@@ -144,6 +147,7 @@ files:
144
147
  - spec/ppl/command/rm_spec.rb
145
148
  - spec/ppl/command/shell_spec.rb
146
149
  - spec/ppl/command/show_spec.rb
150
+ - spec/ppl/command/url_spec.rb
147
151
  - spec/ppl/entity/address_book_spec.rb
148
152
  - spec/ppl/entity/contact_spec.rb
149
153
  - spec/ppl/entity/postal_address_spec.rb
@@ -155,6 +159,7 @@ files:
155
159
  - spec/ppl/format/address_book/organizations_spec.rb
156
160
  - spec/ppl/format/address_book/phone_numbers_spec.rb
157
161
  - spec/ppl/format/address_book/postal_addresses_spec.rb
162
+ - spec/ppl/format/address_book/urls_spec.rb
158
163
  - spec/ppl/format/address_book_spec.rb
159
164
  - spec/ppl/format/contact/birthday_spec.rb
160
165
  - spec/ppl/format/contact/email_addresses_spec.rb
@@ -163,6 +168,7 @@ files:
163
168
  - spec/ppl/format/contact/organization_spec.rb
164
169
  - spec/ppl/format/contact/phone_number_spec.rb
165
170
  - spec/ppl/format/contact/postal_address_spec.rb
171
+ - spec/ppl/format/contact/urls_spec.rb
166
172
  - spec/ppl/format/contact_spec.rb
167
173
  - spec/ppl/format/postal_address/one_line_spec.rb
168
174
  - spec/ppl/format/postal_address_spec.rb