def __init__( self, servers, settings ) : ''' This is the actionable part of the class and is responsible for initializing the class objects, implementing the urwid display and executing the main loop. 'servers' is an object which contains all the necessary information for logging in to the email accounts and extracting headers. settings: <DIC> containing the global settings associated with the program ''' # Import the necessary modules and functions: try: import urwid except ImportError: print("urwid module missing. Try: pip install urwid") import sys sys.exit(1) from miscClasses import threadedExec # This function implements email account access using threads self.settings = settings # Store the settings (mostly global for the program) locally in a dictionary self.servers = servers # This wealth of information will come in handy when we will be deleting emails # Define the palette that will be used by urwid. Note that is defined to be a member of the urwidDisplay class as all objects will be normal_bg_color = 'black' # Here we define the default normal and focus state bg colors for the header lines displayed focus_bg_color = 'light blue' self.palette = [ ( 'title', 'yellow', 'dark blue' ), ( 'account', 'light red', normal_bg_color ), ( 'bw', 'white', normal_bg_color ), ( 'flag', 'dark green', normal_bg_color ), # We define the normal state color scheme for the various parts of the header ( 'date', 'brown', normal_bg_color ), ( 'from', 'dark cyan', normal_bg_color ), ( 'subject', 'dark green', normal_bg_color ), ( 'subjectSeen', 'brown', normal_bg_color ), # We define the 'focus' state color scheme for various parts of the header. Note the 'F_' at the beginning of each name ( 'F_bw', 'white', focus_bg_color ) , # Black and White text when focussed ( 'F_flag', 'light green', focus_bg_color ), ( 'F_date', 'yellow', focus_bg_color ), ( 'F_from', 'light cyan', focus_bg_color ), ( 'F_subject', 'light green', focus_bg_color ), ( 'F_subjectSeen', 'yellow', focus_bg_color ), # We define the normal state flagged for Deletion scheme for the header. Note the 'D_' at the beginning of each name ( 'D_bw', 'dark red', normal_bg_color ), ( 'D_flag', 'dark red', normal_bg_color ), ( 'D_date', 'dark red', normal_bg_color ), ( 'D_from', 'dark red', normal_bg_color ), ( 'D_subject', 'dark red', normal_bg_color ), ( 'D_subjectSeen', 'dark red', normal_bg_color ), # We define the focus state flagged for Deletion scheme for the header. Note the 'DF_' at the beginning of each name. ( 'DF_bw', 'dark red', focus_bg_color ), ( 'DF_flag', 'dark red', focus_bg_color ), ( 'DF_date', 'dark red', focus_bg_color ), ( 'DF_from', 'dark red', focus_bg_color ), ( 'DF_subject', 'dark red', focus_bg_color ), ( 'DF_subjectSeen', 'dark red', focus_bg_color ) ] self.title = urwid.AttrMap( urwid.Text( " FetchHeaders q: Quit a: Abort d: Delete u: UnDelete j: Down k: Up" ), 'title' ) self.div = urwid.Divider() self.titlePile = urwid.Pile( [ self.title, self.div ] ) self.emails = [] # This is a list which will contain the emails whose headers have been displayed. We will use it when shifting focus and marking for deletion. self.focus = -1 # Initially no header has focus. This is donated by the value -1. 0 will donate the first header corresponding to self.emails[0]. self.List = [] # This is the list of objects that will be used to construct the main listbox that displays all email headers and auxiliary information. # We will now extract header information from each account and use it to construct various objects. While doing so we must keep in mind that when focus shifts the objects must be re-drawn explicitly. This can be handled by constructing the lines every time it is required, using separate functions to handle the construction by simply passing them the same information for out in threadedExec( servers, self.settings[ 'maxThreads' ] ) : # This calls the threaded processed to extract information and return it in an iterable queue if out.error: # out.error is True if an Exception is raised while it is being calculated. In such a case we display an error line account = urwid.Text( ('account', ' ' + out.settings[ 'name' ] + ':' ) ) error = urwid.Text(('bw', 'Error!')) accountLine = urwid.Columns( [('fixed', 13, account), error ]) self.List += [ accountLine ] else: # Construct account line widget account = urwid.Text( ( 'account', ' ' + out.settings[ 'name' ] + ':' ) ) if out.settings[ 'showNums' ] : # Numbers are supposed to displayed after the account name numbers = urwid.Text( ( 'bw', '( total: ' + str( out.numAll ) + ' | unseen: ' + str( out.numUnseen ) + ' )' ) ) accountLine = urwid.Columns( [ ( 'fixed', 13, account ), numbers ] ) else : # Don't display numbers accountLine = urwid.Columns( [ ( 'fixed', 13, account ) ] ) self.List += [ accountLine, self.div ] # First line displays account name and number of messages # We now construct and display the email headers for ii in range( len( out.emails ) ) : email = out.emails[ ii ] email.account = out.settings[ 'name' ] # Store name of account associated with each email email.Delete = False # Boolean Flag for tracking if email has to be deleted. email.serial = ii + 1 # Serial Number associated with this email email.numDigits = out.numDigits # No. of digits for displaying serial number, calculated by analyzing the number of emails for this particular account email.listPos = len( self.List ) # Store the position of the email header urwid object (urwid.Columns) in self.List. Will need it for focusing or deletion. self.emails.append( email ) # Add the displayed email to the self.emails list line = self.constructLine( email, focus = False ) self.List.append( line ) # Call constructLine to create header line using data in 'email' object. ii + 1 is serial number self.List += [ self.div, self.div ] # Add two empty lines after account ends self.total = len( self.emails ) # Total no. of emails being displayed # All account information has been input and the urwid display is almost ready: self.listbox = urwid.ListBox( self.List ) self.frame = urwid.Frame( self.listbox, header = self.titlePile ) # By using a frame we ensure that the top title doesn't move when we scroll through the listbox self.loop = urwid.MainLoop( self.frame, self.palette, unhandled_input = self.handler ) # Now we run the main loop: self.loop.run()
def __init__(self, servers, settings): ''' This is the actionable part of the class and is responsible for initializing the class objects, implementing the urwid display and executing the main loop. 'servers' is an object which contains all the necessary information for logging in to the email accounts and extracting headers. settings: <DIC> containing the global settings associated with the program ''' # Import the necessary modules and functions: try: import urwid except ImportError: print("urwid module missing. Try: pip install urwid") import sys sys.exit(1) from miscClasses import threadedExec # This function implements email account access using threads self.settings = settings # Store the settings (mostly global for the program) locally in a dictionary self.servers = servers # This wealth of information will come in handy when we will be deleting emails # Define the palette that will be used by urwid. Note that is defined to be a member of the urwidDisplay class as all objects will be normal_bg_color = 'black' # Here we define the default normal and focus state bg colors for the header lines displayed focus_bg_color = 'light blue' self.palette = [ ('title', 'yellow', 'dark blue'), ('account', 'light red', normal_bg_color), ('bw', 'white', normal_bg_color), ( 'flag', 'dark green', normal_bg_color ), # We define the normal state color scheme for the various parts of the header ('date', 'brown', normal_bg_color), ('from', 'dark cyan', normal_bg_color), ('subject', 'dark green', normal_bg_color), ('subjectSeen', 'brown', normal_bg_color), # We define the 'focus' state color scheme for various parts of the header. Note the 'F_' at the beginning of each name ('F_bw', 'white', focus_bg_color ), # Black and White text when focussed ('F_flag', 'light green', focus_bg_color), ('F_date', 'yellow', focus_bg_color), ('F_from', 'light cyan', focus_bg_color), ('F_subject', 'light green', focus_bg_color), ('F_subjectSeen', 'yellow', focus_bg_color), # We define the normal state flagged for Deletion scheme for the header. Note the 'D_' at the beginning of each name ('D_bw', 'dark red', normal_bg_color), ('D_flag', 'dark red', normal_bg_color), ('D_date', 'dark red', normal_bg_color), ('D_from', 'dark red', normal_bg_color), ('D_subject', 'dark red', normal_bg_color), ('D_subjectSeen', 'dark red', normal_bg_color), # We define the focus state flagged for Deletion scheme for the header. Note the 'DF_' at the beginning of each name. ('DF_bw', 'dark red', focus_bg_color), ('DF_flag', 'dark red', focus_bg_color), ('DF_date', 'dark red', focus_bg_color), ('DF_from', 'dark red', focus_bg_color), ('DF_subject', 'dark red', focus_bg_color), ('DF_subjectSeen', 'dark red', focus_bg_color) ] self.title = urwid.AttrMap( urwid.Text( " FetchHeaders q: Quit a: Abort d: Delete u: UnDelete j: Down k: Up" ), 'title') self.div = urwid.Divider() self.titlePile = urwid.Pile([self.title, self.div]) self.emails = [ ] # This is a list which will contain the emails whose headers have been displayed. We will use it when shifting focus and marking for deletion. self.focus = -1 # Initially no header has focus. This is donated by the value -1. 0 will donate the first header corresponding to self.emails[0]. self.List = [ ] # This is the list of objects that will be used to construct the main listbox that displays all email headers and auxiliary information. # We will now extract header information from each account and use it to construct various objects. While doing so we must keep in mind that when focus shifts the objects must be re-drawn explicitly. This can be handled by constructing the lines every time it is required, using separate functions to handle the construction by simply passing them the same information for out in threadedExec( servers, self.settings['maxThreads'] ): # This calls the threaded processed to extract information and return it in an iterable queue if out.error: # out.error is True if an Exception is raised while it is being calculated. In such a case we display an error line account = urwid.Text( ('account', ' ' + out.settings['name'] + ':')) error = urwid.Text(('bw', 'Error!')) accountLine = urwid.Columns([('fixed', 13, account), error]) self.List += [accountLine] else: # Construct account line widget account = urwid.Text( ('account', ' ' + out.settings['name'] + ':')) if out.settings[ 'showNums']: # Numbers are supposed to displayed after the account name numbers = urwid.Text( ('bw', '( total: ' + str(out.numAll) + ' | unseen: ' + str(out.numUnseen) + ' )')) accountLine = urwid.Columns([('fixed', 13, account), numbers]) else: # Don't display numbers accountLine = urwid.Columns([('fixed', 13, account)]) self.List += [ accountLine, self.div ] # First line displays account name and number of messages # We now construct and display the email headers for ii in range(len(out.emails)): email = out.emails[ii] email.account = out.settings[ 'name'] # Store name of account associated with each email email.Delete = False # Boolean Flag for tracking if email has to be deleted. email.serial = ii + 1 # Serial Number associated with this email email.numDigits = out.numDigits # No. of digits for displaying serial number, calculated by analyzing the number of emails for this particular account email.listPos = len( self.List ) # Store the position of the email header urwid object (urwid.Columns) in self.List. Will need it for focusing or deletion. self.emails.append( email ) # Add the displayed email to the self.emails list line = self.constructLine(email, focus=False) self.List.append( line ) # Call constructLine to create header line using data in 'email' object. ii + 1 is serial number self.List += [self.div, self.div] # Add two empty lines after account ends self.total = len(self.emails) # Total no. of emails being displayed # All account information has been input and the urwid display is almost ready: self.listbox = urwid.ListBox(self.List) self.frame = urwid.Frame( self.listbox, header=self.titlePile ) # By using a frame we ensure that the top title doesn't move when we scroll through the listbox self.loop = urwid.MainLoop(self.frame, self.palette, unhandled_input=self.handler) # Now we run the main loop: self.loop.run()
def main(): ''' Main function that starts the execution of all of the code. ''' args = argParse() # Specify default locations for configuration and specification files: import os homeFolder = os.getenv("HOME") # Basically the value in $HOME packageFolder = '/usr/local/share/fetchheaders' # Location of folder containing all package files # packageFolder = '.' fileConf = homeFolder + '/.fetchheaders.conf' fileSpec = packageFolder + '/fetchheaders.conf.spec' # Path to config specification file # Check if a configuration file has been specified using the -c or --config flag. if args.config: # A configuration file has been provided fileConf = args.config # Read in settings and options from configuration files : servers, globalSettings = setOptions(fileConf, fileSpec) # Override settings and options from command-line arguments : servers, globalSettings = applyArgs(args, servers, globalSettings) # Apply Global Settings. These are applied outside of pollAccount which acts on each account independantly. applyGlobalSettings( globalSettings ) # Apply the global settings contained in the 'globalSettings' dictionary we created from the configuration file and command-line arguments # Now we determine whether the output is intended to go to the terminal (stdout) straight or passed on to urwid if globalSettings['terminal']: # Do NOT use urwid from miscClasses import threadedExec for out in threadedExec(servers, maxThreads): if out.error: # If an error occurs while constructing the Output object the exception is caught and the error flag is set from miscClasses import colorWidth as cW print( cW(out.settings['name'] + ':', 12, colorTitle), end='' ) # We indicate in the output that an Error has occurred. print("Error!\n\n") else: display(out) else: # Use urwid to display the results, interact with the display and possibly flag messages for deletion: from urwidDisplay import urwidDisplay # Create instance of the imported class to create and start the urwid loop to display emails settings = {'maxThreads': maxThreads, 'showFlags': showFlags} urwidDisplay(servers, settings)
def main() : ''' Main function that starts the execution of all of the code. ''' args = argParse() # Specify default locations for configuration and specification files: import os homeFolder = os.getenv( "HOME" ) # Basically the value in $HOME packageFolder = '/usr/local/share/fetchheaders' # Location of folder containing all package files # packageFolder = '.' fileConf = homeFolder + '/.fetchheaders.conf' fileSpec = packageFolder + '/fetchheaders.conf.spec' # Path to config specification file # Check if a configuration file has been specified using the -c or --config flag. if args.config : # A configuration file has been provided fileConf = args.config # Read in settings and options from configuration files : servers, globalSettings = setOptions( fileConf, fileSpec ) # Override settings and options from command-line arguments : servers, globalSettings = applyArgs( args, servers, globalSettings ) # Apply Global Settings. These are applied outside of pollAccount which acts on each account independantly. applyGlobalSettings( globalSettings ) # Apply the global settings contained in the 'globalSettings' dictionary we created from the configuration file and command-line arguments # Now we determine whether the output is intended to go to the terminal (stdout) straight or passed on to urwid if globalSettings[ 'terminal' ]: # Do NOT use urwid from miscClasses import threadedExec for out in threadedExec( servers, maxThreads ): if out.error: # If an error occurs while constructing the Output object the exception is caught and the error flag is set from miscClasses import colorWidth as cW print( cW( out.settings[ 'name' ] + ':', 12, colorTitle ), end = '' ) # We indicate in the output that an Error has occurred. print( "Error!\n\n" ) else: display(out) else: # Use urwid to display the results, interact with the display and possibly flag messages for deletion: from urwidDisplay import urwidDisplay # Create instance of the imported class to create and start the urwid loop to display emails settings = { 'maxThreads': maxThreads, 'showFlags': showFlags } urwidDisplay( servers, settings )