Skip to content

Commit

Permalink
refactor(cli): ♻️ update ingestion analyzer console output
Browse files Browse the repository at this point in the history
  • Loading branch information
keinsell committed Jun 9, 2024
1 parent d0c41a9 commit d7a9806
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 58 deletions.
20 changes: 20 additions & 0 deletions apps/cli/DEVELOPER_LOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
[2024-06-09]

Basic functionality of IngestionAnalyzer is working at some point, information about substances were bundled into migrator/db package which is available in monorepo - yet there is no clear way to synchronize migrations along 3 places - database packages and the atlas toolkit themself which also needs to be synchronized with prisma. Current targets should be set into improving structure of ingestions a little bit and analyzing past ingestions (with memoization as there is no reason to compute it every time) - maybe it's also time to introduce automatic completions for CLI as usage feels a little bit clunky - especially for things like substance names.

Ingestion Analyzer currently is able to provide following information:

----------------------------------------
Ingestion Analysis for "Caffeine"
Route of Administration: Oral
Dosage: 0.0001 kg^1
Dosage Classification: Common
Total Duration: "in 4 hours"
Phases:
* Onset: "now"
* Comeup: "in 9 minutes"
* Peak: "in 39 minutes"
* Offset: "in 2 hours"
* Afterglow: "in 4 hours"
----------------------------------------

[2024-06-05]

Come down to conclusion that scrapper of API information seems to be completely useless in CLI application, data may be delivered through SQL migration that will out of the box perform updates of stale data - I just wonder if there's a some solution for like incremental dumping of database, I really want avoid case where something will be related to substance_id then substance_id got changed or substance itself will get removed and then we'll lose ingestion information.
Expand Down
5 changes: 3 additions & 2 deletions apps/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
A small rust application that holds data in JSON format in XDG.

- Application will be extended to bare complete functionality without wasting time on UI, infrastructure and so on - all
of the "core" locally on your machine idgf.
the "core" locally on your machine idgf.

## Getting started

Expand All @@ -14,6 +14,7 @@ make copy-bin-linux

## TODOs

- Substance definitions? Should they be bundled to CLI?
- Neutral Language Parsing for like substance names, dosages etc.
- Add support for past ingestions for Ingestion Analyzer.
- Analytics
- ~~Add substance definitions applied by migrator.~~
2 changes: 1 addition & 1 deletion apps/cli/src/core/phase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::str::FromStr;
use std::time::Duration;
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Eq, Hash)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Eq, Hash, PartialOrd, Ord, Copy)]
#[serde(rename_all = "snake_case")]
pub enum PhaseClassification {
Onset,
Expand Down
90 changes: 35 additions & 55 deletions apps/cli/src/ingestion_analyzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// possible. This is a very important part of the application

use std::fmt::Debug;
use std::ops::Deref;
use std::time::Duration;

use chrono::{Local};
Expand Down Expand Up @@ -89,65 +90,34 @@ pub async fn analyze_future_ingestion(
}
});

let mut ingestion_phases: IngestionPhases = IngestionPhases::new();

let route_of_administration_phases = route_of_administration.phases.clone();

let parsed_time = parse_date_string(&create_ingestion.ingested_at, Local::now(), Dialect::Us)
.unwrap_or_else(|_| Local::now());

// Start with onset phase, create ingestion phase and add it to ingestion phases
let onset_phase = route_of_administration_phases.get(&PhaseClassification::Onset).unwrap();

let onset_ingestion_phase = IngestionPhase {
phase_classification: PhaseClassification::Onset,
duration: onset_phase.duration_range.clone(),
start_time: parsed_time,
end_time: parsed_time + onset_phase.duration_range.end,
};



let comeup_phase = route_of_administration_phases.get(&PhaseClassification::Comeup).unwrap();

let comeup_ingestion_phase = IngestionPhase {
phase_classification: PhaseClassification::Comeup,
duration: comeup_phase.duration_range.clone(),
start_time: onset_ingestion_phase.end_time.clone(),
end_time: onset_ingestion_phase.end_time + comeup_phase.duration_range.end,
};

