Just wanted to share the current learning project.
Although far from being finished, I the program will get and display email subjects.
Refreshes every 5 minutes.
I welcome all feedback and thoughts.
Although far from being finished, I the program will get and display email subjects.
Refreshes every 5 minutes.
I welcome all feedback and thoughts.
#! /usr/bin/env python3 # Do the imports import imaplib import email import tkinter as tk from functools import partial import re # Set mail server connection vars user = '' passwd = '' server = '' # Create the connection class class Connect: # Connect to the server and return def connect(self, user, passwd, server): mail = imaplib.IMAP4_SSL(server) mail.login(user, passwd) return mail # Class for doin operations on the inbox class GetInbox: # Grab the inbox. This could be any box or a list of boxes def inbox(self, mail): status, self.messages = mail.select('inbox') # Grab the ids of the emails and return as a list def get_ids(self, mail): type, data = mail.search(None, 'ALL') mail_ids = data[0] id_list = mail_ids.split() return id_list # Grab the subject headers and ids. Combine for getting the mail body/content def get_headers(self, mail, id_list): # Set some range vars for grabbing mail first = int(id_list[0]) last = int(id_list[-1]) # Create some empty list newids = [] mylist = [] headers = [] # Covert id to int for id in id_list: newids.append(int(id)) # Fetch mails and append to a list for i in range(last, 0, -1): typ, data = mail.fetch(str(i), '(RFC822)') mylist.append(data) # Loop through the list and get subject headers for header in mylist: for response in header: if isinstance(response, tuple): msg = email.message_from_bytes(response[1]) headers.append(msg['subject']) # Combine subjects and their ids and return new_headers = dict(zip(headers, newids)) return new_headers class Mail: def __init__(self, parent): # Configure the root window self.parent = parent self.parent.columnconfigure(0, weight=1) self.parent.rowconfigure(0, weight=1) # Get screen width & height self.width = self.parent.winfo_screenwidth() self.height = self.parent.winfo_screenheight() # Setup the mainframe container. self.mainframe = tk.Frame(self.parent) self.mainframe['width'] = int(self.width/2) self.mainframe['height'] = int(self.height/2) self.mainframe.grid(column=0, row=0, sticky='new') self.mainframe.grid_columnconfigure(0, weight=3) self.mainframe.grid_rowconfigure(0, weight=3) # Setup header frame to place our widget header self.headerframe = tk.Frame(self.mainframe) self.headerframe['width'] = int((self.width/2)-1) self.headerframe['relief'] = 'ridge' self.headerframe['borderwidth'] = 2 self.headerframe.grid(column=0, row=0, sticky='new') # Setup the mini header frame. This will hold the labels # for the inbox and messages labels self.mini_headerframe = tk.Frame(self.mainframe) self.mini_headerframe.grid(column=0, row=1, sticky='new', pady=3) self.mini_headerframe.grid_columnconfigure(0, weight=1) self.mini_headerframe.grid_columnconfigure(1, weight=10) # Setup the subject frame self.subjectframe = tk.Frame(self.mini_headerframe) self.subjectframe['relief'] = 'solid' self.subjectframe['borderwidth'] = 1 self.subjectframe['border'] = 0 self.subjectframe['highlightthickness'] = 1 self.subjectframe['highlightbackground'] = 'grey65' self.subjectframe.grid(column=0, row=1, sticky='new', pady=2, ipady=2) self.message_frame = tk.Frame(self.mini_headerframe) self.message_frame['relief'] = 'solid' self.message_frame['borderwidth'] = 1 self.message_frame['border'] = 0 self.message_frame['highlightthickness'] = 1 self.message_frame['highlightbackground'] = 'grey65' self.message_frame.grid(column=1, row=1, sticky='new', pady=2) #Setup the inbox label self.inbox_label = tk.Label(self.mini_headerframe) self.inbox_label['text'] = 'Inbox' self.inbox_label['font'] = 'sans 10 bold' self.inbox_label['relief'] = 'solid' self.inbox_label['borderwidth'] = 1 self.inbox_label['border'] = 0 self.inbox_label['highlightthickness'] = 1 self.inbox_label['highlightbackground'] = 'grey65' self.inbox_label.grid(column=0, row=0, sticky='new') # Setup the messages label self.msg_label = tk.Label(self.mini_headerframe) self.msg_label['text'] = 'Messages' self.msg_label['font'] = 'sans 10 bold' self.msg_label['relief'] = 'solid' self.msg_label['borderwidth'] = 1 self.msg_label['border'] = 0 self.msg_label['highlightthickness'] = 1 self.msg_label['highlightbackground'] = 'grey65' self.msg_label.grid(column=1, row=0, sticky='new') # Setup the header label self.header_label = tk.Label(self.headerframe, padx=5, pady=2) self.header_label['text'] = 'Tkinter Email Client' self.header_label['font'] = 'sans 16 bold' self.header_label['fg'] = 'indigo' self.header_label.grid(column=0, row=0, sticky='new') self.update() def update(self): try: self.subjectframe.destroy() # Setup the subject frame self.subjectframe = tk.Frame(self.mini_headerframe) self.subjectframe['relief'] = 'solid' self.subjectframe['borderwidth'] = 1 self.subjectframe['border'] = 0 self.subjectframe['highlightthickness'] = 1 self.subjectframe['highlightbackground'] = 'grey65' self.subjectframe.grid(column=0, row=1, sticky='new', pady=2, ipady=2) i = 0 mail = Connect() mail = mail.connect(user, passwd, server) inbox = GetInbox() messages = inbox.inbox(mail) ids = inbox.get_ids(mail) headers = inbox.get_headers(mail, ids) for subject, id in headers.items(): self.subs = tk.Label(self.subjectframe, padx=5, cursor='hand2', anchor='n') self.subs['text'] = f'{subject} -> {id}' self.subs['font'] = 'sans 10 normal' self.subs.grid(column=0, row=i, sticky='nw') self.subs.bind('<Button-1>', partial(self.get_content, mail, id)) i += 1 mail.close() mail.logout() self.subjectframe.after(10000, self.update) except Exception as error: print(error) # Get the mail body/content def get_content(self, mail, id, event): self.message_frame.destroy() self.message_frame = tk.Frame(self.mini_headerframe) self.message_frame['relief'] = 'solid' self.message_frame['borderwidth'] = 1 self.message_frame['border'] = 0 self.message_frame['highlightthickness'] = 1 self.message_frame['highlightbackground'] = 'grey65' self.message_frame.grid(column=1, row=1, sticky='new', pady=2) mail = Connect() mail = mail.connect(user, passwd, server) inbox = GetInbox() messages = inbox.inbox(mail) type, data = mail.fetch(str(id), '(RFC822)') print(data) for message in data: if isinstance(message, tuple): msg = email.message_from_bytes(message[1]) if msg.is_multipart(): for line in msg.walk(): content_type = line.get_content_type() body = line.get_payload() if content_type == 'text/plain': body = msg.get_payload() else: content_type = msg.get_content_type() if content_type == 'text/plain': body = msg.get_payload() else: body = msg.get_payload() self.content = tk.Label(self.message_frame, anchor='w', wraplength=420) self.content['text'] = self.cleaner(body).strip() self.content.grid(column=0, row=0, sticky='nw') mail.close() mail.logout() def cleaner(self, tags): cleanr = re.compile('<.*?>|&([a-z0-9]+|#[0-9]{1,6}|#x[0-9a-f]{1,6});') cleantext = re.sub(cleanr, '', tags) return cleantext def main(): root = tk.Tk() root.title('Tkinter Email Client') root['pady'] = 5 root['padx'] = 10 root['borderwidth'] = 2 root.geometry(f'{int(root.winfo_screenwidth()/2)}x{int(root.winfo_screenheight()/2)}') Mail(root) root.mainloop() if __name__ == '__main__': main()
I welcome all feedback.
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags
Download my project scripts
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags
Download my project scripts