@duceduc The last version…
Change log:
- list all available folders in the mailbox
- check that the folder(s) provided as arguments exist in the mailbox (!! case sensitive !!). Exact match is required
- print for each Email to delete:
- the date the Email has been sent (not received !)
- the sender Email
- the subject
- fixed some minor bugs…
Program has only been tested on Gmail !..
#!/bin/python3
#====================================================================================================================================
#
# program to delete Emails in GMAIL older than x days in specific folders
# Arguments:
# Arg1 (required): Username to access the mailbox (example: [email protected])
# Arg2 (required): Password to access the mailbox (example: my_password)
# Recommendation: create an application password in GMAIL to avoid some login problems when connecting to the mailbox
# Arg3 (required): Days to keep (example: 10)
# Arg4 (optional): List of folder names to clean (if no arguments are provided, the default folder is "INBOX") (example: INBOX Protection Commercial)
# Example of commands (the first one with 3 folders to cleanup, the second one will cleanup "INBOX" only):
# empty_mailbox.py [email protected] my_password 10 INBOX Protection Commercial
# empty_mailbox.py [email protected] my_password 10
#
# IMPORTANT: tested on GMAIL only... Use it at your own risks
#
#====================================================================================================================================
import datetime
import imaplib, email
from email.header import decode_header
import sys
#====================================================================================================================================
#
# create function to delete mail in a mailbox folder older than x days
# arguments: folder name, number of days to keep
#
#====================================================================================================================================
def delete_email_in_folder(folder,days):
print("Deleting Emails in",folder,"older than",days,"days...")
imap.select(folder)
# create the list of mails to delete based on the number of days to keep
before_date = (datetime.date.today() - datetime.timedelta(days)).strftime("%d-%b-%Y") # date string, 04-Jan-2013
typ, message_id_list = imap.search(None, '(BEFORE {0})'.format(before_date)) # search pointer for msgs before before_date
# convert the string ids to list of email ids
messages = message_id_list[0].split(b' ')
if (len(messages) != 1):
# count the number of messages to delete
count = (len(messages))
# loop to delete messages
while count > 0:
# print the number of remaining mails to delete
print(">>>>",((datetime.datetime.today()).strftime("%Y-%b-%d %H:%M:%S"))," ",count, "mail(s) remaining to delete")
# read email message
res, msg = imap.fetch(messages[count-1], "(RFC822)")
# extract subject and from email address
for response in msg:
if isinstance(response, tuple):
msg = email.message_from_bytes(response[1])
subject, From, Date = obtain_header(msg)
# Printing Subject and From information
print(" Date :", Date)
print(" Subject:", subject)
print(" From :", From)
# mark the mail as deleted
imap.store(messages[count-1], "+FLAGS", "\\Deleted")
# decrement the counter by one
count = count - 1
else:
print("No mail to delete...")
#====================================================================================================================================
#
# create function to extract subject, "from" email address information and the date of the current Email to delete
# arguments: mail message
# Return: the subject, the From information and the date of the Email (the date the Email was sent... not the date the Email was received !)
#
#====================================================================================================================================
def obtain_header(msg):
# decode the email subject
subject, encoding = decode_header(msg["Subject"])[0]
if isinstance(subject, bytes):
subject = subject.decode(encoding)
# decode email sender
From, encoding = decode_header(msg.get("From"))[0]
if isinstance(From, bytes):
From = From.decode(encoding)
# decode email date (sent)
Date, encoding = decode_header(msg.get("Date"))[0]
if isinstance(Date, bytes):
Date = Date.decode(encoding)
# transform date to local date (your current timezone)
datetime_object = datetime.datetime.strptime(Date,'%a, %d %b %Y %H:%M:%S %z')
#Convert it to your local timezone
d=datetime_object.astimezone()
Date = d.strftime("%a, %d %b %Y %H:%M:%S %z")
return subject, From, Date
#====================================================================================================================================
#
# Main Program
#
#====================================================================================================================================
print (">>>>",(datetime.datetime.today()).strftime("%Y-%b-%d %H:%M:%S"))
# read arguments: username, password and number of days have to be provided, folders are optional
arg = sys.argv
# not enough arguments, error message and exit
if (len(arg) <= 3):
print("Error ! not enough arguments: at least 3 are required.")
print(" User, password and number of days are mandatory.")
exit()
# store arguments in variables
my_email = sys.argv[1]
app_generated_password = sys.argv[2]
days = int(sys.argv[3])
folder = sys.argv[4:]
# if no folder has been provided, "INBOX" is the default
if (len(folder) == 0):
folder = ["INBOX"]
# initialize IMAP object for Gmail
imap = imaplib.IMAP4_SSL("imap.gmail.com")
print("Connecting to GMAIL...")
# login to gmail with credentials
imap.login(my_email, app_generated_password)
print("GMAIL connected...\n")
# retrieving list of folders
print("List of various folders:")
folder_list = imap.list()
# error: not able to retrieve list of inboxes
if (folder_list[0] != "OK"):
print("Error ! Not able to retrieve list of Inboxes")
exit()
folders = folder_list[1]
# extract the list of folder names between quotes
list_of_folders = ""
for name in folders:
name_str = name.decode('utf-8')
name_str = name_str.split('/',1)
name_str = name_str[1]
print (name_str[3:-1], end='\n')
list_of_folders = list_of_folders + name_str[2:] + "\n"
# loop to execute the cleanup based on the number of folders provided as parameters
count = (len(folder))
loop = 0
while count > 0:
print(" ")
print(" ")
count = count - 1
# test if folder is included in the folder list
test_folder = ("\""+folder[count]+"\"")
if (test_folder in list_of_folders):
# delete Emails in folder older than x days
delete_email_in_folder(folder[count],days)
loop = 1
else:
print("Error ! Unknown folder in the list of folders:",folder[count])
print(" See above for the list, the folder name must be exactly the same (the folder name validation is case sensitive)")
else:
print(" ")
print(" ")
# delete all the selected messages
if (loop == 1):
print("All selected mails have been deleted")
imap.expunge()
# close the mailbox
imap.close()
print("Closing connection with GMAIL...")
# logout from the server
imap.logout()
print("Connection closed with GMAIL...")
print (">>>>",(datetime.datetime.today()).strftime("%Y-%b-%d %H:%M:%S"))