{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tkinter, os, smtplib\n",
    "\n",
    "from tkinter import messagebox, filedialog\n",
    "\n",
    "from tkinter import *\n",
    "\n",
    "class auto_email:\n",
    "    \"\"\"A class that will hold the login credentials of the user and the structure of the email.\"\"\"\n",
    "    def __init__(self, name, reminder = None, r_name = None, message = None, subject = None):\n",
    "        self.user_email = name\n",
    "        self.reminders_email = reminder\n",
    "        self.remind_name = r_name\n",
    "        self.text_message = message\n",
    "        self.subject_matter = subject\n",
    "        self.authentification = ''\n",
    "        self.smtpObj = smtplib.SMTP_SSL('smtp.gmail.com', 465) \n",
    "        \n",
    "    def email_login(self, password):\n",
    "        self.authentification = self.smtpObj.login(self.user_email, password)\n",
    "        return self.authentification\n",
    "    \n",
    "    def email_structure(self, password): \n",
    "        self.email_login(password)\n",
    "        body = \"Subject: %s.\\nHello %s,\\n %s\" % (self.subject_matter, self.remind_name, self.text_message)\n",
    "        \n",
    "        sendmailStatus = self.smtpObj.sendmail(self.user_email, self.reminders_email, body)\n",
    "        \n",
    "\n",
    "\n",
    "class reminder_program:                        \n",
    "    \"\"\"the GUI automatic email sender for sending automatic emails to non automatic people. \"\"\"\n",
    "    def __init__(self, parent):\n",
    "        \n",
    "        self.main_frame = parent \n",
    "        self.main_frame = Frame(parent, height = 300, width = 600)\n",
    "        self.main_frame.grid()\n",
    "    \n",
    "        self.email_dict = {}\n",
    "        self.sender_email = ''\n",
    "        self.user_directory = ''\n",
    "        self.user_email = ''\n",
    "        self.reminderee_email = ''\n",
    "        self.remindee_email = ''\n",
    "        self.remindee_name = ''\n",
    "        self.text_message_name = ''\n",
    "        self.password = ''\n",
    "        \n",
    "        self.login_register(parent)\n",
    "        \n",
    "    def login_register(self,parent):\n",
    "        #Creates top level window for creating the directory where program will load and store and read files.\n",
    "        self.login_register = Toplevel(parent)\n",
    "        self.login_register.wm_title('User Register / Login')\n",
    "        self.login_register.wm_attributes('-topmost', True)\n",
    "        \n",
    "        register_label = Label(self.login_register, text = 'REGISTER e-mail')\n",
    "        \n",
    "        user_label = Label(self.login_register, text = 'Associate e-mail')\n",
    "        register_email = StringVar()\n",
    "        register_entry = Entry(self.login_register, relief = 'flat', textvariable = register_email)\n",
    "        \n",
    "        directory_label = Label(self.login_register, text = 'Choose Directory')\n",
    "        directory_choice = StringVar()\n",
    "        directory_entry = Entry(self.login_register, relief = 'flat', textvariable = directory_choice)\n",
    "        \n",
    "        program_folder = Label(self.login_register, text = 'Folder Name')\n",
    "        folder_name = StringVar()\n",
    "        directory_folder = Entry(self.login_register, relief = 'flat', textvariable = folder_name)\n",
    "        \n",
    "        create_button = Button(self.login_register, text = \"Create\", width = 12)\n",
    "        \n",
    "        def user_and_email(event):\n",
    "            #Will create the directory with which you want to associate your program.\n",
    "            user_email = register_email.get() #gets the user's email\n",
    "            program_directory = directory_choice.get() #registers a place to create the folder for the email\n",
    "            directory_name = folder_name.get() #registers the folder's name\n",
    "            \n",
    "            self.email_dict[user_email] = program_directory + '\\\\' + directory_name #associates user_email with a directory\n",
    "            #After associating with a directory, the program will create 3 directories inside of your program_directory\n",
    "            for email, directory in self.email_dict.items():\n",
    "                if not os.path.exists(directory):\n",
    "                    os.makedirs(directory)\n",
    "                    os.makedirs(directory + '\\\\' + 'Login')\n",
    "                    os.makedirs(directory + '\\\\' + 'Saved Texts')\n",
    "                    os.makedirs(directory + '\\\\' + 'Peoples emails')\n",
    "            \n",
    "            self.user_directory = program_directory + '\\\\' + directory_name  \n",
    "            #And to ensure no errors two files are automatically created: the remiderees.txt and login_user.txt\n",
    "            with open(self.user_directory + '\\\\' + 'Peoples emails' + '\\\\' + 'reminderees.txt', 'a+') as file:\n",
    "                file.write(user_email + '\\n')\n",
    "    \n",
    "            with open(self.user_directory + '\\\\' + 'Login' + '\\\\' + 'login_user.txt', 'a+') as output:\n",
    "                if user_email not in 'login_user.txt':\n",
    "                    output.write(user_email + '\\n')\n",
    "            return self.email_dict\n",
    "            return self.user_directory\n",
    "        create_button.bind('<Button-1>', user_and_email)\n",
    "        create_button.bind('<Return>', user_and_email)\n",
    "            \n",
    "        #The login section where the program asks for permission to connect to gmail and holds your session \n",
    "        login_label = Label(self.login_register, text = 'LOGIN')\n",
    "        login_email = StringVar()\n",
    "        login_entry = Entry(self.login_register, relief = 'flat', textvariable = login_email)\n",
    "        \n",
    "        user_button = Button(self.login_register, text = 'Select')\n",
    "        \n",
    "        def show_registered_users(event):\n",
    "            #Allows you to choose with which email you would like to send emails with.\n",
    "            dropVar = StringVar()\n",
    "            if self.user_directory != '': \n",
    "                with open(self.user_directory + '\\\\'  + 'Login' + '\\\\' + 'login_user.txt', 'r') as file:\n",
    "                    values = file.read()\n",
    "                    dropVar.set(values)\n",
    "                    \n",
    "                comboentry = OptionMenu(self.login_register, dropVar,\n",
    "                                 values)\n",
    "                comboentry.grid(row = 17, columnspan = 2)\n",
    "                \n",
    "            else:\n",
    "                #If you already have a program directory, simply choose it's name and continue with the login process\n",
    "                select_dir = filedialog.askdirectory(initialdir = 'C:/Users/pablo/Documents/Personal/', \n",
    "                                       title = 'Select directory')\n",
    "                self.user_directory = select_dir\n",
    "                with open(select_dir + '/' + 'Login' + '/' + 'login_user.txt', 'r') as file:\n",
    "                    values = file.read()\n",
    "                    dropVar.set(values)\n",
    "                \n",
    "                def sel_user_name(value):\n",
    "                    #Selects the name chosen from the dropdown after login_user.txt file has been loaded from program_directory\n",
    "                    self.user_email = values\n",
    "                comboentry = OptionMenu(self.login_register, dropVar,\n",
    "                                       values, command = sel_user_name)\n",
    "                comboentry.grid(row=17, columnspan = 2)\n",
    "        \n",
    "            if smtpObj.ehlo()[0] == 250:\n",
    "                #If connection was established then:\n",
    "                connected_http = Label(self.login_register, text = 'You can create a connection to gmail')\n",
    "                connected_http.grid(row = 19, columnspan = 2)\n",
    "            else:\n",
    "                connected_http.configure(text = 'You can\\'t create a connection to gmail')\n",
    "                connected_http.grid(row = 19, columnspan = 2)\n",
    "            #Save the password\n",
    "            password = StringVar()\n",
    "            password_entry = Entry(self.login_register, textvariable = password)\n",
    "            password_entry.grid(row = 18, columnspan = 2)\n",
    "            \n",
    "         \n",
    "            def read_selected(event):\n",
    "                \n",
    "                password_str = password.get()\n",
    "                self.password = password.get()\n",
    "                #Creates an instance of the class auto_email and calls it log_succ (succesful login)\n",
    "                log_succ = auto_email(self.user_email)\n",
    "                self.authentification = log_succ.email_login(password_str)\n",
    "       \n",
    "                if self.authentification[0] == 235:\n",
    "                #If login succesful (==235)\n",
    "                    user_title = Label(self.reminderee_frame, text = 'Welcome: ' + self.user_email)\n",
    "                    user_title.grid(row = 0, column = 0)\n",
    "                    self.login_register.destroy()\n",
    "                else:\n",
    "                    label_error = Label(self.login_register, text = 'error logging in to your email.').grid(row =21, columnspan = 2)\n",
    "                \n",
    "                self.reminderee_registry(parent)\n",
    "                self.message_select(parent)\n",
    "            user_button.bind('<Button-1>', read_selected)\n",
    "            \n",
    "        login_entry.bind('<Button-1>', show_registered_users)\n",
    "        \n",
    "        self.login_register.grid(baseWidth = 250, baseHeight = 400,\n",
    "                                widthInc = 250, heightInc = 400)\n",
    "        register_label.grid(row = 1, columnspan = 2)\n",
    "        user_label.grid(row = 2, column = 0, sticky = 'e')\n",
    "        register_entry.grid(row = 2, column = 1, sticky = 'w')\n",
    "        directory_label.grid(row = 3, column = 0, sticky = 'e')\n",
    "        directory_entry.grid(row = 3, column = 1, sticky = 'w')\n",
    "        program_folder.grid(row = 4, column = 0, sticky = 'e')\n",
    "        directory_folder.grid(row = 4, column = 1, sticky = 'w')\n",
    "        create_button.grid(row=5, columnspan = 2, pady = 5, padx = 85)\n",
    "        login_label.grid(rowspan = 16, columnspan = 2, ipadx = 85, pady = 85)\n",
    "        login_entry.grid(row = 17, columnspan = 2)\n",
    "        user_button.grid(row = 20, columnspan = 2)\n",
    "        \n",
    "    def reminderee_registry(self, parent):\n",
    "        #Read the text which I have paraphrased from Marvin, the paranoid droid's (hitchhikers guide), in order to \n",
    "        #explain how the reminderee_registry works (reminderee_label0)\n",
    "        self.reminderee_frame = Frame(self.main_frame)\n",
    "        reminderee_label0 = Label(self.reminderee_frame,\n",
    "                                 text = 'I\\'d give you advice but you wouldn\\'t really listen. No one ever does.'+\n",
    "                                 '\\nStill at it? This is the sort of thing you life forms enjoy, is it? Well, I\\'ll' +\n",
    "                                 '\\nhave you know that I\\'m an estimate 30 billion times more more intelligent than you.'+\n",
    "                                 '\\nHere I am, brain the size of an \"Intel CORE i5 8th Gen\" and I\\'m asked to tell you' +\n",
    "                                 '\\nto write a person\\'s email and a unique name identifier and to \"Regester\".'+\n",
    "                                 '\\n\\nGhastly, isn\\'t it?'+\n",
    "                                 '\\n\\n Double click the person\\'s name & email. Not that anyone cares what I say, '+\n",
    "                                  '\\nbut if you don\\'t already have a pre-text to send, create one with \"New Message\"'+\n",
    "                                  '\\nand then double click it from the list... I know. Wretched, isn\\'t it?'+\n",
    "                                  '\\nAnd then of course you\\'ve got the terrible pain of pressing \"Send Email\".'+\n",
    "                                  '\\nSounds aweful',\n",
    "                                 justify = 'left')\n",
    "        reminderee_label1 = Label(self.reminderee_frame,\n",
    "                                 text = 'reminderee\\'s e-mail')\n",
    "        reminderee_email = StringVar()\n",
    "        reminderee_entry1 = Entry(self.reminderee_frame,\n",
    "                                  relief = 'flat',\n",
    "                                  textvariable = reminderee_email,\n",
    "                                 width = 40)\n",
    "        \n",
    "        reminderee_label2 = Label(self.reminderee_frame,\n",
    "                                 text = 'their name')\n",
    "        reminderee_name = StringVar()\n",
    "        reminderee_entry2 = Entry(self.reminderee_frame,\n",
    "                                  relief = 'flat',\n",
    "                                  textvariable = reminderee_name,\n",
    "                                 width = 40)\n",
    "        reminderee_listbox = Listbox(self.reminderee_frame, width = 40)\n",
    "        \n",
    "        reg_rem = Button(self.reminderee_frame, text = 'Register', width = 12)\n",
    "        \n",
    "                \n",
    "        def add_reminderee(event):\n",
    "            #If name and email have been provided this will create a new comma dilimmited entry in reminderees.txt\n",
    "            self.remindee_email = reminderee_email.get()\n",
    "            self.remindee_name = reminderee_name.get()\n",
    "            tot_rem = self.remindee_name + ', ' + self.remindee_email\n",
    "            with open(self.user_directory + '/' + 'Peoples emails' + '/' +'reminderees.txt', 'a+') as output:\n",
    "                output.write(tot_rem + '\\n')\n",
    "            reminderee_listbox.insert(END, tot_rem)\n",
    "            reminderee_entry1.delete(0, 'end')\n",
    "            reminderee_entry2.delete(0, 'end')\n",
    "        reg_rem.bind('<Button-1>', add_reminderee)\n",
    "        #And it never hurts to have the list automatically update after reminderee creation is complete.\n",
    "        with open(self.user_directory + '/' + 'Peoples emails' + '/' +'reminderees.txt', 'r') as output:    \n",
    "            remindee = output.readlines()\n",
    "            for line in remindee:\n",
    "                reminderee_listbox.insert(END, line)\n",
    "    \n",
    "        def remindee_mail(event):\n",
    "            #Selects the person you want to remind\n",
    "            selected = reminderee_listbox.curselection()\n",
    "            self.reminderee_email = reminderee_listbox.get(selected)\n",
    "        reminderee_listbox.bind('<Double-Button>', remindee_mail)\n",
    "        \n",
    "        self.reminderee_frame.grid(row = 0, \n",
    "                                   pady = '5m',\n",
    "                                   padx = 40,\n",
    "                                   sticky = 'nwe')\n",
    "        reminderee_label0.grid(row = 0, columnspan = 2, padx = 5, pady = 10, sticky = 'ne')\n",
    "        \n",
    "        reminderee_label1.grid(row = 1, column = 0, sticky = 'ne')\n",
    "        reminderee_entry1.grid(row = 1, column = 1, sticky = 'ne')\n",
    "        \n",
    "        reminderee_label2.grid(row = 2, column = 0, sticky = 'se' )\n",
    "        reminderee_entry2.grid(row = 2, column = 1, sticky = 'se')\n",
    "        \n",
    "        reminderee_listbox.grid(row = 3, column = 1, sticky = 'ne', pady = 8)\n",
    "        reg_rem.grid(row = 3, column = 0, sticky = 'ne')\n",
    "        \n",
    "    def message_select(self, parent):\n",
    "        #where we will be selecting the pre-made texts to send to people\n",
    "        self.select_frame = Frame(self.main_frame)\n",
    "        \n",
    "        message_label = Label(self.select_frame,\n",
    "                             text = 'Select Message')\n",
    "        message_listbox = Listbox(self.select_frame, width = 40)\n",
    "        \n",
    "        for foldername, subfolder,filenames in os.walk(self.user_directory + '/' + 'Saved texts' + '/'):\n",
    "            for files in filenames:\n",
    "                message_listbox.insert(END, files)\n",
    "                \n",
    "        def select_message_listbox(event):\n",
    "            #grabs and holds the selected message to be sent\n",
    "            selection = message_listbox.curselection()\n",
    "            self.text_message_name = message_listbox.get(selection)\n",
    "\n",
    "            \n",
    "        message_listbox.bind('<Double-Button>', select_message_listbox)\n",
    "        \n",
    "        new_message = Button(self.select_frame,\n",
    "                            text = 'New Message')\n",
    "        def new_message_button(event):\n",
    "            #creates a new message and saves it to Saved texts\n",
    "            self.new_message_button = Toplevel(parent)\n",
    "            self.new_message_button.wm_title('New Reminder')\n",
    "            self.new_message_button.wm_attributes('-topmost', True)\n",
    "            \n",
    "            new_message_label = Label(self.new_message_button,\n",
    "                                      text = 'Please write your new message')\n",
    "            new_message_text = Text(self.new_message_button,\n",
    "                                     width = 80, height = 20)\n",
    "            save_button = Button(self.new_message_button,\n",
    "                                text = 'Save Message')\n",
    "            def save_button_retrieve(event):\n",
    "                #This is how we save that text\n",
    "                retrieve_text = new_message_text.get('1.0', 'end-1c')\n",
    "                \n",
    "                self.save_retrieve = Toplevel(parent)\n",
    "                self.save_retrieve.wm_title('Save this message?')\n",
    "                self.save_retrieve.wm_attributes('-topmost', True)\n",
    "                \n",
    "                save_retrieve_label = Label(self.save_retrieve,\n",
    "                                           text = 'Name of text')\n",
    "                save_retrieve_string = StringVar()\n",
    "                save_retrieve_entry = Entry(self.save_retrieve,\n",
    "                                           textvariable = save_retrieve_string)\n",
    "                \n",
    "                save_retrieve_save = Button(self.save_retrieve,\n",
    "                                           text = 'Save me')\n",
    "                def retrieve_save(event):\n",
    "                    #This is how we hold the text message for further use. \n",
    "                    name_pre_writ = save_retrieve_string.get()\n",
    "                    with open(self.user_directory + '/' + 'Saved texts' + '/' + name_pre_writ + '.txt', 'w+') as output:\n",
    "                        name_output = name_pre_writ+'.txt'\n",
    "                        output.write(retrieve_text)\n",
    "                        message_listbox.insert(END, name_output)\n",
    "                    self.save_retrieve.destroy() \n",
    "                save_retrieve_save.bind('<Button-1>', retrieve_save)\n",
    "                save_retrieve_save.bind('<Return>', retrieve_save)\n",
    "                \n",
    "                save_retrieve_cancel = Button(self.save_retrieve,\n",
    "                                             text = 'Cancel',\n",
    "                                             width = 7)\n",
    "                def retrieve_cancel(event):\n",
    "                    #Quit and destroy the text name saving window\n",
    "                    self.save_retrieve.destroy()\n",
    "                save_retrieve_cancel.bind('<Button-1>', retrieve_cancel)\n",
    "                save_retrieve_cancel.bind('<Return>', retrieve_cancel)\n",
    "                \n",
    "                save_retrieve_label.grid(row = 0, column = 0)\n",
    "                save_retrieve_entry.grid(row = 0, column = 1)\n",
    "                save_retrieve_save.grid(row = 1, column = 0)\n",
    "                save_retrieve_cancel.grid(row = 1, column = 1)\n",
    "            save_button.bind('<Button-1>', save_button_retrieve)\n",
    "            save_button.bind('<Return>', save_button_retrieve)\n",
    "            \n",
    "            \n",
    "            cancel_button = Button(self.new_message_button,\n",
    "                                  text = 'Cancel', width = 12)\n",
    "            def message_cancel_button(event):\n",
    "                #Destroy the new_message window\n",
    "                self.new_message_button.destroy()\n",
    "            cancel_button.bind('<Button-1>', message_cancel_button)\n",
    "            cancel_button.bind('<Return>', message_cancel_button)\n",
    "            \n",
    "            \n",
    "            new_message_label.grid(row = 0, columnspan = 2,\n",
    "                                  pady = 5, padx = 10)\n",
    "            new_message_text.grid(row = 1, columnspan = 2,\n",
    "                                  pady = 2, padx = 10)\n",
    "            save_button.grid(row = 2, column = 0,\n",
    "                            pady = 3)\n",
    "            cancel_button.grid(row = 2, column = 1,\n",
    "                              pady = 3)\n",
    "        new_message.bind('<Button-1>', new_message_button)\n",
    "        new_message.bind('<Return>', new_message_button)\n",
    "            \n",
    "            \n",
    "        set_time = Button(self.select_frame,\n",
    "                         text = 'Send Email', width = 11)\n",
    "        def prepare_email(event):\n",
    "            #prompts the user to see their final email and to add a Subject and finally send or abort. \n",
    "            self.time_send = Toplevel(parent)\n",
    "            \n",
    "            to_email = self.reminderee_email.split(',')[1]\n",
    "            name_to = self.reminderee_email.split(',')[0]        \n",
    "            email_rec = name_to\n",
    "            \n",
    "            self.time_send.wm_title('User Register / Login')\n",
    "            self.time_send.wm_attributes('-topmost', True)\n",
    "            \n",
    "            email_from = Label(self.time_send, text = 'From: ' + self.user_email)\n",
    "            email_to = Label(self.time_send, text = 'To: ' + to_email)\n",
    "            with open(self.user_directory + '/' + 'Saved texts' + '/' + self.text_message_name, 'r') as file:\n",
    "                email_body = file.read()\n",
    "                \n",
    "            email_text = Label(self.time_send, text = email_body)\n",
    "            \n",
    "            subject_matter_label = Label(self.time_send, text = 'Subject')\n",
    "            sub_mat = StringVar()\n",
    "            subject_matter = Entry(self.time_send, textvariable = sub_mat)\n",
    "            \n",
    "           \n",
    "            \n",
    "            def send_email(event):\n",
    "                #Creates an instance of auto_email with all of the users and receivers information\n",
    "                subject = sub_mat.get()\n",
    "                #Allows for the user to add a Subject to the email. \n",
    "                email_rec = auto_email(self.user_email, #Your email \n",
    "                                       to_email, #The person's email\n",
    "                                       name_to, #The person's name\n",
    "                                       email_body, #The email body\n",
    "                                       subject)\n",
    "                email_rec.email_structure(self.password) #the email subject and auto_mail function call\n",
    "                sending_mail_listbox = Listbox(self.select_frame, width = 55)\n",
    "                sending_mail_listbox.insert(END, 'Sending email to %s...' % to_email)\n",
    "                sending_mail_listbox.grid(row = 1, column = 1, sticky = 'ne')\n",
    "                \n",
    "                self.time_send.destroy()\n",
    "            subject_matter.bind('<Return>', send_email)\n",
    "            self.time_send.grid()\n",
    "            email_from.grid(row = 0, column = 0, sticky = 'w')\n",
    "            email_to.grid(row = 1, column = 0, sticky = 'w')\n",
    "            email_text.grid(row = 3, columnspan = 2, sticky = 'nsw')\n",
    "            subject_matter_label.grid(row = 2, column = 0, sticky = 'w', ipadx = 3.5)\n",
    "            subject_matter.grid(row = 2, columnspan = 1, sticky = 'e', padx = 3)\n",
    "        \n",
    "        set_time.bind('<Button-1>', prepare_email)    \n",
    "        #Make email: Show it to user: and set time. \n",
    "        \n",
    "        self.select_frame.grid(row = 1, columnspan = 2, sticky = 'sw')\n",
    "        message_label.grid(row = 0, column = 0)\n",
    "        message_listbox.grid(row = 1, column = 0, padx = 40)\n",
    "        new_message.grid(row = 3, column = 0, sticky = 'sw', padx = 40, pady = 10)\n",
    "        set_time.grid(row = 3, column = 0, sticky = 'se', padx = 40, pady = 10)\n",
    "        \n",
    "test = reminder_program\n",
    "root = Tk()\n",
    "root.geometry('{}x{}'.format(750, 710))\n",
    "myapp = reminder_program(root)\n",
    "root.mainloop()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
