Issue Description:
I am currently developing a Python application using WxPython for the GUI. The application involves checking an email inbox using the imaplib module, with the program running in the background to monitor incoming emails from specific senders. To accomplish this, I've implemented threading to manage the continuous checking of the inbox while the GUI remains responsive.
Problem Encountered:
Upon attempting to close the program, I noticed that it frequently freezes and becomes unresponsive. I have tried various strategies, such as using threading.Event to signal the termination of threads and properly closing resources, but the issue persists.
Implemented threading to handle email checking in the background while the GUI remains responsive. Utilized threading.Event to signal the termination of threads when the program is set to close. Ensured proper closure of resources, including the playsound module and the imaplib connection.
import imaplib
import email
import time
from playsound import playsound
import wx
import threading
import sys
login_file = "Login.txt"
song = "Songs/SalesSound.wav"
imap_server = "imap.gmail.com"
imap_ssl_port = 993
email_address = ''
password = ''
sender_email = ["email1", "email2", "email3"]
def play_noise(stop_event):
playsound(song)
def check_for_new_emails(mail):
for sender in sender_email:
mail.select('inbox')
result, data = mail.search(None, f'(UNSEEN FROM "{sender}")')
email_ids = data[0].split()
for email_id in email_ids:
result, message_data = mail.fetch(email_id, '(BODY[HEADER.FIELDS (SUBJECT FROM)])')
raw_email = message_data[0][1].decode("utf-8")
email_message = email.message_from_string(raw_email)
subject = email_message["Subject"]
print(f"New email from {email_message['From']} with subject: {subject}")
play_noise()
print(email_message)
mail.store(email_id, '+FLAGS', '\\Seen')
def close_mail_connection(mail):
mail.close()
mail.logout()
class SalesIncomingGUI(wx.Frame):
def __init__(self, parent, id):
self.mail = None
self.is_running = False
wx.Frame.__init__(self, parent, id, 'Upfluence, Where Salespeople Matter', size=(800, 600))
self.panel = wx.Panel(self)
stop_program = wx.Button(self.panel, label="Stop", pos=(450, 150), size=(50, 50))
start_program = wx.Button(self.panel, label="Start", pos=(350, 150), size=(50, 50))
self.cant_close = wx.MessageDialog(None, "You must stop the program before closing", "Wait a second cowboy", wx.OK)
self.Bind(wx.EVT_BUTTON, self.stop_loop, stop_program)
self.Bind(wx.EVT_BUTTON, self.start_loop, start_program)
self.Bind(wx.EVT_CLOSE, self.close_window)
def alert_box(self):
self.cant_close.ShowModal()
def start_loop(self, event):
if not self.is_running:
self.is_running = True
self.mail = imaplib.IMAP4_SSL(imap_server)
self.mail.login(email_address, password)
self.mail_thread = threading.Thread(target=self.run_loop, args=(self.mail,))
self.mail_thread.start()
def stop_loop(self, event):
if self.is_running:
self.is_running = False
def run_loop(self, mail):
while self.is_running:
print("Running")
check_for_new_emails(mail)
time.sleep(60)
close_mail_connection(mail)
def close_window(self, event):
if self.is_running:
self.alert_box()
else:
sys.exit(0)
if __name__ == '__main__':
with open(login_file, 'r') as file:
for line in file:
key, value = line.strip().split(': ')
if key == 'Email_Address':
email_address = value
elif key == 'Password':
password = value
app = wx.App()
frame = SalesIncomingGUI(parent=None, id=-1)
frame.Show()
app.MainLoop()
if frame.mail_thread:
frame.mail_thread.join()
close_mail_connection(frame.mail)```