journal/tool/main.jq
2024-11-07 08:58:38 +00:00

391 lines
14 KiB
Plaintext

# run as: jq export.json -f tool.jq -Cr --args --
include "utils";
include "args";
include "journalUtils";
def printExperienceStats($stats; $substanceFilter; $consumerFilter; $withTitle):
. as $experience |
($consumerFilter // ["default"]) as $consumerFilter |
$experience.ingestions | filterIngestions($substanceFilter; $consumerFilter) as $ingestions |
($ingestions | ingestionsByConsumer) as $ingestionsByConsumer |
($ingestionsByConsumer | keys) as $consumerNames |
"" as $experienceStatsText |
$experienceStatsText |
if $withTitle then
. += ($experience | formatExperienceTitle | . + "\n")
end | . as $experienceStatsText |
reduce $consumerNames[] as $consumerName ($experienceStatsText;
. as $experienceStatsText |
$experienceStatsText |
if ($consumerNames != ["default"])
then . += "Consumer: \($consumerName)\n"
end | . as $experienceStatsText |
($stats.[$consumerName] | keys) as $substanceNames |
$experienceStatsText | reduce $substanceNames[] as $substanceName (.;
. as $experienceStatsText |
($stats.[$consumerName].[$substanceName] | keys) as $ingestionMethods |
($experienceStatsText | . += "Substance: \($substanceName)\n") as $experienceStatsText |
reduce ($stats.[$consumerName].[$substanceName] | to_entries)[] as $substanceStats ($experienceStatsText;
. as $experienceStatsText |
$substanceStats |
.key as $ingestionMethod |
ifNullDefault(.value.dose; "Unknown") as $dose |
.value.unit as $unit |
($experienceStatsText | . += "Dose (\($ingestionMethod | titleCase)): \($dose) \($unit)\n") as $experienceStatsText |
$experienceStatsText
) | . as $experienceStatsText |
$experienceStatsText | if ($ingestionMethods | length > 1) then
($stats | calculateCombinedDose($substanceName; $consumerName)) as $combinedDose |
. += "Combined Dose: \(ifNullDefault($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 | sort_by(.sortDate) | filterIngestions($substanceFilter; $consumerFilter) as $ingestions |
$ingestions | ingestionsConsumerNames as $consumerNames |
if ($consumerNames == ["default"])
then
["Substance", "Dose", "ROA", "Consumer", "Time"]
else
["Substance", "Dose", "ROA", "Time"]
end | . as $columnTitles |
(reduce $ingestions[] as $ingestion ([]; . as $rows |
$ingestion |
.substanceName as $substanceName |
ifNullDefault(.consumerName; "default") as $consumerName |
formatIngestionDose($customUnits) as $doseText |
formatIngestionROA($customUnits) as $roaText |
formatIngestionTime as $timeText |
$rows | . += [
if ($consumerNames != ["default"])
then [$substanceName, $doseText, $roaText, $consumerName, $timeText]
else [$substanceName, $doseText, $roaText, $timeText] end
]
)) as $rows |
if $pretty then
printPrettyTable(
if $withTitle then ($experience | formatExperienceTitle) else null end;
$columnTitles;
$rows
)
else
$rows | map(join(" | ")) | rtrimstr(" ") as $rows |
(if $withTitle then [$experience | formatExperienceTitle] else [] end) + $rows | join("\n")
end | . as $ingestionLog |
$ingestionLog;
def printExperiencesAdvanced($customUnits; $substanceFilter; $consumerFilter; $sortMethod; $sortOptions; $sortFilterString; sortFilter):
. as $experiences |
($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 sortFilterExperiences:
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 |
(reduce $experiencesData[] as $experienceData ([];
($experienceData.experience.ingestions) as $ingestions |
. +=
if ($experienceData.experience.ingestions |
any(
.substanceName as $substanceName |
$substanceFilter |
any(index($substanceName))
)
) then [$experienceData] else [] end
));
def filterByConsumerFilter:
. as $experiencesData |
(reduce $experiencesData[] as $experienceData ([];
($experienceData.experience.ingestions) as $ingestions |
. +=
if ($experienceData.experience.ingestions |
any(
ifNullDefault(.consumerName; "default") 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
ifNullDefault(.consumerName; "default") == $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
assert($sortOptions.substanceName != null; "substanceName not provided as sortOption") |
filterBySubstanceAndConsumer |
sort_by(highestCombinedDoseSort, oldToNewSort) |
reverse
elif
$sortMethod == "highest-dose-for-method"
then
assert($sortOptions.substanceName != null; "substanceName not provided as sortOption") |
filterByIngestionMethodForSubstance |
sort_by(highestMethodDoseSort, oldToNewSort) |
reverse
end;
def sortFilterFromString($filterString):
(reduce ($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
));
def experiencesWithExtraData($customUnits):
. as $experiences |
(reduce $experiences[] as $experience ([];
. += [{
stats: $experience | experienceStats($customUnits),
$experience
}]
));
$experiences |
experiencesWithExtraData($customUnits) |
sortFilterExperiences |
if ($sortFilterString != null) then . | sortFilterFromString($sortFilterString) end |
if (sortFilter != null) then . | sortFilter end |
.[] 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($ARGS):
def usage:
[
"psychonaut_journal_stats {printExperience,printExperiencesAdvanced}",
""
] | join("\n") | halt_error(1);
. as $exportData |
($ARGS | parseArgs) as $parsedArgs |
$parsedArgs.nonArgs[0] as $program |
($parsedArgs | .nonArgs |= $parsedArgs.nonArgs[1:]) as $parsedArgs |
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] --pretty=bool --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,
pretty: true,
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 == "pretty" then
.pretty |= (ifNullDefault($value; $defaultOptions.pretty) | parseArgBool)
end |
if $arg == "title" then
.withTitle |= (ifNullDefault($value; $defaultOptions.withTitle) | parseArgBool)
end |
if $arg == "stats" then
.withStats |= (ifNullDefault($value; $defaultOptions.withStats) | 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 | 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 | experienceStats($exportData.customUnits)) as $stats |
$ingestionLog +
"\n\nCumulative Doses:\n" +
($experience | printExperienceStats(
$stats;
$options.substanceFilter;
$options.consumerFilter;
false
))
else
$ingestionLog
end
elif $program == "printExperiencesAdvanced" then
def printExperiencesAdvancedUsage($reason):
[
$reason,
"Usage: printExperiencesAdvanced --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 printExperiencesAdvancedUsage(null) end |
if ($parsedArgs.longArgs | has("help")) then printExperiencesAdvancedUsage(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 |
printExperiencesAdvanced(
$exportData.customUnits;
$options.substanceFilter;
$options.consumerFilter;
$options.sortMethod;
$options.sortOptions;
$options.sortFilter; null
)
else
usage
end;
main($ARGS)