tact 1.2.23
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.
- checksums.yaml +7 -0
 - data/.gitignore +9 -0
 - data/Gemfile +4 -0
 - data/LICENSE.txt +21 -0
 - data/README.md +37 -0
 - data/Rakefile +2 -0
 - data/bin/console +14 -0
 - data/bin/setup +8 -0
 - data/bin/tact +4 -0
 - data/lib/tact/card.rb +21 -0
 - data/lib/tact/contact.rb +82 -0
 - data/lib/tact/database.rb +47 -0
 - data/lib/tact/email.rb +57 -0
 - data/lib/tact/phone_number.rb +78 -0
 - data/lib/tact/rolodex.rb +129 -0
 - data/lib/tact/tact.rb +205 -0
 - data/lib/tact/version.rb +3 -0
 - data/lib/tact.rb +1 -0
 - data/tact.gemspec +27 -0
 - metadata +119 -0
 
    
        checksums.yaml
    ADDED
    
    | 
         @@ -0,0 +1,7 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ---
         
     | 
| 
      
 2 
     | 
    
         
            +
            SHA1:
         
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 646f2aeb31eeec006ea63f14c1e323cd8f4943c4
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 03ae8aee41865c91c1052b986b261c6077f021b3
         
     | 
| 
      
 5 
     | 
    
         
            +
            SHA512:
         
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 22c70b517f55076452ed7580571c8d609ef11608a3cd8a9f26d192ff6eaf401b0c6d2adb0fdd6ebeb6a7f200d13bd6689748f442b4755370a1916b9f351037bb
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 5bb758c735ccf9df330fa73efa6def114e46543843b7d79313b896022a8cf60e2bf027240935086b6144bb7d19e1c0f7417afcf246a16b02edfa6ab5b97c97d7
         
     | 
    
        data/.gitignore
    ADDED
    
    
    
        data/Gemfile
    ADDED
    
    
    
        data/LICENSE.txt
    ADDED
    
    | 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            The MIT License (MIT)
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Copyright (c) 2016 ollieshmollie
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            Permission is hereby granted, free of charge, to any person obtaining a copy
         
     | 
| 
      
 6 
     | 
    
         
            +
            of this software and associated documentation files (the "Software"), to deal
         
     | 
| 
      
 7 
     | 
    
         
            +
            in the Software without restriction, including without limitation the rights
         
     | 
| 
      
 8 
     | 
    
         
            +
            to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
         
     | 
| 
      
 9 
     | 
    
         
            +
            copies of the Software, and to permit persons to whom the Software is
         
     | 
| 
      
 10 
     | 
    
         
            +
            furnished to do so, subject to the following conditions:
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            The above copyright notice and this permission notice shall be included in
         
     | 
| 
      
 13 
     | 
    
         
            +
            all copies or substantial portions of the Software.
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
         
     | 
| 
      
 16 
     | 
    
         
            +
            IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
         
     | 
| 
      
 17 
     | 
    
         
            +
            FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
         
     | 
| 
      
 18 
     | 
    
         
            +
            AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
         
     | 
| 
      
 19 
     | 
    
         
            +
            LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
         
     | 
| 
      
 20 
     | 
    
         
            +
            OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
         
     | 
| 
      
 21 
     | 
    
         
            +
            THE SOFTWARE.
         
     | 
    
        data/README.md
    ADDED
    
    | 
         @@ -0,0 +1,37 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # tact
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            A command line rolodex.
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            ## Installation
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
              `$ gem install tact`
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            ## Usage
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            ```     
         
     | 
| 
      
 12 
     | 
    
         
            +
              -v                                    Current version
         
     | 
| 
      
 13 
     | 
    
         
            +
              -h                                    Help
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              <param>                               Search by name
         
     | 
| 
      
 16 
     | 
    
         
            +
              -p <param>                            Search by number
         
     | 
| 
      
 17 
     | 
    
         
            +
              -e <param>                            Search by email
         
     | 
| 
      
 18 
     | 
    
         
            +
              -n <first> <last>                     Adds new name
         
     | 
| 
      
 19 
     | 
    
         
            +
              -np <index> <type> <num>              Adds contact number
         
     | 
| 
      
 20 
     | 
    
         
            +
              -ne <index> <address>                 Adds contact email
         
     | 
| 
      
 21 
     | 
    
         
            +
              -d <index>                            Deletes contact
         
     | 
| 
      
 22 
     | 
    
         
            +
              -dp <index> <num_index>               Deletes contact number
         
     | 
| 
      
 23 
     | 
    
         
            +
              -de <index> <e_index>                 Deletes contact email
         
     | 
| 
      
 24 
     | 
    
         
            +
              -u <index> <first> <last>             Edits contact name
         
     | 
| 
      
 25 
     | 
    
         
            +
              -up <index> <num_index> <type> <num>  Edits contact number
         
     | 
| 
      
 26 
     | 
    
         
            +
              -ue <index> <e_index> <address>       Edits contact email
         
     | 
| 
      
 27 
     | 
    
         
            +
            ```
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            ## Contributing
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            Bug reports and pull requests are welcome on GitHub at https://github.com/ollieshmollie/tact.
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            ## License
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
    
        data/Rakefile
    ADDED
    
    
    
        data/bin/console
    ADDED
    
    | 
         @@ -0,0 +1,14 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require "bundler/setup"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require "tact"
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            # You can add fixtures and/or initialization code here to make experimenting
         
     | 
| 
      
 7 
     | 
    
         
            +
            # with your gem easier. You can also use a different console, if you like.
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            # (If you use this, don't forget to add pry to your Gemfile!)
         
     | 
| 
      
 10 
     | 
    
         
            +
            # require "pry"
         
     | 
| 
      
 11 
     | 
    
         
            +
            # Pry.start
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            require "irb"
         
     | 
| 
      
 14 
     | 
    
         
            +
            IRB.start
         
     | 
    
        data/bin/setup
    ADDED
    
    
    
        data/bin/tact
    ADDED
    
    
    
        data/lib/tact/card.rb
    ADDED
    
    | 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require_relative 'contact'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Tact
         
     | 
| 
      
 4 
     | 
    
         
            +
              class Card
         
     | 
| 
      
 5 
     | 
    
         
            +
                attr_reader :contact
         
     | 
| 
      
 6 
     | 
    
         
            +
                def initialize(contact, index="*")
         
     | 
| 
      
 7 
     | 
    
         
            +
                  @contact = contact
         
     | 
| 
      
 8 
     | 
    
         
            +
                  @index = index
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @phone_numbers = contact.phone_numbers
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @emails = contact.emails
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                def to_s
         
     | 
| 
      
 14 
     | 
    
         
            +
                  string = "=" * 40 + "\n"
         
     | 
| 
      
 15 
     | 
    
         
            +
                  string += "[#{@index}]".red + " #{@contact.to_s}"
         
     | 
| 
      
 16 
     | 
    
         
            +
                  @phone_numbers.each_with_index {|number, i| string += "\s\s" + "[#{i + 1}] " + number.to_s + "\n"}
         
     | 
| 
      
 17 
     | 
    
         
            +
                  @emails.each_with_index {|address, i| string += "\s\s\s\s" + "[#{i + 1}] " + address.to_s + "\n"}
         
     | 
