#!/usr/bin/env ruby require_relative File.join("dist", "pigeon") require "thor" def bail(msg) $stderr.puts 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 `.pigeon` directory if none exists" def new if File.file?(Pigeon::PIGEON_DB_PATH) puts "Pigeon has detected a `pigeon.db` file. Refusing to overwrite existing Pigeon config. Remove config dir or switch to a different directory." raise ConfigAlreadyExists end kp = Pigeon::KeyPair.new() kp.save! puts kp.public_key end desc "show", "Prints a base64 identiy string to STDOUT" def show puts Pigeon::KeyPair.current.public_key end end class Blob < ThorBase desc "set", "Copy arbitrary binary data into the database" def set(data = "") blob = (data != "") ? data : STDIN.read puts Pigeon::Storage.current.set_blob(blob) end desc "get", "Read arbitrary data from the database" def get(hex_digest) puts Pigeon::Storage.current.get_blob(hex_digest) end end class Peer < ThorBase desc "add", "Begin following a Pigeon peer" def add(identity) puts Pigeon::Storage.current.add_peer(identity) end desc "remove", "Stop following a Pigeon peer" def remove(identity) puts Pigeon::Storage.current.remove_peer(identity) end desc "block", "Stop following a Pigeon peer AND refuse to replicate" def block(identity) puts Pigeon::Storage.current.block_peer(identity) end desc "all", "List all Pigeon peers" def all puts Pigeon::Storage.current.all_peers end end class PigeonDraft < ThorBase desc "create", "Begin a new Pigeon message" def create(kind) puts Pigeon::Draft.create(kind: kind).render end desc "append", "Add a key/value pair to the current DRAFT" def append(key, raw_value = "") v = (raw_value != "") ? raw_value : STDIN.read draft = Pigeon::Draft.current if draft puts draft[key] = v else bail("You must create a draft first") end end desc "show", "Print a message to STDOUT. If message_id is missing, current draft will be displayed." def show(message_id = "") if message_id == "" puts Pigeon::Draft.current.render else bail("You must create a draft first") end end desc "sign", "Commit current DRAFT to local feed." def sign draft = Pigeon::Draft.current message = Pigeon::Message.publish(draft) puts message.render end end class PigeonBundle < ThorBase desc "create", "Create a pigeon bundle file" def create(file_path = Pigeon::DEFAULT_BUNDLE_PATH) Pigeon::Bundle.create(file_path) end end class CLI < ThorBase desc "status", "Show various information about the `.pigeon` directory" def status puts " -`. Pigeon Protocol Ruby Client '( @ > Version: #{Pigeon::VERSION} _) ( Peers: #{Pigeon::Storage.current.all_peers.count} / ) Blocked: #{Pigeon::Storage.current.all_blocks.count} /_,' / Logs: #{Pigeon::Storage.current.message_count} \\ / Ident: #{Pigeon::KeyPair.current.public_key} ===m" "m=== " end desc "identity SUBCOMMAND ...ARGS", "Manage `.pigeon` identity" subcommand "identity", Identity desc "blob SUBCOMMAND ...ARGS", "Manage blob storage" subcommand "blob", Blob desc "peer SUBCOMMAND ...ARGS", "Manage blob storage" subcommand "peer", Peer desc "message SUBCOMMAND ...ARGS", "Manage messages" subcommand "draft", PigeonDraft desc "bundle SUBCOMMAND ...ARGS", "Consume and create bundle files" subcommand "bundle", PigeonBundle end end Pigeon::CLI.start(ARGV)