#############################################################################
#
#	Pyro Naming Service Control Tool with GUI (Xnsc)
#
#	This is part of "Pyro" - Python Remote Objects
#	which is (c)1999 Irmen de Jong - irmen@bigfoot.com.
#
#############################################################################

from Tkinter import *
from Pyro.naming import NameServerLocator, NamingError
import Pyro.core
import sys,string

class xnscFrame:

	def quit(self):
		self.master.quit()

	def outputln(self,txt):
		self.text_out.insert(AtEnd(),txt+'\n')
		self.text_out.yview(AtEnd())

	def b_findNS(self,event=None):
		hst,prt = None,Pyro.config.PYRO_NS_BC_PORT
		if event and event.char=='\r':
			# Pressed <return> in entry box
			addr = string.split(self.entry_NSloc.get(),':')
			hst=addr[0]
			if len(addr)>1:
				prt=int(addr[1])
		# We need to keep the host/port for the shutdown button...
		self.NShost = hst
		self.NSport = prt
		self.outputln('*** finding NS')
		locator=NameServerLocator()
		try:	
			self.NS=locator.getNS(hst,prt)
			self.entry_NSloc.delete(0,AtEnd())
			self.entry_NSloc.insert(AtEnd(),self.NS.URI.host+':'+str(self.NS.URI.port))

			self.enable_buttons()
			self.outputln('   found, URI='+str(self.NS.URI))
		except:
			self.disable_buttons()
			self.outputln('   not found:');
			a,b,c = sys.exc_info()
			self.outputln('  '+str(a)+' : '+str(b))
	
	def b_list(self,event=None):
		self.outputln('*** list NS database:')
		dict = self.NS.status()
		keys = dict.keys()
		keys.sort()
		for i in keys:
			self.outputln('  '+i+' --> '+str(dict[i]))
		self.outputln('-----------------------')
	
	def b_register(self,event=None):
		self.outputln('*** registering with NS:')
		name = self.entry_arg1.get()
		try:
			uri=Pyro.core.PyroURI(self.entry_arg2.get())
			try:
				self.NS.register(name,uri)
				self.outputln('  '+name+'  -->  '+str(uri))
			except NamingError,arg:
				self.outputln('  Error from NS: '+str(arg))
		except Pyro.core.URIError:
			self.outputln('   Malformed URI: '+self.entry_arg2.get())

	def b_resolve(self,event=None):
		self.outputln('*** resolving:')
		name=self.entry_arg1.get()
		try:
			uri=self.NS.resolve(name)
			self.outputln('  '+name+'  -->  '+str(uri))
		except NamingError:
			self.outputln('  '+name+'  -->  ## not found ##')
	
	def b_remove(self,event=None):
		name=self.entry_arg1.get()
		self.outputln('*** remove: '+name)
		self.NS.unregister(name)
	
	def b_ping(self,event=None):
		try:
			self.NS.ping()
			self.outputln('*** ping NS: up and running!')
		except: 
			a,b,c = sys.exc_info()
			self.outputln('*** ping NS: exception occured:')
			self.outputln('  '+str(a)+' : '+str(b))
	
	def b_shutdown(self,event=None):
		locator = NameServerLocator()
		try:
			result = locator.sendSysCommand('shutdown',self.NShost,self.NSport,0)
			self.outputln('*** The NS replied to the shutdown message: '+str(result))
		except:
			self.disable_buttons()
			self.outputln('   not found:');
			a,b,c = sys.exc_info()
			self.outputln('  '+str(a)+' : '+str(b))
			
	def enable_buttons(self):
		self.but_ping['state']=NORMAL
		self.but_list['state']=NORMAL
		self.but_resolve['state']=NORMAL
		self.but_register['state']=NORMAL
		self.but_remove['state']=NORMAL
		self.but_shutdown['state']=NORMAL

	def disable_buttons(self):
		self.but_ping['state']=DISABLED
		self.but_list['state']=DISABLED
		self.but_resolve['state']=DISABLED
		self.but_register['state']=DISABLED
		self.but_remove['state']=DISABLED
		self.but_shutdown['state']=DISABLED

	def createWidgets(self):
		frame_NSloc=Frame(self.master,borderwidth=2,relief=GROOVE)
		self.entry_NSloc=Entry(frame_NSloc)
		self.entry_NSloc.bind('<Return>',self.b_findNS)
		self.but_findNS=Button(frame_NSloc,text='Auto Discover NS',command=self.b_findNS)
		Label(frame_NSloc,text='Naming Service Location (host:port)').pack(anchor=W)
		self.entry_NSloc.pack(expand=1,fill=X,side=LEFT)
		self.but_findNS.pack()
	
		frame_cmds=Frame(self.master)
		self.but_ping=Button(frame_cmds,text='Ping',state=DISABLED,command=self.b_ping)
		self.but_list=Button(frame_cmds,text='List',state=DISABLED,command=self.b_list)
		self.but_register=Button(frame_cmds,text='Register',state=DISABLED,command=self.b_register)
		self.but_resolve=Button(frame_cmds,text='Resolve',state=DISABLED,command=self.b_resolve)
		self.but_remove=Button(frame_cmds,text='Remove',state=DISABLED,command=self.b_remove)
		self.but_shutdown=Button(frame_cmds,text='Shutdown',state=DISABLED,command=self.b_shutdown)
		Label(frame_cmds,text='NS commands:').pack(side=LEFT)
		self.but_ping.pack(side=LEFT)
		self.but_list.pack(side=LEFT)
		self.but_register.pack(side=LEFT)
		self.but_resolve.pack(side=LEFT)
		self.but_remove.pack(side=LEFT)
		self.but_shutdown.pack(side=LEFT)

		frame_args=Frame(self.master,borderwidth=2)
		self.entry_arg1=Entry(frame_args)
		self.entry_arg2=Entry(frame_args)
		Label(frame_args,text='Command arguments').pack(side=LEFT)
		self.entry_arg1.pack(expand=1,fill=X)
		self.entry_arg2.pack(expand=1,fill=X)
		
		ys=Scrollbar(self.master,orient=VERTICAL)
		self.text_out=Text(self.master,yscrollcommand=ys.set)
		ys['command']=self.text_out.yview
		self.QUIT=Button(self.master,text='QUIT',command=self.quit)

		# pack root children:
		frame_NSloc.pack(anchor=N,expand=1,fill=X)
		frame_cmds.pack(expand=1,fill=X)
		frame_args.pack(expand=1,fill=X)
		ys.pack(side=LEFT,fill=Y)
		self.text_out.pack()
		self.QUIT.pack()

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

def main():
	root=Tk()
	root.title('xnsc - Python NamingService control tool')
	app=xnscFrame(root)
	root.protocol('WM_DELETE_WINDOW',root.quit)
	root.mainloop()
