Python Forum
Help with structuring a program
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help with structuring a program
#1
Hello,

I'm working on building a small, console based IMAP client using the py_cui and imapclient libraries. I got an initial script up and running, and I am learning/teaching myself as I am going.

Once I got the initial script able to connect to an IMAP server and show the user a list of mailboxes, I realized it was probably time to start organizing things a bit better. My thinking was to aim for Model, Controller, View scheme, with the Model being the imapclient library, the database being whatever IMAP server, and the Controller/view being the py_cui library.

So, I started to split my initial script up into two files, with the idea of separating out the main functionality/jobs.

Here is the initial script, mail_script.py:

import py_cui
import ssl
from imapclient import IMAPClient
from itertools import chain

HOST = "imap.gmail.com"
USERNAME = "[email protected]"
PASSWORD = "apppassword"

client = IMAPClient(HOST)
# client.starttls() --- gmail does not use starttls
client.login(USERNAME, PASSWORD)
#client.select_folder("INBOX")



class Slither:

    def __init__(self, master):
        self.master = master

    # Creating widgets for mailbox list on left and message list on right

        Mailboxes = self.master.add_scroll_menu('Mailboxes', 0, 0, row_span=6, column_span=1)

        get_folders = client.list_folders()
        folder_list = []
        final_list = list(set(chain.from_iterable(folder_list)))
       # Mailboxes.add_item_list(folder_list)

        for folders in get_folders:
        
            folder_list.append(folders[2])
            #final_list = list(set(chain.from_iterable(folder_list)))
        Mailboxes.add_item_list(folder_list)

        Messages = self.master.add_scroll_menu('Messages', 0, 1, row_span=6, column_span=4)
       # if CLIENT_STATE == AUTHENTICATED:
       # message_list = client.list_folders()
       # Messages.add_item_list(message_list)






# Create the CUI with 7 rows 6 columns (may change later), pass it to the wrapper object, and start it
root = py_cui.PyCUI(7, 6)
root.set_title('Slither')
s = Slither(root)
root.start()
And, here are my two new scripts, mail.py and imap.py by which I was trying to organize the code by function/job:

import py_cui
import imap
# from itertools import chain



class Mail:

    def __init__(self, master):
        self.master = master

        # Creating widgets for mailbox list on left and message list on right

        # Connect to an IMAP server
        imap.login()

        # Make Mailbox widget and get a list of folders for account
        Mailboxes = self.master.add_scroll_menu('Mailboxes', 0, 0, row_span=6, column_span=1)
        Mailboxes.add_item_list(imap.get_folders())

        # Make a Messages widget and get a list of messages based on the folder selected. 
        Messages = self.master.add_scroll_menu('Messages', 0, 1, row_span=6, column_span=4)
        # First select the folder
        # message_list = client....whatever method lists messages
        # Messages.add_item_list(message_list)






# Create the CUI with 7 rows 6 columns (may change later), pass it to the wrapper object, and start it
root = py_cui.PyCUI(7, 6)
root.set_title('Mail')
s = Mail(root)
imap.login()
root.start()
### imap.py -- A module for handling all interaction with IMAP servers

import ssl
import imapclient
from imapclient import IMAPClient
def login():

    HOST = "imap.gmail.com"
    USERNAME = "[email protected]"
    PASSWORD = "apppassword"

    client = IMAPClient(HOST)
    #client.starttls() --- gmail does not support starttls
    client.login(USERNAME, PASSWORD)
    return;

def get_folders():
    "Grabbing the list of folders for the account"
    get_folders = client.list_folders()
    folder_list = []
    for folders in get_folders:
        folder_list.append(folders[2])
    return folder_list;



# client.select_folder("INBOX")
As I was working on splitting up the functions/jobs to organize, I started to wonder if I should be putting all of the IMAP related functions into a class, which caused me to further wonder am I reinventing the wheel here? If IMAPClient is already a class inside the imapclient package, is it the right way to go to create another class to call into mail.py for getting data from the IMAP servier? I am worried that, in my effort to organize, I am actually making things more complicated.

I would love to get some advice regarding structuring this program, and program structure in general, as well as when using classes is more appropriate versus when using functions is more appropriate.

Thanks for any help available!

Best,

Matt
Reply
#2
Haven't really read much of the thread, but you certainly want to use classes to model your domain concepts (or use collections.namedtuple when you want immutable value objects). In this case, I'd certainly expect to see something called Message, for example (and that could really be a value object I think).
Reply
#3
Ok, thanks -- is this a good start?

### imap.py -- A module for Slither handling all interaction with IMAP servers

import ssl
import imapclient
from imapclient import IMAPClient

host = "imap.gmail.com"
username = "[email protected]"
password = "twqahnuyavmhsdzl"


class imap:
    def __init__(self, host, username, password):
        self.host = host
        self.username = username
        self.password = password
        self.client = IMAPClient(host)


    def login(self):
        "Handling various auth protocols"
        #client.starttls() --- gmail does not support starttls
        client.login(username, password)
        return;

    def get_folders(self):
        "Grabbing the list of folders for the account"
        get_folders = client.list_folders()
        folder_list = []
        for folders in get_folders:
            folder_list.append(folders[2])
        return folder_list;



    #client.select_folder("INBOX")
I know this is not quite right, or that I am not using it correctly, because I get an error for get_folders about "client" not being defined, which confuses the heck out of me....
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Structuring a large class: privite vs public methods 6hearts 3 1,049 May-05-2023, 10:06 AM
Last Post: Gribouillis
  Structuring and pivoting corrupted dataframe in pandas gunner1905 2 2,231 Sep-18-2021, 01:30 PM
Last Post: gunner1905

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020