|
@@ -10,9 +10,9 @@ use crate::models;
|
|
|
use crate::models::{MailAddress, StrMessage};
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
|
-pub struct SerializableThread{
|
|
|
+pub struct SerializableThread {
|
|
|
pub id: u32,
|
|
|
- pub messages: Vec<String>
|
|
|
+ pub messages: Vec<String>,
|
|
|
}
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
@@ -38,8 +38,9 @@ impl PartialEq for SerializableMessage {
|
|
|
self.subject == other.subject &&
|
|
|
self.date == other.date &&
|
|
|
self.uid == other.uid &&
|
|
|
- self.list == other.list
|
|
|
- // TODO add more properties
|
|
|
+ self.list == other.list &&
|
|
|
+ self.id == other.id &&
|
|
|
+ self.in_reply_to == other.in_reply_to
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -50,14 +51,14 @@ impl From<models::StrMessage> for SerializableMessage {
|
|
|
let naive_date = NaiveDate::from_ymd_opt(
|
|
|
msg.date.year.clone() as i32,
|
|
|
msg.date.month.clone() as u32,
|
|
|
- msg.date.day.clone() as u32
|
|
|
+ msg.date.day.clone() as u32,
|
|
|
).unwrap();
|
|
|
let naive_datetime = naive_date.and_hms_opt(
|
|
|
msg.date.hour.clone() as u32,
|
|
|
msg.date.minute.clone() as u32,
|
|
|
- msg.date.second.clone() as u32
|
|
|
+ msg.date.second.clone() as u32,
|
|
|
).unwrap();
|
|
|
-
|
|
|
+
|
|
|
SerializableMessage {
|
|
|
name: msg.from.name.clone().unwrap_or_else(|| "Undefined Name".to_string()),
|
|
|
from: msg.from.address.clone(),
|
|
@@ -69,27 +70,25 @@ impl From<models::StrMessage> for SerializableMessage {
|
|
|
uid: msg.uid.clone(),
|
|
|
list: msg.list.clone(),
|
|
|
id: msg.id.clone(),
|
|
|
- in_reply_to: msg.in_reply_to.unwrap_or_default()
|
|
|
+ in_reply_to: msg.in_reply_to.unwrap_or_default(),
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-pub struct Indexes{
|
|
|
-
|
|
|
-}
|
|
|
+pub struct Indexes {}
|
|
|
|
|
|
impl Indexes {
|
|
|
- pub fn new() -> Self{
|
|
|
- Indexes{}
|
|
|
+ pub fn new() -> Self {
|
|
|
+ Indexes {}
|
|
|
}
|
|
|
|
|
|
- pub fn add(message: StrMessage) -> anyhow::Result<()>{
|
|
|
+ pub fn add(message: StrMessage) -> anyhow::Result<()> {
|
|
|
let messages = Indexes::update_message_indexes(message.clone()).unwrap_or_default();
|
|
|
if Config::global().out_dir.clone().join("threads.json").exists() {
|
|
|
- match Indexes::update_thread_indexes(message.clone(), messages.clone()){
|
|
|
+ match Indexes::update_thread_indexes(message.clone(), messages.clone()) {
|
|
|
Ok(new_thread_flag) => {
|
|
|
let mut lists: Vec<String> = vec!["Sent".to_string()];
|
|
|
- if message.list != "Sent"{
|
|
|
+ if message.list != "Sent" {
|
|
|
lists.push(message.list.clone())
|
|
|
}
|
|
|
let _ = Self::persist_indexes(lists); // tODO do not override all indexes
|
|
@@ -97,33 +96,33 @@ impl Indexes {
|
|
|
Err(_) => {}
|
|
|
};
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
Ok(())
|
|
|
}
|
|
|
-
|
|
|
- fn update_message_indexes(message: StrMessage) -> anyhow::Result<Vec<SerializableMessage>>{
|
|
|
+
|
|
|
+ fn update_message_indexes(message: StrMessage) -> anyhow::Result<Vec<SerializableMessage>> {
|
|
|
let path = Config::global().out_dir.clone().join("messages.json");
|
|
|
let mut messages: Vec<SerializableMessage> = Self::get_messages()?;
|
|
|
-
|
|
|
+
|
|
|
let s_message = SerializableMessage::from(message);
|
|
|
- if !messages.contains(&s_message){
|
|
|
+ if !messages.contains(&s_message) {
|
|
|
messages.push(s_message);
|
|
|
let _ = Indexes::write_to_json(serde_json::to_string_pretty(&messages)?, path);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
Ok(messages)
|
|
|
}
|
|
|
-
|
|
|
- pub fn update_thread_indexes(message: StrMessage, messages: Vec<SerializableMessage>) -> anyhow::Result<bool>{
|
|
|
+
|
|
|
+ pub fn update_thread_indexes(message: StrMessage, messages: Vec<SerializableMessage>) -> anyhow::Result<bool> {
|
|
|
let mut new_thread_flag = false;
|
|
|
let path = Config::global().out_dir.clone().join("threads.json");
|
|
|
-
|
|
|
+
|
|
|
let mut threads: Vec<SerializableThread> = Self::get_threads()?;
|
|
|
-
|
|
|
+
|
|
|
match message.in_reply_to {
|
|
|
None => {
|
|
|
- threads.push(SerializableThread{
|
|
|
- id: (threads.len() + 1) as u32,
|
|
|
+ threads.push(SerializableThread {
|
|
|
+ id: (threads.len() + 1) as u32,
|
|
|
messages: vec![message.id],
|
|
|
});
|
|
|
new_thread_flag = true;
|
|
@@ -131,7 +130,7 @@ impl Indexes {
|
|
|
Some(in_reply_to) => {
|
|
|
match Self::find_by_id(&messages, in_reply_to) {
|
|
|
None => {
|
|
|
- threads.push(SerializableThread{
|
|
|
+ threads.push(SerializableThread {
|
|
|
id: (threads.len() + 1) as u32,
|
|
|
messages: vec![message.id],
|
|
|
})
|
|
@@ -146,12 +145,12 @@ impl Indexes {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
let _ = Indexes::write_to_json(serde_json::to_string_pretty(&threads)?, path);
|
|
|
Ok(new_thread_flag)
|
|
|
}
|
|
|
-
|
|
|
- pub fn persist_indexes(lists: Vec<String>) -> anyhow::Result<()>{
|
|
|
+
|
|
|
+ pub fn persist_indexes(lists: Vec<String>) -> anyhow::Result<()> {
|
|
|
let mut messages: Vec<SerializableMessage> = Self::get_messages()?;
|
|
|
let mut threads: Vec<SerializableThread> = Self::get_threads()?;
|
|
|
|
|
@@ -161,21 +160,21 @@ impl Indexes {
|
|
|
let from_path = Config::global().out_dir.clone().join(list.clone()).join("from.json");
|
|
|
let to_path = Config::global().out_dir.clone().join(list.clone()).join("to.json");
|
|
|
let cc_path = Config::global().out_dir.clone().join(list.clone()).join("cc.json");
|
|
|
-
|
|
|
+
|
|
|
Self::write_to_json(serde_json::to_string_pretty(&Self::group_threads_by_subject(&mut threads, list.clone(), &mut messages)?)?, subject_path)?;
|
|
|
Self::write_to_json(serde_json::to_string_pretty(&Self::group_threads_by_date(&mut threads, list.clone(), &mut messages)?)?, date_path)?;
|
|
|
Self::write_to_json(serde_json::to_string_pretty(&Self::group_threads_by_cc(&mut threads, list.clone(), &mut messages)?)?, cc_path)?;
|
|
|
- if list != "Sent"{
|
|
|
+ if list != "Sent" {
|
|
|
Self::write_to_json(serde_json::to_string_pretty(&Self::group_threads_by_sender(&mut threads, list.clone(), &mut messages)?)?, from_path)?;
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
Self::write_to_json(serde_json::to_string_pretty(&Self::group_threads_by_receiver(&mut threads, list.clone(), &mut messages)?)?, to_path)?;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
Ok(())
|
|
|
}
|
|
|
|
|
|
- pub fn group_threads_by_subject(mut threads: &mut Vec<SerializableThread>, list: String, messages: &mut Vec<SerializableMessage>) -> anyhow::Result<Vec<(String, Vec<u32>)>>{
|
|
|
+ pub fn group_threads_by_subject(mut threads: &mut Vec<SerializableThread>, list: String, messages: &mut Vec<SerializableMessage>) -> anyhow::Result<Vec<(String, Vec<u32>)>> {
|
|
|
let threads_for_list = Self::get_threads_for_list(list.clone(), threads, messages);
|
|
|
let mut map: HashMap<String, Vec<u32>> = HashMap::new();
|
|
|
|
|
@@ -187,10 +186,10 @@ impl Indexes {
|
|
|
|
|
|
let mut sorted_vec: Vec<(String, Vec<u32>)> = map.into_iter().collect();
|
|
|
sorted_vec.sort_by(|a, b| a.0.cmp(&b.0));
|
|
|
-
|
|
|
+
|
|
|
Ok(sorted_vec)
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
pub fn group_threads_by_date(mut threads: &mut Vec<SerializableThread>, list: String, messages: &mut Vec<SerializableMessage>) -> anyhow::Result<Vec<(NaiveDate, Vec<u32>)>> {
|
|
|
let threads_for_list = Self::get_threads_for_list(list.clone(), threads, messages);
|
|
|
let mut map: HashMap<NaiveDate, Vec<(DateTime<Utc>, u32)>> = HashMap::new();
|
|
@@ -211,14 +210,14 @@ impl Indexes {
|
|
|
(date, sorted_ids)
|
|
|
})
|
|
|
.collect();
|
|
|
-
|
|
|
+
|
|
|
let mut sorted_vec: Vec<(NaiveDate, Vec<u32>)> = sorted_map.into_iter().collect();
|
|
|
sorted_vec.sort_by(|a, b| a.0.cmp(&b.0));
|
|
|
-
|
|
|
+
|
|
|
Ok(sorted_vec)
|
|
|
}
|
|
|
|
|
|
- pub fn group_threads_by_sender(mut threads: &mut Vec<SerializableThread>, list: String, messages: &mut Vec<SerializableMessage>) -> anyhow::Result<Vec<(String, Vec<u32>)>>{
|
|
|
+ pub fn group_threads_by_sender(mut threads: &mut Vec<SerializableThread>, list: String, messages: &mut Vec<SerializableMessage>) -> anyhow::Result<Vec<(String, Vec<u32>)>> {
|
|
|
let mut threads_for_list = Self::get_threads_for_list(list.clone(), threads, messages);
|
|
|
let mut map: HashMap<String, Vec<u32>> = HashMap::new();
|
|
|
|
|
@@ -230,11 +229,11 @@ impl Indexes {
|
|
|
|
|
|
let mut sorted_vec: Vec<(String, Vec<u32>)> = map.into_iter().collect();
|
|
|
sorted_vec.sort_by(|a, b| a.0.cmp(&b.0));
|
|
|
-
|
|
|
+
|
|
|
Ok(sorted_vec)
|
|
|
}
|
|
|
|
|
|
- pub fn group_threads_by_receiver(mut threads: &mut Vec<SerializableThread>, list: String, messages: &mut Vec<SerializableMessage>) -> anyhow::Result<Vec<(String, Vec<u32>)>>{
|
|
|
+ pub fn group_threads_by_receiver(mut threads: &mut Vec<SerializableThread>, list: String, messages: &mut Vec<SerializableMessage>) -> anyhow::Result<Vec<(String, Vec<u32>)>> {
|
|
|
let mut threads_for_list = Self::get_threads_for_list(list.clone(), threads, messages);
|
|
|
let mut map: HashMap<String, Vec<u32>> = HashMap::new();
|
|
|
|
|
@@ -248,11 +247,11 @@ impl Indexes {
|
|
|
|
|
|
let mut sorted_vec: Vec<(String, Vec<u32>)> = map.into_iter().collect();
|
|
|
sorted_vec.sort_by(|a, b| a.0.cmp(&b.0));
|
|
|
-
|
|
|
+
|
|
|
Ok(sorted_vec)
|
|
|
}
|
|
|
|
|
|
- pub fn group_threads_by_cc(mut threads: &mut Vec<SerializableThread>, list: String, messages: &mut Vec<SerializableMessage>) -> anyhow::Result<Vec<(String, Vec<u32>)>>{
|
|
|
+ pub fn group_threads_by_cc(mut threads: &mut Vec<SerializableThread>, list: String, messages: &mut Vec<SerializableMessage>) -> anyhow::Result<Vec<(String, Vec<u32>)>> {
|
|
|
let mut threads_for_list = Self::get_threads_for_list(list.clone(), threads, messages);
|
|
|
let mut map: HashMap<String, Vec<u32>> = HashMap::new();
|
|
|
|
|
@@ -266,11 +265,11 @@ impl Indexes {
|
|
|
|
|
|
let mut sorted_vec: Vec<(String, Vec<u32>)> = map.into_iter().collect();
|
|
|
sorted_vec.sort_by(|a, b| a.0.cmp(&b.0));
|
|
|
-
|
|
|
+
|
|
|
Ok(sorted_vec)
|
|
|
}
|
|
|
-
|
|
|
- fn get_threads_for_list(list: String, mut threads: &mut Vec<SerializableThread>, messages: &mut Vec<SerializableMessage>) -> Vec<SerializableThread>{
|
|
|
+
|
|
|
+ fn get_threads_for_list(list: String, mut threads: &mut Vec<SerializableThread>, messages: &mut Vec<SerializableMessage>) -> Vec<SerializableThread> {
|
|
|
let mut sorted_threads: Vec<SerializableThread>;
|
|
|
sorted_threads = threads
|
|
|
.into_iter()
|
|
@@ -280,8 +279,8 @@ impl Indexes {
|
|
|
.collect::<Vec<_>>();
|
|
|
sorted_threads
|
|
|
}
|
|
|
-
|
|
|
- pub fn persist_threads() -> anyhow::Result<()>{
|
|
|
+
|
|
|
+ pub fn persist_threads() -> anyhow::Result<()> {
|
|
|
let messages: Vec<SerializableMessage> = Self::get_messages()?;
|
|
|
|
|
|
let mut uf = UnionFind::new();
|
|
@@ -323,18 +322,18 @@ impl Indexes {
|
|
|
|
|
|
let thread_path = Config::global().out_dir.clone().join("threads.json");
|
|
|
let _ = Indexes::write_to_json(serde_json::to_string_pretty(&threads)?, thread_path);
|
|
|
-
|
|
|
+
|
|
|
Ok(())
|
|
|
}
|
|
|
-
|
|
|
- fn write_to_json(content: String, path: PathBuf) -> anyhow::Result<()>{
|
|
|
+
|
|
|
+ fn write_to_json(content: String, path: PathBuf) -> anyhow::Result<()> {
|
|
|
let mut file = OpenOptions::new()
|
|
|
.write(true)
|
|
|
.create(true)
|
|
|
.truncate(true)
|
|
|
.open(&path)?;
|
|
|
file.write_all(content.as_bytes())?;
|
|
|
-
|
|
|
+
|
|
|
Ok(())
|
|
|
}
|
|
|
|
|
@@ -355,8 +354,8 @@ impl Indexes {
|
|
|
}
|
|
|
None
|
|
|
}
|
|
|
-
|
|
|
- pub fn get_messages() -> anyhow::Result<Vec<SerializableMessage>>{
|
|
|
+
|
|
|
+ pub fn get_messages() -> anyhow::Result<Vec<SerializableMessage>> {
|
|
|
let path = Config::global().out_dir.clone().join("messages.json");
|
|
|
let messages: Vec<SerializableMessage> = if path.exists() {
|
|
|
let file = File::open(&path)?;
|
|
@@ -365,11 +364,11 @@ impl Indexes {
|
|
|
} else {
|
|
|
Vec::new()
|
|
|
};
|
|
|
-
|
|
|
+
|
|
|
Ok(messages)
|
|
|
}
|
|
|
-
|
|
|
- pub fn get_threads() -> anyhow::Result<Vec<SerializableThread>>{
|
|
|
+
|
|
|
+ pub fn get_threads() -> anyhow::Result<Vec<SerializableThread>> {
|
|
|
let path = Config::global().out_dir.clone().join("threads.json");
|
|
|
|
|
|
let mut threads: Vec<SerializableThread> = if path.exists() {
|
|
@@ -379,28 +378,28 @@ impl Indexes {
|
|
|
} else {
|
|
|
Vec::new()
|
|
|
};
|
|
|
-
|
|
|
+
|
|
|
Ok(threads)
|
|
|
}
|
|
|
-
|
|
|
- fn get_last_from_list_from_thread(thread: &SerializableThread, list: String, messages: &Vec<SerializableMessage>) -> Option<SerializableMessage>{
|
|
|
+
|
|
|
+ fn get_last_from_list_from_thread(thread: &SerializableThread, list: String, messages: &Vec<SerializableMessage>) -> Option<SerializableMessage> {
|
|
|
let mut temp = thread.messages.clone();
|
|
|
temp.reverse();
|
|
|
- for id in temp{
|
|
|
- match Self::find_by_id(messages, id){
|
|
|
+ for id in temp {
|
|
|
+ match Self::find_by_id(messages, id) {
|
|
|
None => {}
|
|
|
Some(message) => {
|
|
|
- if message.list == list {
|
|
|
- return Some(message)
|
|
|
+ if message.list == list {
|
|
|
+ return Some(message);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
None
|
|
|
}
|
|
|
|
|
|
- pub fn delete_from_messages(message_id: String) -> anyhow::Result<SerializableMessage>{
|
|
|
+ pub fn delete_from_messages(message_id: String) -> anyhow::Result<SerializableMessage> {
|
|
|
let path = Config::global().out_dir.clone().join("messages.json");
|
|
|
let file = File::open(&path)?;
|
|
|
let reader = BufReader::new(file);
|
|
@@ -408,16 +407,16 @@ impl Indexes {
|
|
|
let message_for_deletion;
|
|
|
if let Some(pos) = messages.iter().position(|message| message.id == message_id) {
|
|
|
message_for_deletion = messages.remove(pos)
|
|
|
- }else{
|
|
|
- return Err(anyhow!("Cannot delete message from messages.json"))
|
|
|
+ } else {
|
|
|
+ return Err(anyhow!("Cannot delete message from messages.json"));
|
|
|
}
|
|
|
Self::write_to_json(serde_json::to_string_pretty(&messages)?, path)?;
|
|
|
-
|
|
|
+
|
|
|
|
|
|
Ok(message_for_deletion)
|
|
|
}
|
|
|
|
|
|
- pub fn delete_from_threads(message: SerializableMessage) -> anyhow::Result<()>{
|
|
|
+ pub fn delete_from_threads(message: SerializableMessage) -> anyhow::Result<()> {
|
|
|
let path = Config::global().out_dir.clone().join("threads.json");
|
|
|
let file = File::open(&path)?;
|
|
|
let reader = BufReader::new(file);
|
|
@@ -434,7 +433,7 @@ impl Indexes {
|
|
|
}
|
|
|
i += 1;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
Self::write_to_json(serde_json::to_string_pretty(&threads)?, path)?;
|
|
|
Ok(())
|
|
|
}
|