ppl 0.2.0 → 0.3.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 CHANGED
@@ -52,24 +52,19 @@ fred@example.org
52
52
  $ ppl rm dave
53
53
  ```
54
54
 
55
- ### Rename a contact
55
+ ### Change a contact's ID
56
56
  ```bash
57
57
  $ ppl mv dave david
58
58
  ```
59
59
 
60
- Roadmap
61
- -------
62
-
63
- Support for the following commands is planned.
64
-
65
- ### Change a contact's email address
60
+ ### Change a contact's name
66
61
  ```bash
67
- $ ppl email dave david@example.org
62
+ $ ppl name john "John Smith"
68
63
  ```
69
64
 
70
- ### Change a contact's name
65
+ ### Change a contact's email address
71
66
  ```bash
72
- $ ppl name john "John Smith"
67
+ $ ppl email dave david@example.org
73
68
  ```
74
69
 
75
70
  ### Change a contact's birthday
@@ -77,6 +72,54 @@ $ ppl name john "John Smith"
77
72
  $ ppl birthday john 1980-01-01
78
73
  ```
79
74
 
75
+ Roadmap
76
+ -------
77
+
78
+ One of the core ideas of ppl is for it to turn your address book into a Git
79
+ repository. In an earlier version, this was achieved using
80
+ [Rugged](https://github.com/libgit2/rugged). This functionality will be added
81
+ back in so that contact information can be easily synced between computers. In
82
+ the meantime, ppl simply writes to disk.
83
+
84
+ Other data about contacts will also be supported, such as:
85
+ * Postal addresses
86
+ * Phone numbers
87
+ * The name of the organization to which the contact belongs
88
+ * The position of the contact within their organization
89
+
90
+ The email address handling is currently very rudimentary. The eventual plan is
91
+ to support storage of several addresses per contact. Addresses will be able to
92
+ be organized according to location, such as "home" or "work", and it will be
93
+ possible to mark a particular address as "preferred" for each location.
94
+
95
+ Here's a quick mockup of the sort of output `ppl show` should produce a little
96
+ further down the road once some of these goals have been reached:
97
+
98
+ Fred Smith <fred.smith@example.org>
99
+
100
+ -- Email Addresses -------------------------------------------------------------
101
+
102
+ Home
103
+ * fred.smith@example.org
104
+ fsmith@aol.com
105
+
106
+ Work
107
+ * fred.smith@megacorp.com
108
+ fred.s.123@initrode.net
109
+
110
+ -- Postal Addresses ------------------------------------------------------------
111
+
112
+ Home
113
+ 1 Testing Road, TestVille, Testing, CA, 12345
114
+
115
+ Work
116
+ 30 Business Road, TestVille, Testing, CA, 23454
117
+
118
+ -- Telephone Numbers -----------------------------------------------------------
119
+
120
+ 01234567891
121
+ 09876541233
122
+
80
123
  Contributing
81
124
  ------------
82
125
 
@@ -36,5 +36,15 @@ class Ppl::Adapter::Storage::Disk < Ppl::Adapter::Storage
36
36
  return contact
37
37
  end
38
38
 
39
+ def save_contact(contact)
40
+ vcard = @vcard_adapter.encode(contact)
41
+
42
+ basename = contact.id + ".vcf"
43
+ filename = File.join @path, basename
44
+ File.open(filename, "w") do |file|
45
+ file.write(vcard)
46
+ end
47
+ end
48
+
39
49
  end
40
50
 
@@ -18,6 +18,7 @@ class Ppl::Adapter::Storage
18
18
  if contact.nil?
19
19
  raise Ppl::Error::ContactNotFound, id
20
20
  end
21
+ return contact
21
22
  end
22
23
 
23
24
  def save_contact(contact)
@@ -14,6 +14,11 @@ class Ppl::Adapter::Vcard::Vpim
14
14
  name.given = contact.id unless contact.id.nil?
15
15
  name.fullname = contact.name unless contact.name.nil?
16
16
  end
17
+
18
+ if !contact.email_address.nil?
19
+ maker.add_email(contact.email_address)
20
+ end
21
+
17
22
  end
18
23
 
19
24
  return vcard.to_s
@@ -9,6 +9,9 @@ class Ppl::Application::Bootstrap
9
9
  Ppl::Command::ContactList.new,
10
10
  Ppl::Command::ContactRename.new,
11
11
  Ppl::Command::ContactShow.new,
12
+ Ppl::Command::SetBirthday.new,
13
+ Ppl::Command::SetEmail.new,
14
+ Ppl::Command::SetName.new,
12
15
  ]