| 
      
 18 
     | 
    
         
            +
                  string += "=" * 40 + "\n"
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/tact/contact.rb
    ADDED
    
    | 
         @@ -0,0 +1,82 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'colored'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require_relative 'phone_number'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require_relative "email"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module Tact
         
     | 
| 
      
 6 
     | 
    
         
            +
              class Contact
         
     | 
| 
      
 7 
     | 
    
         
            +
                attr_reader :id
         
     | 
| 
      
 8 
     | 
    
         
            +
                attr_accessor :index, :first_name, :last_name
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                @@db = Database.new.db
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                def self.from_hash(hash)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  contact = self.new(hash["first_name"], hash["last_name"], hash["id"])
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                def self.all
         
     | 
| 
      
 17 
     | 
    
         
            +
                  contact_hashes = @@db.execute("select * from contacts order by last_name asc, first_name asc;")
         
     | 
| 
      
 18 
     | 
    
         
            +
                  contact_hashes.each_with_index.map {|c_hash, index| self.from_hash(c_hash) }
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                def self.find_by_id(id)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  contact_hashes = @@db.execute("select * from contacts where id = ?", [id])
         
     | 
| 
      
 23 
     | 
    
         
            +
                  self.from_hash(contact_hashes[0]) if !contact_hashes.empty?
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                def self.find_by_first_name(first_name)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  results = @@db.execute("select * from contacts where upper(first_name) = upper(?);", [first_name])
         
     | 
| 
      
 28 
     | 
    
         
            +
                  results.map {|c_hash| self.from_hash(c_hash) }
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                def self.find_by_last_name(last_name)
         
     | 
| 
      
 32 
     | 
    
         
            +
                  results = @@db.execute("select * from contacts where upper(last_name) = upper(?);", [last_name])
         
     | 
| 
      
 33 
     | 
    
         
            +
                  results.map {|c_hash| self.from_hash(c_hash) }
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                def self.delete(id)
         
     | 
| 
      
 37 
     | 
    
         
            +
                  @@db.execute("delete from contacts where id = ?;", [id])
         
     | 
| 
      
 38 
     | 
    
         
            +
                  @@db.execute("select changes();")[0]["changes()"] == 1 ? true : false
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                def initialize(first_name, last_name, primary_key=nil)
         
     | 
| 
      
 42 
     | 
    
         
            +
                  @id = primary_key
         
     | 
| 
      
 43 
     | 
    
         
            +
                  @first_name = first_name.downcase.capitalize
         
     | 
| 
      
 44 
     | 
    
         
            +
                  @last_name = last_name.downcase.capitalize
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                def save
         
     | 
| 
      
 48 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 49 
     | 
    
         
            +
                    if @id == nil
         
     | 
| 
      
 50 
     | 
    
         
            +
                      if @@db.execute("insert into contacts (first_name, last_name) values (?, ?);", [@first_name, @last_name])
         
     | 
| 
      
 51 
     | 
    
         
            +
                        @id = @@db.execute("select last_insert_rowid()")[0]["last_insert_rowid()"]
         
     | 
| 
      
 52 
     | 
    
         
            +
                        self
         
     | 
| 
      
 53 
     | 
    
         
            +
                      else
         
     | 
| 
      
 54 
     | 
    
         
            +
                        false
         
     | 
| 
      
 55 
     | 
    
         
            +
                      end
         
     | 
| 
      
 56 
     | 
    
         
            +
                    else
         
     | 
| 
      
 57 
     | 
    
         
            +
                      @@db.execute("update contacts set first_name = ?, last_name = ? where id = ?;", [@first_name, @last_name, @id]) ? self : false
         
     | 
| 
      
 58 
     | 
    
         
            +
                    end
         
     | 
| 
      
 59 
     | 
    
         
            +
                  rescue
         
     | 
| 
      
 60 
     | 
    
         
            +
                    puts "Error: Contact already exists".red 
         
     | 
| 
      
 61 
     | 
    
         
            +
                  end
         
     | 
| 
      
 62 
     | 
    
         
            +
                end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                def phone_numbers
         
     | 
| 
      
 65 
     | 
    
         
            +
                  number_hashes = @@db.execute("select * from phone_numbers where contact_id = ? order by type asc;", [@id])
         
     | 
| 
      
 66 
     | 
    
         
            +
                  number_hashes.map {|n_hash| PhoneNumber.from_hash(n_hash) }
         
     | 
| 
      
 67 
     | 
    
         
            +
                end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                def emails
         
     | 
| 
      
 70 
     | 
    
         
            +
                  email_hashes = @@db.execute("select * from emails where contact_id = ?", [@id])
         
     | 
| 
      
 71 
     | 
    
         
            +
                  email_hashes.map {|e_hash| Email.from_hash(e_hash) }
         
     | 
| 
      
 72 
     | 
    
         
            +
                end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                def full_name
         
     | 
| 
      
 75 
     | 
    
         
            +
                  first_name + " " + last_name
         
     | 
| 
      
 76 
     | 
    
         
            +
                end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                def to_s
         
     | 
| 
      
 79 
     | 
    
         
            +
                  "#{full_name}\n".green.bold
         
     | 
| 
      
 80 
     | 
    
         
            +
                end
         
     | 
| 
      
 81 
     | 
    
         
            +
              end
         
     | 
| 
      
 82 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,47 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'sqlite3'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Tact
         
     | 
| 
      
 4 
     | 
    
         
            +
              class Database
         
     | 
| 
      
 5 
     | 
    
         
            +
                attr_reader :db
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                def initialize
         
     | 
| 
      
 8 
     | 
    
         
            +
                  home_dir = File.expand_path("~")
         
     | 
| 
      
 9 
     | 
    
         
            +
                  Dir.mkdir("#{home_dir}/.tact") unless File.exists?("#{home_dir}/.tact")
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @db = SQLite3::Database.new("#{File.expand_path("~")}/.tact/tact.sqlite3")
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @db.results_as_hash = true
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @db.execute("pragma foreign_keys = on")
         
     | 
| 
      
 13 
     | 
    
         
            +
                  create_tables
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                def create_tables
         
     | 
| 
      
 17 
     | 
    
         
            +
                  contact_table = <<~eof
         
     | 
| 
      
 18 
     | 
    
         
            +
                    CREATE TABLE IF NOT EXISTS contacts(
         
     | 
| 
      
 19 
     | 
    
         
            +
                      id integer primary key,
         
     | 
| 
      
 20 
     | 
    
         
            +
                      first_name varchar(255) not null,
         
     | 
| 
      
 21 
     | 
    
         
            +
                      last_name varchar(255) not null,
         
     | 
| 
      
 22 
     | 
    
         
            +
                      constraint name_unique unique (first_name, last_name)
         
     | 
| 
      
 23 
     | 
    
         
            +
                    );
         
     | 
| 
      
 24 
     | 
    
         
            +
                    eof
         
     | 
| 
      
 25 
     | 
    
         
            +
                  phone_numbers_table = <<~eof
         
     | 
| 
      
 26 
     | 
    
         
            +
                    CREATE TABLE IF NOT EXISTS phone_numbers(
         
     | 
| 
      
 27 
     | 
    
         
            +
                      id integer primary key,
         
     | 
| 
      
 28 
     | 
    
         
            +
                      type varchar(255),
         
     | 
| 
      
 29 
     | 
    
         
            +
                      number varchar(255),
         
     | 
| 
      
 30 
     | 
    
         
            +
                      contact_id int,
         
     | 
| 
      
 31 
     | 
    
         
            +
                      foreign key (contact_id) references contacts(id) on delete cascade
         
     | 
| 
      
 32 
     | 
    
         
            +
                    );
         
     | 
