From 15837d36b2a1921ac91451c9359b8ca48e62e2fb Mon Sep 17 00:00:00 2001 From: "Glenn Y. Rolland" Date: Sun, 4 Apr 2021 23:37:13 +0200 Subject: [PATCH] Reoganize code + implement basic report --- src/{cli.cr => hodlerctl/main.cr} | 76 +++++++++++++--------- src/hodlertui/main.cr | 0 src/hodlerweb/main.cr | 0 src/{ => lib}/actions.cr | 19 ++---- src/lib/actions/portfolio-get.cr | 16 +++++ src/lib/actions/portfolio-set.cr | 0 src/{ => lib}/actions/report.cr | 0 src/{ => lib}/actions/tui.cr | 0 src/lib/actions/wallet-get.cr | 15 +++++ src/{ => lib}/actions/web.cr | 0 src/lib/models.cr | 22 +++++++ src/{ => lib}/models/config.cr | 0 src/{ => lib}/models/deposit.cr | 0 src/{ => lib}/models/fee_trade.cr | 0 src/lib/models/portfolio.cr | 46 +++++++++++++ src/{ => lib}/models/ref_wallet.cr | 0 src/{ => lib}/models/trade.cr | 0 src/{ => lib}/models/transaction_trade.cr | 0 src/{ => lib}/models/ui_config.cr | 0 src/{ => lib}/models/wallet.cr | 0 src/{ => lib}/models/wallet_value_trade.cr | 0 src/lib/types.cr | 12 ++++ src/{ => lib}/version.cr | 0 src/main.cr | 14 ---- src/models.cr | 21 ------ src/models/portfolio.cr | 36 ---------- src/types.cr | 4 -- 27 files changed, 163 insertions(+), 118 deletions(-) rename src/{cli.cr => hodlerctl/main.cr} (64%) create mode 100644 src/hodlertui/main.cr create mode 100644 src/hodlerweb/main.cr rename src/{ => lib}/actions.cr (68%) create mode 100644 src/lib/actions/portfolio-get.cr create mode 100644 src/lib/actions/portfolio-set.cr rename src/{ => lib}/actions/report.cr (100%) rename src/{ => lib}/actions/tui.cr (100%) create mode 100644 src/lib/actions/wallet-get.cr rename src/{ => lib}/actions/web.cr (100%) create mode 100644 src/lib/models.cr rename src/{ => lib}/models/config.cr (100%) rename src/{ => lib}/models/deposit.cr (100%) rename src/{ => lib}/models/fee_trade.cr (100%) create mode 100644 src/lib/models/portfolio.cr rename src/{ => lib}/models/ref_wallet.cr (100%) rename src/{ => lib}/models/trade.cr (100%) rename src/{ => lib}/models/transaction_trade.cr (100%) rename src/{ => lib}/models/ui_config.cr (100%) rename src/{ => lib}/models/wallet.cr (100%) rename src/{ => lib}/models/wallet_value_trade.cr (100%) create mode 100644 src/lib/types.cr rename src/{ => lib}/version.cr (100%) delete mode 100644 src/main.cr delete mode 100644 src/models.cr delete mode 100644 src/models/portfolio.cr delete mode 100644 src/types.cr diff --git a/src/cli.cr b/src/hodlerctl/main.cr similarity index 64% rename from src/cli.cr rename to src/hodlerctl/main.cr index 94788f5..a55adb9 100644 --- a/src/cli.cr +++ b/src/hodlerctl/main.cr @@ -1,27 +1,30 @@ -require "./models" -require "./actions" -require "./models" +require "option_parser" +require "yaml" +require "colorize" +require "xdg_basedir" +require "completion" + +require "../lib/version" +require "../lib/types" +require "../lib/models" +require "../lib/actions" +require "../lib/models" module Hodler - class Cli - alias Options = { - action: Action::Type, - verbose_enable: Bool, - config_file: String - } + class CtlCli property config : ConfigModel? - property options : Options? + property options : GlobalOptions? def initialize @config = nil @options = nil end - def self.parse_options(args) : Options + def self.parse_options(args) : GlobalOptions # default values - action = Action::Type::Report + action = ReportAction config_file = XDGBasedir.full_path("hodler/wallet.yml", :config, :read).as(String) verbose_enable = true @@ -58,20 +61,32 @@ module Hodler parser.separator parser.separator "Commands" - parser.on("report", "Compute report") do - parser.banner = "Usage: #{Version::PROGRAM} list [arguments]" - action = Action::Type::Report + parser.on("get", "Get given object") do + parser.banner = "Usage: #{Version::PROGRAM} get [arguments]" + + parser.separator + parser.separator "Commands" + + parser.on("portfolio", "Show current portfolio") do + parser.banner = "Usage: #{Version::PROGRAM} portfolio [arguments]" + action = GetPortfolioAction + end + + parser.on("wallet", "Show given wallet") do + parser.banner = "Usage: #{Version::PROGRAM} portfolio [arguments]" + action = GetWalletAction + end end - parser.on("tui", "Run ncurses interactive UI") do - parser.banner = "Usage: #{Version::PROGRAM} tui [arguments]" - action = Action::Type::TextUi - end + # parser.on("tui", "Run ncurses interactive UI") do + # parser.banner = "Usage: #{Version::PROGRAM} tui [arguments]" + # action = TextUiAction + # end - parser.on("web", "Run web interactive UI") do - parser.banner = "Usage: #{Version::PROGRAM} web [arguments]" - action = Action::Type::WebUi - end + # parser.on("web", "Run web interactive UI") do + # parser.banner = "Usage: #{Version::PROGRAM} web [arguments]" + # action = WebUiAction + # end parser.separator @@ -102,12 +117,12 @@ module Hodler verbose_enable: verbose_enable, config_file: config_file, action: action - }.as(Options) + }.as(GlobalOptions) end def self.parse_config(options) - puts "Loading configuration...".colorize(:yellow) if options[:verbose_enable] config_file = options[:config_file] + puts "Loading configuration... #{config_file}".colorize(:yellow) if options[:verbose_enable] if ! File.exists? config_file STDERR.puts "ERROR: Unable to read configuration file '#{config_file}'".colorize(:red) @@ -126,14 +141,12 @@ module Hodler end def self.run(args) - app = Cli.new - options = Cli.parse_options(args) - config = Cli.parse_config(options) + app = CtlCli.new + options = CtlCli.parse_options(args) + config = CtlCli.parse_config(options) app.options = options app.config = config - portfolio = PortfolioFactory.build(options, config) - action = ActionFactory.build(options, config) action.perform @@ -142,3 +155,6 @@ module Hodler end end end + +Hodler::CtlCli.run(ARGV) + diff --git a/src/hodlertui/main.cr b/src/hodlertui/main.cr new file mode 100644 index 0000000..e69de29 diff --git a/src/hodlerweb/main.cr b/src/hodlerweb/main.cr new file mode 100644 index 0000000..e69de29 diff --git a/src/actions.cr b/src/lib/actions.cr similarity index 68% rename from src/actions.cr rename to src/lib/actions.cr index e8da3e8..767304c 100644 --- a/src/actions.cr +++ b/src/lib/actions.cr @@ -1,4 +1,6 @@ +require "tablo" + module Hodler class Action enum Type @@ -11,7 +13,8 @@ module Hodler return false end - def initialize(config : ConfigModel) + def initialize(global_options : GlobalOptions, config : ConfigModel) + @global_options = global_options @config = config end @@ -29,26 +32,16 @@ module Hodler wallets[from_id] -= tr.from.amount wallets[fee_id] -= tr.fee.amount wallets[to_id] += tr.to.amount - - pp tr - pp wallets end - end end class ActionFactory def self.build(options, config) - action_class = Action - [ReportAction, WebUiAction, TextUiAction].each do |cls| - action_class = cls if cls.match(options[:action]) - end - action = action_class.new(config) + action = options[:action].new(options, config) end end end -require "./actions/report" -require "./actions/tui" -require "./actions/web" +require "./actions/*" diff --git a/src/lib/actions/portfolio-get.cr b/src/lib/actions/portfolio-get.cr new file mode 100644 index 0000000..4accfe1 --- /dev/null +++ b/src/lib/actions/portfolio-get.cr @@ -0,0 +1,16 @@ + +require "../actions" + +module Hodler + class GetPortfolioAction < Action + def self.match(action) + # return (action == Action::Type::Report) + end + + # Display Wallet, Symbol, Held, Initial Value, Current Value, Evolution (%) + def perform + portfolio = PortfolioFactory.build(@global_options, @config) + puts portfolio.to_report + end + end +end diff --git a/src/lib/actions/portfolio-set.cr b/src/lib/actions/portfolio-set.cr new file mode 100644 index 0000000..e69de29 diff --git a/src/actions/report.cr b/src/lib/actions/report.cr similarity index 100% rename from src/actions/report.cr rename to src/lib/actions/report.cr diff --git a/src/actions/tui.cr b/src/lib/actions/tui.cr similarity index 100% rename from src/actions/tui.cr rename to src/lib/actions/tui.cr diff --git a/src/lib/actions/wallet-get.cr b/src/lib/actions/wallet-get.cr new file mode 100644 index 0000000..7d64256 --- /dev/null +++ b/src/lib/actions/wallet-get.cr @@ -0,0 +1,15 @@ + +require "../actions" + +module Hodler + class GetPortfolioAction < Action + def self.match(action) + # return (action == Action::Type::Report) + end + + def perform + portfolio = PortfolioFactory.build(@global_options, @config) + puts portfolio.to_report + end + end +end diff --git a/src/actions/web.cr b/src/lib/actions/web.cr similarity index 100% rename from src/actions/web.cr rename to src/lib/actions/web.cr diff --git a/src/lib/models.cr b/src/lib/models.cr new file mode 100644 index 0000000..f7b5985 --- /dev/null +++ b/src/lib/models.cr @@ -0,0 +1,22 @@ + +require "yaml" + +module Hodler + class Model + include YAML::Serializable + end +end + +require "./types" +require "./models/*" + +# require "./models/deposit" +# require "./models/fee_trade" +# require "./models/portfolio" +# require "./models/ref_wallet" +# require "./models/trade" +# require "./models/transaction_trade" +# require "./models/ui_config" +# require "./models/wallet" +# require "./models/wallet_value_trade" +# diff --git a/src/models/config.cr b/src/lib/models/config.cr similarity index 100% rename from src/models/config.cr rename to src/lib/models/config.cr diff --git a/src/models/deposit.cr b/src/lib/models/deposit.cr similarity index 100% rename from src/models/deposit.cr rename to src/lib/models/deposit.cr diff --git a/src/models/fee_trade.cr b/src/lib/models/fee_trade.cr similarity index 100% rename from src/models/fee_trade.cr rename to src/lib/models/fee_trade.cr diff --git a/src/lib/models/portfolio.cr b/src/lib/models/portfolio.cr new file mode 100644 index 0000000..5032beb --- /dev/null +++ b/src/lib/models/portfolio.cr @@ -0,0 +1,46 @@ + +require "../models" + +module Hodler + class PortfolioModel < Model + + property wallets : Array(WalletModel) + + + def initialize() + @wallets = [] of WalletModel + end + + def import_wallets(wallets : Array(WalletModel)) + wallets.each do |wallet| + @wallets << wallet + end + end + + def add_wallet + end + + def remove_wallet + end + + def to_report + data = @wallets.map{|row| [row.name, row.type.to_s, row.refs.map{|ref| ref.sym}.join(", ")] } + # pp data + table = Tablo::Table.new(data, connectors: Tablo::CONNECTORS_SINGLE_ROUNDED) do |t| + t.add_column("Name") { |row| row[0] } + t.add_column("Type") { |row| row[1] } + t.add_column("Symbols", width: 40) { |row| row[2] } + end + end + end + + class PortfolioFactory + def self.build(options : GlobalOptions, config : ConfigModel) : PortfolioModel + portfolio = PortfolioModel.new + + portfolio.import_wallets(config.wallets) + + return portfolio + end + end +end diff --git a/src/models/ref_wallet.cr b/src/lib/models/ref_wallet.cr similarity index 100% rename from src/models/ref_wallet.cr rename to src/lib/models/ref_wallet.cr diff --git a/src/models/trade.cr b/src/lib/models/trade.cr similarity index 100% rename from src/models/trade.cr rename to src/lib/models/trade.cr diff --git a/src/models/transaction_trade.cr b/src/lib/models/transaction_trade.cr similarity index 100% rename from src/models/transaction_trade.cr rename to src/lib/models/transaction_trade.cr diff --git a/src/models/ui_config.cr b/src/lib/models/ui_config.cr similarity index 100% rename from src/models/ui_config.cr rename to src/lib/models/ui_config.cr diff --git a/src/models/wallet.cr b/src/lib/models/wallet.cr similarity index 100% rename from src/models/wallet.cr rename to src/lib/models/wallet.cr diff --git a/src/models/wallet_value_trade.cr b/src/lib/models/wallet_value_trade.cr similarity index 100% rename from src/models/wallet_value_trade.cr rename to src/lib/models/wallet_value_trade.cr diff --git a/src/lib/types.cr b/src/lib/types.cr new file mode 100644 index 0000000..801d3c6 --- /dev/null +++ b/src/lib/types.cr @@ -0,0 +1,12 @@ + +require "./actions/*" + +module Hodler + alias AmountT = Float64 | Int64 + + alias GlobalOptions = { + action: Action.class, + verbose_enable: Bool, + config_file: String + } +end diff --git a/src/version.cr b/src/lib/version.cr similarity index 100% rename from src/version.cr rename to src/lib/version.cr diff --git a/src/main.cr b/src/main.cr deleted file mode 100644 index 0be6109..0000000 --- a/src/main.cr +++ /dev/null @@ -1,14 +0,0 @@ - -require "option_parser" -require "yaml" -require "colorize" -require "xdg_basedir" -require "completion" - -require "./version" -require "./types" -require "./models" -require "./cli" - -Hodler::Cli.run(ARGV) - diff --git a/src/models.cr b/src/models.cr deleted file mode 100644 index 3335470..0000000 --- a/src/models.cr +++ /dev/null @@ -1,21 +0,0 @@ - -require "yaml" - -module Hodler - class Model - include YAML::Serializable - end -end - -require "./types" -require "./models/config" -require "./models/deposit" -require "./models/fee_trade" -require "./models/portfolio" -require "./models/ref_wallet" -require "./models/trade" -require "./models/transaction_trade" -require "./models/ui_config" -require "./models/wallet" -require "./models/wallet_value_trade" - diff --git a/src/models/portfolio.cr b/src/models/portfolio.cr deleted file mode 100644 index 6d700c6..0000000 --- a/src/models/portfolio.cr +++ /dev/null @@ -1,36 +0,0 @@ - -require "../models" - -module Hodler - class PortfolioModel < Model - - property wallets : Array(WalletModel) - - - def initialize - @wallets = [] of WalletModel - end - - def import_wallets(wallets : Array(WalletModel)) - wallets.each do |wallet_config| - wallet = WalletModel.new(wallet_config.name, wallet_config.type) - # wallet.import(wallet_config) - pp wallet_config - end - end - - def add_wallet - end - - def remove_wallet - end - end - - class PortfolioFactory - def self.build(options : Cli::Options, config : ConfigModel) - portfolio = PortfolioModel.new - - portfolio.import_wallets(config.wallets) - end - end -end diff --git a/src/types.cr b/src/types.cr deleted file mode 100644 index e044d4f..0000000 --- a/src/types.cr +++ /dev/null @@ -1,4 +0,0 @@ - -module Hodler - alias AmountT = Float32 | Int32 -end