journal/tool/main.jq
2024-11-10 08:24:51 +00:00

323 lines
11 KiB
Plaintext

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;