let peak_phase = route_of_administration_phases.get(&PhaseClassification::Peak).unwrap();

let peak_ingestion_phase = IngestionPhase {
phase_classification: PhaseClassification::Peak,
duration: peak_phase.duration_range.clone(),
start_time: comeup_ingestion_phase.end_time.clone(),
end_time: comeup_ingestion_phase.end_time + peak_phase.duration_range.end,
};

let offset_phase = route_of_administration_phases.get(&PhaseClassification::Offset).unwrap();

let offset_ingestion_phase = IngestionPhase {
phase_classification: PhaseClassification::Offset,
duration: offset_phase.duration_range.clone(),
start_time: peak_ingestion_phase.end_time.clone(),
end_time: peak_ingestion_phase.end_time + offset_phase.duration_range.end,
};

let afterglow_phase = route_of_administration_phases.get(&PhaseClassification::Afterglow).unwrap();

let afterglow_ingestion_phase = IngestionPhase {
phase_classification: PhaseClassification::Afterglow,
duration: afterglow_phase.duration_range.clone(),
start_time: offset_ingestion_phase.end_time.clone(),
end_time: offset_ingestion_phase.end_time + afterglow_phase.duration_range.end,
};

ingestion_phases.insert(PhaseClassification::Onset, onset_ingestion_phase);
ingestion_phases.insert(PhaseClassification::Comeup, comeup_ingestion_phase);
ingestion_phases.insert(PhaseClassification::Peak, peak_ingestion_phase);
ingestion_phases.insert(PhaseClassification::Offset, offset_ingestion_phase);
ingestion_phases.insert(PhaseClassification::Afterglow, afterglow_ingestion_phase);
let mut end_time = parsed_time;

let phase_classifications = [
PhaseClassification::Onset,
PhaseClassification::Comeup,
PhaseClassification::Peak,
PhaseClassification::Offset,
PhaseClassification::Afterglow,
];

let ingestion_phases: IngestionPhases = phase_classifications.iter().filter_map(|classification| {
route_of_administration_phases.get(&classification.clone()).map(|phase| {
let ingestion_phase = IngestionPhase {
phase_classification: classification.clone(),
duration: phase.duration_range.clone(),
start_time: end_time,
end_time: end_time + phase.duration_range.end,
};
end_time = end_time + ingestion_phase.duration.end;
(classification.clone(), ingestion_phase)
})
}).collect();

let ingestion_analysis = IngestionAnalysis {
substance_name: substance.name.clone(),
Expand All @@ -164,15 +134,25 @@ pub async fn analyze_future_ingestion(
}

pub fn pretty_print_ingestion_analysis(ingestion_analysis: &IngestionAnalysis) {
println!("{}", "-".repeat(40));
println!("Ingestion Analysis for {:?}", ingestion_analysis.substance_name);
println!("Route of Administration: {:?}", ingestion_analysis.route_of_administration_classification);
println!("Dosage: {:?}", ingestion_analysis.dosage);
println!("Dosage Classification: {:?}", ingestion_analysis.dosage_classification);
println!("Total Duration: {:?}", HumanTime::from(chrono::Duration::from_std(ingestion_analysis.total_duration).unwrap()).to_string());
println!("Phases:");
for (phase_classification, phase) in ingestion_analysis.phases.iter() {
// Convert HashMap to Vec
let mut phases: Vec<(&PhaseClassification, &IngestionPhase)> = ingestion_analysis.phases.iter().collect();

// Sort Vec based on PhaseClassification
phases.sort_by_key(|&(classification, _)| *classification);

// Iterate over sorted Vec
for (phase_classification, phase) in phases {
println!("* {:?}: {:?}", phase_classification, HumanTime::from(phase.start_time).to_string());
}

println!("{}", "-".repeat(40));
}


Expand Down

0 comments on commit d7a9806

Please sign in to comment.