Exemple #1
0
class WatchIpGui:
    def __init__(self, master, title='IP Watchdog'):
        self.master = master
        self.master.title(title)
        self.menubar = Menu(self.master)
        self.cbInternalIp = BooleanVar()
        self.cbExternalIp = BooleanVar()
        self.cbHostname   = BooleanVar()
        self.unitSelection = StringVar()
        self.watch = WatchIP()
        self.watch.getCurrentIP()
        self.vInternalIp = StringVar()
        self.vExternalIp = StringVar()
        self.vHostname   = StringVar()
        self.isStarted = False
        self.newWindow = True
        self.preExec = False
        self.scale = None
        self.stop = True
        
        self.execWatchThread = None
        
        self.display()
        
        self.emailConfig = EmailConfigGui(master, False, properties='.ipwatcher.email.properties')
        
        
    def display(self, startExecution=False):
        
        self.startExecution = startExecution
        
         
        if self.newWindow == False:
            self.top.update()
            self.top.deiconify()
            
            if self.startExecution == True:
                self.action()
        
        else:
            curRow = 0
    
    
            ## Menu Bar
            
            filemenu = Menu(self.menubar, tearoff=0)
            filemenu.add_command(label="Execute", command=self.action)
    
            filemenu.add_separator()
    
            filemenu.add_command(label="Exit", command=self.quit)
            self.menubar.add_cascade(label="File", menu=filemenu)
            editmenu = Menu(self.menubar, tearoff=0)
    
            editmenu.add_separator()
    
            editmenu.add_command(label="Preferences", command=self.showPrefs)
    
            self.menubar.add_cascade(label="Edit", menu=editmenu)
            helpmenu = Menu(self.menubar, tearoff=0)
            helpmenu.add_command(label="IP Watchdog Help", command=self.helpButton)
            helpmenu.add_command(label="About...", command=self.showVersion)
            self.menubar.add_cascade(label="Help", menu=helpmenu)
            self.master.config(menu=self.menubar)
            ## End Menu Bar
    
            self.top = Toplevel(menu=self.menubar, width=500, relief=RAISED,
                                borderwidth=2)
            
            self.top.protocol("WM_DELETE_WINDOW",self.quit)
    
            gridWidth = 30
            px = 5
            lWidth = 15
            py = 18
    
            #Grid Start
    
            #Notify on Change
            Label(self.top, text='Notify on Change in:',
                  relief=RIDGE, bg='gray',  width=gridWidth).grid(row=curRow, column=0, columnspan=2, pady=py)
    
            curRow += 1
            
            Label(self.top, text='Internal IP', relief=RIDGE,  width=15).grid(row=curRow, column=0)
            Checkbutton(self.top,variable=self.cbInternalIp).grid(row=curRow, column=1, sticky=W, padx=px)
    
            curRow += 1
            
            Label(self.top, text='External IP', relief=RIDGE,  width=15).grid(row=curRow, column=0)
            Checkbutton(self.top,variable=self.cbExternalIp).grid(row=curRow, column=1, sticky=W,padx=px)
    
            curRow += 1
            
            Label(self.top, text='Hostname', relief=RIDGE,  width=15).grid(row=curRow, column=0)
            Checkbutton(self.top,variable=self.cbHostname).grid(row=curRow, column=1, sticky=W,padx=px)
    
    
            #Change Frequency
            curRow += 1
            Label(self.top, text='Poll Frequency:',
                  relief=RIDGE, bg='gray',  width=gridWidth).grid(row=curRow,
                                                                  column=0, columnspan=2, pady=py)
            curRow += 1     
            Label(self.top, text='Units', relief=RIDGE,  width=15).grid(row=curRow, column=0)
            self.optionList = ['minute(s)','hour(s)','day(s)']
            self.unitSelection.set(self.optionList[0])
            OptionMenu(self.top, self.unitSelection, *self.optionList, command=self.updateInterval).grid(row=curRow, column=1, stick=EW)
            
            self.min = 5.0
            self.max = 60.0
    
            curRow += 1
            Label(self.top, text='Interval', relief=SUNKEN,  width=lWidth).grid(row=curRow, column=0,padx=px)
            self.scl = Scale(self.top, from_=self.min, to=self.max, orient=HORIZONTAL)
            self.scl.grid(row=curRow, column=1,padx=px)
    
    
            #Current Values
            curRow += 1
            Label(self.top, text='Current Values:',
                  relief=RIDGE, bg='gray',  width=gridWidth).grid(row=curRow,
                                                                  column=0, columnspan=2, pady=py)
    
            
            curRow += 1
            Label(self.top, text='Internal IP', relief=SUNKEN,  width=lWidth).grid(row=curRow, column=0,padx=px)
            self.eInternalIp = Entry(self.top,state='readonly', textvariable=self.vInternalIp)
            self.eInternalIp.grid(row=curRow, column=1, sticky=W,padx=px)
            
            
    
            curRow += 1
            
            Label(self.top, text='External IP', relief=SUNKEN,  width=lWidth).grid(row=curRow, column=0,padx=px)
            self.eExternalIp = Entry(self.top,state='readonly', textvariable=self.vExternalIp)
            self.eExternalIp.grid(row=curRow, column=1, sticky=W,padx=px)
            #self.vExternalIp.set()
    
            curRow += 1
            
            Label(self.top, text='Hostname', relief=SUNKEN,  width=lWidth).grid(row=curRow, column=0, padx=px)
            self.eHostname = Entry(self.top,state='readonly', textvariable=self.vHostname)
            self.eHostname.grid(row=curRow, column=1, sticky=W,padx=px)
    
    
            #Actions
            
            curRow += 1
            Label(self.top, text='Actions:',
                  relief=RIDGE, bg='gray',  width=gridWidth).grid(row=curRow,
                                                                  column=0, columnspan=2, pady=py)
            
            curRow += 1      
            Button(self.top, text='Quit',bg='blue', fg='white', command=self.quit).grid(row=curRow,column=0, pady=5)
            self.actionButton =Button(self.top, text='Start',bg='blue', fg='white', command=self.action)
            self.actionButton.grid(row=curRow,column=1, pady=5)
            
            self.updateEntries()
            self.newWindow = False
    
            #Grid End
        
    def updateEntries(self):
        self.vInternalIp.set(self.watch.curInternalIp)
        self.vExternalIp.set(self.watch.curExternalIp)
        self.vHostname.set(self.watch.curHostName)
      
    def showPrefs(self): 
        self.emailConfig.display(self, self.preExec)
        self.top.withdraw()
        
    
    def helpButton(self):
        pass
    
    def showVersion(self):
        pass

    def quit(self): 
        if self.execWatchThread != None:
            if self.execWatchThread.isAlive():
                self.execWatchThread.join()
                
        os.sys.exit(0)
        
    def action(self):
        
        if not self.isStarted:
            
            if self.emailConfig.checkMissingConfig() == True: 
                self.preExec = True
                msg = "Please configure the outgoing email."
                tkMessageBox.showinfo('Configure Email', msg)
                self.showPrefs()
                   
            elif self.emailConfig.getPassword() == "":
                self.preExec = True
                msg = "Enter your password to start watching."
                tkMessageBox.showinfo('Authenticate', msg)
                self.showPrefs()
                
            else:
                self.getNotificationList()
 
                if len(self.notifyList) == 0:
                    tkMessageBox.showerror("Insufficient Input", "Please check an item to watch.")
                    
                else:
                    msg = "I will minimize the window and then I will poll the system in " + str(self.scl.get()) + " " + self.unitSelection.get().replace('(s)','')
                    msg += " intervals. Finally I will email/text on change in:\n\n" + '\n'.join(self.notifyList)
                     
                    if tkMessageBox.askokcancel('Execute Confirmation', msg):
                        self.isStarted = not self.isStarted
                        self.actionButton.config(text='Stop')
                        self.top.iconify() 
                        
                        self.normalizeInterval()
                        em = self.emailConfig
                        self.execWatchThread = ExecuteWatchThread(self.scale, em.fromAddress.get(),em.getPassword(),em.recipients.get(),
                                                                   self.cbInternalIp.get(), self.cbExternalIp.get(),
                                                                   self.cbHostname.get(), em.server.get(), em.port.get())
                        self.execWatchThread.start() 
                        