13
16
  commands.each do |command|
14
17
  command.storage = storage_adapter
@@ -0,0 +1,30 @@
1
+
2
+ class Ppl::Command::SetBirthday < Ppl::Application::Command
3
+
4
+ def initialize
5
+ @name = "birthday"
6
+ @description = "Change a contact's birthday"
7
+ end
8
+
9
+ def execute(input, output)
10
+
11
+ contact_id = input.arguments.shift
12
+ birthday = input.arguments.shift
13
+
14
+ if contact_id.nil? || birthday.nil?
15
+ raise Ppl::Error::IncorrectUsage
16
+ end
17
+
18
+ birthday = Date.parse birthday
19
+
20
+ contact = @storage.require_contact(contact_id)
21
+
22
+ contact.birthday = birthday
23
+
24
+ storage.save_contact(contact)
25
+
26
+ return true
27
+ end
28
+
29
+ end
30
+
@@ -0,0 +1,23 @@
1
+
2
+ class Ppl::Command::SetEmail < Ppl::Application::Command
3
+
4
+ def initialize
5
+ @name = "email"
6
+ @description = "Change a contact's email address"
7
+ end
8
+
9
+ def execute(input, output)
10
+
11
+ contact_id = input.arguments.shift
12
+ email_address = input.arguments.shift
13
+
14
+ contact = @storage.require_contact(contact_id)
15
+ contact.email_address = email_address
16
+
17
+ storage.save_contact(contact)
18
+
19
+ return true
20
+ end
21
+
22
+ end
23
+
@@ -0,0 +1,28 @@
1
+
2
+ class Ppl::Command::SetName < Ppl::Application::Command
3
+
4
+ def initialize
5
+ @name = "name"
6
+ @description = "Change a contact's name"
7
+ end
8
+
9
+ def execute(input, output)
10
+
11
+ contact_id = input.arguments.shift
12
+ name = input.arguments.shift
13
+
14
+ if contact_id.nil? || name.nil?
15
+ raise Ppl::Error::IncorrectUsage
16
+ end
17
+
18
+ contact = @storage.require_contact(contact_id)
19
+
20
+ contact.name = name.dup
21
+
22
+ storage.save_contact(contact)
23
+
24
+ return true
25
+ end
26
+
27
+ end
28
+
data/lib/ppl.rb CHANGED
@@ -1,7 +1,7 @@
1
1
 
2
2
  module Ppl
3
3
 
4
- Version = "0.2.0"
4
+ Version = "0.3.0"
5
5
 
6
6
  module Adapter
7
7
  end
@@ -43,6 +43,9 @@ require "ppl/command/contact_delete"
43
43
  require "ppl/command/contact_list"
44
44
  require "ppl/command/contact_show"
45
45
  require "ppl/command/contact_rename"
46
+ require "ppl/command/set_birthday"
47
+ require "ppl/command/set_email"
48
+ require "ppl/command/set_name"
46
49
 
47
50
  require "ppl/entity/address_book"
48
51
  require "ppl/entity/contact"
data/ppl.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
  Gem::Specification.new do |spec|
3
3
 
4
4
  spec.name = "ppl"
5
- spec.version = "0.2.0"
5
+ spec.version = "0.3.0"
6
6
  spec.date = "2012-11-23"
7
7
 
8
8
  spec.summary = "CLI Address Book"
@@ -79,5 +79,21 @@ describe Ppl::Adapter::Storage::Disk do
79
79
 