| 
      
 33 
     | 
    
         
            +
                    eof
         
     | 
| 
      
 34 
     | 
    
         
            +
                  emails_table = <<~eof
         
     | 
| 
      
 35 
     | 
    
         
            +
                    CREATE TABLE IF NOT EXISTS emails(
         
     | 
| 
      
 36 
     | 
    
         
            +
                      id integer primary key,
         
     | 
| 
      
 37 
     | 
    
         
            +
                      address varchar(255),
         
     | 
| 
      
 38 
     | 
    
         
            +
                      contact_id,
         
     | 
| 
      
 39 
     | 
    
         
            +
                      foreign key (contact_id) references contacts(id) on delete cascade
         
     | 
| 
      
 40 
     | 
    
         
            +
                    );
         
     | 
| 
      
 41 
     | 
    
         
            +
                    eof
         
     | 
| 
      
 42 
     | 
    
         
            +
                  @db.execute(contact_table)
         
     | 
| 
      
 43 
     | 
    
         
            +
                  @db.execute(phone_numbers_table)
         
     | 
| 
      
 44 
     | 
    
         
            +
                  @db.execute(emails_table)
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
              end
         
     | 
| 
      
 47 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/tact/email.rb
    ADDED
    
    | 
         @@ -0,0 +1,57 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require_relative 'database'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Tact
         
     | 
| 
      
 4 
     | 
    
         
            +
              class Email
         
     | 
| 
      
 5 
     | 
    
         
            +
                attr_reader :id
         
     | 
| 
      
 6 
     | 
    
         
            +
                attr_accessor :address, :index
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                @@db = Database.new.db
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                def self.from_hash(hash)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  self.new(hash["address"], hash["contact_id"], hash["id"])
         
     | 
| 
      
 12 
     | 
    
         
            +
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                def self.all
         
     | 
| 
      
 15 
     | 
    
         
            +
                  email_hashes = @@db.execute("select * from emails;")
         
     | 
| 
      
 16 
     | 
    
         
            +
                  email_hashes.map {|e_hash| Email.from_hash(e_hash) }
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                def self.find_by_id(id)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  email_hashes = @@db.execute("select * from emails where id = ?", [id])
         
     | 
| 
      
 21 
     | 
    
         
            +
                  self.from_hash(email_hashes[0]) if !email_hashes.empty?
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                def self.find_by_address(address)
         
     | 
| 
      
 25 
     | 
    
         
            +
                  email_hashes = @@db.execute("select * from emails where address = ?", [address])
         
     | 
| 
      
 26 
     | 
    
         
            +
                  email_hashes.map {|e_hash| self.from_hash(e_hash) }
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                def self.delete(id)
         
     | 
| 
      
 30 
     | 
    
         
            +
                  @@db.execute("delete from emails where id = ?;", [id])
         
     | 
| 
      
 31 
     | 
    
         
            +
                  @@db.execute("select changes();")[0]["changes()"] == 1 ? true : false
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                def initialize(address, contact_id, primary_key=nil)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  @id = primary_key
         
     | 
| 
      
 36 
     | 
    
         
            +
                  @address = address
         
     | 
| 
      
 37 
     | 
    
         
            +
                  @contact_id = contact_id
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                def save
         
     | 
| 
      
 41 
     | 
    
         
            +
                  if @id == nil
         
     | 
| 
      
 42 
     | 
    
         
            +
                    if @@db.execute("insert into emails (address, contact_id) values (?, ?);", [@address, @contact_id])
         
     | 
| 
      
 43 
     | 
    
         
            +
                      @id = @@db.execute("select last_insert_rowid();")[0]["last_insert_rowid()"]
         
     | 
| 
      
 44 
     | 
    
         
            +
                      self
         
     | 
| 
      
 45 
     | 
    
         
            +
                    else
         
     | 
| 
      
 46 
     | 
    
         
            +
                      false
         
     | 
| 
      
 47 
     | 
    
         
            +
                    end
         
     | 
| 
      
 48 
     | 
    
         
            +
                  else
         
     | 
| 
      
 49 
     | 
    
         
            +
                    @@db.execute("update emails set address = ?, contact_id = ? where id = ?;", [@address, @contact_id, @id]) ? self : false
         
     | 
| 
      
 50 
     | 
    
         
            +
                  end
         
     | 
| 
      
 51 
     | 
    
         
            +
                end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                def to_s
         
     | 
| 
      
 54 
     | 
    
         
            +
                  "<#{@address}>"
         
     | 
| 
      
 55 
     | 
    
         
            +
                end
         
     | 
| 
      
 56 
     | 
    
         
            +
              end
         
     | 
| 
      
 57 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,78 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'colored'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require_relative 'database'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module Tact
         
     | 
| 
      
 5 
     | 
    
         
            +
              class PhoneNumber
         
     | 
| 
      
 6 
     | 
    
         
            +
                attr_reader :id
         
     | 
| 
      
 7 
     | 
    
         
            +
                attr_accessor :number, :index, :type
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                @@db = Database.new.db
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                def self.format_number(number)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  n = number.gsub(/[^\d]/, "")
         
     | 
| 
      
 13 
     | 
    
         
            +
                  chars = n.chars
         
     | 
| 
      
 14 
     | 
    
         
            +
                  if chars.count == 10
         
     | 
| 
      
 15 
     | 
    
         
            +
                    chars.insert(3, '-')
         
     | 
| 
      
 16 
     | 
    
         
            +
                    chars.insert(7, '-')
         
     | 
| 
      
 17 
     | 
    
         
            +
                  elsif chars.count == 11
         
     | 
| 
      
 18 
     | 
    
         
            +
                    chars.insert(0, '+')
         
     | 
| 
      
 19 
     | 
    
         
            +
                    chars.insert(2, ' ')
         
     | 
| 
      
 20 
     | 
    
         
            +
                    chars.insert(6, '-')
         
     | 
| 
      
 21 
     | 
    
         
            +
                    chars.insert(10, '-')
         
     | 
| 
      
 22 
     | 
    
         
            +
                  elsif chars.count == 7
         
     | 
| 
      
 23 
     | 
    
         
            +
                    chars.insert(3, '-')
         
     | 
| 
      
 24 
     | 
    
         
            +
                  else
         
     | 
| 
      
 25 
     | 
    
         
            +
                    return n
         
     | 
| 
      
 26 
     | 
    
         
            +
                  end
         
     | 
| 
      
 27 
     | 
    
         
            +
                  return chars.join
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                def self.from_hash(hash)
         
     | 
| 
      
 31 
     | 
    
         
            +
                  self.new(hash["type"], hash["number"], hash["contact_id"], hash["id"])
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                def self.all
         
     | 
| 
      
 35 
     | 
    
         
            +
                  number_hashes = @@db.execute("select * from phone_numbers;")
         
     | 
| 
      
 36 
     | 
    
         
            +
                  number_hashes.map {|n_hash| self.from_hash(n_hash) }
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                def self.delete(id)
         
     | 
| 
      
 40 
     | 
    
         
            +
                  @@db.execute("delete from phone_numbers where id = ?;", [id])
         
     | 
