ppl 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -15,6 +15,12 @@ like "people". You might be interested in ppl if:
15
15
  Usage
16
16
  -----
17
17
 
18
+ ### Add a contact
19
+
20
+ ```bash
21
+ $ ppl add adam "Adam Brown"
22
+ ```
23
+
18
24
  ### List all contacts
19
25
 
20
26
  ```bash
@@ -44,16 +50,17 @@ dave Dave Jones 1980-01-02 100 days
44
50
  joe Joe Bloggs 1980-01-03 101 days
45
51
  ```
46
52
 
53
+ ### Delete a contact
54
+
55
+ ```bash
56
+ $ ppl rm workadam
57
+ ```
58
+
47
59
  Roadmap
48
60
  -------
49
61
 
50
62
  Support for the following commands is planned.
51
63
 
52
- ### Add a contact
53
- ```bash
54
- $ ppl add adam --email=adam.brown@example.org --birthday=1980-01-04
55
- ```
56
-
57
64
  ### Update a contact
58
65
  ```bash
59
66
  $ ppl set adam --email=adam.brown@example.com
@@ -64,11 +71,6 @@ $ ppl set adam --email=adam.brown@example.com
64
71
  $ ppl mv adam workadam
65
72
  ```
66
73
 
67
- ### Delete a contact
68
- ```bash
69
- $ ppl rm workadam
70
- ```
71
-
72
74
  In a highly optimistic version of the future, I plan to integrate Git.
73
75
  Any commands that modify the address book will also commit their changes.
74
76
  Then this will be posisble:
data/bin/ppl CHANGED
@@ -11,5 +11,6 @@ class String
11
11
  alias_method :each, :each_line
12
12
  end
13
13
 
14
- Ppl::CLI.start *ARGV
14
+ cli = Ppl::CLI.new
15
+ cli.run ARGV
15
16
 
@@ -12,9 +12,13 @@ class Ppl::Address_Book
12
12
 
13
13
  def contact(id)
14
14
  filename = File.join @path, id + ".vcard"
15
- vcard = IO.read filename
16
- vcard = Vpim::Vcard.decode(vcard).first
17
- contact = Ppl::Contact.new(id, vcard)
15
+ if !File.exists? filename
16
+ return nil
17
+ end
18
+
19
+ vcard = IO.read filename
20
+ vcard = Vpim::Vcard.decode(vcard).first
21
+ contact = Ppl::Contact.new(id, vcard)
18
22
  end
19
23
 
20
24
  def contacts
@@ -38,5 +42,33 @@ class Ppl::Address_Book
38
42
  self.find_all { |contact| contact.birthday.nil? == false }
39
43
  end
40
44
 
45
+ def create_contact(id, full_name)
46
+
47
+ vcard = Vpim::Vcard::Maker.make2 do |maker|
48
+ maker.add_name do |name|
49
+ name.given = full_name
50
+ end
51
+ end
52
+
53
+ contact = Ppl::Contact.new(id, vcard)
54
+ self.save_contact contact
55
+ contact
56
+ end
57
+
58
+ def delete_contact(id)
59
+ filename = File.join @path, id + ".vcard"
60
+ if !File.exists? filename
61
+ return false
62
+ end
63
+ File.delete filename
64
+ end
65
+
66
+ def save_contact(contact)
67
+ filename = File.join @path, contact.id + ".vcard"
68
+ File.open(filename, "w") do |file|
69
+ file.write contact.to_s
70
+ end
71
+ end
72
+
41
73
  end
42
74
 
data/lib/ppl/cli.rb CHANGED
@@ -1,22 +1,49 @@
1
1
 
2
2
  require "ppl"
3
- require "ppl/command"
3
+ require "optparse"
4
4
 
5
5
  class Ppl::CLI
6
6
 
7
- def self.start(*args)
7
+ def initialize
8
+ @address_book = Ppl::Address_Book.new("/home/h2s/doc/contacts")
9
+ @commands = commands
8
10
 
9
- command = args.shift
10
- if command
11
- command = command.strip
12
- else
13
- command = "help"
11
+ find_command("help").commands = @commands
12
+ end
13
+
14
+ def run(argv)
15
+ command_name = argv.shift
16
+ command = find_command command_name
17
+
18
+ if command.nil?
19
+ command = find_command "help"
20
+ end
21
+
22
+ command.run argv
23
+ end
24
+
25
+
26
+ private
27
+
28
+ def commands
29
+ @commands = []
30
+ Ppl::Command.constants.each do |name|
31
+ constant = Ppl::Command.const_get(name)
32
+ @commands.push constant.new
14
33
  end
