Allow extra commands to be called

This commit is contained in:
Daniel O'Connell 2019-10-03 18:12:45 +02:00
parent 654429d22b
commit 5bb673038d
2 changed files with 53 additions and 15 deletions

View File

@ -27,8 +27,9 @@ following keys:
* :seller - the seller's (i.e. the entity to be paid) information. This is required * :seller - the seller's (i.e. the entity to be paid) information. This is required
* :buyer - the buyer's (i.e. the entity that will pay) information. This is required * :buyer - the buyer's (i.e. the entity that will pay) information. This is required
* :items - a list of items to be paid for * :items - a list of items to be paid for
* :font-path - (optional) *the path to a font file, e.g. "/usr/share/fonts/truetype/freefont/FreeSans.ttf" * :credentials - (optional) JIRA and Tempo access credentials. These are needed if the price depends on tracked time
* :credentials - JIRA and Tempo access credentials. These are needed if the price depends on tracked time * :font-path - (optional) the path to a font file, e.g. "/usr/share/fonts/truetype/freefont/FreeSans.ttf"
* :callbacks - (optional) a list of commands to be called with the resulting pdf file
See `resources/config.edn` for an example configuration. See `resources/config.edn` for an example configuration.
@ -118,3 +119,22 @@ If a confirmation email is to be sent, a :smtp key must also be provided, e.g.:
Each invoice can also be sent via email to the appropriate seller. For this to work, both the seller Each invoice can also be sent via email to the appropriate seller. For this to work, both the seller
and the buyer must have an :email key set and the credentials must contain a :smtp key with the and the buyer must have an :email key set and the credentials must contain a :smtp key with the
:smtp settings for the email server. :smtp settings for the email server.
## Callbacks
A list of additional commands can be added to each invoice. Each command will be called with
the generated invoice as its final parameter, e.g.
{:seller {...}
:buyer {...}
:items [...]
:callbacks [["ls" "-l"] ["rm"] ["du" "-sh"]]}
Will call the following commands (assuming that the generated invoice is `/path/to/file.pdf`):
ls -l /path/to/file.pdf
du -sh /path/to/file.pdf
rm /path/to/file.pdf
The last one will obviously fail, as the file no longer exists, and the error message will be displayed

View File

@ -4,6 +4,7 @@
[invoices.jira :refer [prev-timesheet prev-month]] [invoices.jira :refer [prev-timesheet prev-month]]
[clojure.tools.cli :refer [parse-opts]] [clojure.tools.cli :refer [parse-opts]]
[clojure.string :as str] [clojure.string :as str]
[clojure.java.shell :refer [sh]]
[postal.core :refer [send-message]]) [postal.core :refer [send-message]])
(:gen-class)) (:gen-class))
@ -49,20 +50,36 @@
:error (= :SUCCESS) :error (= :SUCCESS)
(println " - email sent: ")))) (println " - email sent: "))))
(defn run-callback [file callback]
(let [command (concat callback [file])
str-command (str/join " " command)
result (apply sh command)]
(if (= (:exit result) 0)
(println " *" str-command)
(println " X" str-command ":\n" (:err result)))
(assoc result :command str-command)))
(defn run-callbacks [invoice callbacks]
(doall (map (partial run-callback invoice) callbacks)))
(defn date-applies? [when {to :to from :from}] (defn date-applies? [when {to :to from :from}]
(and (or (nil? to) (-> when .toString (compare to) (< 0))) (and (or (nil? to) (-> when .toString (compare to) (< 0)))
(or (nil? from) (-> when .toString (compare from) (>= 0))))) (or (nil? from) (-> when .toString (compare from) (>= 0)))))
(defn for-month [when {seller :seller buyer :buyer items :items creds :credentials font-path :font-path} & [number]]
(->> (defn render-month [when {seller :seller buyer :buyer items :items creds :credentials font-path :font-path} number]
(pdf/render seller buyer (pdf/render seller buyer
(->> items (->> items
(filter (partial date-applies? when)) (filter (partial date-applies? when))
(map (partial set-price (prev-timesheet when creds)))) (map (partial set-price (prev-timesheet when creds))))
(pdf/last-working-day when) (pdf/last-working-day when)
(invoice-number when number) (invoice-number when number)
font-path) font-path))
(send-email (:email buyer) (:email seller) creds)))
(defn for-month [when {seller :seller buyer :buyer creds :credentials callbacks :callbacks :as invoice} & [number]]
(let [file (-> when (render-month invoice number) (str ".pdf") java.io.File. .getAbsolutePath)]
(send-email (:email buyer) (:email seller) creds file)
(run-callbacks file callbacks)))
(defn get-invoices [nips config] (defn get-invoices [nips config]
(if (seq nips) (if (seq nips)
@ -95,7 +112,7 @@
(exit 0))) (exit 0)))
(defn -main (defn -main
"I don't do a whole lot ... yet." "Generate invoice pdfs"
[& args] [& args]
(let [{:keys [options arguments errors summary]} (parse-opts args cli-options)] (let [{:keys [options arguments errors summary]} (parse-opts args cli-options)]
(cond (cond
@ -104,5 +121,6 @@
(not= 1 (count arguments)) (exit -1 "No config file provided")) (not= 1 (count arguments)) (exit -1 "No config file provided"))
(println "Generating invoices") (println "Generating invoices")
(doseq [[i invoice] (map-indexed vector (get-invoices (:company options) (first arguments)))] (doseq [[i invoice] (map-indexed vector (get-invoices (:company options) (first arguments)))]
(for-month (:when options) invoice (+ i (:number options)))) (for-month (:when options) invoice (+ i (:number options)))
)) (println)))
(shutdown-agents))