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()