Skip to content

Commit

Permalink
✨ Add aggregate stats endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
malted committed Sep 5, 2024
1 parent e3a2c07 commit 337412e
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 38 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "replit-takeout"
version = "1.4.2"
version = "1.5.0"
edition = "2021"
authors = ["Ben Dixon <malted@malted.dev>"]

Expand Down
69 changes: 35 additions & 34 deletions src/airtable.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use airtable_api::{Airtable, Record};
use anyhow::Result;
use anyhow::{Context, Result};
use chrono::{DateTime, Utc};
use dotenv::var;
use once_cell::sync::Lazy;
Expand Down Expand Up @@ -93,50 +93,51 @@ pub async fn update_records(records: Vec<Record<AirtableSyncedUser>>) -> Result<
Ok(())
}

pub async fn aggregates() -> Result<()> {
let url = format!(
"https://api.airtable.com/v0/{}/{}/aggregate",
var("AIRTABLE_BASE_ID")?,
TABLE
);

// Set up headers
#[derive(Debug, Serialize)]
pub struct AggregateStats {
file_count: u64,
repl_count: u64,
}
pub async fn aggregates() -> Result<AggregateStats> {
let client = reqwest::Client::new();
let mut headers = HeaderMap::new();
headers.insert(
AUTHORIZATION,
HeaderValue::from_str(&format!("Bearer {}", var("AIRTABLE_API_KEY")?))?,
);
headers.insert(CONTENT_TYPE, HeaderValue::from_static("application/json"));

// Payload for the sum aggregation
let payload = json!({
"aggregations": [
{
"aggregator": "sum",
"field": "File Count"
}
]
});

// Create a client and send the request
let client = reqwest::Client::new();

let url = format!(
"https://api.airtable.com/v0/{}/{}",
var("AIRTABLE_BASE_ID")?,
TABLE
);

let response = client
.post(&url)
.get(&url)
.headers(headers)
.json(&payload)
.send()
.await?
.json::<Value>()
.await?;

// Check if the request was successful
if response.status().is_success() {
let data: Value = response.json().await?;
let column_sum = data["results"][0]["sum"].as_f64().unwrap_or(0.0);
println!("The sum of {} is: {}", "File Count", column_sum);
} else {
println!("Error: {}, {:?}", response.status(), response.text().await?);
}
let records = response["records"]
.as_array()
.context("failed to parse records")?;

Ok(())
let file_count: u64 = records
.iter()
.map(|r| r["fields"]["File Count"].as_u64().unwrap_or(0))
.sum();

let repl_count: u64 = records
.iter()
.map(|r| r["fields"]["Repl Count"].as_u64().unwrap_or(0))
.sum();

Ok(AggregateStats {
file_count,
repl_count,
})
}

use std::fmt;
Expand Down
9 changes: 7 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use base64::{
};
use rand::Rng;
use replit_takeout::{
airtable::{self, ProcessState},
airtable::{self, AggregateStats, ProcessState},
replit_graphql::{ExportProgress, ProfileRepls, QuickUser},
};
use rocket::serde::json::Json;
Expand Down Expand Up @@ -55,7 +55,7 @@ async fn rocket() -> _ {
});

rocket::build()
.mount("/", routes![hello, signup, get_progress])
.mount("/", routes![hello, signup, get_progress, get_stats])
.manage(State {
token_to_id_cache: tokio::sync::RwLock::new(HashMap::new()),
})
Expand Down Expand Up @@ -158,6 +158,11 @@ async fn get_progress(token: String, state: &rocket::State<State>) -> Option<Jso
}
}

#[get("/stats")]
async fn get_stats() -> Option<Json<AggregateStats>> {
Some(Json(airtable::aggregates().await.ok()?))
}

async fn airtable_loop() -> Result<()> {
let initial_wait = rand::thread_rng().gen_range(0..60);
tokio::time::sleep(Duration::from_secs(initial_wait)).await;
Expand Down

0 comments on commit 337412e

Please sign in to comment.