| 
      
 41 
     | 
    
         
            +
                  @@db.execute("select changes();")[0]["changes()"] == 1 ? true : false
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                def self.find_by_id(id)
         
     | 
| 
      
 45 
     | 
    
         
            +
                  number_hashes = @@db.execute("select * from phone_numbers where id = ?", [id])
         
     | 
| 
      
 46 
     | 
    
         
            +
                  self.from_hash(number_hashes[0]) if !number_hashes.empty?
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                def self.find_by_number(number)
         
     | 
| 
      
 50 
     | 
    
         
            +
                  number_hashes = @@db.execute("select * from phone_numbers where number = ?", [number])
         
     | 
| 
      
 51 
     | 
    
         
            +
                  number_hashes.map {|n_hash| self.from_hash(n_hash) }
         
     | 
| 
      
 52 
     | 
    
         
            +
                end
         
     | 
| 
      
 53 
     | 
    
         
            +
                
         
     | 
| 
      
 54 
     | 
    
         
            +
                def initialize(type, number, contact_id, primary_key=nil)
         
     | 
| 
      
 55 
     | 
    
         
            +
                  @id = primary_key
         
     | 
| 
      
 56 
     | 
    
         
            +
                  @type = type.downcase.capitalize
         
     | 
| 
      
 57 
     | 
    
         
            +
                  @number = number.gsub(/\D/, "")
         
     | 
| 
      
 58 
     | 
    
         
            +
                  @contact_id = contact_id
         
     | 
| 
      
 59 
     | 
    
         
            +
                end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                def save
         
     | 
| 
      
 62 
     | 
    
         
            +
                  if @id == nil
         
     | 
| 
      
 63 
     | 
    
         
            +
                    if @@db.execute("INSERT INTO phone_numbers (type, number, contact_id) values (?, ?, ?);", [@type, @number, @contact_id])
         
     | 
| 
      
 64 
     | 
    
         
            +
                      @id = @@db.execute("select last_insert_rowid();")[0]["last_insert_rowid()"]
         
     | 
| 
      
 65 
     | 
    
         
            +
                      self
         
     | 
| 
      
 66 
     | 
    
         
            +
                    else
         
     | 
| 
      
 67 
     | 
    
         
            +
                      false
         
     | 
| 
      
 68 
     | 
    
         
            +
                    end
         
     | 
| 
      
 69 
     | 
    
         
            +
                  else
         
     | 
| 
      
 70 
     | 
    
         
            +
                    @@db.execute("update phone_numbers set type = ?, number = ?, contact_id = ? where id = ?;", [@type, @number, @contact_id]) ? self : false
         
     | 
| 
      
 71 
     | 
    
         
            +
                  end
         
     | 
| 
      
 72 
     | 
    
         
            +
                end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                def to_s
         
     | 
| 
      
 75 
     | 
    
         
            +
                  "#{type.yellow}: #{PhoneNumber.format_number(number).bold}"
         
     | 
| 
      
 76 
     | 
    
         
            +
                end
         
     | 
| 
      
 77 
     | 
    
         
            +
              end
         
     | 
| 
      
 78 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/tact/rolodex.rb
    ADDED
    
    | 
         @@ -0,0 +1,129 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'sqlite3'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'colored'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require_relative 'card'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require_relative 'database'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            module Tact
         
     | 
| 
      
 7 
     | 
    
         
            +
              class Rolodex
         
     | 
| 
      
 8 
     | 
    
         
            +
                
         
     | 
| 
      
 9 
     | 
    
         
            +
                def initialize
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @cards = load_cards
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @db = Database.new.db
         
     | 
| 
      
 12 
     | 
    
         
            +
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                def load_cards
         
     | 
| 
      
 15 
     | 
    
         
            +
                  cards = Contact.all.each_with_index.map do |contact, index|
         
     | 
| 
      
 16 
     | 
    
         
            +
                    Card.new(contact, index + 1)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
                  cards
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                def add_contact(first_name, last_name)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  Contact.new(first_name, last_name).save
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                def add_phone_number(contact_index, type, number)
         
     | 
| 
      
 26 
     | 
    
         
            +
                  contact = find_contact(contact_index)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  PhoneNumber.new(type, number, contact.id).save
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                def add_email(contact_index, address)
         
     | 
| 
      
 31 
     | 
    
         
            +
                  contact = find_contact(contact_index)
         
     | 
| 
      
 32 
     | 
    
         
            +
                  Email.new(address, contact.id).save
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                def delete_contact(contact_index)
         
     | 
| 
      
 36 
     | 
    
         
            +
                  contact = find_contact(contact_index)
         
     | 
| 
      
 37 
     | 
    
         
            +
                  Contact.delete(contact.id)
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                def delete_phone_number(contact_index, num_index)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  phone_number = find_phone_number(contact_index, num_index)
         
     | 
| 
      
 42 
     | 
    
         
            +
                  PhoneNumber.delete(phone_number.id)
         
     | 
| 
      
 43 
     | 
    
         
            +
                end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                def delete_email(contact_index, email_index)
         
     | 
| 
      
 46 
     | 
    
         
            +
                  email = find_email(contact_index, email_index)
         
     | 
| 
      
 47 
     | 
    
         
            +
                  Email.delete(email.id)
         
     | 
| 
      
 48 
     | 
    
         
            +
                end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                def edit_contact_name(contact_index, new_first_name, new_last_name)
         
     | 
| 
      
 51 
     | 
    
         
            +
                  contact = find_contact(contact_index)
         
     | 
| 
      
 52 
     | 
    
         
            +
                  contact.first_name = new_first_name.downcase.capitalize
         
     | 
| 
      
 53 
     | 
    
         
            +
                  contact.last_name = new_last_name.downcase.capitalize
         
     | 
| 
      
 54 
     | 
    
         
            +
                  contact.save
         
     | 
| 
      
 55 
     | 
    
         
            +
                end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                def edit_phone_number(contact_index, num_index, new_type, new_number)
         
     | 
| 
      
 58 
     | 
    
         
            +
                  new_type = new_type.downcase.capitalize
         
     | 
| 
      
 59 
     | 
    
         
            +
                  new_number = new_number.gsub(/\D/, "")
         
     | 
| 
      
 60 
     | 
    
         
            +
                  phone_number = find_phone_number(contact_index, num_index)
         
     | 
| 
      
 61 
     | 
    
         
            +
                  phone_number.type = new_type
         
     | 
| 
      
 62 
     | 
    
         
            +
                  phone_number.number = new_number
         
     | 
| 
      
 63 
     | 
    
         
            +
                  phone_number.save
         
     | 
| 
      
 64 
     | 
    
         
            +
                end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                def edit_email(contact_index, email_index, new_address)
         
     | 
| 
      
 67 
     | 
    
         
            +
                  email = find_email(contact_index, email_index)
         
     | 
| 
      
 68 
     | 
    
         
            +
                  email.address = new_address
         
     | 
| 
      
 69 
     | 
    
         
            +
                  email.save
         
     | 
| 
      
 70 
     | 
    
         
            +
                end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                def find_contact(contact_index)
         
     | 
| 
      
 73 
     | 
    
         
            +
                  begin 
         
     | 
| 
      
 74 
     | 
    
         
            +
                    @cards[contact_index - 1].contact
         
     | 
