Browse Source

create/rename/delete folders functionality added

Yurii Sokolovskyi 3 months ago
parent
commit
f8fe7faf81
3 changed files with 107 additions and 2 deletions
  1. 69 0
      src/imap.rs
  2. 26 1
      src/imap/imap_client.rs
  3. 12 1
      src/main.rs

+ 69 - 0
src/imap.rs

@@ -276,6 +276,75 @@ pub async fn delete_email_by_uid(list: String, uid: u32) -> anyhow::Result<()>{
     Ok(())
 }
 
+#[cfg(not(target_os = "wasi"))]
+pub async fn create_folder(name: String) -> anyhow::Result<()>{
+    let tls = native_tls::TlsConnector::builder().build().unwrap();
+    let client = imap::connect((Config::global().imap_domain.clone(), 993), Config::global().imap_domain.clone(), &tls).unwrap();
+    let mut imap_session = client
+        .login(Config::global().username.clone(), Config::global().password.clone())
+        .map_err(|e| e.0)?;
+
+    imap_session.create(name)?;
+    imap_session.logout()?;
+
+    Ok(())
+}
+
+#[cfg(target_os = "wasi")]
+pub async fn create_folder(name: String) -> anyhow::Result<()>{
+    let mut client = connect_to_imap_server(Config::global().imap_domain.clone() ,993).await?; // TODO move port to config
+    client.login(Config::global().username.clone(), Config::global().password.clone()).await?;
+    client.create_folder(name.clone()).await?;
+    client.logout().await?;
+    Ok(())
+}
+
+#[cfg(not(target_os = "wasi"))]
+pub async fn rename_folder(name: String, new_name: String) -> anyhow::Result<()>{
+    let tls = native_tls::TlsConnector::builder().build().unwrap();
+    let client = imap::connect((Config::global().imap_domain.clone(), 993), Config::global().imap_domain.clone(), &tls).unwrap();
+    let mut imap_session = client
+        .login(Config::global().username.clone(), Config::global().password.clone())
+        .map_err(|e| e.0)?;
+
+    imap_session.rename(name, new_name)?;
+    imap_session.logout()?;
+
+    Ok(())
+}
+
+#[cfg(target_os = "wasi")]
+pub async fn rename_folder(name: String, new_name: String) -> anyhow::Result<()>{
+    let mut client = connect_to_imap_server(Config::global().imap_domain.clone() ,993).await?; // TODO move port to config
+    client.login(Config::global().username.clone(), Config::global().password.clone()).await?;
+    client.rename_folder(name.clone(), new_name.clone()).await?;
+    client.logout().await?;
+    Ok(())
+}
+
+#[cfg(not(target_os = "wasi"))]
+pub async fn delete_folder(name: String) -> anyhow::Result<()>{
+    let tls = native_tls::TlsConnector::builder().build().unwrap();
+    let client = imap::connect((Config::global().imap_domain.clone(), 993), Config::global().imap_domain.clone(), &tls).unwrap();
+    let mut imap_session = client
+        .login(Config::global().username.clone(), Config::global().password.clone())
+        .map_err(|e| e.0)?;
+
+    imap_session.delete(name)?;
+    imap_session.logout()?;
+
+    Ok(())
+}
+
+#[cfg(target_os = "wasi")]
+pub async fn delete_folder(name: String) -> anyhow::Result<()>{
+    let mut client = connect_to_imap_server(Config::global().imap_domain.clone() ,993).await?; // TODO move port to config
+    client.login(Config::global().username.clone(), Config::global().password.clone()).await?;
+    client.delete_folder(name.clone()).await?;
+    client.logout().await?;
+    Ok(())
+}
+
 fn store(
     path: PathBuf,
     uid: String,

+ 26 - 1
src/imap/imap_client.rs

@@ -6,6 +6,7 @@ use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader, ReadHalf, WriteHalf};
 use tokio::net::TcpStream;
 use tokio_rustls::rustls::{ClientConfig, RootCertStore};
 use std::convert::TryFrom;
+use anyhow::anyhow;
 use imap_proto::{self, MailboxDatum};
 use imap_proto::parser::parse_response;
 
@@ -36,7 +37,8 @@ impl Client {
         let mut response = String::new();
         let mut temp = String::new();
         while let Ok(bytes) = self.reader.read_line(&mut temp).await {
-            if bytes == 0 || temp.contains(&*format!("{} OK", id)) {
+            println!("Temp: {:?}", temp);
+            if bytes == 0 || temp.contains(&*id.to_string()) { // if bytes == 0 || temp.contains(&*format!("{} OK", id))
                 break;
             }
             response += &*temp;
@@ -135,6 +137,29 @@ impl Client {
         self.run_command(format!("{} EXPUNGE", id)).await.unwrap();
         Ok(())
     }
+    
+    pub async fn create_folder(&mut self, name: String) -> anyhow::Result<()>{
+        if name.is_empty() { return Err(anyhow!("Folder name is empty")) }
+        let id = "aCreateFolder".to_string();
+        self.run_command(format!("{} CREATE \"{}\"", id, name)).await.unwrap();
+        Ok(())
+    }
+
+    pub async fn delete_folder(&mut self, name: String) -> anyhow::Result<()>{
+        if name.is_empty() { return Err(anyhow!("Folder name is empty")) }
+
+        let id = "aDeleteFolder".to_string();
+        self.run_command(format!("{} DELETE \"{}\"", id, name)).await.unwrap();
+        Ok(())
+    }
+
+    pub async fn rename_folder(&mut self, name: String, new_name: String) -> anyhow::Result<()>{
+        if name.is_empty() { return Err(anyhow!("Folder name is empty")) }
+
+        let id = "aRenameFolder".to_string();
+        self.run_command(format!("{} RENAME \"{}\" \"{}\"", id, name, new_name)).await.unwrap();
+        Ok(())
+    }
 }
 
 pub async fn connect_to_imap_server(domain: String, port: u16) -> anyhow::Result<Client> {

+ 12 - 1
src/main.rs

@@ -23,6 +23,7 @@ use axum::extract::Query;
 use axum::{Json, Router};
 #[cfg(not(target_os = "wasi"))]
 use axum::http::Method;
+#[cfg(not(target_os = "wasi"))]
 use axum::response::{IntoResponse, Response};
 #[cfg(not(target_os = "wasi"))]
 use axum::routing::{get, post};
@@ -309,12 +310,17 @@ async fn main() -> anyhow::Result<()> {
     //             )
     //     )
     //     .unwrap();
-    // 
+    
+    
     // let _ = send_email(email).await;
     
     
     // delete_email("Sent".to_string(), 4).await;
     
+    // imap::create_folder("testFolder".to_string()).await.unwrap();
+    // imap::rename_folder("testFolder".to_string(), "newTestFolder".to_string()).await.unwrap();
+    // imap::delete_folder("newTestFolder".to_string()).await.unwrap();
+    
     
     // API
     println!("Server is running on {}", Config::global().api_port);
@@ -354,6 +360,11 @@ async fn main() {
     // delete_email("lqo7m8r2.1js7w080jvr2o@express.medallia.com".to_string()).await.expect("Unable to delete an email");
 
 
+    // imap::create_folder("testFolder".to_string()).await.unwrap();
+    // imap::rename_folder("testFolder".to_string(), "newTestFolder".to_string()).await.unwrap();
+    // imap::delete_folder("newTestFolder".to_string()).await.unwrap();
+    
+    
     // API
     // Define the CORS layer
     let cors = CorsLayer::new()