80
80
  end
81
81
 
82
+ describe "#save_contact" do
83
+
84
+ before(:each) do
85
+ end
86
+
87
+ it "should write the contact to disk" do
88
+ @adapter.should_receive(:encode).with(@contact).and_return("asdfg")
89
+
90
+ @contact.id = "test"
91
+ @storage.save_contact(@contact)
92
+
93
+ File.read("/contacts/test.vcf").should eq "asdfg"
94
+ end
95
+
96
+ end
97
+
82
98
  end
83
99
 
@@ -17,6 +17,11 @@ describe Ppl::Adapter::Vcard::Vpim, "#encode" do
17
17
  @adapter.encode(@contact).should include("FN:John Doe")
18
18
  end
19
19
 
20
+ it "should encode the contact's email address" do
21
+ @contact.email_address = "john@example.org"
22
+ @adapter.encode(@contact).should include("EMAIL:john@example.org")
23
+ end
24
+
20
25
  end
21
26
 
22
27
 
@@ -28,12 +28,21 @@ describe Ppl::Application::Bootstrap do
28
28
  it "should contain the 'add' command" do
29
29
  @bootstrap.command_suite.find_command("add").should_not be nil
30
30
  end
31
+ it "should contain the 'birthday' command" do
32
+ @bootstrap.command_suite.find_command("birthday").should_not be nil
33
+ end
34
+ it "should contain the 'email' command" do
35
+ @bootstrap.command_suite.find_command("email").should_not be nil
36
+ end
31
37
  it "should contain the 'ls' command" do
32
38
  @bootstrap.command_suite.find_command("ls").should_not be nil
33
39
  end
34
40
  it "should contain the 'mv' command" do
35
41
  @bootstrap.command_suite.find_command("mv").should_not be nil
36
42
  end
43
+ it "should contain the 'name' command" do
44
+ @bootstrap.command_suite.find_command("name").should_not be nil
45
+ end
37
46
  it "should contain the 'rm' command" do
38
47
  @bootstrap.command_suite.find_command("rm").should_not be nil
39
48
  end