| 
      
 75 
     | 
    
         
            +
                  rescue 
         
     | 
| 
      
 76 
     | 
    
         
            +
                    puts "Error: Contact index out of range".red
         
     | 
| 
      
 77 
     | 
    
         
            +
                    exit
         
     | 
| 
      
 78 
     | 
    
         
            +
                  end
         
     | 
| 
      
 79 
     | 
    
         
            +
                end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                def find_phone_number(contact_index, num_index)
         
     | 
| 
      
 82 
     | 
    
         
            +
                  contact = find_contact(contact_index)
         
     | 
| 
      
 83 
     | 
    
         
            +
                  phone_number = contact.phone_numbers[num_index - 1]
         
     | 
| 
      
 84 
     | 
    
         
            +
                  if phone_number then phone_number
         
     | 
| 
      
 85 
     | 
    
         
            +
                  else 
         
     | 
| 
      
 86 
     | 
    
         
            +
                    puts "Error: Phone number index out of range".red
         
     | 
| 
      
 87 
     | 
    
         
            +
                    exit
         
     | 
| 
      
 88 
     | 
    
         
            +
                  end
         
     | 
| 
      
 89 
     | 
    
         
            +
                end
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
                def find_email(contact_index, email_index)
         
     | 
| 
      
 92 
     | 
    
         
            +
                  contact = find_contact(contact_index)
         
     | 
| 
      
 93 
     | 
    
         
            +
                  email = contact.emails[email_index - 1]
         
     | 
| 
      
 94 
     | 
    
         
            +
                  if email then email
         
     | 
| 
      
 95 
     | 
    
         
            +
                  else
         
     | 
| 
      
 96 
     | 
    
         
            +
                    puts "Error: Email index out of range".red
         
     | 
| 
      
 97 
     | 
    
         
            +
                    exit
         
     | 
| 
      
 98 
     | 
    
         
            +
                  end
         
     | 
| 
      
 99 
     | 
    
         
            +
                end
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
                def find_by_name(param)
         
     | 
| 
      
 102 
     | 
    
         
            +
                  param = param.split(" ").map {|name| name.capitalize }.join(" ")
         
     | 
| 
      
 103 
     | 
    
         
            +
                  search_results = []
         
     | 
| 
      
 104 
     | 
    
         
            +
                  @cards.each {|card| search_results.push(card) if card.contact.full_name.include?(param)}
         
     | 
| 
      
 105 
     | 
    
         
            +
                  search_results
         
     | 
| 
      
 106 
     | 
    
         
            +
                end
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
                def find_by_number(param)
         
     | 
| 
      
 109 
     | 
    
         
            +
                  contact_ids = @db.execute("select distinct contact_id from phone_numbers where number like '%#{param}%';")
         
     | 
| 
      
 110 
     | 
    
         
            +
                  contact_ids.map {|hash| convert_to_card(hash["contact_id"]) } 
         
     | 
| 
      
 111 
     | 
    
         
            +
                end
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
                def find_by_email(param)
         
     | 
| 
      
 114 
     | 
    
         
            +
                  contact_ids = @db.execute("select distinct contact_id from emails where address like '%#{param}%';")
         
     | 
| 
      
 115 
     | 
    
         
            +
                  contact_ids.map {|hash| convert_to_card(hash["contact_id"]) }
         
     | 
| 
      
 116 
     | 
    
         
            +
                end
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
                def convert_to_card(contact_id)
         
     | 
| 
      
 119 
     | 
    
         
            +
                  results = @cards.select {|card| card.contact.id == contact_id }
         
     | 
| 
      
 120 
     | 
    
         
            +
                  results[0]
         
     | 
| 
      
 121 
     | 
    
         
            +
                end
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
                def to_s
         
     | 
| 
      
 124 
     | 
    
         
            +
                  string = ""
         
     | 
| 
      
 125 
     | 
    
         
            +
                  @cards.each {|card| string += card.to_s}
         
     | 
| 
      
 126 
     | 
    
         
            +
                  string
         
     | 
| 
      
 127 
     | 
    
         
            +
                end
         
     | 
| 
      
 128 
     | 
    
         
            +
              end
         
     | 
| 
      
 129 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/tact/tact.rb
    ADDED
    
    | 
         @@ -0,0 +1,205 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require_relative "rolodex.rb"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'optparse'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'tact/version'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'colored'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            module Tact
         
     | 
| 
      
 7 
     | 
    
         
            +
              class Tact
         
     | 
| 
      
 8 
     | 
    
         
            +
                def initialize(args)
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @dex = Rolodex.new
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @options = {}
         
     | 
| 
      
 11 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 12 
     | 
    
         
            +
                    OptionParser.new do |opt|
         
     | 
| 
      
 13 
     | 
    
         
            +
                      opt.banner = "Usage: tact [OPTIONS] [ARGUMENTS]"
         
     | 
| 
      
 14 
     | 
    
         
            +
                      opt.on('-n', '--new', 'New entry') do
         
     | 
| 
      
 15 
     | 
    
         
            +
                        @options[:new] = true
         
     | 
| 
      
 16 
     | 
    
         
            +
                      end
         
     | 
| 
      
 17 
     | 
    
         
            +
                      opt.on('-u', '--update', 'Update entry') do
         
     | 
| 
      
 18 
     | 
    
         
            +
                        @options[:update] = true 
         
     | 
| 
      
 19 
     | 
    
         
            +
                      end
         
     | 
| 
      
 20 
     | 
    
         
            +
                      opt.on('-d', '--delete', 'Delete entry') do
         
     | 
| 
      
 21 
     | 
    
         
            +
                        @options[:delete] = true
         
     | 
| 
      
 22 
     | 
    
         
            +
                      end
         
     | 
| 
      
 23 
     | 
    
         
            +
                      opt.on('-p', '--phone', 'Edit phone number') do
         
     | 
| 
      
 24 
     | 
    
         
            +
                        @options[:number] = true
         
     | 
| 
      
 25 
     | 
    
         
            +
                      end
         
     | 
| 
      
 26 
     | 
    
         
            +
                      opt.on('-e', '--email', 'Edit email') do
         
     | 
| 
      
 27 
     | 
    
         
            +
                        @options[:email] = true
         
     | 
| 
      
 28 
     | 
    
         
            +
                      end
         
     | 
| 
      
 29 
     | 
    
         
            +
                      opt.on("-v", "--version", "Version") do 
         
     | 
| 
      
 30 
     | 
    
         
            +
                        @options[:version] = true
         
     | 
| 
      
 31 
     | 
    
         
            +
                      end
         
     | 
| 
      
 32 
     | 
    
         
            +
                      opt.on("-h", "--help", "Help") do
         
     | 
| 
      
 33 
     | 
    
         
            +
                        @options[:help] = true
         
     | 
| 
      
 34 
     | 
    
         
            +
                      end
         
     | 
| 
      
 35 
     | 
    
         
            +
                    end.parse!
         
     | 
| 
      
 36 
     | 
    
         
            +
                  rescue
         
     | 
| 
      
 37 
     | 
    
         
            +
                    puts "Invalid option".red
         
     | 
| 
      
 38 
     | 
    
         
            +
                    puts help_message
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
                  @args = args
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                def help_message
         
     | 
| 
      
 44 
     | 
    
         
            +
                  <<~EOF
         
     | 
