Переглянути джерело

converting emails in parallel with downloading

Yurii Sokolovskyi 2 місяців тому
батько
коміт
ba9b6da1f4
2 змінених файлів з 36 додано та 42 видалено
  1. 21 8
      src/imap.rs
  2. 15 34
      src/main.rs

+ 21 - 8
src/imap.rs

@@ -29,6 +29,7 @@ use async_imap::extensions::idle::IdleResponse::NewData;
 use async_imap_wasi::{Client, Session};
 #[cfg(target_os = "wasi")]
 use async_imap_wasi::extensions::idle::IdleResponse::NewData;
+use crate::indexes::Indexes;
 
 /// create TLS connect with the IMAP server
 pub async fn connect_to_imap() -> anyhow::Result<Client<TlsStream<TcpStream>>>{
@@ -149,7 +150,18 @@ pub async fn fetch_and_store_emails(session: &mut Session<TlsStream<TcpStream>>,
                 match mail_file {
                     Ok(file) => {
                         // TODO convert and persist html
-                        stored_paths.push((uid.to_string().parse().unwrap(), file))
+                        // persist to the maildir
+                        stored_paths.push((uid.to_string().parse().unwrap(), file.clone()));
+                        
+                        // persist to the output dir
+                        match add_email(file.clone(), uid.clone()){
+                            Ok(_) => {}
+                            Err(_) => {println!("Error adding email from {:?}", file.clone())}
+                        };
+                        
+                        // TODO adjust indexes
+                        Indexes::persist_threads().expect("Unable to persist threads");
+                        Indexes::persist_indexes(vec![list.clone()]).expect("Unable to persist indexes");
                     },
                     Err(e) => eprintln!("Failed to store email: {}", e),
                 }
@@ -323,13 +335,14 @@ pub async fn check_for_updates(mailbox: String) -> anyhow::Result<()> {
                 // TODO add more cases like delete, move...
                 NewData(data) => {
                     // TODO do not update all emails (IMAP returns * {number} RECENT) and do it only for one mailbox
-                    let new_paths = download_email_from_imap().await.expect("Cannot download new emails");
-                    for (uid, path) in new_paths.clone() {
-                        match add_email(path.clone(), uid.clone()){
-                            Ok(_) => {}
-                            Err(_) => {println!("Error adding email from {:?}", path.clone())}
-                        };
-                    }
+                    // TODO CHANGE IT!!!
+                    // let new_paths = download_email_from_imap().await.expect("Cannot download new emails");
+                    // for (uid, path) in new_paths.clone() {
+                    //     match add_email(path.clone(), uid.clone()){
+                    //         Ok(_) => {}
+                    //         Err(_) => {println!("Error adding email from {:?}", path.clone())}
+                    //     };
+                    // }
                 }
                 reason => {
                     println!("IDLE failed {:?}", reason);

+ 15 - 34
src/main.rs

@@ -331,53 +331,34 @@ async fn run(){
     parse_args();
 
     // API
-    tokio::spawn(async move {
+    let api_task = tokio::spawn(async move {
         run_api().await
     });
-    // run_api().await;
     
     // downloading new emails
-    let new_paths = imap::download_email_from_imap().await.expect("Cannot download new emails");
-    
-    let mut lists: Vec<String> = Vec::new();
-
-    for mail_list in std::fs::read_dir(Config::global().maildir.clone())
-        .expect("could not read maildir")
-        .filter_map(|m| m.ok())
-    {
-        let dir_name = mail_list.file_name().into_string().unwrap();
-        
-        if dir_name.starts_with('.') || ["cur", "new", "tmp"].contains(&dir_name.as_str()) {
-            continue; 
-        }
-        
-        lists.push(dir_name.clone());
-    }
+    imap::download_email_from_imap().await.expect("Cannot download new emails");
     
+    // Uncomment to convert to HTML without downloading
     // let mut uid = 1; // fake uid for tests
     // for entry in std::fs::read_dir(Config::global().maildir.clone().join("INBOX").join("new")).expect("could not read maildir").filter_map(|m| m.ok()){
-    for (uid, path) in new_paths.clone() {
-        // let path = entry.path();
+    //     let path = entry.path();
+    // 
+    //     match add_email(path.clone(), uid.clone()){
+    //         Ok(_) => {}
+    //         Err(_) => {println!("Error adding email from {:?}", path.clone())}
+    //     };
+    //     
+    //     uid += 1;
+    // }
 
-        match add_email(path.clone(), uid.clone()){
-            Ok(_) => {}
-            Err(_) => {println!("Error adding email from {:?}", path.clone())}
-        };
-        
-        // uid += 1;
-    }
-
-    // TODO update indexes along with persisting emails
-    let threads_indexes_path = Config::global().out_dir.clone().join("threads.json");
-    if !threads_indexes_path.exists() {
-        Indexes::persist_threads().expect("Unable to persist threads");
-        Indexes::persist_indexes(lists).expect("Unable to persist indexes");    
-    }
 
     // monitor updates in INBOX
     if let Err(e) = check_for_updates("INBOX".to_string()).await {
         eprintln!("Failed to monitor mailbox: {:?}", e);
     }
+    
+    // dont stop the program while API is running
+    api_task.await.expect("Error while running API");
 }
 
 /// Entry point for a wasi env