diff --git a/RicohReader.py b/RicohReader.py index 3727168..fc0009c 100644 --- a/RicohReader.py +++ b/RicohReader.py @@ -1,7 +1,9 @@ import os import Pmw import time +import os.path import datetime +import traceback import webbrowser import tkinter as tk from tkinter import ttk @@ -63,6 +65,8 @@ def resource_path(relative_path): file=resource_path('images/c6503.png')).subsample(4, 4) self.c6503f = tk.PhotoImage( file=resource_path('images/c6503f.png')).subsample(4, 4) + self.no_connection = tk.PhotoImage( + file=resource_path('images/NoConnection.png')).subsample(4, 4) #Create styles for progress bars self.style=ttk.Style() @@ -86,9 +90,12 @@ def resource_path(relative_path): 'yellow.Horizontal.TProgressbar',] #Define window properties - root.title('Ricoh Resource Monitor') + root.title('Ricoh Resource Monitor v3.4') root.iconbitmap(resource_path('images/icon.ico')) + #Grab the current time for logfile creation + self.current_time=datetime.datetime.now().strftime('%Y-%m-%d_%H-%M') + #Create variables to hold current paper deficit self.deficit=tk.IntVar() self.deficit.set(0) @@ -110,7 +117,7 @@ def resource_path(relative_path): font=(None, 6), cursor="hand2") self.q.pack(side=tk.RIGHT, anchor=tk.S) self.balloon = Pmw.Balloon(parent) - self.balloon.bind(self.q, 'RRM v3.3\n' + self.balloon.bind(self.q, 'RRM v3.4\n' 'Emilio Garcia\n' 'SC&I IT Helpdesk') self.q.bind("", @@ -149,7 +156,7 @@ def __init__(self, parent, *args, **kwargs): self.checklist.append([self.check, var]) self.check.pack(anchor=tk.W) #If the printer is one that we refill on our paper route, autoload - if entry['Name'] in ['CI-121','CI-202L', 'CI-202R', + if entry['Name'] in ['CI-121', 'CI-202L', 'CI-202R', 'CI-335', 'SDW-FL2', 'ANX-A', 'ANX-B']: self.check.invoke() @@ -215,15 +222,22 @@ def spawn_despawn(self, status, name): #If unchecked, subtract deficit and destroy printer frame self.all_check.deselect() try: + #Try reducing the total deficit self.parent.deficit.set( self.parent.deficit.get()-self.nametowidget( '.!mainapplication.!itemframe.a'+name['Name']).deficit()) self.parent.reams.set(self.parent.deficit.get()/500) + except Exception as e: + #Might fail if a "No Connection" frame is spawned + print(e) + try: + #Remove printer frames by name self.nametowidget( '.!mainapplication.!itemframe.a'+name['Name']).destroy() self.parent.update() - except: + except Exception as e: #When 'none' is called, it may try to destroy unspawned printer + print(e) return def none(self): @@ -305,175 +319,196 @@ def __init__(self, parent, printer): '\nEID: ' +printer['EID']) printer_name.pack() - printer_model=tk.Label(self, text=get(printer['IP'], 'public', - parent.parent.model_OID)) - printer_model.pack() - - url='http://' + printer['IP'] + '/web/guest/en/websys/webArch/mainFrame.cgi' - printer_IP=tk.Label(self, text=printer['IP'], fg="blue", - font=(None, 8, 'underline'), cursor="hand2") - balloon.bind(printer_IP, 'Go to printer control panel') - printer_IP.bind("", - lambda event,aurl=url:webbrowser.open(aurl)) - #Bind event property to label to create a hyperlink - printer_IP.pack() - - alert_frame=tk.Frame(self) - alert_frame.pack() - - scrollbar=tk.Scrollbar(alert_frame) - alerts_list=tk.Listbox(alert_frame, height=3, width=30, fg='red', - relief='flat', bg=default_bg, activestyle='none', - borderwidth=0, selectbackground=default_bg, - highlightthickness=0, selectforeground='red') - alerts_list.pack(side=tk.LEFT, pady=(5,0)) - alerts=walk(printer['IP'], 'public', parent.parent.error_base_OID) - alert_length=0 - #alerts is returned as an interator, so we define a counter to track - #its size - for item in alerts: - alerts_list.insert(tk.END, item[1].decode('utf-8')) - alert_length+=1 - if alert_length>3: - #Only pack the scrollbar if there are 3 or more messages - #The scrollbar must be at least 3 lines long, so this is the - #smallest possible size - scrollbar.pack(side=tk.RIGHT, fill=tk.Y) - alerts_list.config(yscrollcommand=scrollbar.set) - scrollbar.config(command=alerts_list.yview) - - #Start finding the correct picture to match the model - model=printer_model.cget('text').decode('utf-8') - printer_image=None - if model == 'MP C6004ex': - printer_image=parent.parent.c6004ex - elif model == 'MP C3504ex': - printer_image=parent.parent.c3504ex - elif model == 'MP C6503': - #The C6503 may or may not have an LCT + try: + printer_model=tk.Label(self, text=get(printer['IP'], 'public', + parent.parent.model_OID)) + printer_model.pack() + + url='http://' + printer['IP'] + '/web/guest/en/websys/webArch/mainFrame.cgi' + printer_IP=tk.Label(self, text=printer['IP'], fg="blue", + font=(None, 8, 'underline'), cursor="hand2") + balloon.bind(printer_IP, 'Go to printer control panel') + printer_IP.bind("", + lambda event,aurl=url:webbrowser.open(aurl)) + #Bind event property to label to create a hyperlink + printer_IP.pack() + + alert_frame=tk.Frame(self) + alert_frame.pack() + + scrollbar=tk.Scrollbar(alert_frame) + alerts_list=tk.Listbox(alert_frame, height=3, width=30, fg='red', + relief='flat', bg=default_bg, activestyle='none', + borderwidth=0, selectbackground=default_bg, + highlightthickness=0, selectforeground='red') + alerts_list.pack(side=tk.LEFT, pady=(5,0)) + alerts=walk(printer['IP'], 'public', parent.parent.error_base_OID) + alert_length=0 + #alerts is returned as an interator, so we define a counter to track + #its size + for item in alerts: + alerts_list.insert(tk.END, item[1].decode('utf-8')) + alert_length+=1 + if alert_length>3: + #Only pack the scrollbar if there are 3 or more messages + #The scrollbar must be at least 3 lines long, so this is the + #smallest possible size + scrollbar.pack(side=tk.RIGHT, fill=tk.Y) + alerts_list.config(yscrollcommand=scrollbar.set) + scrollbar.config(command=alerts_list.yview) + + #Start finding the correct picture to match the model + model=printer_model.cget('text').decode('utf-8') + printer_image=None + if model == 'MP C6004ex': + printer_image=parent.parent.c6004ex + elif model == 'MP C3504ex': + printer_image=parent.parent.c3504ex + elif model == 'MP C6503': + #The C6503 may or may not have an LCT + for item in walk(printer['IP'], + 'public', + parent.parent.tray_names_base_OID + ): + #Check if the tray names contain 'LCT' + if 'LCT' in item[1].decode('utf-8'): + printer_image=parent.parent.c6503f + break + if printer_image is None: + #If the image still has not been set, it must be non-LCT C6503 + printer_image=parent.parent.c6503 + + #Now that we know where the image should point to, create image object + printer_image_canvas=tk.Canvas(self, width=135, height=140) + printer_image_canvas.pack() + printer_image_canvas.create_image(135,140,image=printer_image, + anchor='se') + printer_image_canvas.image=printer_image + + #Start drawing ink bars + ink_frame=tk.Frame(self) + ink_frame.pack() + for i, item in enumerate(walk(printer['IP'], 'public', + parent.parent.ink_levels_base_OID)): + if i==1: + #Skip waste toner cartridge + continue + inner_ink_frame=tk.Frame(ink_frame) + inner_ink_frame.pack(pady=0) + ink_bar=ttk.Progressbar(inner_ink_frame, value=item[1], + style=parent.parent.styles[i]) + ink_level=tk.Label(inner_ink_frame, text=" "+str(item[1])+"%", + foreground='red' if item[1]<=20 else 'black', + bd=0) + ink_bar.pack(side=tk.LEFT, pady=0) + ink_level.pack(side=tk.RIGHT, pady=0) + + #Start grabbing tray info + tray_names=[] + tray_current_level=[] + tray_max_level=[] for item in walk(printer['IP'], 'public', parent.parent.tray_names_base_OID ): - #Check if the tray names contain 'LCT' - if 'LCT' in item[1].decode('utf-8'): - printer_image=parent.parent.c6503f - break - if printer_image is None: - #If the image still has not been set, it must be non-LCT C6503 - printer_image=parent.parent.c6503 - - #Now that we know where the image should point to, create image object - printer_image_canvas=tk.Canvas(self, width=135, height=140) - printer_image_canvas.pack() - printer_image_canvas.create_image(135,140,image=printer_image, - anchor='se') - printer_image_canvas.image=printer_image - - #Start drawing ink bars - ink_frame=tk.Frame(self) - ink_frame.pack() - for i, item in enumerate(walk(printer['IP'], 'public', - parent.parent.ink_levels_base_OID)): - if i==1: - #Skip waste toner cartridge - continue - inner_ink_frame=tk.Frame(ink_frame) - inner_ink_frame.pack(pady=0) - ink_bar=ttk.Progressbar(inner_ink_frame, value=item[1], - style=parent.parent.styles[i]) - ink_level=tk.Label(inner_ink_frame, text=" "+str(item[1])+"%", - foreground='red' if item[1]<=20 else 'black', - bd=0) - ink_bar.pack(side=tk.LEFT, pady=0) - ink_level.pack(side=tk.RIGHT, pady=0) - - #Start grabbing tray info - tray_names=[] - tray_current_level=[] - tray_max_level=[] - for item in walk(printer['IP'], - 'public', - parent.parent.tray_names_base_OID - ): - tray_names.append(item[1].decode('utf-8').replace('Paper','').replace('Tray 3 (LCT)','LCT')) - for item in walk(printer['IP'], - 'public', - parent.parent.tray_current_capacity_base_OID - ): - tray_current_level.append(item[1]) - for item in walk(printer['IP'], - 'public', - parent.parent.tray_max_capacity_base_OID - ): - tray_max_level.append(item[1]) - - tray_frame=tk.Frame(self) - tray_frame.pack(pady=(10,5)) - #Start counting info now, now that we can ignore the Bypass Tray - self.printer_deficit=0 - self.max_capacity=0 - for i, item in enumerate(tray_names): - if item=='Bypass Tray': - continue - self.max_capacity+=tray_max_level[i] - self.printer_deficit+=tray_max_level[i]-tray_current_level[i] - tray_line=tk.Frame(tray_frame, height=20, width=170) - #Set propogate to 0 so we can manually define frame size - tray_line.pack_propagate(0) - - tray_info=tk.Frame(tray_line, height=20, width=120) - tray_info.pack_propagate(0) - tray_info.pack(side=tk.RIGHT) - - tray_label=tk.Label(tray_line, text=item + ": ", - font=(None, 9, 'bold')) - tray_label.pack(side=tk.LEFT, anchor=tk.W) - percent=int((tray_current_level[i]/tray_max_level[i])*100) - tray_percent=tk.Label(tray_info, text=str(percent)+'%', - foreground='red' if percent<=50 else 'black', - anchor=tk.E, width=5) - tray_current_value=tk.Label(tray_info, - text='('+str(tray_current_level[i])) - tray_max_value=tk.Label(tray_info, text=str(tray_max_level[i])+')', - anchor=tk.E) - slash=tk.Label(tray_info, text='/', bd=0) - - tray_percent.pack(side=tk.LEFT) - tray_max_value.pack(side=tk.RIGHT) - slash.pack(side=tk.RIGHT) - tray_current_value.pack(side=tk.RIGHT) + tray_names.append(item[1].decode('utf-8').replace('Paper','').replace('Tray 3 (LCT)','LCT')) + for item in walk(printer['IP'], + 'public', + parent.parent.tray_current_capacity_base_OID + ): + tray_current_level.append(item[1]) + for item in walk(printer['IP'], + 'public', + parent.parent.tray_max_capacity_base_OID + ): + tray_max_level.append(item[1]) + + tray_frame=tk.Frame(self) + tray_frame.pack(pady=(10,5)) + #Start counting info now, now that we can ignore the Bypass Tray + self.printer_deficit=0 + self.max_capacity=0 + for i, item in enumerate(tray_names): + if item=='Bypass Tray': + continue + self.max_capacity+=tray_max_level[i] + self.printer_deficit+=tray_max_level[i]-tray_current_level[i] + tray_line=tk.Frame(tray_frame, height=20, width=170) + #Set propogate to 0 so we can manually define frame size + tray_line.pack_propagate(0) + + tray_info=tk.Frame(tray_line, height=20, width=120) + tray_info.pack_propagate(0) + tray_info.pack(side=tk.RIGHT) + + tray_label=tk.Label(tray_line, text=item + ": ", + font=(None, 9, 'bold')) + tray_label.pack(side=tk.LEFT, anchor=tk.W) + percent=int((tray_current_level[i]/tray_max_level[i])*100) + tray_percent=tk.Label(tray_info, text=str(percent)+'%', + foreground='red' if percent<=50 else 'black', + anchor=tk.E, width=5) + tray_current_value=tk.Label(tray_info, + text='('+str(tray_current_level[i])) + tray_max_value=tk.Label(tray_info, text=str(tray_max_level[i])+')', + anchor=tk.E) + slash=tk.Label(tray_info, text='/', bd=0) + + tray_percent.pack(side=tk.LEFT) + tray_max_value.pack(side=tk.RIGHT) + slash.pack(side=tk.RIGHT) + tray_current_value.pack(side=tk.RIGHT) + + tray_line.pack(anchor=tk.W, fill=tk.BOTH, expand=True) + + #Update the master record of loaded printer deficits/reams needed + parent.parent.deficit.set( + parent.parent.deficit.get()+self.printer_deficit + ) + parent.parent.reams.set(parent.parent.deficit.get()/500) + + #Start drawing the paper fill bar + self.paper_percentage=int( + ((self.max_capacity-self.printer_deficit)/self.max_capacity)*100 + ) + bar_width=165 + paper_level_canvas=tk.Canvas(self, width=bar_width, height=20) + paper_level_canvas.pack(side=tk.BOTTOM) + paper_level_canvas.create_rectangle(2, 2, bar_width-1, 14, + fill="gainsboro", outline="#757575") + tray_fill_bar_width=int((self.paper_percentage*bar_width)/100)-1 + #Subtract 1 to avoid edge-to-edge overlap + paper_level_canvas.create_rectangle(3, 3, tray_fill_bar_width, 14, + fill='darkgray', + width=0 + ) + paper_level_canvas.create_text(80,8, font=(None, 8), + text='Paper fill: ' + + str(self.paper_percentage)+'%' + ) + balloon.bind(paper_level_canvas, '-' + str(self.printer_deficit) + + ' pages' + ' | -' + + str(self.printer_deficit/500) + ' reams') - tray_line.pack(anchor=tk.W, fill=tk.BOTH, expand=True) - - #Update the master record of loaded printer deficits/reams needed - parent.parent.deficit.set( - parent.parent.deficit.get()+self.printer_deficit - ) - parent.parent.reams.set(parent.parent.deficit.get()/500) - - #Start drawing the paper fill bar - self.paper_percentage=int( - ((self.max_capacity-self.printer_deficit)/self.max_capacity)*100 - ) - bar_width=165 - paper_level_canvas=tk.Canvas(self, width=bar_width, height=20) - paper_level_canvas.pack(side=tk.BOTTOM) - paper_level_canvas.create_rectangle(2, 2, bar_width-1, 14, - fill="gainsboro", outline="#757575") - tray_fill_bar_width=int((self.paper_percentage*bar_width)/100)-1 - #Subtract 1 to avoid edge-to-edge overlap - paper_level_canvas.create_rectangle(3, 3, tray_fill_bar_width, 14, - fill='darkgray', - width=0 - ) - paper_level_canvas.create_text(80,8, font=(None, 8), - text='Paper fill: ' + - str(self.paper_percentage)+'%' - ) - balloon.bind(paper_level_canvas, '-' + str(self.printer_deficit) - + ' pages' + ' | -' + - str(self.printer_deficit/500) + ' reams') + except Exception as err: + #Display error image + no_connection_canvas=tk.Canvas(self, width=155, height=150) + no_connection_canvas.pack(pady=(100,0)) + no_connection_canvas.create_image(155, 150, + image=parent.parent.no_connection, + anchor=tk.SE) + no_connection_canvas.image=parent.parent.no_connection + no_connection_label=tk.Label(self, text="No connection!\n" + "Check the log file for more info", + foreground='red') + no_connection_label.pack() + + #log error and stack trace to logfile + log=open('RRM_log_' + parent.parent.current_time + '.txt','a') + log.write('(' + datetime.datetime.now().strftime('%H:%M') + ') ' + + printer['Name'] + ': ' + str(err) + '\n' + + traceback.format_exc() + '\n') + def deficit(self): #Return the printer's paper deficit to subtract when despawning frame return self.printer_deficit