From 1aba1cd4c637670cd79351ba282afd7be80bf81a Mon Sep 17 00:00:00 2001 From: "Glenn Y. Rolland" Date: Fri, 1 Jan 2021 19:26:55 +0100 Subject: [PATCH] Re-organize code for readability --- src/lib/app.cr | 90 ++++++++++++++++++++++++++++++++ src/lib/cli.cr | 49 ++++++++++++++++++ src/main.cr | 137 ++----------------------------------------------- 3 files changed, 142 insertions(+), 134 deletions(-) create mode 100644 src/lib/app.cr create mode 100644 src/lib/cli.cr diff --git a/src/lib/app.cr b/src/lib/app.cr new file mode 100644 index 0000000..c632fd5 --- /dev/null +++ b/src/lib/app.cr @@ -0,0 +1,90 @@ + +require "crustache" + +class HappyApp + def initialize(csv = "", wait = 5, send = false) + @config = csv + @wait = wait + @send = send + @device = "" + end + + def validate() + if File.exists? @config + LOG.info { "Found configuration file '#{@config}'. Good." } + else + LOG.error { "ERROR: configuration file '#{@config}' does not exist!" } + exit 1 + end + + if !@device.to_s.empty? + LOG.info { "Found device '#{@device}'. Good." } + else + LOG.error { "ERROR: unable to detect kdeconnect device!" } + exit 1 + end + end + + def detect_device() + @device = `kdeconnect-cli --list-available --id-only`.strip + end + + def send_message(row_h) + template = Crustache.parse row_h["message"] + row_h["message"] = Crustache.render template, row_h + LOG.debug { "Rendered text = #{row_h["message"]}" } + + if !@send + LOG.warn { "Dry-run mode. Not sending message for #{row_h.values}" } + return + end + + LOG.warn { "Sending message for #{row_h.values}" } + res = Process.run( + "kdeconnect-cli", + [ + "--device", @device, + "--destination", row_h["number"], + "--send-sms", row_h["message"] + ], + output: STDOUT, + input: STDIN, + error: STDERR + ) + if !res.success? + LOG.warn { "Command status error for #{row_h.values}" } + end + + rescue e + LOG.error { "Error while sending message for #{row_h.values}. #{e.message}" } + end + + def exec() + File.open(@config) do |csv_fh| + csv = CSV.new(csv_fh, headers: true, strip: true) + # puts csv.inspect + csv.each do |row_strip| + row = row_strip.row + row_h = row.to_h + + if row["firstname"] =~ /^\s*$/ || row["firstname"] =~ /^#.*$/ + LOG.debug { "Skipping line for #{row_h.values}" } + next + end + + # Check number + if row["number"].empty? + LOG.warn { "Missing number for #{row_h.values}. Skipping" } + next + end + row_h["number"] = row["number"].gsub(/\s+/,"") + + send_message(row_h) + sleep @wait + + end + puts "SUCCESS" + end + end +end + diff --git a/src/lib/cli.cr b/src/lib/cli.cr new file mode 100644 index 0000000..a6cc6a0 --- /dev/null +++ b/src/lib/cli.cr @@ -0,0 +1,49 @@ + +require "clim" + +class HappyCli < Clim + main do + desc "Happy Send - Mass send short text messages via your smartphone + kdeconnect" + + usage "happy-send [options] [arguments] ..." + + option "-s", "--send", + type: Bool, + default: false, + desc: "Send message for real (=not dry-run)" + + option "-w", "--wait=SECONDS", + type: Int32, + default: 5, + desc: "Wait SECONDS between each message (default: 5)" + + option "-v", "--verbose", + type: Bool, + default: false, + desc: "Enable debug messages" + + option "-c FILE", "--csv=FILE", + type: String, + required: true, + desc: "Use given CSV (mandatory fields: number,message)" + + run do |opts, args| + Log.setup(:warn) + Log.setup(:debug) if opts.verbose + + if opts.send + Log.warn { "Disabling dry-run mode : messages will be sent !" } + STDERR.puts "Disabling dry-run mode. Type 'yes' to confirm or anything else to exit" + if STDIN.gets.to_s.strip != "yes" + Log.warn { "Disabling dry-run was not confirmed. Exiting" } + exit 1 + end + end + + app = HappyApp.new(csv: opts.csv, send: opts.send, wait: opts.wait) + app.detect_device + app.validate + app.exec + end + end +end diff --git a/src/main.cr b/src/main.cr index b05917d..f684a26 100644 --- a/src/main.cr +++ b/src/main.cr @@ -1,142 +1,11 @@ -require "clim" require "csv" require "log" -require "crustache" require "colorize" +require "./lib/app.cr" +require "./lib/cli.cr" + LOG = ::Log.for("happy") #LOG = Logger.new(STDOUT, level: Logger::WARN) -class HappyApp - - def initialize(csv = "", wait = 5, send = false) - @config = csv - @wait = wait - @send = send - @device = "" - end - - def validate() - if File.exists? @config - LOG.info { "Found configuration file '#{@config}'. Good." } - else - LOG.error { "ERROR: configuration file '#{@config}' does not exist!" } - exit 1 - end - - if !@device.to_s.empty? - LOG.info { "Found device '#{@device}'. Good." } - else - LOG.error { "ERROR: unable to detect kdeconnect device!" } - exit 1 - end - end - - def detect_device() - @device = `kdeconnect-cli --list-available --id-only`.strip - end - - def send_message(row_h) - - template = Crustache.parse row_h["message"] - row_h["message"] = Crustache.render template, row_h - LOG.debug { "Rendered text = #{row_h["message"]}" } - - if !@send - LOG.warn { "Dry-run mode. Not sending message for #{row_h.values}" } - return - end - - LOG.warn { "Sending message for #{row_h.values}" } - res = Process.run( - "kdeconnect-cli", - [ - "--device", @device, - "--destination", row_h["number"], - "--send-sms", row_h["message"] - ], - output: STDOUT, - input: STDIN, - error: STDERR - ) - if !res.success? - LOG.warn { "Command status error for #{row_h.values}" } - end - - rescue e - LOG.error { "Error while sending message for #{row_h.values}. #{e.message}" } - end - - def exec() - File.open(@config) do |csv_fh| - csv = CSV.new(csv_fh, headers: true, strip: true) - # puts csv.inspect - csv.each do |row_strip| - row = row_strip.row - row_h = row.to_h - - if row["firstname"] =~ /^\s*$/ || row["firstname"] =~ /^#.*$/ - LOG.debug { "Skipping line for #{row_h.values}" } - next - end - - # Check number - if row["number"].empty? - LOG.warn { "Missing number for #{row_h.values}. Skipping" } - next - end - row_h["number"] = row["number"].gsub(/\s+/,"") - - send_message(row_h) - sleep @wait - - end - puts "SUCCESS" - end - end -end - -class HappyCli < Clim - main do - desc "Happy Send - Mass send short text messages via your smartphone + kdeconnect" - - option "-s", "--send", - type: Bool, - desc: "really send messages (dry-run by default)" - - option "-w", "--wait=SECONDS", - type: Int32, - default: 5, - desc: "wait SECONDS between each message (default: 5)" - - option "-v", "--verbose", - type: Bool, - desc: "enable debug messages" - - option "-c FILE", "--csv=FILE", - type: String, - required: true, - desc: "CSV with firstname,lastname,number,message" - - run do |opts, args| - Log.setup(:warn) - Log.setup(:debug) if opts.verbose - - if opts.send - Log.warn { "Disabling dry-run mode : messages will be sent !" } - STDERR.puts "Disabling dry-run mode. Type 'yes' to confirm or anything else to exit" - if STDIN.gets.to_s.strip != "yes" - Log.warn { "Disabling dry-run was not confirmed. Exiting" } - exit 1 - end - end - - app = HappyApp.new(csv: opts.csv, send: opts.send, wait: opts.wait) - app.detect_device - app.validate - app.exec - end - end -end - HappyCli.start(ARGV)