@@ -0,0 +1,50 @@
1
+
2
+ describe Ppl::Command::SetBirthday do
3
+
4
+ before(:each) do
5
+ @input = Ppl::Application::Input.new
6
+ @output = Ppl::Application::Output.new(nil, nil)
7
+ @contact = Ppl::Entity::Contact.new
8
+ @command = Ppl::Command::SetBirthday.new
9
+ @storage = double(Ppl::Adapter::Storage)
10
+
11
+ @command.storage = @storage
12
+ @contact.id = "jim"
13
+ end
14
+
15
+ describe "#name" do
16
+ it "should be 'birthday'" do
17
+ @command.name.should eq "birthday"
18
+ end
19
+ end
20
+
21
+ describe "#execute" do
22
+
23
+ it "should change the contact's birthday" do
24
+ @storage.should_receive(:require_contact).and_return(@contact)
25
+ @storage.should_receive(:save_contact) do |contact|
26
+ contact.birthday.strftime.should eq "1980-01-01"
27
+ end
28
+ @input.arguments = ["jim", "1980-01-01"]
29
+ @command.execute(@input, @output)
30
+ end
31
+
32
+ it "should raise an error if no contact ID is given" do
33
+ @input.arguments = [nil, "1980-01-01"]
34
+ expect{@command.execute(@input, @output)}.to raise_error(Ppl::Error::IncorrectUsage)
35
+ end
36
+
37
+ it "should raise an error if no birthday is given" do
38
+ @input.arguments = ["jim"]
39
+ expect{@command.execute(@input, @output)}.to raise_error(Ppl::Error::IncorrectUsage)
40
+ end
41
+
42
+ it "should raise an error if the birthday isn't a valid date" do
43
+ @input.arguments = ["jim", "poiuytrewq"]
44
+ expect{@command.execute(@input, @output)}.to raise_error(ArgumentError)
45
+ end
46
+
47
+ end
48
+
49
+ end
50
+
@@ -0,0 +1,38 @@
1
+
2
+ describe Ppl::Command::SetEmail do
3
+
4
+ before(:each) do
5
+ @input = Ppl::Application::Input.new
6
+ @output = Ppl::Application::Output.new(nil, nil)
7
+ @contact = Ppl::Entity::Contact.new
8
+ @command = Ppl::Command::SetEmail.new
9
+ @storage = double(Ppl::Adapter::Storage)
10
+
11
+ @command.storage = @storage
12
+ @contact.id = "jim"
13
+ end
14
+
15
+ describe "#name" do
16
+ it "should be 'email'" do
17
+ @command.name.should eq "email"
18
+ end
19
+ end
20
+
21
+ describe "#execute" do
22
+
23
+ it "should change the contact's email address" do
24
+
25
+ @storage.should_receive(:require_contact).and_return(@contact)
26
+
27
+ @storage.should_receive(:save_contact) do |contact|
28
+ contact.email_address.should eq "jim@example.org"
29
+ end
30
+
31
+ @input.arguments = ["jim", "jim@example.org"]
32
+ @command.execute(@input, @output)
33
+ end
34
+
35
+ end
36
+
37
+ end
38
+
@@ -0,0 +1,45 @@
1
+
2
+ describe Ppl::Command::SetName do
3
+
4
+ before(:each) do
5
+ @input = Ppl::Application::Input.new
6
+ @output = Ppl::Application::Output.new(nil, nil)
7
+ @contact = Ppl::Entity::Contact.new
8
+ @command = Ppl::Command::SetName.new
9
+ @storage = double(Ppl::Adapter::Storage)
10
+
11
+ @command.storage = @storage
12
+ @contact.id = "jim"
13
+ end
14
+
15
+ describe "#name" do
16
+ it "should be 'name'" do
17
+ @command.name.should eq "name"
18
+ end
19
+ end
20
+
21
+ describe "#execute" do
22
+
23
+ it "should change the contact's name" do
24
+ @storage.should_receive(:require_contact).and_return(@contact)
25
+ @storage.should_receive(:save_contact) do |contact|
26
+ contact.name.should eq "Jim Jamieson"
27
+ end
28
+ @input.arguments = ["jim", "Jim Jamieson"]
29
+ @command.execute(@input, @output)
30
+ end
31
+
32
+ it "should raise an error if no contact ID is given" do
33
+ @input.arguments = [nil, "Jim Jamieson"]
34
+ expect{@command.execute(@input, @output)}.to raise_error(Ppl::Error::IncorrectUsage)
35
+ end
36
+
37
+ it "should raise an error if no name is given" do
38
+ @input.arguments = ["jim"]
39
+ expect{@command.execute(@input, @output)}.to raise_error(Ppl::Error::IncorrectUsage)
40
+ end
41
+
42
+ end
43
+
44
+ end
45
+
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: 0.2.0
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -44,6 +44,9 @@ files:
44
44
  - lib/ppl/command/contact_list.rb
45
45
  - lib/ppl/command/contact_rename.rb
46
46
  - lib/ppl/command/contact_show.rb
47
+ - lib/ppl/command/set_birthday.rb
48
+ - lib/ppl/command/set_email.rb
49
+ - lib/ppl/command/set_name.rb
47
50
  - lib/ppl/entity/address_book.rb
48
51
  - lib/ppl/entity/contact.rb
49
52
  - lib/ppl/error/contact_not_found.rb
@@ -66,6 +69,9 @@ files:
66
69
  - spec/ppl/command/contact_list_spec.rb
67
70
  - spec/ppl/command/contact_rename_spec.rb
68
71
  - spec/ppl/command/contact_show_spec.rb
72
+ - spec/ppl/command/set_birthday_spec.rb
73
+ - spec/ppl/command/set_email_spec.rb
74
+ - spec/ppl/command/set_name_spec.rb
69
75
  - spec/ppl/entity/address_book_spec.rb
70
76
  - spec/ppl/entity/contact_spec.rb
71
77
  - spec/spec_helper.rb