import ConfigParser import gtk import urllib import xmlrpclib import socket from pyscrabble import constants from pyscrabble import gtkconstants from pyscrabble import gtkutil from pyscrabble import serialize from pyscrabble import util from pyscrabble import lookup from twisted.internet import reactor class RegisterWindow(gtk.Window): ''' Window for Viewing the Public Server listing ''' def __init__(self, lw): ''' Constructor @param lw: Login Window instance ''' gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL) self.connect("destroy", self.onDestroy ) self.connect("delete_event", self.onDelete_event ) self.set_size_request( constants.REGISTER_WINDOW_HEIGHT, constants.REGISTER_WINDOW_WIDTH ) self.set_resizable( False ) self.set_border_width( 10 ) self.set_title(_('Find a Server')) self.loginWindow = lw box = gtk.VBox(False) s = _("Server Listing") label = gtk.Label() label.set_markup("%s" % s) label.set_justify(gtk.JUSTIFY_CENTER) box.pack_start(label) box.pack_start(self.getView()) box.pack_start(self.getButtons()) self.add(box) self.show_all() reactor.callLater(0.5, self.loadServers) def loadServers(self): ''' Load servers ''' self.servers = self.readServers() if not self.servers: self.destroy() return self.serverList.clear() for host,g_port,w_port,location in self.servers: try: loc = 'http://%s:%s/xmlrpc' % (host,w_port) s = xmlrpclib.Server(loc) numUsers = s.getNumUsers() except: numUsers="N/A" self.serverList.append( (host,location, numUsers) ) self.buttonbox.foreach(lambda b: b.set_sensitive(True)) def onDelete_event(self, widget, event, data=None): ''' Callback when the widget is deleted @param widget: @param event: @param data: ''' self.destroy() def onDestroy(self, widget, data=None): ''' Callback when the widget is destroyed @param widget: @param data: ''' pass def readServers(self): ''' Read the server config file @return: Server config parser ''' try: file, headers = urllib.urlretrieve(constants.SERVER_LISTING_LOCATION) except: self.error(util.ErrorMessage(_("Could not read server listing. Please try another time."))) return None parser = ConfigParser.ConfigParser() parser.read(file) servers = [] for server in parser.sections(): servers.append( (server, parser.get(server, "g_port"), parser.get(server, "w_port"), parser.get(server, "location")) ) servers.extend( util.getAdditionalHosts() ) return servers def getView(self): ''' Show treeview of servers @return gtk.ScrolledWindow ''' self.serverList = gtk.ListStore(str, str, str) self.serverView = gtk.TreeView( self.serverList ) col1 = gtk.TreeViewColumn(_('Name')) cell1 = gtk.CellRendererText() col1.pack_start(cell1, True) col1.add_attribute(cell1, 'text', 0) col2 = gtk.TreeViewColumn(_('Location')) cell2 = gtk.CellRendererText() col2.pack_start(cell2, True) col2.add_attribute(cell2, 'text', 1) col3 = gtk.TreeViewColumn(_('Registered Users')) cell3 = gtk.CellRendererText() col3.pack_start(cell3, True) col3.add_attribute(cell3, 'text', 2) self.serverView.append_column( col1 ) self.serverView.append_column( col2 ) self.serverView.append_column( col3 ) self.serverList.append( (_('Loading...'), '', '') ) win = gtk.ScrolledWindow() win.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) win.add(self.serverView) return win def getButtons(self): ''' Get buttons @return: gtk.ButtonBox ''' self.buttonbox = gtk.VButtonBox() button = gtk.Button(_("Register")) button.connect("clicked", self.showCreateUserDialog_cb) button.set_sensitive(False) self.buttonbox.add(button) button = gtk.Button( _('Add to Hostname dropdown') ) button.connect("clicked", self.addServerToHost) button.set_sensitive(False) self.buttonbox.add(button) button = gtk.Button(_("Close")) button.connect("clicked", self.closeWindow_cb) button.set_sensitive(False) self.buttonbox.add(button) vbox = gtk.VBox(False, 0) vbox.pack_start(self.buttonbox, False, False, 0) return vbox def closeWindow_cb(self, widget): ''' Close the window @param widget: Widget that was clicked to activate this callback ''' self.destroy() def showCreateUserDialog_cb(self, button = None): ''' Show dialog to create new user @param button: Widget that was clicked to activate this handler. ''' s = _("Register New User") dialog = gtk.Dialog(title=s, flags=gtk.DIALOG_MODAL) dialog.vbox.set_border_width( 5 ) header = gtk.Label() header.set_markup("%s:" % s) dialog.vbox.pack_start(header) s = _("Username") username = gtkutil.EntryWithLabel( label="%s:" % s) dialog.vbox.pack_start( username ) s = _("Password") password1 = gtkutil.EntryWithLabel(label="%s: " %s, visibility=False) dialog.vbox.pack_start( password1 ) s = _("Confirm Password") password2 = gtkutil.EntryWithLabel(label="%s: " %s, visibility=False) dialog.vbox.pack_start( password2 ) okbutton = gtk.Button(_("Create")) cancelbutton = gtk.Button(_("Cancel")) dialog.action_area.pack_start(okbutton) dialog.action_area.pack_start(cancelbutton) okbutton.connect("clicked", self.createNewUser_cb, username, password1, password2, dialog) cancelbutton.connect("clicked", lambda b: dialog.destroy() ) dialog.show_all() def createNewUser_cb(self, widget, username, password1, password2, dialog): ''' @param widget: @param username: @param password1: @param password2: @param dialog: ''' uname = username.get_text() pw1 = password1.get_text() pw2 = password2.get_text() if len(uname) == 0: self.error(util.ErrorMessage(_("You must enter a username")),dialog) return if len(pw1) == 0: self.error(util.ErrorMessage(_("You must enter a password")),dialog) return if pw1 != pw2: self.error(util.ErrorMessage(_("Passwords do not match")),dialog) return server = gtkutil.getSelectedItem(self.serverView, 0) if server is None: server = self.servers[0][0] for h,g,w,l in self.servers: if h == server: g_port = g w_port = w try: loc = 'http://%s:%s/xmlrpc' % (server,w_port) s = xmlrpclib.ServerProxy(loc) val,msg = s.createNewUser(uname, util.hashPassword(pw1)) except socket.error: self.error(util.ErrorMessage(_('Could not connect to server')),dialog) return if not val: self.error(util.ErrorMessage(lookup.SERVER_MESSAGE_LOOKUP[msg]),dialog) return dialog.destroy() g_loc = '%s:%s' % (server,g_port) self.loginWindow.populateFields_cb(uname, pw1, g_loc) self.destroy() def addServerToHost(self, widget): ''' Add the selectedserver to the host @param widget: ''' server = gtkutil.getSelectedItem(self.serverView, 0) if server is None: server = self.servers.sections[0][0] for h,g,w,l in self.servers: if h == server: g_port = g self.loginWindow.populateFields_cb(None,None,'%s:%s' % (server,g_port) ) self.destroy() def error(self, data, parent=None): ''' Show error dialog. @param data: ErrorMessage data @see: L{util.ErrorMessage} ''' s = _("Error") if not parent: parent = self self.dialog = gtk.MessageDialog(parent=parent, type=gtk.MESSAGE_ERROR, buttons=gtk.BUTTONS_OK, message_format="") self.dialog.set_markup("%s: %s" % (s, data.getErrorMessage())) self.dialog.connect("response", lambda w,e: self.dialog.destroy()) self.dialog.show() self.dialog.run()