| 
      
 45 
     | 
    
         
            +
              
         
     | 
| 
      
 46 
     | 
    
         
            +
                    -v                                    Current version
         
     | 
| 
      
 47 
     | 
    
         
            +
                    -h                                    Help
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                    <param>                               Search by name
         
     | 
| 
      
 50 
     | 
    
         
            +
                    -p <param>                            Search by number
         
     | 
| 
      
 51 
     | 
    
         
            +
                    -e <param>                            Search by email
         
     | 
| 
      
 52 
     | 
    
         
            +
                    -n <first> <last>                     Adds new name
         
     | 
| 
      
 53 
     | 
    
         
            +
                    -np <index> <type> <num>              Adds contact number
         
     | 
| 
      
 54 
     | 
    
         
            +
                    -ne <index> <address>                 Adds contact email
         
     | 
| 
      
 55 
     | 
    
         
            +
                    -d <index>                            Deletes contact
         
     | 
| 
      
 56 
     | 
    
         
            +
                    -dp <index> <num_index>               Deletes contact number
         
     | 
| 
      
 57 
     | 
    
         
            +
                    -de <index> <e_index>                 Deletes contact email
         
     | 
| 
      
 58 
     | 
    
         
            +
                    -u <index> <first> <last>             Edits contact name
         
     | 
| 
      
 59 
     | 
    
         
            +
                    -up <index> <num_index> <type> <num>  Edits contact number
         
     | 
| 
      
 60 
     | 
    
         
            +
                    -ue <index> <e_index> <address>       Edits contact email
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                  EOF
         
     | 
| 
      
 63 
     | 
    
         
            +
                end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                def run
         
     | 
| 
      
 66 
     | 
    
         
            +
                  if !args_are_valid?
         
     | 
| 
      
 67 
     | 
    
         
            +
                    puts "Error: Invalid input".red
         
     | 
| 
      
 68 
     | 
    
         
            +
                    puts help_message
         
     | 
| 
      
 69 
     | 
    
         
            +
                    exit
         
     | 
| 
      
 70 
     | 
    
         
            +
                  end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                  if @options[:new]
         
     | 
| 
      
 73 
     | 
    
         
            +
                    if !@options[:number] && !@options[:email]
         
     | 
| 
      
 74 
     | 
    
         
            +
                      first_name = @args[0]
         
     | 
| 
      
 75 
     | 
    
         
            +
                      last_name = @args[1]
         
     | 
| 
      
 76 
     | 
    
         
            +
                      @dex.add_contact(first_name, last_name)
         
     | 
| 
      
 77 
     | 
    
         
            +
                    elsif @options[:number]
         
     | 
| 
      
 78 
     | 
    
         
            +
                      contact_index = @args[0].to_i
         
     | 
| 
      
 79 
     | 
    
         
            +
                      type = @args[1]
         
     | 
| 
      
 80 
     | 
    
         
            +
                      number = @args[2]
         
     | 
| 
      
 81 
     | 
    
         
            +
                      @dex.add_phone_number(contact_index, type, number)
         
     | 
| 
      
 82 
     | 
    
         
            +
                    elsif @options[:email]
         
     | 
| 
      
 83 
     | 
    
         
            +
                      contact_index = @args[0].to_i
         
     | 
| 
      
 84 
     | 
    
         
            +
                      address = @args[1]
         
     | 
| 
      
 85 
     | 
    
         
            +
                      @dex.add_email(contact_index, address)
         
     | 
| 
      
 86 
     | 
    
         
            +
                    end
         
     | 
| 
      
 87 
     | 
    
         
            +
                  
         
     | 
| 
      
 88 
     | 
    
         
            +
                  elsif @options[:delete]
         
     | 
| 
      
 89 
     | 
    
         
            +
                    if !@options[:number] && !@options[:email]
         
     | 
| 
      
 90 
     | 
    
         
            +
                      contact_index = @args[0].to_i
         
     | 
| 
      
 91 
     | 
    
         
            +
                      @dex.delete_contact(contact_index)
         
     | 
| 
      
 92 
     | 
    
         
            +
                    elsif @options[:number]
         
     | 
| 
      
 93 
     | 
    
         
            +
                      contact_index = @args[0].to_i
         
     | 
| 
      
 94 
     | 
    
         
            +
                      number_index = @args[1].to_i
         
     | 
| 
      
 95 
     | 
    
         
            +
                      @dex.delete_phone_number(contact_index, number_index)
         
     | 
| 
      
 96 
     | 
    
         
            +
                    elsif @options[:email]
         
     | 
| 
      
 97 
     | 
    
         
            +
                      contact_index = @args[0].to_i
         
     | 
| 
      
 98 
     | 
    
         
            +
                      email_index = @args[1].to_i
         
     | 
| 
      
 99 
     | 
    
         
            +
                      @dex.delete_email(contact_index, email_index)
         
     | 
| 
      
 100 
     | 
    
         
            +
                    end
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
                  elsif @options[:update]
         
     | 
| 
      
 103 
     | 
    
         
            +
                    if !@options[:number] && !@options[:email]
         
     | 
| 
      
 104 
     | 
    
         
            +
                      contact_index = @args[0].to_i
         
     | 
| 
      
 105 
     | 
    
         
            +
                      first_name = @args[1]
         
     | 
| 
      
 106 
     | 
    
         
            +
                      last_name = @args[2]
         
     | 
| 
      
 107 
     | 
    
         
            +
                      @dex.edit_contact_name(contact_index, first_name, last_name)
         
     | 
| 
      
 108 
     | 
    
         
            +
                    elsif @options[:number]
         
     | 
| 
      
 109 
     | 
    
         
            +
                      contact_index = @args[0].to_i
         
     | 
| 
      
 110 
     | 
    
         
            +
                      number_index = @args[1].to_i
         
     | 
| 
      
 111 
     | 
    
         
            +
                      new_type = @args[2]
         
     | 
| 
      
 112 
     | 
    
         
            +
                      new_number = @args[3]
         
     | 
| 
      
 113 
     | 
    
         
            +
                      @dex.edit_phone_number(contact_index, number_index, new_type, new_number)
         
     | 
| 
      
 114 
     | 
    
         
            +
                    elsif @options[:email]
         
     | 
| 
      
 115 
     | 
    
         
            +
                      contact_index = @args[0].to_i
         
     | 
| 
      
 116 
     | 
    
         
            +
                      email_index = @args[1].to_i
         
     | 
| 
      
 117 
     | 
    
         
            +
                      new_address = @args[2]
         
     | 
| 
      
 118 
     | 
    
         
            +
                      @dex.edit_email(contact_index, email_index, new_address)
         
     | 
| 
      
 119 
     | 
    
         
            +
                    end
         
     | 
| 
      
 120 
     | 
    
         
            +
                    
         
     | 
| 
      
 121 
     | 
    
         
            +
                  elsif @options[:help]
         
     | 
| 
      
 122 
     | 
    
         
            +
                    puts help_message
         
     | 
| 
      
 123 
     | 
    
         
            +
                  elsif @options[:version]
         
     | 
| 
      
 124 
     | 
    
         
            +
                    puts "tact version #{VERSION}"
         
     | 
| 
      
 125 
     | 
    
         
            +
                  else
         
     | 
| 
      
 126 
     | 
    
         
            +
                    if @args.empty?
         
     | 