#                        self.emailOnChange() 
#                        self.top.deiconify()
                        print "Done"       

        else:
            self.actionButton.config(text='Start')
            self.isStarted = not self.isStarted
            if self.execWatchThread.isAlive():
                self.execWatchThread.join()
                
            print "She is gone"
            print "Living? ", self.execWatchThread.isAlive()
            
            
    def getNotificationList(self):
        self.notifyList = []

        if self.cbExternalIp.get():
            self.notifyList.append('External IP')
            
        if self.cbInternalIp.get():
            self.notifyList.append('Internal IP')
            
        if self.cbHostname.get():
            self.notifyList.append('Hostname')  
             
            
    
    
    def emailOnChange(self):
        self.normalizeInterval()
        print "Is Started: ", self.isStarted
        
        if self.scale != None:
            
            while self.isStarted == True:
                
                time.sleep(30)
                if self.watchedValueHasChange() == True:
                    tkMessageBox.showinfo("Change Detected", self.watch.getCurrentIpString())
                    
                else:
                    tkMessageBox.showinfo("No Change Detected", self.watch.getCurrentIpString())
                    print "Is Started: ", self.isStarted
                
        
    
    def normalizeInterval(self):
        self.scale = self.scl.get()
        if self.unitSelection.get() == 'minutes(s)':
            self.scale = self.scale * 60
            
        elif self.unitSelection.get() == 'hour(s)':
            self.scale = self.scale * 60  * 60
        
        elif self.unitSelection.get() == 'days(s)':
            self.scale = self.scale * 24 * 60 * 60
        else:
            self.ErrStr = "Error:  Unknown unit --> " + str(self.unitSelection.get())
            
        print self.scale
        self.scale = 120
        
        
        
    def updateInterval(self, event=None):
        if self.unitSelection.get() == self.optionList[0]:
            self.min = 5
            self.max = 60

        elif self.unitSelection.get() == self.optionList[1]:
            self.min = 1
            self.max = 24
        else:
            self.min = 1
            self.max = 7
            
        self.scl.config(from_=self.min)
        self.scl.config(to=self.max)
