(ns tservice.plugins.merge-rnaseq-expression.commons (:require [clojure.data.csv :as csv] [clojure.string :as clj-str] [tservice.lib.files :refer [get-tservice-workdir get-plugin-jar-dir get-path-variable]] [tservice.lib.fs :as fs-lib] [clojure.java.io :as io] [clojure.java.shell :as shell :refer [sh]]) (:import [org.apache.commons.io.input BOMInputStream])) (defn add-env-to-path [plugin-name] (let [env-bin-path (fs-lib/join-paths (get-plugin-jar-dir) "envs" plugin-name "bin") path (get-path-variable)] (str env-bin-path ":" path))) (defn hashmap->parameters "{ '-d' 'true' '-o' 'output' } -> '-d true -o output'" [coll] (clj-str/join " " (map #(clj-str/join " " %) (into [] coll)))) (defn call-command! [cmd parameters-coll] (shell/with-sh-env {:PATH (add-env-to-path "merge-rnaseq-expression") :LC_ALL "en_US.utf-8" :LANG "en_US.utf-8"} (let [command ["bash" "-c" (format "%s %s" cmd (hashmap->parameters parameters-coll))] result (apply sh command) status (if (= (:exit result) 0) "Success" "Error") msg (str (:out result) "\n" (:err result))] {:status status :msg msg}))) (defn csv-data->maps [csv-data] (map zipmap (->> (first csv-data) ;; First row is the header (map keyword) ;; Drop if you want string keys instead repeat) (rest csv-data))) (defn bom-reader "Remove `Byte Order Mark` and return reader" [filepath] (-> filepath io/input-stream BOMInputStream. io/reader)) (defn guess-separator [filepath] (with-open [reader (bom-reader filepath)] (let [header (first (line-seq reader)) seps [\tab \, \; \space] sep-map (->> (map #(hash-map % (count (clj-str/split header (re-pattern (str %))))) seps) (into {}))] (key (apply max-key val sep-map))))) (defn read-csv [^String file] (when (.isFile (io/file file)) (with-open [reader (io/reader file)] (doall (->> (csv/read-csv reader :separator (guess-separator file)) csv-data->maps))))) (defn vec-remove "Remove elem in coll" [pos coll] (vec (concat (subvec coll 0 pos) (subvec coll (inc pos))))) (defn write-csv! "Write row-data to a csv file, row-data is a vector that each element is a map." [path row-data] (let [columns (keys (first row-data)) headers (map name columns) rows (mapv #(mapv % columns) row-data)] (with-open [file (io/writer path)] (csv/write-csv file (cons headers rows) :separator \tab)))) (defn write-csv-by-cols! [path row-data columns] (let [headers (map name columns) rows (mapv #(mapv % columns) row-data)] (with-open [file (io/writer path)] (csv/write-csv file (cons headers rows))))) (defn is-localpath? [filepath] (re-matches #"^file:\/\/.*" filepath)) (defn correct-filepath [filepath] (if (is-localpath? filepath) (if (re-matches #"^file:\/\/\/.*" filepath) ; Absolute path with file:// (clj-str/replace filepath #"^file:\/\/" "") (fs-lib/join-paths (get-tservice-workdir) (clj-str/replace filepath #"^file:\/\/" ""))) filepath))