Compare commits

...

10 commits

Author SHA1 Message Date
baalajimaestro 7c772a3f8f
Fix readme
Signed-off-by: baalajimaestro <me@baalajimaestro.me>
2022-08-22 13:06:22 +05:30
baalajimaestro 3892eef8ed
Add gitlab ci config
Signed-off-by: baalajimaestro <me@baalajimaestro.me>
2022-08-22 12:46:56 +05:30
baalajimaestro b47b3c7dc2
Add a dockerfile for docker deployments
Signed-off-by: baalajimaestro <me@baalajimaestro.me>
2022-08-22 12:44:57 +05:30
baalajimaestro 17942894f0
Improve README for clarity
Signed-off-by: baalajimaestro <me@baalajimaestro.me>
2022-08-22 12:36:10 +05:30
baalajimaestro 9129ec9a34
Run cargo fmt
Signed-off-by: baalajimaestro <me@baalajimaestro.me>
2022-08-22 12:23:51 +05:30
baalajimaestro 38a3fb72a6
Add a check to prevent purging everything
Signed-off-by: baalajimaestro <me@baalajimaestro.me>
2022-08-22 12:23:13 +05:30
baalajimaestro 4d860b8d6a
Add print on purge finish
Signed-off-by: baalajimaestro <me@baalajimaestro.me>
2022-08-22 11:34:59 +05:30
baalajimaestro 2ff13e7f97
Use a file to handle multiple patterns
Signed-off-by: baalajimaestro <me@baalajimaestro.me>
2022-08-22 11:10:04 +05:30
baalajimaestro bd5b25a9b8
Bump rust version
Signed-off-by: baalajimaestro <me@baalajimaestro.me>
2022-08-22 11:09:43 +05:30
baalajimaestro 3ab90997e0
Add patterns file to gitignore
Signed-off-by: baalajimaestro <me@baalajimaestro.me>
2022-08-22 11:09:09 +05:30
6 changed files with 69 additions and 23 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
/target
patterns.txt

10
.gitlab-ci.yml Normal file
View file

@ -0,0 +1,10 @@
docker-build:
image: docker:latest
stage: build
services:
- docker:dind
before_script:
- echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" registry.baalajimaestro.me --password-stdin
script:
- docker build . -t registry.baalajimaestro.me/baalajimaestro/mail-deleter:latest
- docker push registry.baalajimaestro.me/baalajimaestro/mail-deleter:latest

View file

@ -2,7 +2,7 @@
name = "mail-deleter"
version = "0.1.0"
authors = ["baalajimaestro <me@baalajimaestro.me>"]
edition = "2018"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

15
Dockerfile Normal file
View file

@ -0,0 +1,15 @@
FROM rust:bullseye as builder
RUN mkdir /app
COPY src /app/src
COPY Cargo.toml /app
WORKDIR /app
RUN cargo build --release
FROM gcr.io/distroless/cc:latest
COPY --from=builder /app/target/release/mail-deleter /
VOLUME /patterns.txt
CMD ["./mail-deleter"]

View file

@ -1,8 +1,13 @@
# Mail Deleter
Recently, I had a spammer spamming over atleast 1k emails with the same exact text. I decided manual deletion is literally impossible.
Filtering mails that come through different mail ids or from ids that also carry valuable info, can be hard
This script might be helpful for others who are hopeless due to such a spam!
This simple program deletes mail based on all the info the `Show Original` section of your mail shows. You can choose the mailing list, or any parameter there and add it to `patterns.txt` before executing
Just insert your email id, password (for gmail you need to see the comment), in the respective places
And let it run!
You can add as many patterns as you wish, and all of these patterns are parsed as regex patterns, so feel free to do that as well.
**Required variables:**
- `IMAP_DOMAIN`: IMAP Server Domain
- `IMAP_PORT`: IMAP Server Port
- `IMAP_USERNAME`: IMAP Authentication Username
- `IMAP_PASSWORD`: IMAP Authentication Password

View file

@ -8,6 +8,8 @@
use imap;
use regex::Regex;
use std::fs::File;
use std::io::{prelude::*, BufReader};
fn main() {
fetch_inbox_top().unwrap();
@ -15,32 +17,45 @@ fn main() {
fn fetch_inbox_top() -> imap::error::Result<Option<String>> {
let domain = std::env::var("IMAP_DOMAIN").unwrap_or("none".to_string());
let imap_port = std::env::var("IMAP_PORT")
.unwrap_or("none".to_string())
.parse::<u16>()
.unwrap();
let username = std::env::var("IMAP_USERNAME").unwrap_or("none".to_string());
let password = std::env::var("IMAP_PASSWORD").unwrap_or("none".to_string());
let pattern = std::env::var("DELETE_PATTERN").unwrap_or("none".to_string());
let client = imap::ClientBuilder::new(domain, 993).native_tls()?;
let client = imap::ClientBuilder::new(domain, imap_port).native_tls()?;
let mut imap_session = client.login(username, password).map_err(|e| e.0)?;
let inbox = imap_session.select("Inbox")?;
let re = Regex::new(format!("({})+", &pattern).as_str()).unwrap();
let subject = Regex::new(r"Subject: (.*)").unwrap();
for i in 1 as u32..inbox.exists {
let messages = imap_session.fetch((inbox.exists - i).to_string(), "RFC822")?;
let message = if let Some(m) = messages.iter().next() {
m
} else {
return Ok(None);
};
let body = message.body().unwrap_or("NULL".as_bytes());
let body = std::str::from_utf8(body).unwrap_or("NULL").to_string();
if re.is_match(&body) {
imap_session
.store(format!("{}", message.message), "+FLAGS (\\Deleted)")
.unwrap();
let subject_re = subject.captures(&body).unwrap();
println!("Deleted Mail with Subject: {}", &subject_re[1]);
let file = File::open("patterns.txt")?;
let reader = BufReader::new(file);
for line in reader.lines() {
let re = Regex::new(format!("({})+", line?).as_str()).unwrap();
if re.as_str() == "()+" {
break;
}
println!("Working on Pattern: {}", re.as_str());
for i in 1 as u32..inbox.exists {
let messages = imap_session.fetch((inbox.exists - i).to_string(), "RFC822")?;
let message = if let Some(m) = messages.iter().next() {
m
} else {
return Ok(None);
};
let body = message.body().unwrap_or("NULL".as_bytes());
let body = std::str::from_utf8(body).unwrap_or("NULL").to_string();
if re.is_match(&body) {
imap_session
.store(format!("{}", message.message), "+FLAGS (\\Deleted)")
.unwrap();
let subject_re = subject.captures(&body).unwrap();
println!("Deleted Mail with Subject: {}", &subject_re[1]);
}
}
}
imap_session.expunge().unwrap();
imap_session.logout()?;
println!("\n\n\n********PURGED ALL REQUESTED MAIL********");
Ok(Some("logout".to_string()))
}