34
+ @commands.sort! { |a,b| a.name <=> b.name }
15
35
 
16
- Ppl::Command.load
17
- Ppl::Command.run(command, args)
36
+ @commands.each do |command|
37
+ command.address_book = @address_book
38
+ command.commands = @commands
39
+ end
40
+ end
18
41
 
42
+ def find_command(name)
43
+ matches = @commands.select { |command| command.name == name }
44
+ matches.first
19
45
  end
20
46
 
47
+
21
48
  end
22
49
 
@@ -0,0 +1,40 @@
1
+
2
+ class Ppl::Command::Add < Ppl::Command
3
+
4
+ def name
5
+ "add"
6
+ end
7
+
8
+ def summary
9
+ "Add a new contact"
10
+ end
11
+
12
+ def banner
13
+ "Usage: ppl add <contact> <name>"
14
+ end
15
+
16
+ def options(parser)
17
+ end
18
+
19
+ def execute(argv, options)
20
+
21
+ contact_id = argv.shift
22
+ name = argv.shift
23
+
24
+ if contact_id.nil? || name.nil?
25
+ $stderr.puts @option_parser
26
+ return false
27
+ end
28
+
29
+ contact = @address_book.contact contact_id
30
+ if !contact.nil?
31
+ raise "contact '#{contact_id}' already exists"
32
+ end
33
+
34
+ contact = @address_book.create_contact contact_id, name
35
+ puts contact
36
+
37
+ end
38
+
39
+ end
40
+
@@ -1,5 +1,5 @@
1
1
 
2
- class Ppl::Command::Birthdays < Ppl::Command::Base
2
+ class Ppl::Command::Birthdays < Ppl::Command
3
3
 
4
4
  def name
5
5
  "birthdays"
@@ -9,7 +9,14 @@ class Ppl::Command::Birthdays < Ppl::Command::Base
9
9
  "Show a list of upcoming birthdays"
10
10
  end
11
11
 
12
- def index
12
+ def banner
13
+ "Usage: ppl birthdays"
14
+ end
15
+
16
+ def options(parser)
17
+ end
18
+
19
+ def execute(argv, options)
13
20
  today = Date.today
14
21
 
15
22
  @address_book.with_birthday.each do |contact|
@@ -1,5 +1,5 @@
1
1
 
2
- class Ppl::Command::Help < Ppl::Command::Base
2
+ class Ppl::Command::Help < Ppl::Command
3
3
 
4
4
  def name
5
5
  "help"
@@ -9,20 +9,23 @@ class Ppl::Command::Help < Ppl::Command::Base
9
9
  "Show a list of available commands"
10
10
  end
11
11
 
12
- def index
12
+ def banner
13
+ "Usage: ppl <command> [options]"
14
+ end
15
+
16
+ def options(parser)
17
+ end
13
18
 
19
+ def execute(argv, options)
20
+ puts @option_parser
14
21
  puts
15
- Ppl::Command.constants.each do |constant|
16
- if constant.to_s != "Base"
17
- command = Ppl::Command.const_get(constant).new(@arguments, @options)
18
- puts(
19
- sprintf(" %-10s", command.name) +
20
- sprintf("%s", command.summary)
21
- )
22
- end
22
+ @commands.each do |command|
23
+ puts(
24
+ sprintf(" %-10s", command.name) +
25
+ sprintf("%s", command.summary)
26
+ )
23
27
  end
24
28
  puts
25
-
26
29
  end
27
30
 
28
31
  end
@@ -1,5 +1,5 @@
1
1
 
2
- class Ppl::Command::List < Ppl::Command::Base
2
+ class Ppl::Command::List < Ppl::Command
3
3
 
4
4
  def name
5
5
  "list"
@@ -9,14 +9,22 @@ class Ppl::Command::List < Ppl::Command::Base
9
9
  "Show a list of all contacts"
10
10
  end
11
11
 
12
- def index
12
+ def banner
13
+ "Usage: ppl list"
14
+ end
15
+
16
+ def options(parser)
17
+ end
18
+
19
+ def execute(argv, options)
13
20
  @address_book.each do |contact|
14
21
  puts(
15
- sprintf("%-20s", contact.id).red +
16
- sprintf("%-20s", contact.name).yellow +
17
- sprintf("%-20s", contact.email).blue
22
+ sprintf("%-10s", contact.id + ":") +
23
+ sprintf("%s ", contact.name) +
24
+ sprintf("%-20s", "<" + contact.email + ">")
18
25
  )
