diff --git a/.gitignore b/.gitignore index 34540df..15ee6ec 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ servers.conf recordings/* sounds/* *.sqlite3 +*.shelve diff --git a/frn/clienttracker.py b/frn/clienttracker.py index d348156..5bbfa5e 100644 --- a/frn/clienttracker.py +++ b/frn/clienttracker.py @@ -3,12 +3,13 @@ # Copyright 2010 Maurizio Porrato # See LICENSE.txt for copyright info +import shelve from twisted.python import log class ClientTracker(object): - def __init__(self, cbClient, cbNet, cbMute, cbBlock, cbAdmin): + def __init__(self, filename, cbClient, cbNet, cbMute, cbBlock, cbAdmin): self._clientData = {} self._net = {} self._mute = {} @@ -19,6 +20,24 @@ class ClientTracker(object): self.cbMute = cbMute self.cbBlock = cbBlock self.cbAdmin = cbAdmin + self.filename = filename + self.load() + + def load(self, filename=None): + s = shelve.open(filename or self.filename) + try: + self._mute = s['mute'] + self._block = s['block'] + self._admin = s['admin'] + except KeyError: pass + s.close() + + def save(self, filename=None): + s = shelve.open(filename or self.filename) + s['mute'] = self._mute + s['block'] = self._block + s['admin'] = self._admin + s.close() def getClient(self, clientId): return self._clientData[clientId].user @@ -76,7 +95,7 @@ class ClientTracker(object): if clientId in self._mute: client.user.M = 1 a = self._mute[clientId].AI - self._mute[clientId].update(client.user.dict()) + self._mute[clientId].update(**client.user.dict()) self._mute[clientId].AI = a else: client.user.M = 0 @@ -85,6 +104,7 @@ class ClientTracker(object): if client.user.EA in self._admin: client.role = "ADMIN" self._admin[client.user.EA].update(client.user.dict()) + self.save() if len(nc) == 1: self.cbNet(self.getNetworkList()) self.cbClient(net, self.getClientList(net)) @@ -101,6 +121,7 @@ class ClientTracker(object): if not self._net[net]: del self._net[net] self.cbNet(self.getNetworkList()) + self.save() self.cbClient(net, self.getClientList(net)) def setStatus(self, clientId, status): @@ -114,6 +135,7 @@ class ClientTracker(object): if clientId not in self._mute: self._mute[clientId] = self.getClient(clientId).copy(AI=admin.ON) self._clientData[clientId].user.M = 1 + self.save() net = self.getClient(clientId).NT self.cbClient(net, self.getClientList(net)) self.cbMute(self.getMuteList()) @@ -125,6 +147,7 @@ class ClientTracker(object): self._clientData[clientId].user.M = 0 net = self._clientData[clientId].user.NT self.cbClient(net, self.getClientList(net)) + self.save() self.cbMute(self.getMuteList()) def block(self, admin, clientId): @@ -132,21 +155,25 @@ class ClientTracker(object): self._block[clientId] = self.getClient(clientId).copy(AI=admin.ON) if clientId in self._clientData: net = self._clientData[clientId].user.NT + self.save() self.cbBlock(self.getBlockList()) def unBlock(self, clientId): if clientId in self._block: del self._block[clientId] + self.save() self.cbBlock(self.getBlockList()) def admin(self, clientId): if clientId not in self._admin: self._admin[clientId] = self.getClient(clientId).copy() + self.save() self.cbAdmin(self.getAdminList()) def unAdmin(self, clientId): if clientId in self._admin: del self._admin[clientId] + self.save() self.cbAdmin(self.getAdminList()) diff --git a/frn/manager/remote.py b/frn/manager/remote.py index 5e28eb9..8d6d5b5 100644 --- a/frn/manager/remote.py +++ b/frn/manager/remote.py @@ -12,45 +12,28 @@ from frn.protocol.manager import FRNManagerClient, FRNManagerClientFactory class CustomManagerClientFactory(FRNManagerClientFactory): - def __init__(self, user, onConnect, onDisconnect): + def __init__(self, user): self.user = user - self.onConnect = onConnect - self.onDisconnect = onDisconnect self.authResult = False self.client = None - self.managerReady = Deferred() - self.client = None + self.authDone = False + self.deferred = Deferred() - def clientConnectionFailed(self, connector, reason): - self.authResult = False - self.client = None - self.managerReady = Deferred() - self.onDisconnect(self.protocol) - FRNManagerClientFactory.clientConnectionFailed( - self, connector, reason) - self.managerConnection.addCallback(self.connectionReady) + def managerConnected(self, connection): + def authReply(auth): + self.authResult = auth + self.authDone = (auth['al'] == '0') + if self.authDone: + self.deferred.callback(auth) + connection.sendServerLogin(self.user).addCallback(authReply) - def clientConnectionLost(self, connector, reason): - self.authResult = False - self.client = None - self.managerReady = Deferred() - self.onDisconnect(self.protocol) - FRNManagerClientFactory.clientConnectionLost( - self, connector, reason) - self.managerConnection.addCallback(self.connectionReady) + def managerDisconnected(self, connection): + pass - def connectionReady(self, client): - def authDone(res): - log.msg("Auth: %s" % str(res)) - if res['al'] == '0': - self.authResult = res - self.onConnect(client) - self.managerReady.callback(res) - else: - client.transport.loseConnection() - return res - self.client = client - self.client.sendServerLogin(self.user).addCallback(authDone) + def buildProtocol(self, addr): + p = FRNManagerClientFactory.buildProtocol(self, addr) + self.client = p + return p class RemoteManager(object): @@ -63,21 +46,13 @@ class RemoteManager(object): self.port = port self.factory = None - def onManagerConnect(self, protocol): - pass - - def onManagerDisconnect(self, protocol): - pass - def doConnect(self): self.reactor.connectTCP(self.server, self.port, self.factory) - self.factory.managerConnection.addCallback(self.factory.connectionReady) - return self.factory.managerReady def serverLogin(self, user): - self.factory = CustomManagerClientFactory( - user, self.onManagerConnect, self.onManagerDisconnect) - return self.doConnect() + self.factory = CustomManagerClientFactory(user) + self.doConnect() + return self.factory.deferred def serverLogout(self, user): if self.factory.client is not None: diff --git a/frn/protocol/manager.py b/frn/protocol/manager.py index 8fca71a..5986b82 100644 --- a/frn/protocol/manager.py +++ b/frn/protocol/manager.py @@ -20,9 +20,7 @@ class FRNManagerClient(LineOnlyReceiver): def connectionMade(self): log.msg("Connected to manager [%s]" % self.transport.getPeer().host) self.notifications = [] - if not self.factory.managerConnection.called: # FIXME: Why??? - log.msg("Firing manager connection callback!") - self.factory.managerConnection.callback(self) + self.factory.managerConnected(self) def connectionLost(self, reason): log.msg("Manager disconnected") @@ -31,7 +29,7 @@ class FRNManagerClient(LineOnlyReceiver): except: pass for d in self.notifications: d.errback(reason) - self.factory.managerConnection = Deferred() + self.factory.managerDisconnected(self) def notifyFinish(self): self.notifications.append(Deferred()) @@ -102,8 +100,11 @@ class FRNManagerClientFactory(ReconnectingClientFactory): protocol = FRNManagerClient - def startFactory(self): - self.managerConnection = Deferred() + def managerConnected(self, connection): + pass + + def managerDisconnected(self, connection): + pass class FRNManagerServer(LineOnlyReceiver): diff --git a/frn/protocol/server.py b/frn/protocol/server.py index d10f2ed..7993619 100644 --- a/frn/protocol/server.py +++ b/frn/protocol/server.py @@ -110,9 +110,9 @@ class FRNServer(BufferingLineReceiver, TimeoutMixin): def authReturned(result): self.role, clientId = result log.msg("AUTH result: %s %s" % (self.role, clientId)) + self.user = FRNUser(**body) + self.user.ID = clientId if self.role == 'OK': - self.user = FRNUser(**body) - self.user.ID = clientId if self.user.EA == self.factory.serverAuth.OW: self.role = 'OWNER' elif self.factory.tracker.isAdmin(self.user.EA): @@ -272,12 +272,13 @@ class FRNServerFactory(ServerFactory): protocol = FRNServer - def __init__(self, manager, serverAuth): + def __init__(self, trackerfile, manager, serverAuth): self.manager = manager self.serverAuth = serverAuth self.talking = None self.officialNets = [] self.tracker = ClientTracker( + trackerfile, self.sendClientList, self.sendNetworkList, self.sendMuteList, self.sendBlockList, self.sendAdminList) diff --git a/server.py b/server.py index 7f815be..6c7c248 100755 --- a/server.py +++ b/server.py @@ -43,6 +43,7 @@ if __name__ == '__main__': password = acfg.get(account_name, 'password') reactor.listenTCP(10024, FRNServerFactory( + pjoin(basedir, 'tracker.shelve'), # DatabaseUserStore( # ConnectionPool("sqlite3", "frn_users.sqlite3", # check_same_thread=False)),