class SimpleNotificationSystem():
    def __init__(self,master,title='Simple Notification System (SNS)'):
        
        self.pathToExe =StringVar()
        self.args = StringVar()
        self.master = master
        self.menubar = Menu(self.master)
        self.title = title
        self.newWindow = True 
        self.preExec = False
        self.logDir = ""#'..' + os.sep + 'logs'
        self.spacer = '*' * 80 + '\n'
        self.spacer += self.spacer + '\n'
        dateStamp = str(datetime.date.today()) + strftime("_%H%M%S")
        self.errorLog = self.logDir + os.sep + 'SNS.' + str(dateStamp) + ".log"
        writeLog(self.errorLog, "Starting SNS on .... " + str(dateStamp) + "\n")
        writeLog(self.errorLog, self.spacer)
        
        
        self.emailConfig = EmailConfigGui(master, False, self.errorLog)
        
        if self.emailConfig.checkMissingConfig() == True:
            message = "This is either the first time you have run this program "
            message += "or you are missing some required configuration"
            
            tkMessageBox.showinfo('Required Configuration Options', message)
            self.emailConfig.display(self)
            
        else:
            self.display()
            
        
       
    def cancel(self): 
        #tkMessageBox.showinfo("Cheers", "Have a good one :) " )
        os.sys.exit(0)
        
    def helpButton(self):
        pass
    
    def showVersion(self):
        pass
        
    def submit(self):
        text = 'COMMAND RESULTS:\n'
        self.preExec = True
        
        
        if self.emailConfig.checkMissingConfig() == True: 
            msg = "Please configure the outgoing email."
            tkMessageBox.showinfo('Configure Email', msg)
            self.showPrefs()
            
                   
        elif self.emailConfig.getPassword() == "":
            msg = "Enter your password, hit apply and then resubmit"
            tkMessageBox.showinfo('Authenticate', msg)
            self.showPrefs()
            
        else:
            msg = 'Shall I minimize the window and execute ' + os.path.basename(self.pathToExe.get()) + ' now?'
            if tkMessageBox.askokcancel('Execute Confirmation', msg):
                self.top.iconify()
                try:
                    text += self.captureOutput(self.pathToExe.get() + " " + self.args.get())
                    
                    
                    subject = self.pathToExe.get() + " <-- Command completed"
                    
                    emObj = self.emailConfig
                     
                    email = EmailWrapper(emObj.recipients.get(),subject,text, 
                                         emObj.fromAddress.get(), emObj.getPassword(),emObj.server.get(),emObj.port.get())
                    
                    email.mail()
                    
                    if email.hasErrors == True:
                        msg = email.errString
                        msg += "\nValues: \n"
                        msg +=  email.toString()
                        tkMessageBox.showerror('Mail Error Generated', msg)
                        self.top.deiconify()
                        
                    else:
                        tkMessageBox.showinfo("Execution Complete", subject)
                        self.top.deiconify()
                    
                except IOError as inst:
                    output = "ERROR GENERATED in EmailAfterExec.submit:\n"
                    output += "Exception Type: " + str(type(inst)) + "\n"
                    output += "Exception: " + str(inst) + "\n" 
                    tkMessageBox.showerror('Submit Error Generated', output)
                    self.top.deiconify()
            
        
        
        
    ## ----------------------------------------------------------------------------
    ## captureOutput -  Wrapper function that captures the standard output of an
    ##                  external command and returns that ouput in string format
    ##                  
    ## ---------------------------------------------------------------------------- 
    def captureOutput(self, cmd):
        try:
            stream = os.popen(cmd)
            output = stream.read()
            stream.close()
            
        except Exception as inst:
            output = "ERROR GENERATED:\n"
            output += "CMD: " + cmd + "\n"
            output += "Exception Type: " + str(type(inst)) + "\n"
            output += "Exception: " + str(inst) + "\n"
    
            
        return str(output) 
    
    def showPrefs(self): 
        self.emailConfig.display(self,self.preExec)
        self.top.withdraw()
        
    def browseForExe(self):
        tmp = askopenfilename()
        if tmp != "":
            self.pathToExe.set(tmp)

    def display(self, startExecution=False):
        self.startExecution = startExecution
         
        if self.newWindow == False:
            self.top.update()
            self.top.deiconify()
            
            if self.startExecution == True:
                self.submit()

        
        else:
            ## Menu Bar
           
            filemenu = Menu(self.menubar, tearoff=0)
            filemenu.add_command(label="Execute", command=self.submit)
    
            filemenu.add_separator()
    
            filemenu.add_command(label="Exit", command=self.cancel)
            self.menubar.add_cascade(label="File", menu=filemenu)
            editmenu = Menu(self.menubar, tearoff=0)
    
            editmenu.add_separator()
    
            editmenu.add_command(label="Preferences", command=self.showPrefs)
    
            self.menubar.add_cascade(label="Edit", menu=editmenu)
            helpmenu = Menu(self.menubar, tearoff=0)
            helpmenu.add_command(label="Email After Execution Help", command=self.helpButton)
            helpmenu.add_command(label="About...", command=self.showVersion)
            self.menubar.add_cascade(label="Help", menu=helpmenu)
            self.master.config(menu=self.menubar)
            ## End Menu Bar
            
            
            #self.top = Toplevel(self.master)
            
            
            
            self.top = Toplevel(menu=self.menubar, width=500, relief=RAISED,
                                borderwidth=2)
            
            self.top.protocol("WM_DELETE_WINDOW",self.cancel)
            self.top.title(self.title)
            self.top.resizable(width=FALSE, height=FALSE)
            
            
            Label(self.top, text="Programs To Execute",
                               bd=2,relief=SOLID,width=60, bg='gray').grid(columnspan=2,row=6, pady=8)
                               
            
            Label(self.top, text="Path",
                               bd=2,relief=SOLID,width=30).grid(row=7,sticky=W)
            self.ePath = Entry(self.top,width=35, textvariable=self.pathToExe)
            self.ePath.grid(row=7,column=1, pady=3, padx=5,sticky=W)
            
            Button(self.top, text='+',bg='blue', fg='white', command=self.browseForExe).grid(row=7,column=2)
                               
            Label(self.top, text="Args",
                               bd=2,relief=SOLID,width=30).grid(row=8,sticky=W)
                               
            self.eArgs = Entry(self.top,width=35, textvariable=self.args)
            self.eArgs.grid(row=8,column=1, pady=3, padx=5,sticky=W)
            
            Button(self.top, text='Help',bg='gray', fg='white', command=self.cancel).grid(row=9,column=0,pady=10)
            Button(self.top, text='Submit',bg='blue', fg='white', command=self.submit).grid(row=9,column=1,pady=10)
            Button(self.top, text='Quit',bg='red', fg='white', command=self.cancel).grid(row=9,column=2,pady=10)
            self.newWindow = False