19
26
  end
27
+ return true
20
28
  end
21
29
 
22
30
  end
@@ -0,0 +1,38 @@
1
+
2
+ class Ppl::Command::Rm < Ppl::Command
3
+
4
+ def name
5
+ "rm"
6
+ end
7
+
8
+ def summary
9
+ "Delete a contact"
10
+ end
11
+
12
+ def banner
13
+ "Usage: ppl rm <contact>"
14
+ end
15
+
16
+ def options(parser)
17
+ end
18
+
19
+ def execute(argv, options)
20
+
21
+ contact_id = argv.first
22
+
23
+ if contact_id.nil?
24
+ $stderr.puts @option_parser
25
+ return false
26
+ end
27
+
28
+ contact = @address_book.contact contact_id
29
+ if contact.nil?
30
+ raise "contact '#{contact_id}' not found"
31
+ end
32
+
33
+ @address_book.delete_contact contact_id
34
+
35
+ end
36
+
37
+ end
38
+
@@ -0,0 +1,49 @@
1
+
2
+ class Ppl::Command::Set < Ppl::Command
3
+
4
+ def name
5
+ "set"
6
+ end
7
+
8
+ def summary
9
+ "Change the details of a contact"
10
+ end
11
+
12
+ def banner
13
+ "Usage: ppl set <contact> [options]"
14
+ end
15
+
16
+ def options(parser)
17
+ parser.on("-e", "--email <email>", "Email address") do |email|
18
+ @options[:email] = email
19
+ end
20
+ end
21
+
22
+ def execute(argv, options)
23
+
24
+ contact_id = argv.first
25
+
26
+ if contact_id.nil?
27
+ $stderr.puts @option_parser
28
+ return false
29
+ end
30
+
31
+ contact = @address_book.contact contact_id
32
+ if contact.nil?
33
+ raise "contact '#{contact_id}' not found"
34
+ end
35
+
36
+ contact.vcard.make do |maker|
37
+ maker.name do |name|
38
+ name.fullname = 's'
39
+ end
40
+ puts maker
41
+ end
42
+
43
+ if !options[:email].nil?
44
+ #contact.vcard.add_email options[:email]
45
+ end
46
+ end
47
+
48
+ end
49
+
@@ -1,7 +1,5 @@
1
1
 
2
- require "ppl/command/base"
3
-
4
- class Ppl::Command::Show < Ppl::Command::Base
2
+ class Ppl::Command::Show < Ppl::Command
5
3
 
6
4
  def name
7
5
  "show"
@@ -11,14 +9,34 @@ class Ppl::Command::Show < Ppl::Command::Base
11
9
  "Show full details of a single contact"
12
10
  end
13
11
 
14
- def index
15
- contact = @address_book.contact @arguments.first
12
+ def banner
13
+ "Usage: ppl show <contact>"
14
+ end
15
+
16
+ def options(parser)
17
+ end
18
+
19
+ def execute(argv, options)
20
+
21
+ contact_id = argv.first
22
+
23
+ if contact_id.nil?
24
+ $stderr.puts @option_parser
25
+ return false
26
+ end
27
+
28
+ contact = @address_book.contact contact_id
29
+ if contact.nil?
30
+ raise "contact '#{contact_id}' not found"
31
+ end
32
+
16
33
 
17
- puts contact.name.yellow
34
+ puts contact.name
18
35
  contact.emails.each do |email|
19
- puts email.blue
36
+ puts email
20
37
  end
21
38
 
39
+ return true
22
40
  end
23
41
 
24
42
  end
data/lib/ppl/command.rb CHANGED
@@ -1,26 +1,55 @@
1
1
 
2
- module Ppl
3
- module Command
2
+ class Ppl::Command
4
3
 
5
- def self.load
6
- Dir[File.join(File.dirname(__FILE__), "command", "*.rb")].each do |file|
7
- require file
8
- end
4
+ attr_accessor :address_book
5
+ attr_accessor :commands
6
+
7
+ def initialize
8
+ @option_parser = OptionParser.new do |parser|
9
+ parser.banner = self.banner
10
+ self.options parser
9
11
  end
12
+ end
10
13
 
11
- def self.run(command, arguments=[])
14
+ def name
15
+ raise NotImplementedError
16
+ end
12
17
 
