From b892946c25de5b1ab24d16e042e56171f5faf768 Mon Sep 17 00:00:00 2001 From: chaos Date: Sat, 23 Nov 2024 18:40:25 +0000 Subject: [PATCH] update --- run.sh | 37 --- runTests.sh | 28 --- tool/journalUtils.jq | 70 ------ tool/lib/.jq-lsp.jq | 2 - tool/lib/JSONLib.jq | 233 ------------------- tool/lib/ansiLib.jq | 24 -- tool/lib/argsLib.jq | 45 ---- tool/lib/gojqExtendedLib.jq | 7 - tool/lib/journalLib.jq | 309 ------------------------ tool/lib/journalLibTests.jq | 22 -- tool/lib/journalTypes.jq | 117 ---------- tool/lib/logLib.jq | 106 --------- tool/lib/numberLib.jq | 2 - tool/lib/stringLib.jq | 10 - tool/lib/stubs/gojq-extended/stubs.jq | 0 tool/lib/stubs/jq/stubs.jq | 2 - tool/lib/substancesLib.jq | 0 tool/lib/tableLib.jq | 84 ------- tool/lib/testLib.jq | 114 --------- tool/lib/typeLib.jq | 89 ------- tool/lib/utilsLib.jq | 34 --- tool/main.jq | 322 -------------------------- tool/testdata/tests_export.json | 205 ---------------- tool/tests.jq | 9 - 24 files changed, 1871 deletions(-) delete mode 100755 run.sh delete mode 100755 runTests.sh delete mode 100644 tool/journalUtils.jq delete mode 100644 tool/lib/.jq-lsp.jq delete mode 100644 tool/lib/JSONLib.jq delete mode 100644 tool/lib/ansiLib.jq delete mode 100644 tool/lib/argsLib.jq delete mode 100644 tool/lib/gojqExtendedLib.jq delete mode 100644 tool/lib/journalLib.jq delete mode 100644 tool/lib/journalLibTests.jq delete mode 100644 tool/lib/journalTypes.jq delete mode 100644 tool/lib/logLib.jq delete mode 100644 tool/lib/numberLib.jq delete mode 100644 tool/lib/stringLib.jq delete mode 100644 tool/lib/stubs/gojq-extended/stubs.jq delete mode 100644 tool/lib/stubs/jq/stubs.jq delete mode 100644 tool/lib/substancesLib.jq delete mode 100644 tool/lib/tableLib.jq delete mode 100644 tool/lib/testLib.jq delete mode 100644 tool/lib/typeLib.jq delete mode 100644 tool/lib/utilsLib.jq delete mode 100644 tool/main.jq delete mode 100644 tool/testdata/tests_export.json delete mode 100644 tool/tests.jq diff --git a/run.sh b/run.sh deleted file mode 100755 index ad3cdce..0000000 --- a/run.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env bash - -set -eu - -WORKING_DIRECTORY=$(pwd) -TOOL_DIR="$(cd -- "$(dirname -- "$0")" && pwd)/tool" -cd "${WORKING_DIRECTORY}" - -JQ=${JQ:-jq} -export JQ_FLAVOUR=${JQ_FLAVOUR:-"$(basename "${JQ}")"} - -run() { - if [ -d "${TOOL_DIR}/lib/stubs/${JQ_FLAVOUR}" ]; then - STUBS_DIR="${TOOL_DIR}/lib/stubs/${JQ_FLAVOUR}" - else - STUBS_DIR="${TOOL_DIR}/lib/stubs/jq" - fi - - FILES_ARGS=() - if [ "${EXPORT_FILE:-}" != "" ] && [ -f "${EXPORT_FILE}" ]; then - FILES_ARGS+=(--arg exportFileName "${EXPORT_FILE:-}") - if [ "${JQ_FLAVOUR}" != "gojq-extended" ]; then - FILES_ARGS+=(--slurpfile exportFile "${EXPORT_FILE}") - fi - else - FILES_ARGS+=(--argjson exportFileName null) - FILES_ARGS+=(--argjson exportFile null) - fi - - ${JQ} -nr -L "$(realpath "${TOOL_DIR}")" -L "$(realpath "${TOOL_DIR}/lib")" -L "$(realpath "${STUBS_DIR}")" \ - "${FILES_ARGS[@]}" \ - 'include "main"; main' \ - --args -- "$@" -} - -run "$@" - diff --git a/runTests.sh b/runTests.sh deleted file mode 100755 index 4a69a10..0000000 --- a/runTests.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env bash - -SCRIPT_DIR="$(cd -- "$(dirname -- "$0")" && pwd)" -cd "${SCRIPT_DIR}/tool" || return - -JQ=${JQ:-jq} -export JQ_FLAVOUR=${JQ_FLAVOUR:-"$(basename "${JQ}")"} -export JQ_TYPECHECKING=1 - -if [ ! -d "./lib/stubs/${JQ_FLAVOUR}" ]; then - STUBS_DIR="./lib/stubs/${JQ_FLAVOUR}" -else - STUBS_DIR="./lib/stubs/jq" -fi - -runTests() { - echo "Running Tests with JQ=${JQ}" - export JQ_FLAVOUR=${JQ_FLAVOUR:-"$(basename "${JQ}")"} - ${JQ} -nr \ - -L "$(realpath .)" -L "$(realpath ./lib)" -L "$(realpath "${STUBS_DIR}")" \ - "include \"tests\"; testsMain" -} - -runTests - -if command -v gojq 2>/dev/null >/dev/null; then - JQ=gojq JQ_FLAVOUR=gojq runTests -fi \ No newline at end of file diff --git a/tool/journalUtils.jq b/tool/journalUtils.jq deleted file mode 100644 index 7c0360b..0000000 --- a/tool/journalUtils.jq +++ /dev/null @@ -1,70 +0,0 @@ -import "lib/utilsLib" as utilsLib; -import "lib/stringLib" as stringLib; -import "lib/numberLib" as numberLib; -import "lib/journalLib" as journalLib; - -def formatExperienceTitle: - . as $experience | - "\"\(.title)\": \(.creationDate / 1000 | strftime("%d-%m-%Y"))"; - -def formatDose($dose; $unit; $isEstimate; $standardDeviation): - if $dose == null then - "Unknown \($unit)" - else - (if $isEstimate then "~" else "" end) as $estimate | - (if $standardDeviation != null then "±\($standardDeviation)" else "" end) as $standardDeviation | - - "\($estimate)\($dose | numberLib::round(2))\($standardDeviation) \($unit)" - end; - -def formatIngestionDose($customUnits): - . as $ingestion | - (. | journalLib::ingestionDose($customUnits)) as $dose | - (. | journalLib::ingestionUnit($customUnits)) as $unit | - (. | journalLib::ingestionStandardDeviation($customUnits)) as $standardDeviation | - $customUnits | map(select(.id == $ingestion.customUnitId))[0] as $customUnit | - if $ingestion.dose == null then - "Unknown" - elif $customUnit == null then - formatDose($dose; $unit; $ingestion.isDoseAnEstimate; $standardDeviation) - else - formatDose($dose; $unit; $ingestion.isDoseAnEstimate; $standardDeviation) + - " (" + - formatDose($customUnit.dose; $unit; $customUnit.isEstimate; $customUnit.estimatedDoseStandardDeviation) + - " * " + - formatDose($ingestion.dose; $customUnit.unit; $ingestion.isDoseAnEstimate; $ingestion.estimatedDoseStandardDeviation) + - ")" - end; - -def formatIngestionTime: - . as $ingestion | - $ingestion.time / 1000 | strftime("%a %I:%M %p"); - -def formatIngestionROA($customUnits; $substitutions): - . as $ingestion | - $ingestion.administrationRoute as $roa | - - (if - $substitutions | has($roa) - then - $substitutions | .[$roa] - else - $roa | stringLib::titleCase - end) as $roaText | - - $ingestion.customUnitId as $customUnitId | - - if - $customUnitId == null - then - $roaText - else - $customUnits | map(select(.id == $customUnitId))[0] as $customUnit | - "\($roaText) (\($customUnit.name))" - end; - -def formatIngestionROA($customUnits): formatIngestionROA($customUnits; {}); - -def formatIngestionInfo: - . as $ingestionInfo | - formatDose(.dose; .unit; .isEstimate; .standardDeviation); \ No newline at end of file diff --git a/tool/lib/.jq-lsp.jq b/tool/lib/.jq-lsp.jq deleted file mode 100644 index a8fb776..0000000 --- a/tool/lib/.jq-lsp.jq +++ /dev/null @@ -1,2 +0,0 @@ -def _readFile($filename): empty; -def _writeFileString($filename): empty; \ No newline at end of file diff --git a/tool/lib/JSONLib.jq b/tool/lib/JSONLib.jq deleted file mode 100644 index b9baa70..0000000 --- a/tool/lib/JSONLib.jq +++ /dev/null @@ -1,233 +0,0 @@ -import "ansiLib" as ansiLib; - -def isColourSupported: - $ENV["JQ_SUPPORTS_COLOUR"] == "1"; - -def colourEscapes: - def parseJQColours: - split(":") | - { - "null": (.[0] // "0"), - "false": (.[1] // "0"), - "true": (.[2] // "0"), - "number": (.[3] // "0"), - "string": (.[4] // "0"), - "array": (.[5] // "0"), - "object": (.[6] // "0"), - "objectKey": (.[7] // "0"), - }; - - def parseGOJQColours: - split(":") | - { - "null": (.[0] // "0"), - "false": (.[1] // "0"), - "true": (.[2] // "0"), - "number": (.[3] // "0"), - "string": (.[4] // "0"), - "objectKey": (.[5] // "0"), - "array": (.[6] // "0"), - "object": (.[7] // "0"), - }; - def defaultColours: - if ($ENV["JQ_FLAVOUR"] | tostring | startswith("gojq")) then - "90:33:33:36:32:34;1" | parseGOJQColours - else - "0;90:0;39:0;39:0;39:0;32:1;39:1;39:1;34" | parseJQColours - end; - - try ( - if $ENV["JQ_COLORS"] != null then - $ENV["JQ_COLORS"] | parseJQColours - elif $ENV["GOJQ_COLORS"] != null then - $ENV["GOJQ_COLORS"] | parseGOJQColours - else - defaultColours - end - ) catch ( - defaultColours - ); - -def _encodeJSONValuePlainPretty($indent; $currentDepth): - ([range($indent * $currentDepth) | " "] | join("")) as $currentIndentDepthIndent | - ([range($indent * ($currentDepth + 1)) | " "] | join("")) as $nextDepthIndent | - "\n" as $currentIndentDepthNewline | - " " as $currentIndentDepthSpace | - - . as $value | - (. | type) as $valueType | - if $valueType == "array" then - ($value | length) as $numValues | - - if $numValues > 0 then - "[" + - $currentIndentDepthNewline + - ([ - $value[] | - $nextDepthIndent + - _encodeJSONValuePlainPretty($indent; $currentDepth + 1) - ] | join("," + $currentIndentDepthNewline)) + - $currentIndentDepthNewline + - $currentIndentDepthIndent + - "]" - else - "[]" - end - elif $valueType == "object" then - ($value | keys | length) as $numKeys | - - if $numKeys > 0 then - "{" + - $currentIndentDepthNewline + - ([ - $value | keys | sort[] | - . as $objectKey | - $value[$objectKey] as $objectValue | - - $nextDepthIndent + - ($objectKey | tojson) + - ":" + - $currentIndentDepthSpace + - ($objectValue | _encodeJSONValuePlainPretty($indent; $currentDepth + 1)) - ] | join("," + $currentIndentDepthNewline)) + - $currentIndentDepthNewline + - $currentIndentDepthIndent + - "}" - else - "{}" - end - else - tojson - end; - -def _encodeJSONValueColourCompact: - colourEscapes as $escapes | - - def colourText($text; $kind): - ansiLib::CSR + $escapes[$kind] + "m" + $text + ansiLib::CSR + "0m"; - - . as $value | - (. | type) as $valueType | - if $valueType == "null" then - colourText("null"; "null") - elif $valueType == "boolean" then - ($value | tostring) as $boolStr | - colourText($boolStr; $boolStr) - elif $valueType == "number" then - colourText($value | tostring; "number") - elif $valueType == "string" then - colourText($value | tojson; "string") - elif $valueType == "array" then - ($value | length) as $numValues | - - if $numValues > 0 then - colourText("["; "array") + - ([ - $value[] | - _encodeJSONValueColourCompact - ] | join(colourText(","; "array"))) + - colourText("]"; "array") - else - colourText("[]"; "array") - end - elif $valueType == "object" then - ($value | keys | length) as $numKeys | - - if $numKeys > 0 then - colourText("{"; "object") + - ([ - $value | keys | sort[] | - . as $objectKey | - $value[$objectKey] as $objectValue | - - colourText($objectKey | tojson; "objectKey") + - colourText(":"; "object") + - ($objectValue | _encodeJSONValueColourCompact) - ] | join(colourText(","; "object"))) + - colourText("}"; "object") - else - colourText("{}"; "object") - end - end; - -def _encodeJSONValueColourPretty($indent; $currentDepth): - colourEscapes as $escapes | - - def colourText($text; $kind): - ansiLib::CSR + $escapes[$kind] + "m" + $text + ansiLib::CSR + "0m"; - - ([range($indent * $currentDepth) | " "] | join("")) as $currentIndentDepthIndent | - ([range($indent * ($currentDepth + 1)) | " "] | join("")) as $nextDepthIndent | - "\n" as $currentIndentDepthNewline | - " " as $currentIndentDepthSpace | - - . as $value | - (. | type) as $valueType | - if $valueType == "null" then - colourText("null"; "null") - elif $valueType == "boolean" then - ($value | tostring) as $boolStr | - colourText($boolStr; $boolStr) - elif $valueType == "number" then - colourText($value | tostring; "number") - elif $valueType == "string" then - colourText($value | tojson; "string") - elif $valueType == "array" then - ($value | length) as $numValues | - - if $numValues > 0 then - colourText("["; "array") + - $currentIndentDepthNewline + - ([ - $value[] | - $nextDepthIndent + - _encodeJSONValueColourPretty($indent; $currentDepth + 1) - ] | join(colourText(","; "array") + $currentIndentDepthNewline)) + - $currentIndentDepthNewline + - $currentIndentDepthIndent + - colourText("]"; "array") - else - colourText("[]"; "array") - end - elif $valueType == "object" then - ($value | keys | length) as $numKeys | - - if $numKeys > 0 then - colourText("{"; "object") + - $currentIndentDepthNewline + - ([ - $value | keys | sort[] | - . as $objectKey | - $value[$objectKey] as $objectValue | - - $nextDepthIndent + - colourText($objectKey | tojson; "objectKey") + - colourText(":"; "object") + - $currentIndentDepthSpace + - ($objectValue | _encodeJSONValueColourPretty($indent; $currentDepth + 1)) - ] | join(colourText(","; "object") + $currentIndentDepthNewline)) + - $currentIndentDepthNewline + - $currentIndentDepthIndent + - colourText("}"; "object") - else - colourText("{}"; "object") - end - end; - -def encodeJSON($withColour; $indent): - if ($withColour == false) and ($indent == 0) then - tojson - else - if $withColour and isColourSupported then - if $indent > 0 then - _encodeJSONValueColourPretty($indent; 0) - else - _encodeJSONValueColourCompact - end - else - _encodeJSONValuePlainPretty($indent; 0) - end - end; - - - \ No newline at end of file diff --git a/tool/lib/ansiLib.jq b/tool/lib/ansiLib.jq deleted file mode 100644 index 49917df..0000000 --- a/tool/lib/ansiLib.jq +++ /dev/null @@ -1,24 +0,0 @@ -def supportsColour: - $ENV["JQ_SUPPORTS_COLOR"] == "1" or $ENV["JQ_SUPPORTS_COLOUR"] == "1" ; - -def CSR: - "\u001b["; - -def resetColours: - CSR + "0m"; - -def colourText($colourCode): - . as $text | - if supportsColour | not then - $text - else - CSR + ($colourCode | tostring) + "m" + $text + resetColours - end; - -def colourText($colourCode; $mode): - . as $text | - if supportsColour | not then - $text - else - CSR + ($mode | tostring) + ";" + ($colourCode | tostring) + "m" + $text + resetColours - end; \ No newline at end of file diff --git a/tool/lib/argsLib.jq b/tool/lib/argsLib.jq deleted file mode 100644 index bde15ad..0000000 --- a/tool/lib/argsLib.jq +++ /dev/null @@ -1,45 +0,0 @@ -def parseArgBool: - . as $value | - if ($value | type) == "boolean" then - $value - elif - $value == "true" or $value == "on" or $value == "yes" - then - true - elif - $value == "false" or $value == "off" or $value == "no" - then - false - else - error("invalid bool value") - end; - -def parseArgs: - . as $args | - if - ($args.named | has("argsJson")) - then $args.named.argsJson[0] else $args.positional end | . as $args | - - reduce $args[] as $arg ({ - shortArgs: [], - longArgs: {}, - nonArgs: [] - }; ( - if ($arg | test("^-[\\-a-zA-Z]") | not) then - .nonArgs += [$arg] - else - if $arg | startswith("--") then - $arg[2:] as $arg | - ($arg | contains("=")) as $containsValue | - if $containsValue then - ($arg | split("=")) as $argSplit | - $argSplit[0] as $arg | $argSplit[1] as $value | - .longArgs[$arg] |= $value - else - .longArgs[$arg] |= null - end - else - .shortArgs += [$arg[1:]] - end - end - )); \ No newline at end of file diff --git a/tool/lib/gojqExtendedLib.jq b/tool/lib/gojqExtendedLib.jq deleted file mode 100644 index 470d546..0000000 --- a/tool/lib/gojqExtendedLib.jq +++ /dev/null @@ -1,7 +0,0 @@ -include "stubs"; - -def checkSupported: - $ENV.JQ_FLAVOUR == "gojq-extended"; - -def readFile($filename): _readFile($filename); -def writeFileString($filename): _writeFileString($filename); \ No newline at end of file diff --git a/tool/lib/journalLib.jq b/tool/lib/journalLib.jq deleted file mode 100644 index 2dc3965..0000000 --- a/tool/lib/journalLib.jq +++ /dev/null @@ -1,309 +0,0 @@ -import "utilsLib" as utilsLib; -import "numberLib" as numberLib; -import "journalTypes" as journalTypes; - -def ingestionDose($customUnits): - . as $ingestion | - journalTypes::ensureIngestion | - - if .customUnitId != null then - ($customUnits | map(select(.id == $ingestion.customUnitId))[0]) as $customUnit | - .dose * $customUnit.dose | . as $dose | - $dose - else - .dose - end; - -def addStandardDeviations($expectationX; $standardDeviationX; $expectationY; $standardDeviationY): - (pow($standardDeviationX; 2) + pow($expectationX; 2)) as $sumX | - (pow($standardDeviationY; 2) + pow($expectationY; 2)) as $sumY | - (pow($expectationX; 2) * pow($expectationY; 2)) as $expectations | - ($sumX * $sumY - $expectations) as $productVariance | - if $productVariance > 0.0000001 then - $productVariance | sqrt | numberLib::round(2) - else - null - end; - -def ingestionStandardDeviation($customUnits): - . as $ingestion | - journalTypes::ensureIngestion | - - if .customUnitId != null then - ($customUnits | map(select(.id == $ingestion.customUnitId))[0]) as $customUnit | - - ($ingestion.dose // 0) as $expectationX | - ($ingestion.estimatedDoseStandardDeviation // 0) as $standardDeviationX | - ($customUnit.dose // 0) as $expectationY | - ($customUnit.estimatedDoseStandardDeviation // 0) as $standardDeviationY | - - addStandardDeviations($expectationX; $standardDeviationX; $expectationY; $standardDeviationY) - else - .estimatedDoseStandardDeviation - end; - -def ingestionUnit($customUnits): - . as $ingestion | - journalTypes::ensureIngestion | - if .customUnitId != null then - ($customUnits | map(select(.id == $ingestion.customUnitId))[0]) as $customUnit | - $customUnit.originalUnit - else - .units - end; - -def ingestionConsumerName: - . as $ingestion | - journalTypes::ensureIngestion | - $ingestion.consumerName // "default"; - -def filterIngestions($substanceFilter; $consumerFilter): - . as $ingestions | - ($substanceFilter // []) as $substanceFilter | - (($substanceFilter | length) > 0) as $shouldFilterBySubstance | - ($consumerFilter // []) as $consumerFilter | - (($consumerFilter | length) > 0) as $shouldFilterByConsumer | - - journalTypes::ensureIngestions | - - if $shouldFilterBySubstance or $shouldFilterByConsumer then - [ - $ingestions[] as $ingestion | - if - (if $shouldFilterBySubstance then ([$substanceFilter[] | . == $ingestion.substanceName] | any) else true end - and - if $shouldFilterByConsumer then ([$consumerFilter[] | . == ($ingestion | ingestionConsumerName)] | any) else true end) - then $ingestion - else null end - ] | map(select(. != null)) - else $ingestions end; - -def ingestionsSubstanceNames: - . as $ingestions | - journalTypes::ensureIngestions | - [$ingestions[].substanceName] | utilsLib::orderedUnique; - -def ingestionsConsumerNames: - . as $ingestions | - journalTypes::ensureIngestions | - [$ingestions[] | ingestionConsumerName] | utilsLib::orderedUnique; - -def ingestionsByConsumer: - . as $ingestions | - journalTypes::ensureIngestions | - ($ingestions | ingestionsConsumerNames) as $consumerNames | - [ - $consumerNames[] as $consumerName | - { - key: $consumerName, - value: $ingestions | map(select((. | ingestionConsumerName) == $consumerName)), - } - ] | from_entries; - -def defaultIngestionInfo: - { - unit: "", - dose: null, - isUnknown: false, - isEstimate: false, - # TODO - standardDeviation: null - }; - -def ingestionInfo($customUnits): - . as $ingestion | - .substanceName as $name | - .administrationRoute as $administrationRoute | - . | ingestionStandardDeviation($customUnits) as $standardDeviation | - . | ingestionDose($customUnits) as $dose | - . | ingestionUnit($customUnits) as $unit | - . | ingestionConsumerName as $consumerName | - - defaultIngestionInfo as $ingestionInfo | - $ingestionInfo | - - if ($dose == null) then .isUnknown |= true end | - - if ($standardDeviation != null) then - .isEstimate |= true - end | - - .unit |= $unit | - .dose |= $dose | - .standardDeviation |= $standardDeviation; - -def addIngestionInfo($rhs): - . as $lhs | - - if (.unit != "" and $rhs.unit != "") then - utilsLib::assert(.unit == $rhs.unit; "units mismatch, todo add reasonable conversions") - else - .unit |= $rhs.unit - end | - - - if ($rhs.dose == null) then .isUnknown |= true end | - - if ($rhs.standardDeviation != null) then - .isEstimate |= true - end | - - .dose += $rhs.dose | - .standardDeviation += $rhs.standardDeviation; - -def addIngestionInfos: - . as $ingestionInfos | - reduce $ingestionInfos[] as $ingestionInfo (defaultIngestionInfo; - . | addIngestionInfo($ingestionInfo) - ); - -def experienceStats($customUnits): - . as $experience | - journalTypes::ensureExperience | - $experience.ingestions as $ingestions | - (reduce $ingestions[] as $ingestion ({}; . as $stats | - $ingestion | - .substanceName as $name | - .administrationRoute as $administrationRoute | - (. | ingestionConsumerName) as $consumerName | - - $stats | - .[$consumerName].[$ingestion.substanceName].[$administrationRoute] as $ingestionStats | - - if $ingestionStats == null then - ($ingestion | ingestionInfo($customUnits)) - else - $ingestionStats | addIngestionInfo($ingestion | ingestionInfo($customUnits)) - end | . as $ingestionStats | - - $stats | - .[$consumerName].[$ingestion.substanceName].[$administrationRoute] |= $ingestionStats - )); - -def statsCalculateCombinedDose($substanceName; $consumerName): - . as $stats | - utilsLib::assert($stats | has($consumerName); "consumer not found in stats") | - utilsLib::assert($stats[$consumerName] | has($substanceName); - "substance for consumer not found in stats" - ) | - - .[$consumerName].[$substanceName] | values | addIngestionInfos; - -def experiencesWithExtraData($customUnits): - . as $experiences | - journalTypes::ensureExperiences | - (reduce $experiences[] as $experience ([]; - ($experience | experienceStats($customUnits)) as $stats | - . += [{ - $stats, - $experience - }] - )); - -def filterSortExperiences($customUnits; $substanceFilter; $consumerFilter; $sortMethod; $sortOptions): - . as $experiences | - journalTypes::ensureExperiences | - ($consumerFilter // ["default"]) as $consumerFilter | - $sortOptions | - # If filtering results by substances but no sortOptions.substanceName is defined, use the first one as a default - (.substanceName |= - if - $sortOptions.substanceName == null - and - (($substanceFilter | length) >= 1) - then - $substanceFilter[0] - else - null - end - ) | . as $sortOptions | - $sortOptions | (.ingestionMethod |= ($sortOptions.ingestionMethod // "ORAL")) | . as $sortOptions | - $sortOptions | (.consumerName |= ($sortOptions.consumerName // "default")) | . as $sortOptions | - - def sortFilter: - def oldToNewSort: .experience.sortDate; - def highestCombinedDoseSort: .stats.[$sortOptions.consumerName].[$sortOptions.substanceName] | [to_entries[] | .value.dose] | add; - def highestMethodDoseSort: .stats.[$sortOptions.consumerName].[$sortOptions.substanceName].[$sortOptions.ingestionMethod // "ORAL"].dose; - - def filterBySubstanceFilter: - . as $experiencesData | - [ - $experiencesData[] as $experienceData | - ($experienceData.experience.ingestions) as $ingestions | - if ($experienceData.experience.ingestions | - any( - . as $ingestion | - $substanceFilter | - any(index($ingestion.substanceName)) - ) - ) then $experienceData else null end - ] | map(select(. != null)); - - def filterByConsumerFilter: - . as $experiencesData | - (reduce $experiencesData[] as $experienceData ([]; - ($experienceData.experience.ingestions) as $ingestions | - . += - if ($experienceData.experience.ingestions | - any( - (. | ingestionConsumerName) as $consumerName | - $consumerFilter | - any(index($consumerName)) - ) - ) then [$experienceData] else [] end - )); - - def filterBySubstanceAndConsumer: - . as $experiencesData | - (reduce $experiencesData[] as $experienceData ([]; - ($experienceData.experience.ingestions) as $ingestions | - . += - if - ($experienceData.experience.ingestions | - any( - .substanceName == $sortOptions.substanceName - and - (. | ingestionConsumerName) == $sortOptions.consumerName - )) - then [$experienceData] else [] end - )); - - def filterByIngestionMethodForSubstance: - . as $experiencesData | filterBySubstanceAndConsumer as $experiencesData | - (reduce $experiencesData[] as $experienceData ([]; - ($experienceData.experience.ingestions) as $ingestions | - . += if ($experienceData.experience.ingestions | any(.substanceName == $sortOptions.substanceName and .administrationRoute == $sortOptions.ingestionMethod)) - then [$experienceData] else [] end - )); - - # speeds up by excluding everything not containing substances & consumers not in filters, wouldn't show any data anyway - if $substanceFilter != null then filterBySubstanceFilter end | - filterByConsumerFilter | - - if - $sortMethod == "old-to-new" or $sortMethod == null - then - sort_by(oldToNewSort) - elif - $sortMethod == "highest-combined-dose" - then - utilsLib::assert($sortOptions.substanceName != null; "substanceName not provided as sortOption") | - filterBySubstanceAndConsumer | - sort_by(highestCombinedDoseSort, oldToNewSort) | - reverse - elif - $sortMethod == "highest-dose-for-method" - then - utilsLib::assert($sortOptions.substanceName != null; "substanceName not provided as sortOption") | - filterByIngestionMethodForSubstance | - sort_by(highestMethodDoseSort, oldToNewSort) | - reverse - end; - - $experiences | - experiencesWithExtraData($customUnits) | - sortFilter; - -def experienceByTitle($name): - utilsLib::assert((. | type) == "array"; "experienceByTitle takes a array of experiences as input") | - map(select(.title == $name))[0]; \ No newline at end of file diff --git a/tool/lib/journalLibTests.jq b/tool/lib/journalLibTests.jq deleted file mode 100644 index 1784390..0000000 --- a/tool/lib/journalLibTests.jq +++ /dev/null @@ -1,22 +0,0 @@ -import "testLib" as testLib; -import "journalLib" as journalLib; - -import "testdata/tests_export" as $exportDataArray; - -def journalLibTests: - testLib::expectPassed(testLib::runTest( - "invalid input to experienceByTitle"; - ( - null | journalLib::experienceByTitle("Test") - ); - . == "experienceByTitle takes a array of experiences as input"; - true - )) | - testLib::expectPassed(testLib::runTest( - "experience not found"; - ( - $exportDataArray[0].experiences | journalLib::experienceByTitle("Test") - ); - . == null; - false - )); \ No newline at end of file diff --git a/tool/lib/journalTypes.jq b/tool/lib/journalTypes.jq deleted file mode 100644 index 5f3ebd2..0000000 --- a/tool/lib/journalTypes.jq +++ /dev/null @@ -1,117 +0,0 @@ -import "typeLib" as typeLib; - -def ensureAdministrationRoute: - . as $administrationRoute | - if typeLib::typecheckingEnabled then - if [ - "ORAL", - "SUBLINGUAL", - "BUCCAL", - "INSUFFLATED", - "RECTAL", - "TRANSDERMAL", - "SUBCUTANEOUS", - "INTRAMUSCULAR", - "INTRAVENOUS", - "SMOKED", - "INHALED" - ] | any(index($administrationRoute)) | not then - typeLib::typeErrorText("administrationRoute") - end - end; - -def ensureIngestion: - . as $ingestion | - if typeLib::typecheckingEnabled then - typeLib::ensureObject | - - $ingestion | typeLib::ensureKey("ingestion"; "substanceName") | - .substanceName | typeLib::ensureWrapError("experience:substanceName"; typeLib::ensureString) | - - $ingestion | typeLib::ensureKey("ingestion"; "time") | - .time | typeLib::ensureWrapError("experience:time"; typeLib::ensureNumber) | - - $ingestion | typeLib::ensureKey("ingestion"; "creationDate") | - .creationDate | typeLib::ensureWrapError("experience:creationDate"; typeLib::ensureNumber) | - - # TODO: check routes - $ingestion | - typeLib::ensureKey("ingestion"; "administrationRoute") | - $ingestion.administrationRoute | - typeLib::ensureWrapError("experience:administrationRoute"; typeLib::ensureString) | - $ingestion.administrationRoute | - ensureAdministrationRoute | - - typeLib::ensureWrapError( - "experience:dose"; - $ingestion | typeLib::ensureIfKey("dose"; typeLib::ensureNullOr(typeLib::ensureNumber)) - ) | - - $ingestion | typeLib::ensureKey("ingestion"; "isDoseAnEstimate") | - .isDoseAnEstimate | typeLib::ensureWrapError("experience:isDoseAnEstimate"; typeLib::ensureBool) | - - $ingestion | typeLib::ensureKey("ingestion"; "units") | - .units | typeLib::ensureWrapError("experience:units"; typeLib::ensureString) | - - $ingestion | typeLib::ensureKey("ingestion"; "notes") | - .notes | typeLib::ensureWrapError("experience:notes"; typeLib::ensureString) | - - typeLib::ensureWrapError( - "experience:stomachFullness"; - $ingestion | typeLib::ensureIfKey("stomachFullness"; typeLib::ensureNullOr(typeLib::ensureString)) - ) | - - typeLib::ensureWrapError( - "experience:customUnitId"; - $ingestion | typeLib::ensureIfKey("customUnitId"; typeLib::ensureNullOr(typeLib::ensureNumber)) - ) | - - $ingestion - end; - -def ensureIngestions: - . as $ingestions | - if typeLib::typecheckingEnabled then - (reduce $ingestions[] as $ingestion (null; $ingestion | ensureIngestion)) - end; - -def ensureExperience: - . as $experience | - if typeLib::typecheckingEnabled then - $experience | typeLib::ensureObject | - - $experience | typeLib::ensureKey("experience"; "title") | - $experience.title | typeLib::ensureWrapError("experience:title"; typeLib::ensureString) | - - $experience | typeLib::ensureKey("experience"; "text") | - $experience.text | typeLib::ensureWrapError("experience:text"; typeLib::ensureString) | - - $experience | typeLib::ensureKey("experience"; "creationDate") | - $experience.creationDate | typeLib::ensureWrapError("experience:creationDate"; typeLib::ensureNumber) | - - $experience | typeLib::ensureKey("experience"; "sortDate") | - $experience.sortDate | typeLib::ensureWrapError("experience:sortDate"; typeLib::ensureNumber) | - - $experience | typeLib::ensureKey("experience"; "ingestions") | - $experience.ingestions | typeLib::ensureWrapError("experience:ingestions"; typeLib::ensureArray) | - $experience.ingestions | ensureIngestions | - - $experience - end; - -def ensureExperiences: - . as $experiences | - if typeLib::typecheckingEnabled then - (reduce $experiences[] as $experience (null; $experience | ensureExperience)) - end; - -def ensureExportData: - . as $exportData | - if typeLib::typecheckingEnabled then - typeLib::ensureObject | - typeLib::ensureKey("exportData"; "customSubstances") | - typeLib::ensureKey("exportData"; "customUnits") | - typeLib::ensureKey("exportData"; "experiences") | - typeLib::ensureKey("exportData"; "substanceCompanions") | - .experiences | ensureExperiences - end; \ No newline at end of file diff --git a/tool/lib/logLib.jq b/tool/lib/logLib.jq deleted file mode 100644 index faa9b90..0000000 --- a/tool/lib/logLib.jq +++ /dev/null @@ -1,106 +0,0 @@ -import "typeLib" as typeLib; -import "ansiLib" as ansiLib; -import "JSONLib" as JSONLib; - -def logLevels: - [ - "trace", - "debug", - "info", - "warn", - "error", - "fatal" - ]; - -def isJSONTooComplex: - (.. | length) > 128; - -def isValidLogLevel($logLevel): - logLevels | any(index($logLevel)); - -def ensureLogLevel: - . as $logLevel | - if typeLib::typecheckingEnabled then - if isValidLogLevel($logLevel) | not then typeLib::typeErrorText("logLevel") end - end; - -def maxLogLevel: - ($ENV["JQ_LOGLEVEL"] // "info") as $maxLogLevel | - if isValidLogLevel($maxLogLevel) | not then - "info" - else $maxLogLevel end; - -def shouldLog($logLevel): - maxLogLevel as $maxLogLevel | - logLevels as $logLevels | - reduce range($logLevels | length) as $logLevelIndex ({}; - .[$logLevels[$logLevelIndex]] = $logLevelIndex - ) as $logLevelIndexes | - $logLevelIndexes[$maxLogLevel] <= $logLevelIndexes[$logLevel]; - -def ansiColourByName: - . as $name | - { - "red": "31", - "yellow": "33", - "blue": "36", - "gray": "37" - }[$name]; - -def levelColour: - . as $logLevel | - { - "trace": "yellow", - "debug": "gray", - "info": "blue", - "warn": "yellow", - "error": "red", - "fatal": "red" - }[$logLevel] | ansiColourByName; - -def log($logLevel; $msg; $data): - . as $input | - ($logLevel | ensureLogLevel) | - ($msg | typeLib::ensureNullOr(typeLib::ensureString)) | - - if shouldLog($logLevel) then - ($logLevel | levelColour) as $logLevelColour | - ($logLevel | ascii_upcase | ansiLib::colourText($logLevelColour)) as $logLevelText | - ($msg | ansiLib::colourText("gray" | ansiColourByName)) as $msgText | - - if $data != null then - if $data | isJSONTooComplex | not then - $data | JSONLib::encodeJSON(true; 2) - else - $data | tojson - end - else "" end | . as $dataText | - - "\($logLevelText) \($msgText) \($dataText)\n" | - if $logLevel == "fatal" then halt_error(1) else stderr end - end | - - $input; - -def trace($msg; $data): log("trace"; $msg; $data); -def debug($msg; $data): log("debug"; $msg; $data); -def info($msg; $data): log("info"; $msg; $data); -def warn($msg; $data): log("warn"; $msg; $data); -def error($msg; $data): log("error"; $msg; $data); -def fatal($msg; $data): log("fatal"; $msg; $data); - -def trace($msg): trace($msg; null); -def debug($msg): debug($msg; null); -def info($msg): info($msg; null); -def warn($msg): warn($msg; null); -def error($msg): error($msg; null); -def fatal($msg): fatal($msg; null); - -def logTest: - ([ - "trace", - "debug", - "info", - "warn", - "error" - ][] | log(.; "example text \(.)"; {})) | empty; \ No newline at end of file diff --git a/tool/lib/numberLib.jq b/tool/lib/numberLib.jq deleted file mode 100644 index 6aab3d0..0000000 --- a/tool/lib/numberLib.jq +++ /dev/null @@ -1,2 +0,0 @@ -def round(precision): - . * pow(10; precision) | round / pow(10; precision); diff --git a/tool/lib/stringLib.jq b/tool/lib/stringLib.jq deleted file mode 100644 index d18526e..0000000 --- a/tool/lib/stringLib.jq +++ /dev/null @@ -1,10 +0,0 @@ -def titleCase: - [splits("\\b") | select(length>0)] - | map((.[:1]|ascii_upcase) + (.[1:] |ascii_downcase)) - | join(""); - -def lpad(string;len;fill): - if len == 0 then string else (fill * len)[0:len] + string end; - -def rpad(string;len;fill): - if len == 0 then string else string + (fill * len)[0:len] end; \ No newline at end of file diff --git a/tool/lib/stubs/gojq-extended/stubs.jq b/tool/lib/stubs/gojq-extended/stubs.jq deleted file mode 100644 index e69de29..0000000 diff --git a/tool/lib/stubs/jq/stubs.jq b/tool/lib/stubs/jq/stubs.jq deleted file mode 100644 index b362c74..0000000 --- a/tool/lib/stubs/jq/stubs.jq +++ /dev/null @@ -1,2 +0,0 @@ -def _readFile($filename): error("_readFile only supported in gojq-extended"); -def _writeFileString($filename): error("_writeFileString only supported in gojq-extended"); \ No newline at end of file diff --git a/tool/lib/substancesLib.jq b/tool/lib/substancesLib.jq deleted file mode 100644 index e69de29..0000000 diff --git a/tool/lib/tableLib.jq b/tool/lib/tableLib.jq deleted file mode 100644 index a1f9aad..0000000 --- a/tool/lib/tableLib.jq +++ /dev/null @@ -1,84 +0,0 @@ -import "stringLib" as stringLib; - -def printPrettyTable($title; $columnTitles; $rows): - if [$rows[] | length] | unique | length > 1 then error("non-even number of columns") end | - - $title | if . == null then "" end | . as $title | - - " | " as $numColumnseperator | - - def padRow($numColumns; $maxColumnLengths): - . as $row | - [ - range($numColumns) as $columnNumber | - $row[$columnNumber] as $content | - if $columnNumber == 0 then - stringLib::lpad($content; $maxColumnLengths[$columnNumber] - ($content | length) ; " ") - else - stringLib::rpad($content; $maxColumnLengths[$columnNumber] - ($content | length) ; " ") - end - ]; - - ([$rows[] | length] | unique[0]) as $numColumns | - ([$columnTitles | length] | unique[0]) as $numColumnTitles | - if $numColumns != $numColumnTitles then error("unequal title rows and columns") end | - - [$columnTitles[] | length] as $maxColumnLengths | - (reduce $rows[] as $column ($maxColumnLengths; - [ - range($numColumns) as $columnNumber | - [ - .[$columnNumber], - ($column[$columnNumber] | length) - ] | max - ] - )) as $maxColumnLengths | - - $columnTitles | - padRow($numColumns; $maxColumnLengths) | - join($numColumnseperator) as $columnTitleRow | - - [$rows[] | padRow($numColumns; $maxColumnLengths)] as $rows | - - $title | length as $titleLength | - - ((($numColumns - 1) * ($numColumnseperator | length)) + ($maxColumnLengths | add)) as $maxRowLength | - [ - $maxRowLength, - $titleLength - ] | max as $maxLength | - - - # Pad title to be centered to maximum row length - $title | if $titleLength < $maxRowLength then - stringLib::lpad($title; ($maxLength - $titleLength) / 2; " ") - end | . as $title | - - # if title is longer than maximum row length, pad the first row the difference between them - if $titleLength > $maxRowLength then - [ - $rows[] as $row | - [ - stringLib::lpad($row[0]; $titleLength - $maxRowLength; " ") - ] + $row[1:] - ] - else $rows end | . as $rows | - - ($rows | map(join($numColumnseperator))) as $rows | - if $title != "" then - - [ - $title, - ([range($maxLength) | "-"] | join("")), - - $columnTitleRow, - ([range($maxLength) | "-"] | join("")), - $rows - ] | flatten | join("\n") + "\n" - else - - [ - $columnTitleRow, - $rows - ] | flatten | join("\n") + "\n" - end; diff --git a/tool/lib/testLib.jq b/tool/lib/testLib.jq deleted file mode 100644 index 897f8d4..0000000 --- a/tool/lib/testLib.jq +++ /dev/null @@ -1,114 +0,0 @@ -def printTestResult: - . as $result | $result | - if .passed then - "Test \"\(.name)\" Passed" - else - "Test \"\(.name)\" Failed\nReason: \(.reason)\nOutput: \(.output | tojson)" - end; - -def runTest($name; testExpr; checkResult; $expectError): - try ( - (null | testExpr) as $output | - if $expectError then - { - $name, - passed: false, - reason: "Expected error but no error was raised", - $output - } - elif ($output | checkResult) then - { - $name, - passed: true, - $output - } - else - { - $name, - passed: false, - reason: "Result was different from expected", - $output - } - end - ) catch ( - . as $error | - if ($expectError | not) then - { - $name, - passed: false, - reason: "Error caught when no error was expected", - output: $error - } - elif ($expectError and ($error | checkResult)) then - { - $name, - passed: true, - output: $error - } - elif ($expectError and ($error | checkResult | not)) then - { - $name, - passed: false, - reason: "Expected error but received different error", - output: $error - } - else - error("unknown error") - end - ); - -def expectPassed: - if (.passed | not) then - error(. | printTestResult) - end; -def expectPassed($result): $result | expectPassed; - -def expectFailed: - if (.passed) then - error(. | printTestResult) - end; -def expectFailed($result): $result | expectFailed; - -def testTests: - expectPassed(runTest( - "passing test"; - true; - . == true; - false - )) | - expectPassed(runTest( - "error expected and equal"; - error("error"); - . == "error"; - true - )) | - expectFailed(runTest( - "failing test"; - true; - . == false; - false - )) | - expectFailed(runTest( - "error expected but no error"; - null; - . == null; - true - )) | - expectFailed(runTest( - "error not expected"; - error("error"); - . == null; - false - )) | - expectFailed(runTest( - "error different"; - error("error"); - . == "different error"; - true - )); - -def testLibMain: - testTests | - "Tests Passed\n" | - halt_error(0); - diff --git a/tool/lib/typeLib.jq b/tool/lib/typeLib.jq deleted file mode 100644 index 5d7d62a..0000000 --- a/tool/lib/typeLib.jq +++ /dev/null @@ -1,89 +0,0 @@ -import "testLib" as testLib; - -def typecheckingEnabled: - if $ENV["JQ_TYPECHECKING"] != null then - ["true", "1", "debug"] | any(index($ENV["JQ_TYPECHECKING"])) - else false end; - -def typecheckingDebug: - if $ENV["JQ_TYPECHECKING"] == "debug" then - true - else false end; - -def dumpType: - if (. | type) == "object" then - . | [to_entries | sort_by(.key)[] | {"\(.key)": (.value|dumpType)}] | add - elif (. | type) == "array" then - [.[] | dumpType] as $array | - if ($array | length > 0) then - if ($array | all(select(. == $array[0]))) then - [$array[0]] - else - $array - end - else - "array:empty/unknown" - end - else - . | type - end; - -def typeErrorText: - . as $type | - "Type Error Checking '\($type)'"; - -def typeErrorText($type): $type | typeErrorText; - -def typeError($type): - if typecheckingDebug then debug({typeName: $type, value: ., valueType: . | dumpType}) end | - error($type | typeErrorText); - -def ensureNull: if typecheckingEnabled and (. | type != "null") then typeError("null") end; -def ensureBool: if typecheckingEnabled and (. | type) != "boolean" then typeError("bool") end; -def ensureString: if typecheckingEnabled and (. | type) != "string" then typeError("string") end; -def ensureArray: if typecheckingEnabled and (. | type) != "array" then typeError("array") end; -def ensureObject: if typecheckingEnabled and (. | type) != "object" then typeError("object") end; -def ensureNumber: if typecheckingEnabled and (. | type) != "number" then typeError("number") end; - -def ensureNull($value): $value | ensureNull; -def ensureBool($value): $value | ensureBool; -def ensureString($value): $value | ensureString; -def ensureArray($value): $value | ensureArray; -def ensureObject($value): $value | ensureObject; -def ensureNumber($value): $value | ensureNumber; - -def ensureNullOr(ensureType): - if . == null then . else . | ensureType end; - -def ensureKey($type; $key): if (. | has($key) | not) then typeError("\($type):\($key)") end; -def ensureKey($value; $type; $key): $value | ensureKey($type; $key); - -def ensureIfKey($key; ensureType): if (. | has($key)) then .[$key] | ensureType end; - -def ensureWrapError($newType; ensureType): - . as $value | - try (. | ensureType) - catch ( - . as $prevError | - if typecheckingDebug then debug({$newType, $prevError}) end | - error(typeErrorText($newType)) - ); - -def ensureWrapError($value; $newType; ensureType): - $value | ensureWrapError($newType; ensureType); - -# JQ_TYPECHECKING=true required for tests -def typeLibTests: - testLib::expectPassed(testLib::runTest( - "null is null"; - (null | ensureNull); - true; - false - )) | - testLib::expectPassed(testLib::runTest( - "boolean is not null"; - (true | ensureNull); - (. == typeErrorText("null")); - true - )); - diff --git a/tool/lib/utilsLib.jq b/tool/lib/utilsLib.jq deleted file mode 100644 index 9dabdc3..0000000 --- a/tool/lib/utilsLib.jq +++ /dev/null @@ -1,34 +0,0 @@ -import "stringLib" as stringLib; - -def debugLog($target; $value): - if - ($ENV["JQ_DEBUG"] == $target) - or - ($target == "*") - or - ($ENV["JQ_DEBUG"] | split(",") | any(. as $debugTarget | $target | startswith($debugTarget | split("*")[0]))) - then - debug({$target, $value}) - end; - -def assert(cond; $msg): if cond then . else error($msg) end; -def assert($loc; cond; $msg): assert(cond; "\($loc.file):\($loc.line): " + $msg); - -def firstN($n): .[:$n]; - -def orderedUnique: - (reduce .[] as $value ([]; - if - (. | any(index($value)) | not) - then . += [$value] - else . end - )); - -def sortFilterFromString($filterString): - ($filterString | split("|")).[] as $filter | - if - $filter == "reverse" then . | reverse - elif ($filter | startswith("firstN")) then - ($filter | ltrimstr("firstN(") | rtrimstr(")")) as $arg | - . | firstN($arg | try fromjson catch error("invalid number passed to firstN")) - end; \ No newline at end of file diff --git a/tool/main.jq b/tool/main.jq deleted file mode 100644 index 89fdecc..0000000 --- a/tool/main.jq +++ /dev/null @@ -1,322 +0,0 @@ -import "lib/typeLib" as typeLib; -import "lib/argsLib" as argsLib; -import "lib/stringLib" as stringLib; -import "lib/tableLib" as tableLib; -import "lib/utilsLib" as utilsLib; -import "lib/journalLib" as journalLib; -import "lib/gojqExtendedLib" as gojqExtendedLib; -import "lib/journalTypes" as journalTypes; - -import "journalUtils" as journalUtils; - -def printExperienceStats($stats; $substanceFilter; $consumerFilter; $withTitle): - . as $experience | - - ($consumerFilter // ["default"]) as $consumerFilter | - - $experience.ingestions | - journalLib::filterIngestions($substanceFilter; $consumerFilter) | - sort_by(.sortDate) as $ingestions | - - ($ingestions | journalLib::ingestionsSubstanceNames) as $substanceNames | - ($ingestions | journalLib::ingestionsByConsumer) as $ingestionsByConsumer | - - ($ingestionsByConsumer | keys) as $consumerNames | - - "" as $experienceStatsText | - $experienceStatsText | - if $withTitle then - . += ($experience | journalUtils::formatExperienceTitle | . + "\n") - end | . as $experienceStatsText | - - reduce $consumerNames[] as $consumerName ($experienceStatsText; - . as $experienceStatsText | - $experienceStatsText | - if ($consumerNames != ["default"]) - then . += "Consumer: \($consumerName)\n" - end | . as $experienceStatsText | - - ($ingestionsByConsumer[$consumerName] | journalLib::ingestionsSubstanceNames) as $consumerSubstanceNames | - - $experienceStatsText | reduce $consumerSubstanceNames[] as $substanceName (.; - . as $experienceStatsText | - - ($stats.[$consumerName].[$substanceName] | keys) as $ingestionMethods | - - ($experienceStatsText | . += "Substance: \($substanceName)\n") as $experienceStatsText | - - reduce ($stats.[$consumerName].[$substanceName] | to_entries)[] as $ingestionMethodInfo ($experienceStatsText; - . as $experienceStatsText | - - $ingestionMethodInfo | - .key as $ingestionMethod | - .value as $ingestionInfo | - - def formatIngestionInfo: - if $ingestionInfo.dose == null then - "Unknown \($ingestionInfo.unit)" - else - if $ingestionInfo.isEstimate then "~" else "" end + - "\($ingestionInfo.dose * 100 | round / 100)" + - if $ingestionInfo.standardDeviation != null then - "±\($ingestionInfo.standardDeviation)" - else "" end + - - if $ingestionInfo.isUnknown then "+ Unknown" else "" end + - " \($ingestionInfo.unit)" - end; - - $experienceStatsText | - . += "Dose (\($ingestionMethod | stringLib::titleCase)): \($ingestionInfo | formatIngestionInfo)\n" | - . as $experienceStatsText | - - $experienceStatsText - ) | . as $experienceStatsText | - - $experienceStatsText | if ($ingestionMethods | length > 1) then - ($stats | journalLib::statsCalculateCombinedDose($substanceName; $consumerName)) as $combinedDose | - . += "Combined Dose: \($combinedDose.dose // "Unknown") \($combinedDose.unit)\n" - end | . as $experienceStatsText | - - $experienceStatsText | . += "\n" - ) - ) | rtrimstr("\n\n"); - -def printExperienceLog($customUnits; $substanceFilter; $consumerFilter; $pretty; $withTitle): - . as $experience | - ($consumerFilter // ["default"]) as $consumerFilter | - - $experience.ingestions | - journalLib::filterIngestions($substanceFilter; $consumerFilter) | - sort_by(.sortDate) as $ingestions | - - $ingestions | journalLib::ingestionsConsumerNames as $consumerNames | - - if ($consumerNames != ["default"]) then - ["Substance", "Dose", "ROA", "Consumer", "Time"] - else - ["Substance", "Dose", "ROA", "Time"] - end | . as $columnTitles | - - [ - $ingestions[] as $ingestion | - $ingestion | - .substanceName as $substanceName | - journalLib::ingestionConsumerName as $consumerName | - journalUtils::formatIngestionDose($customUnits) as $doseText | - journalUtils::formatIngestionROA($customUnits) as $roaText | - journalUtils::formatIngestionTime as $timeText | - if ($consumerNames != ["default"]) - then [$substanceName, $doseText, $roaText, $consumerName, $timeText] - else [$substanceName, $doseText, $roaText, $timeText] end - ] as $rows | - - tableLib::printPrettyTable( - if $withTitle then ($experience | journalUtils::formatExperienceTitle) else null end; - $columnTitles; - $rows - ); - -def printExperiences($customUnits; $substanceFilter; $consumerFilter): - . as $experiences | - - $experiences | - .[] as $entry | - $entry.experience as $experience | - $entry.stats as $stats | - ($experience | printExperienceLog( - $customUnits; - $substanceFilter; - $consumerFilter; - true; - true - )) + - "\nCumulative Doses:\n" + - ($experience | printExperienceStats( - $stats; - $substanceFilter; - $consumerFilter; - false - )) + "\n"; - - -def main: - def usage: - [ - "psychonaut_journal_stats {printExperience,printExperiences}", - "" - ] | join("\n") | halt_error(1); - - ($ARGS | argsLib::parseArgs) as $parsedArgs | - - $parsedArgs.nonArgs[0] as $program | - ($parsedArgs | .nonArgs |= $parsedArgs.nonArgs[1:]) as $parsedArgs | - - if gojqExtendedLib::checkSupported then - if $parsedArgs.longArgs["export-file"] then - $parsedArgs.longArgs["export-file"] - else - $ARGS.named["exportFileName"] - end | . as $exportFileName | - { - name: $exportFileName, - content: gojqExtendedLib::readFile($exportFileName) | fromjson - } - else - if $parsedArgs.longArgs | has("export-file") then - "--export-file was provided but this version of jq doesn't support reading files" + - "using EXPORT_FILE instead\n" | stderr - end | - { - name: $ARGS.named["exportFileName"], - content: $ARGS.named["exportFile"][0] - } - end | . as $exportFile | - - $exportFile.name as $exportFileName | - $exportFile.content as $exportData | - - if $exportData == null then - if gojqExtendedLib::checkSupported then - "please set EXPORT_FILE= or --export-file to a valid psychonaut journal export file\n" | - halt_error(1) - else - "please set EXPORT_FILE= to a valid psychonaut journal export file\n" | - halt_error(1) - end - end | - - $exportData | journalTypes::ensureExportData | - - if $program == null then - if any($parsedArgs.shortArgs[]; . == "h") then usage end | - if ($parsedArgs.longArgs | has("help")) then usage end | - - usage - elif $program == "printExperience" then - def printExperienceUsage($reason): - [ - $reason, - "Usage: printExperience [experienceTitle] --title=bool --stats=bool --substance-filter=[substanceNames,] --consumer-filter=[consumerNames,]", - "" - ] | map(select(. != null)) | join("\n") | halt_error(1); - - if any($parsedArgs.shortArgs[]; . == "h") then printExperienceUsage(null) end | - if ($parsedArgs.longArgs | has("help")) then printExperienceUsage(null) end | - - $parsedArgs.nonArgs[0] as $experienceTitle | - if $experienceTitle == null then printExperienceUsage("experienceTitle not provided") end | - - { - substanceFilter: null, - consumerFilter: null, - withTitle: true, - withStats: true, - } as $defaultOptions | - $defaultOptions as $options | - - reduce ($parsedArgs.longArgs | to_entries[]) as $longArg ($options; ( - $longArg.key as $arg | - $longArg.value as $value | - - if $arg == "title" then - .withTitle |= ($value // $defaultOptions.withTitle | argsLib::parseArgBool) - end | - if $arg == "stats" then - .withStats |= ($value // $defaultOptions.withStats | argsLib::parseArgBool) - end | - if $arg == "substance-filter" then - .substanceFilter |= ($parsedArgs.longArgs.["substance-filter"] | split(",")) - end | - if $arg == "consumer-filter" then - .consumerFilter |= ($parsedArgs.longArgs.["consumer-filter"] | split(",")) - end - )) | . as $options | - - $exportData.experiences | journalLib::experienceByTitle($experienceTitle) as $experience | - if $experience == null then error("Experience not found") end | - - ($experience | printExperienceLog( - $exportData.customUnits; - $options.substanceFilter; - $options.consumerFilter; - $options.pretty; - $options.withTitle - )) as $ingestionLog | - - if $options.withStats then - ($experience | journalLib::experienceStats($exportData.customUnits)) as $stats | - $ingestionLog + - "\n\nCumulative Doses:\n" + - ($experience | printExperienceStats( - $stats; - $options.substanceFilter; - $options.consumerFilter; - false - )) - else - $ingestionLog - end - elif $program == "printExperiences" then - def printExperiencesUsage($reason): - [ - $reason, - "Usage: printExperiences --substance-filter=[substanceNames,] --consumer-filter=[consumerNames,] --sort-method={old-to-new,highest-combined-dose,highest-dose-for-method} --sort-option-substance-name=[string] --sort-options-ingestion-method=[string] --sort-options-consumer-name=[string] --sort-filter={firstN(x),reverse}", - "" - ] | map(select(. != null)) | join("\n") | halt_error(1); - - if any($parsedArgs.shortArgs[]; . == "h") then printExperiencesUsage(null) end | - if ($parsedArgs.longArgs | has("help")) then printExperiencesUsage(null) end | - - { - substanceFilter: null, - consumerFilter: null, - sortMethod: "old-to-new", - sortOptions: {}, - sortFilter: null - } as $defaultOptions | - $defaultOptions as $options | - - reduce ($parsedArgs.longArgs | to_entries[]) as $longArg ($options; ( - $longArg.key as $arg | - $longArg.value as $value | - if $arg == "substance-filter" then - .substanceFilter |= ($parsedArgs.longArgs.["substance-filter"] | split(",")) - end | - if $arg == "consumer-filter" then - .consumerFilter |= ($parsedArgs.longArgs.["consumer-filter"] | split(",")) - end | - if $arg == "sort-method" then - .sortMethod |= $parsedArgs.longArgs.["sort-method"] - end | - if $arg == "sort-option-substance-name" then - .sortOptions.substanceName |= $parsedArgs.longArgs.["sort-option-substance-name"] - end | - if $arg == "sort-option-ingestion-method" then - .sortOptions.ingestionMethod |= $parsedArgs.longArgs.["sort-option-ingestion-method"] - end | - if $arg == "sort-option-consumer-name" then - .sortOptions.consumerName |= $parsedArgs.longArgs.["sort-option-consumer-name"] - end | - if $arg == "sort-filter" then - .sortFilter |= $parsedArgs.longArgs.["sort-filter"] - end - )) | . as $options | - - $exportData.experiences | - journalLib::filterSortExperiences( - $exportData.customUnits; - $options.substanceFilter; - $options.consumerFilter; - $options.sortMethod; - $options.sortOptions - ) | - if ($options.sortFilter != null) then utilsLib::sortFilterFromString($options.sortFilter) end | - printExperiences( - $exportData.customUnits; - $options.substanceFilter; - $options.consumerFilter - ) - else - usage - end; diff --git a/tool/testdata/tests_export.json b/tool/testdata/tests_export.json deleted file mode 100644 index eae5d2c..0000000 --- a/tool/testdata/tests_export.json +++ /dev/null @@ -1,205 +0,0 @@ -{ - "substanceCompanions": [ - { - "substanceName": "Caffeine", - "color": "BLUE" - }, - { - "color": "BROWN", - "substanceName": "N-Acetylcysteine" - }, - { - "substanceName": "Custom", - "color": "CYAN" - } - ], - "customUnits": [ - { - "substanceName": "Caffeine", - "isEstimate": false, - "isArchived": false, - "creationDate": 1730892759000, - "administrationRoute": "ORAL", - "unit": "pill", - "originalUnit": "mg", - "id": 1251361475, - "estimatedDoseStandardDeviation": null, - "name": "Tablet", - "dose": 200, - "note": "" - } - ], - "experiences": [ - { - "isFavorite": false, - "text": "", - "creationDate": 1730892508000, - "title": "Experience 1", - "ratings": [], - "sortDate": 1730892507000, - "timedNotes": [], - "ingestions": [ - { - "estimatedDoseStandardDeviation": null, - "dose": 20, - "stomachFullness": null, - "administrationRoute": "INSUFFLATED", - "substanceName": "Caffeine", - "creationDate": 1730892508000, - "units": "mg", - "time": 1730892507000, - "isDoseAnEstimate": false, - "notes": "", - "consumerName": null, - "customUnitId": null - }, - { - "customUnitId": null, - "estimatedDoseStandardDeviation": null, - "time": 1730892510000, - "stomachFullness": null, - "substanceName": "Caffeine", - "dose": 20, - "notes": "", - "creationDate": 1730892511000, - "isDoseAnEstimate": true, - "units": "mg", - "consumerName": null, - "administrationRoute": "INSUFFLATED" - }, - { - "estimatedDoseStandardDeviation": null, - "dose": 100, - "units": "mg", - "creationDate": 1730892529000, - "isDoseAnEstimate": false, - "consumerName": null, - "notes": "", - "administrationRoute": "ORAL", - "time": 1730892528000, - "substanceName": "Caffeine", - "customUnitId": null, - "stomachFullness": "EMPTY" - }, - { - "substanceName": "Caffeine", - "notes": "", - "customUnitId": null, - "time": 1730892533000, - "isDoseAnEstimate": true, - "administrationRoute": "ORAL", - "units": "mg", - "estimatedDoseStandardDeviation": null, - "dose": 100, - "creationDate": 1730892534000, - "stomachFullness": "EMPTY", - "consumerName": null - }, - { - "estimatedDoseStandardDeviation": 20, - "isDoseAnEstimate": true, - "administrationRoute": "ORAL", - "dose": 100, - "time": 1730892549000, - "units": "mg", - "consumerName": null, - "creationDate": 1730892554000, - "notes": "", - "substanceName": "Caffeine", - "stomachFullness": "EMPTY", - "customUnitId": null - }, - { - "stomachFullness": "EMPTY", - "notes": "", - "dose": 250, - "isDoseAnEstimate": false, - "time": 1730892600000, - "administrationRoute": "ORAL", - "creationDate": 1730892603000, - "estimatedDoseStandardDeviation": null, - "units": "mg", - "consumerName": null, - "customUnitId": null, - "substanceName": "N-Acetylcysteine" - } - ], - "location": null - }, - { - "text": "", - "sortDate": 1730892605000, - "isFavorite": false, - "ingestions": [ - { - "stomachFullness": "EMPTY", - "dose": 250, - "isDoseAnEstimate": false, - "substanceName": "N-Acetylcysteine", - "notes": "", - "consumerName": null, - "customUnitId": null, - "creationDate": 1730892610000, - "estimatedDoseStandardDeviation": null, - "time": 1730892605000, - "units": "mg", - "administrationRoute": "ORAL" - }, - { - "substanceName": "Custom", - "stomachFullness": null, - "customUnitId": null, - "time": 1730892696000, - "isDoseAnEstimate": false, - "units": "mg", - "notes": "", - "consumerName": null, - "estimatedDoseStandardDeviation": null, - "administrationRoute": "SMOKED", - "creationDate": 1730892698000, - "dose": 100 - }, - { - "dose": null, - "estimatedDoseStandardDeviation": null, - "substanceName": "Custom", - "units": "mg", - "administrationRoute": "SMOKED", - "creationDate": 1730892704000, - "notes": "", - "consumerName": null, - "customUnitId": null, - "time": 1730892702000, - "isDoseAnEstimate": false, - "stomachFullness": null - }, - { - "stomachFullness": "EMPTY", - "time": 1730892770000, - "consumerName": null, - "dose": 1, - "isDoseAnEstimate": false, - "customUnitId": 1251361475, - "substanceName": "Caffeine", - "notes": "", - "estimatedDoseStandardDeviation": null, - "administrationRoute": "ORAL", - "units": "mg", - "creationDate": 1730892771000 - } - ], - "title": "Experience 2", - "creationDate": 1730892610000, - "location": null, - "ratings": [], - "timedNotes": [] - } - ], - "customSubstances": [ - { - "description": "", - "name": "Custom", - "units": "mg" - } - ] -} diff --git a/tool/tests.jq b/tool/tests.jq deleted file mode 100644 index fd66db2..0000000 --- a/tool/tests.jq +++ /dev/null @@ -1,9 +0,0 @@ -import "lib/testLib" as testLib; -import "lib/typeLib" as typeLib; -import "lib/journalLibTests" as journalLibTests; - -def testsMain: - testLib::testTests | - typeLib::typeLibTests | - journalLibTests::journalLibTests | - "Tests Passed\n" | halt_error(0);