#!/usr/bin/env ruby require_relative "../lib/pigeon" require "thor" def db if File.file?(Pigeon::PIGEON_DB_PATH) $db ||= Pigeon::Database.new else warn("You must first run `pigeon-cli identity new`.") exit 1 end end def bail(msg) warn msg exit 1 end module Pigeon class ThorBase < Thor no_commands do def exit_on_failure? true end end end class Identity < ThorBase class ConfigAlreadyExists < StandardError; end desc "new", "Creates a new identiy in `.pgn` directory if none exists" def new if File.file?(Pigeon::PIGEON_DB_PATH) puts <<-END Pigeon has detected a `pigeon.db` file. Refusing to overwrite existing Pigeon config. Remove config dir or switch to a different directory." END raise ConfigAlreadyExists end $db = Pigeon::Database.new puts db.who_am_i.multihash end desc "show", "Prints your identiy string to STDOUT" def show puts db.who_am_i.multihash end end class Blob < ThorBase desc "set", "Copy arbitrary binary data into the database" def set(data = "") blob = data != "" ? data : STDIN.read puts db.add_blob(blob) end desc "get", "Read arbitrary data from the database" def get(hex_digest) puts db.get_blob(hex_digest) end end class Peer < ThorBase desc "add", "Begin following a Pigeon peer" def add(identity) puts db.add_peer(identity) end desc "remove", "Stop following a Pigeon peer" def remove(identity) puts db.remove_peer(identity) end desc "block", "Stop following a Pigeon peer AND refuse to replicate" def block(identity) puts db.block_peer(identity) end desc "all", "List all Pigeon peers" def all puts db.all_peers end end class PigeonDraft < ThorBase desc "create", "Begin a new Pigeon message" def create(kind) puts db.new_draft(kind: kind).render_as_draft end desc "append", "Add a key/value pair to the current DRAFT" def append(key, raw_value = "") v = raw_value != "" ? raw_value : STDIN.read if db.get_draft db.update_draft(key, v) puts db.get_draft.render_as_draft else bail("You must create a draft first") end end desc "show", "Print current message to STDOUT." def show puts db.get_draft.render_as_draft end desc "sign", "Commit current DRAFT to local feed." def sign puts db.publish_draft(db.get_draft).render end end class PigeonBundle < ThorBase desc "create", "Create a pigeon bundle file" def create(file_path = Pigeon::DEFAULT_BUNDLE_PATH) db.export_bundle(file_path) end desc "ingest", "Ingest a pigeon bundle file" def ingest(file_path = Pigeon::DEFAULT_BUNDLE_PATH) db.import_bundle(file_path) end end class PigeonMessage < ThorBase desc "find", "Find a pigeon message in the local DB" def find(multihash) puts db.read_message(multihash).render end desc "find-all", "Find all message IDs of a particular identity." def find_all(author = nil) puts db.all_messages(author).join(Pigeon::CR) + Pigeon::CR end desc "last", "Grab your last message. INTERNAL USE ONLY" def last me = db.who_am_i mcount = db.get_message_count_for(me.multihash) multihash = db.get_message_by_depth(me.multihash, mcount - 1) puts multihash end end class CLI < ThorBase desc "status", "Show various information about the `.pgn` directory" def status me = db.who_am_i.multihash mine = db.get_message_count_for(me) puts " -`. Pigeon Protocol Ruby Client '( @ > Version: #{Pigeon::VERSION} _) ( Peers: #{db.all_peers.count} / ) Blocked: #{db.all_blocks.count} /_,' / Msgs Published: #{mine} \\ / Msgs Total: #{db.all_messages.count} ===m\" \"m=== Your local identity hash: #{me} " end desc "blob SUBCOMMAND ...ARGS", "Manage blob storage" subcommand "blob", Blob desc "bundle SUBCOMMAND ...ARGS", "Consume and create bundle files" subcommand "bundle", PigeonBundle desc "draft SUBCOMMAND ...ARGS", "Manage drafts" subcommand "draft", PigeonDraft desc "identity SUBCOMMAND ...ARGS", "Manage `.pgn` identity" subcommand "identity", Identity desc "message SUBCOMMAND ...ARGS", "Manage blob storage" subcommand "message", PigeonMessage desc "peer SUBCOMMAND ...ARGS", "Manage blob storage" subcommand "peer", Peer end end Pigeon::CLI.start(ARGV)