13
- options = {
14
- :path => "/home/h2s/doc/contacts"
15
- }
18
+ def summary
19
+ raise NotImplementedError
20
+ end
16
21
 
17
- klass = command.capitalize
22
+ def banner
23
+ raise NotImplementedError
24
+ end
25
+
26
+ def options(parser)
27
+ raise NotImplementedError
28
+ end
18
29
 
19
- command = Ppl::Command::List.new(arguments, options)
20
- command = Ppl::Command.const_get(klass).new(arguments, options)
21
- command.send("index")
30
+ def run(argv)
31
+
32
+ @options = {}
33
+ begin
34
+ @option_parser.parse! ARGV
35
+ rescue OptionParser::ParseError
36
+ $stderr.puts $!
37
+ $stderr.puts @option_parser
38
+ return false
39
+ end
40
+
41
+ begin
42
+ status = self.execute argv, @options
43
+ rescue RuntimeError
44
+ $stderr.puts "ppl: " + $!.to_s
22
45
  end
23
46
 
47
+ return status
24
48
  end
49
+
50
+ def execute(argv, options)
51
+ raise NotImplementedError
52
+ end
53
+
25
54
  end
26
55
 
data/lib/ppl/contact.rb CHANGED
@@ -4,6 +4,7 @@ require "active_support/core_ext/time/calculations.rb"
4
4
  class Ppl::Contact
5
5
 
6
6
  attr_reader :id
7
+ attr_reader :vcard
7
8
 
8
9
  def initialize(id, vcard)
9
10
  @id = id
@@ -34,5 +35,9 @@ class Ppl::Contact
34
35
  @vcard.name.fullname
35
36
  end
36
37
 
38
+ def to_s
39
+ @vcard.to_s
40
+ end
41
+
37
42
  end
38
43
 
data/lib/ppl.rb CHANGED
@@ -4,4 +4,13 @@ end
4
4
 
5
5
  require "ppl/address_book"
6
6
  require "ppl/contact"
7
+ require "ppl/cli"
8
+ require "ppl/command"
9
+ require "ppl/command/add"
10
+ require "ppl/command/birthdays"
11
+ require "ppl/command/help"
12
+ require "ppl/command/list"
13
+ require "ppl/command/rm"
14
+ require "ppl/command/set"
15
+ require "ppl/command/show"
7
16
 
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 = "0.0.4"
6
- spec.date = "2012-11-11"
5
+ spec.version = "0.0.5"
6
+ spec.date = "2012-11-13"
7
7
 
8
8
  spec.summary = "CLI Address Book"
9
9
  spec.description = "Command-line driven address book"
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.0.4
4
+ version: 0.0.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-11 00:00:00.000000000 Z
12
+ date: 2012-11-13 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Command-line driven address book
15
15
  email: henry@henrysmith.org
@@ -27,13 +27,14 @@ files:
27
27
  - lib/ppl/address_book.rb
28
28
  - lib/ppl/cli.rb
29
29
  - lib/ppl/command.rb
30
- - lib/ppl/command/base.rb
30
+ - lib/ppl/command/add.rb
31
31
  - lib/ppl/command/birthdays.rb
32
32
  - lib/ppl/command/help.rb
33
33
  - lib/ppl/command/list.rb
34
+ - lib/ppl/command/rm.rb
35
+ - lib/ppl/command/set.rb
34
36
  - lib/ppl/command/show.rb
35
37
  - lib/ppl/contact.rb
36
- - lib/ppl/ppl.rb
37
38
  - ppl.gemspec
38
39
  homepage: https://github.com/h2s/ppl
39
40
  licenses:
@@ -1,29 +0,0 @@
1
-
2
- require "vpim/vcard"
3
- require "colored"
4
-
5
-
6
- class Ppl::Command::Base
7
-
8
-
9
- attr_reader :arguments
10
- attr_reader :options
11
-
12
-
13
- def initialize(arguments=[], options={})
14
- @arguments = arguments
15
- @options = options
16
-
17
- @address_book = Ppl::Address_Book.new(@options[:path])
18
- end
19
-
20
-
21
- def name
22
- end
23
-
24
-
25
- def summary
26
- end
27
-
28
- end
29
-
data/lib/ppl/ppl.rb DELETED
@@ -1,15 +0,0 @@
1
-
2
-
3
- module Ppl
4
-
5
- class App
6
-
7
- def run
8
- puts ARGV
9
- cmd = Ppl::Commands::List.new
10
- end
11
-
12
- end
13
-
14
- end
15
-