use std::collections::HashMap;
use chrono::{DateTime, Utc};
use mongodb::bson::doc;
use serde::{Deserialize, Serialize};
use crate::{config::IConfig, routes::queue::InternalQueueItem};
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(untagged)]
pub enum Data {
Presence {
id: String,
platform: String,
presence_type: String,
retrieved_at: DateTime<Utc>,
added_by: Option<String>,
added_at: Option<DateTime<Utc>>,
},
Content {
id: String,
platform: String,
content_type: String,
retrieved_at: DateTime<Utc>,
content_id: String,
deleted: Option<bool>,
retrieved_from: Option<String>,
created_at: Option<DateTime<Utc>>,
body: Option<String>,
media: Option<Vec<String>>,
references: Option<HashMap<String, String>>,
added_by: Option<String>,
added_at: Option<DateTime<Utc>>,
},
Meta {
id: String,
platform: String,
username: String,
private: bool,
suspended_or_banned: bool,
retrieved_at: DateTime<Utc>,
display_name: Option<String>,
profile_picture: Option<String>,
bio: Option<String>,
verified: Option<bool>,
references: Option<HashMap<String, String>>,
link: Option<String>,
added_by: Option<String>,
added_at: Option<DateTime<Utc>>,
},
}
impl Data {
pub fn tag(self, uuid: &str) -> Self {
match self {
Data::Presence {
id,
platform,
presence_type,
retrieved_at,
..
} => Data::Presence {
id,
platform,
presence_type,
retrieved_at,
added_by: Some(uuid.to_string()),
added_at: Some(Utc::now()),
},
Data::Content {
id,
platform,
content_type,
retrieved_at,
content_id,
deleted,
retrieved_from,
created_at,
body,
media,
references,
..
} => Data::Content {
id,
platform,
content_type,
retrieved_at,
content_id,
deleted,
retrieved_from,
created_at,
body,
media,
references,
added_by: Some(uuid.to_string()),
added_at: Some(Utc::now()),
},
Data::Meta {
id,
platform,
username,
private,
suspended_or_banned,
display_name,
profile_picture,
bio,
verified,
references,
link,
retrieved_at,
..
} => Data::Meta {
id,
platform,
username,
private,
suspended_or_banned,
display_name,
profile_picture,
bio,
verified,
references,
link,
retrieved_at,
added_by: Some(uuid.to_string()),
added_at: Some(Utc::now()),
},
}
}
pub fn verify(&self, config: &IConfig) -> bool {
match self {
Data::Presence {
platform,
presence_type,
..
} => config.valid_presence_type(platform, presence_type),
Data::Content {
platform,
content_type,
..
} => config.valid_content_type(platform, content_type),
Data::Meta { platform, .. } => config.valid_platform(platform),
}
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Datas {
pub queue_id: Option<String>,
pub data: Vec<Data>,
}
impl Datas {
pub fn tag(self, uuid: &str) -> Self {
let mut tagged_data = Vec::new();
for data in self.data {
tagged_data.push(data.tag(uuid))
}
Datas {
data: tagged_data,
..self
}
}
pub fn verify_for_config(self, config: &IConfig) -> Self {
let mut verified_data = Vec::new();
for data in self.data {
if data.verify(config) {
verified_data.push(data);
}
}
Datas {
data: verified_data,
..self
}
}
pub fn meta(&self) -> Option<Data> {
for data in &self.data {
if let Data::Meta { .. } = data {
return Some(data.clone());
}
}
None
}
pub fn info(&self) -> (String, String, String, Option<String>) {
if let Some(meta) = self.meta() {
let (platform_id, platform, added_by, username) = match meta {
Data::Meta {
id,
platform,
added_by,
username,
..
} => (id, platform, added_by, Some(username)),
_ => panic!("Expected Data::Meta."),
};
(platform_id, platform, added_by.unwrap(), username)
} else {
let data = self.data[0].clone();
let (platform_id, platform, added_by) = match data {
Data::Presence {
id,
platform,
added_by,
..
} => (id, platform, added_by),
Data::Content {
id,
platform,
added_by,
..
} => (id, platform, added_by),
_ => panic!("Expected Data::Presence or Data::Content."),
};
(platform_id, platform, added_by.unwrap(), None)
}
}
pub fn verify_for_queue(self, queue_item: InternalQueueItem) -> Self {
let mut verified_data = Vec::new();
for data in &self.data {
let verified: bool = match &data {
Data::Meta { platform, id, .. } => {
&queue_item.platform == platform
&& (&queue_item.platform_id == id
|| !&queue_item.confirmed_id)
}
Data::Content { platform, id, .. } => {
&queue_item.platform_id == id
&& &queue_item.platform == platform
}
Data::Presence { platform, id, .. } => {
&queue_item.platform_id == id
&& &queue_item.platform == platform
}
};
if verified {
verified_data.push(data.clone());
}
}
Datas {
data: verified_data,
..self
}
}
}