From 0806b43003af381417af8a7e0935855f6f2e71ef Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Sat, 16 Nov 2024 14:31:02 -0800 Subject: [PATCH] Dedupe every.org donations --- src/every_org.rs | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/src/every_org.rs b/src/every_org.rs index 79320eb..0c8bd22 100644 --- a/src/every_org.rs +++ b/src/every_org.rs @@ -1,8 +1,8 @@ use crate::{is_past, Donor}; -use chrono::{DateTime, Utc}; +use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime, Utc}; use reqwest::Client; use serde::Deserialize; -use std::{error::Error, fs::File, num::ParseFloatError}; +use std::{collections::HashMap, error::Error, fs::File, num::ParseFloatError}; use thiserror::Error; const DONOR_CSV_PATH: &str = "every_org_donors/donors.csv"; @@ -37,6 +37,7 @@ pub(crate) async fn get_every_org_donors(now: DateTime) -> Result) -> Result::from_naive_utc_and_offset(naive_datetime, chrono::offset::Utc); + is_past(now, datetime) } else { true }; @@ -61,6 +65,31 @@ pub(crate) async fn get_every_org_donors(now: DateTime) -> Result) -> Vec { + let mut donors = donors + .drain(..) + .map(|donor| { + // "created" is "this payment made" not "when donor started donating" + let created = donor.created.as_deref().unwrap_or(""); + let created_date = NaiveDate::parse_from_str(created, "%m/%d/%Y").ok(); + (created_date, donor) + }) + .collect::>(); + donors.sort_by_key(|(date, _)| date.clone()); + let mut deduped = HashMap::new(); + for (_, donor) in donors { + let Some(donor_id) = &donor.donor_id else { + continue; + }; + if !deduped.contains_key(donor_id) { + deduped.insert(donor_id.clone(), donor); + } + } + + deduped.drain().map(|(_, v)| v).collect::>() +} + #[allow(dead_code)] #[derive(Debug, Deserialize)] pub(crate) struct EveryOrgDonorCsv {