| 
      
 127 
     | 
    
         
            +
                      print @dex
         
     | 
| 
      
 128 
     | 
    
         
            +
                    else
         
     | 
| 
      
 129 
     | 
    
         
            +
                      params = @args.join(' ')
         
     | 
| 
      
 130 
     | 
    
         
            +
                      if @options.empty?
         
     | 
| 
      
 131 
     | 
    
         
            +
                        puts @dex.find_by_name(params)
         
     | 
| 
      
 132 
     | 
    
         
            +
                      elsif @options[:number]
         
     | 
| 
      
 133 
     | 
    
         
            +
                        puts @dex.find_by_number(params)
         
     | 
| 
      
 134 
     | 
    
         
            +
                      elsif @options[:email]
         
     | 
| 
      
 135 
     | 
    
         
            +
                        puts @dex.find_by_email(params)
         
     | 
| 
      
 136 
     | 
    
         
            +
                      end
         
     | 
| 
      
 137 
     | 
    
         
            +
                    end
         
     | 
| 
      
 138 
     | 
    
         
            +
                  end
         
     | 
| 
      
 139 
     | 
    
         
            +
                end
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
                def args_are_valid?
         
     | 
| 
      
 142 
     | 
    
         
            +
                  case 
         
     | 
| 
      
 143 
     | 
    
         
            +
             
     | 
| 
      
 144 
     | 
    
         
            +
                  when @options[:new]
         
     | 
| 
      
 145 
     | 
    
         
            +
                    return false if @options[:delete] || @options[:version] || @options[:update] || @options[:help]
         
     | 
| 
      
 146 
     | 
    
         
            +
                    if @options[:number]
         
     | 
| 
      
 147 
     | 
    
         
            +
                      return false if @options[:email]
         
     | 
| 
      
 148 
     | 
    
         
            +
                      return false if @args.length != 3
         
     | 
| 
      
 149 
     | 
    
         
            +
                      return false if @args[0].to_i == 0
         
     | 
| 
      
 150 
     | 
    
         
            +
                    elsif @options[:email]
         
     | 
| 
      
 151 
     | 
    
         
            +
                      return false if @args.length != 2
         
     | 
| 
      
 152 
     | 
    
         
            +
                      return false if @args[0].to_i == 0
         
     | 
| 
      
 153 
     | 
    
         
            +
                    else
         
     | 
| 
      
 154 
     | 
    
         
            +
                      return false if @args.length != 2
         
     | 
| 
      
 155 
     | 
    
         
            +
                    end
         
     | 
| 
      
 156 
     | 
    
         
            +
                    true
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
                  when @options[:delete]
         
     | 
| 
      
 159 
     | 
    
         
            +
                    return false if @options[:new] || @options[:version] || @options[:update] || @options[:help]
         
     | 
| 
      
 160 
     | 
    
         
            +
                    if @options[:number]
         
     | 
| 
      
 161 
     | 
    
         
            +
                      return false if @options[:email]
         
     | 
| 
      
 162 
     | 
    
         
            +
                      return false if @args.length != 2
         
     | 
| 
      
 163 
     | 
    
         
            +
                      return false if @args[0].to_i == 0
         
     | 
| 
      
 164 
     | 
    
         
            +
                      return false if @args[1].to_i == 0
         
     | 
| 
      
 165 
     | 
    
         
            +
                    elsif @options[:email]
         
     | 
| 
      
 166 
     | 
    
         
            +
                      return false if @options[:number]
         
     | 
| 
      
 167 
     | 
    
         
            +
                      return false if @args.length != 2
         
     | 
| 
      
 168 
     | 
    
         
            +
                      return false if @args[0].to_i == 0
         
     | 
| 
      
 169 
     | 
    
         
            +
                      return false if @args[1].to_i == 0
         
     | 
| 
      
 170 
     | 
    
         
            +
                    else
         
     | 
| 
      
 171 
     | 
    
         
            +
                      return false if @args.length != 1
         
     | 
| 
      
 172 
     | 
    
         
            +
                      return false if @args[0].to_i == 0
         
     | 
| 
      
 173 
     | 
    
         
            +
                    end
         
     | 
| 
      
 174 
     | 
    
         
            +
                    true
         
     | 
| 
      
 175 
     | 
    
         
            +
                  
         
     | 
| 
      
 176 
     | 
    
         
            +
                  when @options[:update]
         
     | 
| 
      
 177 
     | 
    
         
            +
                    return false if @options[:new] || @options[:version] || @options[:delete] || @options[:help]
         
     | 
| 
      
 178 
     | 
    
         
            +
                    if @options[:number]
         
     | 
| 
      
 179 
     | 
    
         
            +
                      return false if @options[:email]
         
     | 
| 
      
 180 
     | 
    
         
            +
                      return false if @args.length != 4
         
     | 
| 
      
 181 
     | 
    
         
            +
                      return false if @args[0].to_i == 0
         
     | 
| 
      
 182 
     | 
    
         
            +
                    elsif @options[:email]
         
     | 
| 
      
 183 
     | 
    
         
            +
                      return false if @options[:number]
         
     | 
| 
      
 184 
     | 
    
         
            +
                      return false if @args.length != 3
         
     | 
| 
      
 185 
     | 
    
         
            +
                      return false if @args[0].to_i == 0
         
     | 
| 
      
 186 
     | 
    
         
            +
                    else
         
     | 
| 
      
 187 
     | 
    
         
            +
                      return false if @args.length != 3
         
     | 
| 
      
 188 
     | 
    
         
            +
                      return false if @args[0].to_i == 0
         
     | 
| 
      
 189 
     | 
    
         
            +
                    end
         
     | 
| 
      
 190 
     | 
    
         
            +
                    true
         
     | 
| 
      
 191 
     | 
    
         
            +
                  
         
     | 
| 
      
 192 
     | 
    
         
            +
                  when @options[:help]
         
     | 
| 
      
 193 
     | 
    
         
            +
                    return false if @options[:new] || @options[:version] || @options[:delete] || @options[:update]
         
     | 
| 
      
 194 
     | 
    
         
            +
                    true
         
     | 
| 
      
 195 
     | 
    
         
            +
             
     | 
| 
      
 196 
     | 
    
         
            +
                  when @options[:version]
         
     | 
| 
      
 197 
     | 
    
         
            +
                    return false if @options[:new] || @options[:update] || @options[:delete] || @options[:help]
         
     | 
| 
      
 198 
     | 
    
         
            +
                    true
         
     | 
| 
      
 199 
     | 
    
         
            +
                  
         
     | 
| 
      
 200 
     | 
    
         
            +
                  else
         
     | 
| 
      
 201 
     | 
    
         
            +
                    true
         
     | 
| 
      
 202 
     | 
    
         
            +
                  end
         
     | 
| 
      
 203 
     | 
    
         
            +
                end
         
     | 
| 
      
 204 
     | 
    
         
            +
              end
         
     | 
| 
      
 205 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/tact/version.rb
    ADDED
    
    
    
        data/lib/tact.rb
    ADDED
    
    | 
         @@ -0,0 +1 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'tact/tact'
         
     | 
    
        data/tact.gemspec
    ADDED
    
    | 
         @@ -0,0 +1,27 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # coding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
            lib = File.expand_path('../lib', __FILE__)
         
     | 
| 
      
 3 
     | 
    
         
            +
            $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'tact/version'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            Gem::Specification.new do |spec|
         
     | 
| 
      
 7 
     | 
    
         
            +
              spec.name          = "tact"
         
     | 
| 
      
 8 
     | 
    
         
            +
              spec.version       = Tact::VERSION
         
     | 
| 
      
 9 
     | 
    
         
            +
              spec.authors       = ["ollieshmollie"]
         
     | 
| 
      
 10 
     | 
    
         
            +
              spec.email         = ["oliverduncan@icloud.com"]
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              spec.summary       = %q{A command line rolodex.}
         
     | 
| 
      
 13 
     | 
    
         
            +
              spec.homepage      = "https://www.github.com/ollieshmollie/tact"
         
     | 
| 
      
 14 
     | 
    
         
            +
              spec.license       = "MIT"
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              spec.files         = `git ls-files -z`.split("\x0").reject do |f|
         
     | 
| 
      
 17 
     | 
    
         
            +
                f.match(%r{^(test|spec|features)/})
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
              spec.executables   = ["tact"]
         
     | 
| 
      
 20 
     | 
    
         
            +
              spec.require_paths = ["lib"]
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              spec.add_runtime_dependency "sqlite3", "~> 1.3"
         
     | 
| 
      
 23 
     | 
    
         
            +
              spec.add_runtime_dependency "colored", "~> 1.2"
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
              spec.add_development_dependency "bundler", "~> 1.13"
         
     | 
| 
      
 26 
     | 
    
         
            +
              spec.add_development_dependency "rake", "~> 10.0"
         
     | 
| 
      
 27 
     | 
    
         
            +
            end
         
     | 
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,119 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: tact
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version
         
     | 
| 
      
 4 
     | 
    
         
            +
              version: 1.2.23
         
     | 
| 
      
 5 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 6 
     | 
    
         
            +
            authors:
         
     | 
| 
      
 7 
     | 
    
         
            +
            - ollieshmollie
         
     | 
| 
      
 8 
     | 
    
         
            +
            autorequire: 
         
     | 
| 
      
 9 
     | 
    
         
            +
            bindir: bin
         
     | 
| 
      
 10 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2016-12-20 00:00:00.000000000 Z
         
     | 
| 
      
 12 
     | 
    
         
            +
            dependencies:
         
     | 
| 
      
 13 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 14 
     | 
    
         
            +
              name: sqlite3
         
     | 
| 
      
 15 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 16 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 17 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 18 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 19 
     | 
    
         
            +
                    version: '1.3'
         
     | 
| 
      
 20 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 21 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 22 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 23 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 24 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 25 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 26 
     | 
    
         
            +
                    version: '1.3'
         
     | 
| 
      
 27 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 28 
     | 
    
         
            +
              name: colored
         
     | 
| 
      
 29 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 30 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 31 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 32 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 33 
     | 
    
         
            +
                    version: '1.2'
         
     | 
| 
      
 34 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 35 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 36 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 37 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 38 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 39 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 40 
     | 
    
         
            +
                    version: '1.2'
         
     | 
| 
      
 41 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 42 
     | 
    
         
            +
              name: bundler
         
     | 
| 
      
 43 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 44 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 45 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 46 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 47 
     | 
    
         
            +
                    version: '1.13'
         
     | 
| 
      
 48 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 49 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 50 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 51 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 52 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 53 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 54 
     | 
    
         
            +
                    version: '1.13'
         
     | 
| 
      
 55 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 56 
     | 
    
         
            +
              name: rake
         
     | 
| 
      
 57 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 58 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 59 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 60 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 61 
     | 
    
         
            +
                    version: '10.0'
         
     | 
| 
      
 62 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 63 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 64 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 65 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 66 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 67 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 68 
     | 
    
         
            +
                    version: '10.0'
         
     | 
| 
      
 69 
     | 
    
         
            +
            description: 
         
     | 
| 
      
 70 
     | 
    
         
            +
            email:
         
     | 
| 
      
 71 
     | 
    
         
            +
            - oliverduncan@icloud.com
         
     | 
| 
      
 72 
     | 
    
         
            +
            executables:
         
     | 
| 
      
 73 
     | 
    
         
            +
            - tact
         
     | 
| 
      
 74 
     | 
    
         
            +
            extensions: []
         
     | 
| 
      
 75 
     | 
    
         
            +
            extra_rdoc_files: []
         
     | 
| 
      
 76 
     | 
    
         
            +
            files:
         
     | 
| 
      
 77 
     | 
    
         
            +
            - ".gitignore"
         
     | 
| 
      
 78 
     | 
    
         
            +
            - Gemfile
         
     | 
| 
      
 79 
     | 
    
         
            +
            - LICENSE.txt
         
     | 
| 
      
 80 
     | 
    
         
            +
            - README.md
         
     | 
| 
      
 81 
     | 
    
         
            +
            - Rakefile
         
     | 
| 
      
 82 
     | 
    
         
            +
            - bin/console
         
     | 
| 
      
 83 
     | 
    
         
            +
            - bin/setup
         
     | 
| 
      
 84 
     | 
    
         
            +
            - bin/tact
         
     | 
| 
      
 85 
     | 
    
         
            +
            - lib/tact.rb
         
     | 
| 
      
 86 
     | 
    
         
            +
            - lib/tact/card.rb
         
     | 
| 
      
 87 
     | 
    
         
            +
            - lib/tact/contact.rb
         
     | 
| 
      
 88 
     | 
    
         
            +
            - lib/tact/database.rb
         
     | 
| 
      
 89 
     | 
    
         
            +
            - lib/tact/email.rb
         
     | 
| 
      
 90 
     | 
    
         
            +
            - lib/tact/phone_number.rb
         
     | 
| 
      
 91 
     | 
    
         
            +
            - lib/tact/rolodex.rb
         
     | 
| 
      
 92 
     | 
    
         
            +
            - lib/tact/tact.rb
         
     | 
| 
      
 93 
     | 
    
         
            +
            - lib/tact/version.rb
         
     | 
| 
      
 94 
     | 
    
         
            +
            - tact.gemspec
         
     | 
| 
      
 95 
     | 
    
         
            +
            homepage: https://www.github.com/ollieshmollie/tact
         
     | 
| 
      
 96 
     | 
    
         
            +
            licenses:
         
     | 
| 
      
 97 
     | 
    
         
            +
            - MIT
         
     | 
| 
      
 98 
     | 
    
         
            +
            metadata: {}
         
     | 
| 
      
 99 
     | 
    
         
            +
            post_install_message: 
         
     | 
| 
      
 100 
     | 
    
         
            +
            rdoc_options: []
         
     | 
| 
      
 101 
     | 
    
         
            +
            require_paths:
         
     | 
| 
      
 102 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 103 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 104 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 105 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 106 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 107 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 108 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 109 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 110 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 111 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 112 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 113 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 114 
     | 
    
         
            +
            rubyforge_project: 
         
     | 
| 
      
 115 
     | 
    
         
            +
            rubygems_version: 2.5.1
         
     | 
| 
      
 116 
     | 
    
         
            +
            signing_key: 
         
     | 
| 
      
 117 
     | 
    
         
            +
            specification_version: 4
         
     | 
| 
      
 118 
     | 
    
         
            +
            summary: A command line rolodex.
         
     | 
| 
      
 119 
     | 
    
         
            +
            test_files: []
         
     |