Fix regressions introduced by new simple XML parser.
This commit is contained in:
parent
214cb07962
commit
17eb5f0ca3
|
@ -129,13 +129,16 @@ class DatabaseManager(object):
|
||||||
('ID', 'EA', 'PW', 'ON', 'BC', 'NN', 'CT', 'NT', 'DS', 'IP', 'registration', 'lastlogin', 'server', 'port'),
|
('ID', 'EA', 'PW', 'ON', 'BC', 'NN', 'CT', 'NT', 'DS', 'IP', 'registration', 'lastlogin', 'server', 'port'),
|
||||||
data[0]))
|
data[0]))
|
||||||
log.msg("Mailing password to user %s" % str(u))
|
log.msg("Mailing password to user %s" % str(u))
|
||||||
with open('mailtemplate.txt','r') as tplfile:
|
tplfile = open('mailtemplate.txt','r')
|
||||||
|
try:
|
||||||
tpl = tplfile.read()
|
tpl = tplfile.read()
|
||||||
mailbody = string.Template(tpl).safe_substitute(u)
|
mailbody = string.Template(tpl).safe_substitute(u)
|
||||||
sendmail('127.0.0.1',
|
sendmail('127.0.0.1',
|
||||||
'admin@gnuradionetwork.org',
|
'admin@gnuradionetwork.org',
|
||||||
[u['EA']],
|
[u['EA']],
|
||||||
mailbody, port=2525)
|
mailbody, port=25)
|
||||||
|
finally:
|
||||||
|
tplfile.close()
|
||||||
return "OK"
|
return "OK"
|
||||||
return self._pool.runQuery(
|
return self._pool.runQuery(
|
||||||
"SELECT * FROM frn_users WHERE _ea=?", (user.EA,)
|
"SELECT * FROM frn_users WHERE _ea=?", (user.EA,)
|
||||||
|
|
|
@ -23,7 +23,7 @@ class CustomManagerClientFactory(FRNManagerClientFactory):
|
||||||
def authReply(auth):
|
def authReply(auth):
|
||||||
self.resetDelay()
|
self.resetDelay()
|
||||||
self.authResult = auth
|
self.authResult = auth
|
||||||
self.authDone = (auth['al'] == '0')
|
self.authDone = (auth['AL'] == '0')
|
||||||
if self.authDone:
|
if self.authDone:
|
||||||
self.deferred.callback(auth)
|
self.deferred.callback(auth)
|
||||||
connection.sendServerLogin(self.user).addCallback(authReply)
|
connection.sendServerLogin(self.user).addCallback(authReply)
|
||||||
|
|
|
@ -1,311 +1,311 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010 Maurizio Porrato <maurizio.porrato@gmail.com>
|
# Copyright 2010 Maurizio Porrato <maurizio.porrato@gmail.com>
|
||||||
# See LICENSE.txt for copyright info
|
# See LICENSE.txt for copyright info
|
||||||
|
|
||||||
from Queue import Queue
|
from Queue import Queue
|
||||||
from twisted.internet.protocol import ReconnectingClientFactory
|
from twisted.internet.protocol import ReconnectingClientFactory
|
||||||
from twisted.protocols.policies import TimeoutMixin
|
from twisted.protocols.policies import TimeoutMixin
|
||||||
from twisted.internet.task import LoopingCall
|
from twisted.internet.task import LoopingCall
|
||||||
from twisted.python import log
|
from twisted.python import log
|
||||||
from frn.protocol import versions
|
from frn.protocol import versions
|
||||||
from frn.user import FRNUser
|
from frn.user import FRNUser
|
||||||
from frn.protocol.common import BufferingLineReceiver
|
from frn.protocol.common import BufferingLineReceiver
|
||||||
from frn.utility import *
|
from frn.utility import *
|
||||||
|
|
||||||
|
|
||||||
class FRNClient(BufferingLineReceiver, TimeoutMixin):
|
class FRNClient(BufferingLineReceiver, TimeoutMixin):
|
||||||
|
|
||||||
def connectionMade(self):
|
def connectionMade(self):
|
||||||
BufferingLineReceiver.connectionMade(self)
|
BufferingLineReceiver.connectionMade(self)
|
||||||
self.user.VX = versions.client
|
self.user.VX = versions.client
|
||||||
self.serverdata = {}
|
self.serverdata = {}
|
||||||
self.txq = Queue()
|
self.txq = Queue()
|
||||||
self.setTimeout(25.0)
|
self.setTimeout(25.0)
|
||||||
self.login()
|
self.login()
|
||||||
|
|
||||||
def connectionLost(self, reason):
|
def connectionLost(self, reason):
|
||||||
self.serverdata = {}
|
self.serverdata = {}
|
||||||
BufferingLineReceiver.connectionLost(self, reason)
|
BufferingLineReceiver.connectionLost(self, reason)
|
||||||
|
|
||||||
def ready(self):
|
def ready(self):
|
||||||
self.status = 'READY'
|
self.status = 'READY'
|
||||||
self.msgbuffer = []
|
self.msgbuffer = []
|
||||||
self.phase = 0
|
self.phase = 0
|
||||||
self.expectRawData(1)
|
self.expectRawData(1)
|
||||||
|
|
||||||
def startMultiLineMessage(self, msgtype):
|
def startMultiLineMessage(self, msgtype):
|
||||||
self.status = msgtype
|
self.status = msgtype
|
||||||
self.phase = None
|
self.phase = None
|
||||||
self.setLineMode()
|
self.setLineMode()
|
||||||
|
|
||||||
def stopMultiLineMessage(self):
|
def stopMultiLineMessage(self):
|
||||||
handler = getattr(self, 'decode'+self.status, None)
|
handler = getattr(self, 'decode'+self.status, None)
|
||||||
status = self.status
|
status = self.status
|
||||||
message = self.msgbuffer
|
message = self.msgbuffer
|
||||||
self.ready()
|
self.ready()
|
||||||
if handler is not None:
|
if handler is not None:
|
||||||
handler(message)
|
handler(message)
|
||||||
else:
|
else:
|
||||||
self.unimplemented(status, message)
|
self.unimplemented(status, message)
|
||||||
|
|
||||||
def collectMultiLineMessage(self, line):
|
def collectMultiLineMessage(self, line):
|
||||||
if self.phase is None:
|
if self.phase is None:
|
||||||
self.expected_lines = int(line.strip())
|
self.expected_lines = int(line.strip())
|
||||||
self.msgbuffer = []
|
self.msgbuffer = []
|
||||||
self.phase = 0
|
self.phase = 0
|
||||||
else:
|
else:
|
||||||
self.msgbuffer.append(line)
|
self.msgbuffer.append(line)
|
||||||
self.phase += 1
|
self.phase += 1
|
||||||
if self.phase >= self.expected_lines:
|
if self.phase >= self.expected_lines:
|
||||||
self.stopMultiLineMessage()
|
self.stopMultiLineMessage()
|
||||||
|
|
||||||
def lineReceived(self, line):
|
def lineReceived(self, line):
|
||||||
if self.status == 'AUTH':
|
if self.status == 'AUTH':
|
||||||
if self.phase == 0:
|
if self.phase == 0:
|
||||||
self.latest_client_version = int(line.strip())
|
self.latest_client_version = int(line.strip())
|
||||||
self.phase = 1
|
self.phase = 1
|
||||||
else:
|
else:
|
||||||
self.serverdata = parseSimpleXML(line.strip())
|
self.serverdata = parseSimpleXML(line.strip())
|
||||||
if int(self.serverdata['sv']) > 2009004:
|
if int(self.serverdata['SV']) > 2009004:
|
||||||
self.sendLine(responseToChallange(
|
self.sendLine(responseToChallange(
|
||||||
self.serverdata['kp']))
|
self.serverdata['KP']))
|
||||||
self.ready()
|
self.ready()
|
||||||
self.setTimeout(10.0)
|
self.setTimeout(10.0)
|
||||||
self.factory.resetDelay()
|
self.factory.resetDelay()
|
||||||
self.loginResponse(self.serverdata)
|
self.loginResponse(self.serverdata)
|
||||||
else:
|
else:
|
||||||
self.collectMultiLineMessage(line)
|
self.collectMultiLineMessage(line)
|
||||||
|
|
||||||
def expectedReceived(self, data):
|
def expectedReceived(self, data):
|
||||||
self.resetTimeout()
|
self.resetTimeout()
|
||||||
if self.status == 'READY':
|
if self.status == 'READY':
|
||||||
packet_type = ord(data[0])
|
packet_type = ord(data[0])
|
||||||
if packet_type == 0: # Keepalive
|
if packet_type == 0: # Keepalive
|
||||||
self.ready()
|
self.ready()
|
||||||
self.pong()
|
self.pong()
|
||||||
elif packet_type == 1: # TX ack
|
elif packet_type == 1: # TX ack
|
||||||
self.status = 'TX'
|
self.status = 'TX'
|
||||||
self.expectRawData(2)
|
self.expectRawData(2)
|
||||||
elif packet_type == 2: # Audio
|
elif packet_type == 2: # Audio
|
||||||
self.status = 'AUDIO'
|
self.status = 'AUDIO'
|
||||||
self.expectRawData(327) # Two ID bytes + 10 GSM frames
|
self.expectRawData(327) # Two ID bytes + 10 GSM frames
|
||||||
elif packet_type == 3: # Client list
|
elif packet_type == 3: # Client list
|
||||||
self.status = 'CLIENTS'
|
self.status = 'CLIENTS'
|
||||||
self.expectRawData(2) # Discard two null bytes
|
self.expectRawData(2) # Discard two null bytes
|
||||||
elif packet_type == 4: # Text
|
elif packet_type == 4: # Text
|
||||||
self.startMultiLineMessage('TEXT')
|
self.startMultiLineMessage('TEXT')
|
||||||
elif packet_type == 5: # Channel list
|
elif packet_type == 5: # Channel list
|
||||||
self.startMultiLineMessage('NETWORKS')
|
self.startMultiLineMessage('NETWORKS')
|
||||||
elif packet_type == 6: # Admin list
|
elif packet_type == 6: # Admin list
|
||||||
self.startMultiLineMessage('ADMIN')
|
self.startMultiLineMessage('ADMIN')
|
||||||
elif packet_type == 7: # Access list
|
elif packet_type == 7: # Access list
|
||||||
self.startMultiLineMessage('ACCESS')
|
self.startMultiLineMessage('ACCESS')
|
||||||
elif packet_type == 8: # Block list
|
elif packet_type == 8: # Block list
|
||||||
self.startMultiLineMessage('BLOCK')
|
self.startMultiLineMessage('BLOCK')
|
||||||
elif packet_type == 9: # Mute list
|
elif packet_type == 9: # Mute list
|
||||||
self.startMultiLineMessage('MUTE')
|
self.startMultiLineMessage('MUTE')
|
||||||
elif packet_type == 10: # Access list flags
|
elif packet_type == 10: # Access list flags
|
||||||
self.startMultiLineMessage('ACCESSFLAGS')
|
self.startMultiLineMessage('ACCESSFLAGS')
|
||||||
else:
|
else:
|
||||||
log.err("Unknown packet type %d" % packet_type)
|
log.err("Unknown packet type %d" % packet_type)
|
||||||
elif self.status == 'CLIENTS':
|
elif self.status == 'CLIENTS':
|
||||||
self.startMultiLineMessage('CLIENTS')
|
self.startMultiLineMessage('CLIENTS')
|
||||||
elif self.status == 'AUDIO':
|
elif self.status == 'AUDIO':
|
||||||
self.ready()
|
self.ready()
|
||||||
self.decodeAUDIO(ord(data[0])*256+ord(data[1]), data[2:])
|
self.decodeAUDIO(ord(data[0])*256+ord(data[1]), data[2:])
|
||||||
elif self.status == 'TX':
|
elif self.status == 'TX':
|
||||||
self.ready()
|
self.ready()
|
||||||
self.decodeTX(ord(data[0])*256+ord(data[1]))
|
self.decodeTX(ord(data[0])*256+ord(data[1]))
|
||||||
|
|
||||||
def login(self):
|
def login(self):
|
||||||
ap = "CT:"+self.user.asXML(
|
ap = "CT:"+self.user.asXML(
|
||||||
'VX','EA','PW','ON','BC','DS','NN','CT','NT')
|
'VX','EA','PW','ON','BC','DS','NN','CT','NT')
|
||||||
self.status = 'AUTH'
|
self.status = 'AUTH'
|
||||||
self.phase = 0
|
self.phase = 0
|
||||||
self.sendLine(ap)
|
self.sendLine(ap)
|
||||||
|
|
||||||
def pong(self):
|
def pong(self):
|
||||||
self.sendLine('P')
|
self.sendLine('P')
|
||||||
|
|
||||||
def setStatus(self, status):
|
def setStatus(self, status):
|
||||||
self.sendLine('ST:%s' % str(status))
|
self.sendLine('ST:%s' % str(status))
|
||||||
|
|
||||||
def stopTransmission(self):
|
def stopTransmission(self):
|
||||||
self.sendLine('RX0')
|
self.sendLine('RX0')
|
||||||
|
|
||||||
def startTransmission(self):
|
def startTransmission(self):
|
||||||
self.sendLine('TX0')
|
self.sendLine('TX0')
|
||||||
|
|
||||||
def sendAudioFrame(self, frame):
|
def sendAudioFrame(self, frame):
|
||||||
self.resetTimeout()
|
self.resetTimeout()
|
||||||
self.sendLine('TX1')
|
self.sendLine('TX1')
|
||||||
self.transport.write(frame)
|
self.transport.write(frame)
|
||||||
|
|
||||||
def streamStep(self, count):
|
def streamStep(self, count):
|
||||||
if count > 1:
|
if count > 1:
|
||||||
log.msg("WARNING: lost %d ticks" % (count-1))
|
log.msg("WARNING: lost %d ticks" % (count-1))
|
||||||
for i in range(count):
|
for i in range(count):
|
||||||
self.sendAudioFrame(self.txq.get_nowait())
|
self.sendAudioFrame(self.txq.get_nowait())
|
||||||
|
|
||||||
def stopStreaming(self):
|
def stopStreaming(self):
|
||||||
self.txtimer.stop()
|
self.txtimer.stop()
|
||||||
|
|
||||||
def _streamAck(self):
|
def _streamAck(self):
|
||||||
self.txtimer = LoopingCall.withCount(self.streamStep)
|
self.txtimer = LoopingCall.withCount(self.streamStep)
|
||||||
self.txtimer.start(0.20).addCallback(
|
self.txtimer.start(0.20).addCallback(
|
||||||
lambda _: self.stopTransmission()).addErrback(
|
lambda _: self.stopTransmission()).addErrback(
|
||||||
lambda _: self.stopTransmission())
|
lambda _: self.stopTransmission())
|
||||||
|
|
||||||
def feedStreaming(self, frames):
|
def feedStreaming(self, frames):
|
||||||
if type(frames) == list:
|
if type(frames) == list:
|
||||||
for frame in frames:
|
for frame in frames:
|
||||||
self.txq.put_nowait(frame)
|
self.txq.put_nowait(frame)
|
||||||
else:
|
else:
|
||||||
self.txq.put_nowait(frames)
|
self.txq.put_nowait(frames)
|
||||||
|
|
||||||
def startStreaming(self):
|
def startStreaming(self):
|
||||||
self.startTransmission()
|
self.startTransmission()
|
||||||
|
|
||||||
def sendTextMessage(self, dest, text):
|
def sendTextMessage(self, dest, text):
|
||||||
self.sendLine('TM:'+formatSimpleXML(dict(ID=dest, MS=text)))
|
self.sendLine('TM:'+formatSimpleXML(dict(ID=dest, MS=text)))
|
||||||
|
|
||||||
def addAdmin(self, client_ip):
|
def addAdmin(self, client_ip):
|
||||||
self.sendLine("AA:"+formatSimpleXML(dict(IP=client_ip)))
|
self.sendLine("AA:"+formatSimpleXML(dict(IP=client_ip)))
|
||||||
|
|
||||||
def removeAdmin(self, client_ip):
|
def removeAdmin(self, client_ip):
|
||||||
self.sendLine("DA:"+formatSimpleXML(dict(IP=client_ip)))
|
self.sendLine("DA:"+formatSimpleXML(dict(IP=client_ip)))
|
||||||
|
|
||||||
def addMute(self, client_ip):
|
def addMute(self, client_ip):
|
||||||
self.sendLine("MC:"+formatSimpleXML(dict(IP=client_ip)))
|
self.sendLine("MC:"+formatSimpleXML(dict(IP=client_ip)))
|
||||||
|
|
||||||
def removeMute(self, client_ip):
|
def removeMute(self, client_ip):
|
||||||
self.sendLine("UM:"+formatSimpleXML(dict(IP=client_ip)))
|
self.sendLine("UM:"+formatSimpleXML(dict(IP=client_ip)))
|
||||||
|
|
||||||
def addBlock(self, client_ip):
|
def addBlock(self, client_ip):
|
||||||
self.sendLine("BC:"+formatSimpleXML(dict(IP=client_ip)))
|
self.sendLine("BC:"+formatSimpleXML(dict(IP=client_ip)))
|
||||||
|
|
||||||
def removeBlock(self, client_ip):
|
def removeBlock(self, client_ip):
|
||||||
self.sendLine("UC:"+formatSimpleXML(dict(IP=client_ip)))
|
self.sendLine("UC:"+formatSimpleXML(dict(IP=client_ip)))
|
||||||
|
|
||||||
def addAccess(self, email):
|
def addAccess(self, email):
|
||||||
self.sendLine("AT:"+formatSimpleXML(dict(EA=email)))
|
self.sendLine("AT:"+formatSimpleXML(dict(EA=email)))
|
||||||
|
|
||||||
def removeAccess(self, email):
|
def removeAccess(self, email):
|
||||||
self.sendLine("DT:"+formatSimpleXML(dict(EA=email)))
|
self.sendLine("DT:"+formatSimpleXML(dict(EA=email)))
|
||||||
|
|
||||||
def addTalk(self, email):
|
def addTalk(self, email):
|
||||||
self.sendLine("ETX:"+formatSimpleXML(dict(EA=email)))
|
self.sendLine("ETX:"+formatSimpleXML(dict(EA=email)))
|
||||||
|
|
||||||
def removeTalk(self, email):
|
def removeTalk(self, email):
|
||||||
self.sendLine("RTX:"+formatSimpleXML(dict(EA=email)))
|
self.sendLine("RTX:"+formatSimpleXML(dict(EA=email)))
|
||||||
|
|
||||||
def accessFlagEnable(self, enable):
|
def accessFlagEnable(self, enable):
|
||||||
if enable:
|
if enable:
|
||||||
v = 1
|
v = 1
|
||||||
else:
|
else:
|
||||||
v = 0
|
v = 0
|
||||||
self.sendLine("ENA:%d" % v)
|
self.sendLine("ENA:%d" % v)
|
||||||
|
|
||||||
def accessFlagTalk(self, enable):
|
def accessFlagTalk(self, enable):
|
||||||
if enable:
|
if enable:
|
||||||
v = 1
|
v = 1
|
||||||
else:
|
else:
|
||||||
v = 0
|
v = 0
|
||||||
self.sendLine("TXR:%d" % v)
|
self.sendLine("TXR:%d" % v)
|
||||||
|
|
||||||
def unimplemented(self, status, msg):
|
def unimplemented(self, status, msg):
|
||||||
log.msg("Unimplemented: %s: %s" % (status, msg))
|
log.msg("Unimplemented: %s: %s" % (status, msg))
|
||||||
|
|
||||||
def decodeAUDIO(self, from_id, frames):
|
def decodeAUDIO(self, from_id, frames):
|
||||||
self.audioFrameReceived(from_id, frames)
|
self.audioFrameReceived(from_id, frames)
|
||||||
|
|
||||||
def decodeTX(self, my_id):
|
def decodeTX(self, my_id):
|
||||||
self._streamAck()
|
self._streamAck()
|
||||||
|
|
||||||
def decodeTEXT(self, msg):
|
def decodeTEXT(self, msg):
|
||||||
self.textMessageReceived(msg[0], msg[1], msg[2])
|
self.textMessageReceived(msg[0], msg[1], msg[2])
|
||||||
|
|
||||||
def decodeCLIENTS(self, msg):
|
def decodeCLIENTS(self, msg):
|
||||||
self.clientsListUpdated([parseSimpleXML(x) for x in msg])
|
self.clientsListUpdated([parseSimpleXML(x) for x in msg])
|
||||||
|
|
||||||
def decodeNETWORKS(self, msg):
|
def decodeNETWORKS(self, msg):
|
||||||
self.networksListUpdated(msg)
|
self.networksListUpdated(msg)
|
||||||
|
|
||||||
def decodeADMIN(self, msg):
|
def decodeADMIN(self, msg):
|
||||||
self.adminListUpdated([parseSimpleXML(x) for x in msg])
|
self.adminListUpdated([parseSimpleXML(x) for x in msg])
|
||||||
|
|
||||||
def decodeACCESS(self, msg):
|
def decodeACCESS(self, msg):
|
||||||
self.accessListUpdated([parseSimpleXML(x) for x in msg])
|
self.accessListUpdated([parseSimpleXML(x) for x in msg])
|
||||||
|
|
||||||
def decodeBLOCK(self, msg):
|
def decodeBLOCK(self, msg):
|
||||||
self.blockListUpdated([parseSimpleXML(x) for x in msg])
|
self.blockListUpdated([parseSimpleXML(x) for x in msg])
|
||||||
|
|
||||||
def decodeMUTE(self, msg):
|
def decodeMUTE(self, msg):
|
||||||
self.muteListUpdated([parseSimpleXML(x) for x in msg])
|
self.muteListUpdated([parseSimpleXML(x) for x in msg])
|
||||||
|
|
||||||
def decodeACCESSFLAGS(self, msg):
|
def decodeACCESSFLAGS(self, msg):
|
||||||
self.accessFlagsUpdated(msg[0], msg[1])
|
self.accessFlagsUpdated(msg[0], msg[1])
|
||||||
|
|
||||||
def decodeUNKNOWN(self, code, msg):
|
def decodeUNKNOWN(self, code, msg):
|
||||||
log.msg("%s: %s" % (code, msg))
|
log.msg("%s: %s" % (code, msg))
|
||||||
|
|
||||||
def loginResponse(self, info):
|
def loginResponse(self, info):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def audioFrameReceived(self, from_id, frame):
|
def audioFrameReceived(self, from_id, frame):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def textMessageReceived(self, client, message, target):
|
def textMessageReceived(self, client, message, target):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def clientsListUpdated(self, clients):
|
def clientsListUpdated(self, clients):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def networksListUpdated(self, networks):
|
def networksListUpdated(self, networks):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def adminListUpdated(self, admins):
|
def adminListUpdated(self, admins):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def accessListUpdated(self, access):
|
def accessListUpdated(self, access):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def blockListUpdated(self, blocks):
|
def blockListUpdated(self, blocks):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def muteListUpdated(self, mutes):
|
def muteListUpdated(self, mutes):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def accessFlagsUpdated(self, access, talk):
|
def accessFlagsUpdated(self, access, talk):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class FRNClientFactory(ReconnectingClientFactory):
|
class FRNClientFactory(ReconnectingClientFactory):
|
||||||
|
|
||||||
protocol = FRNClient
|
protocol = FRNClient
|
||||||
maxRetries = 10
|
maxRetries = 10
|
||||||
|
|
||||||
def __init__(self, user):
|
def __init__(self, user):
|
||||||
self.user = user
|
self.user = user
|
||||||
|
|
||||||
def startedConnecting(self, connector):
|
def startedConnecting(self, connector):
|
||||||
log.msg('Started to connect')
|
log.msg('Started to connect')
|
||||||
|
|
||||||
def buildProtocol(self, addr):
|
def buildProtocol(self, addr):
|
||||||
log.msg('Connected')
|
log.msg('Connected')
|
||||||
p = ReconnectingClientFactory.buildProtocol(self, addr)
|
p = ReconnectingClientFactory.buildProtocol(self, addr)
|
||||||
p.user = self.user
|
p.user = self.user
|
||||||
return p
|
return p
|
||||||
|
|
||||||
def clientConnectionLost(self, connector, reason):
|
def clientConnectionLost(self, connector, reason):
|
||||||
log.msg('Lost connection. Reason: %s' % reason)
|
log.msg('Lost connection. Reason: %s' % reason)
|
||||||
ReconnectingClientFactory.clientConnectionLost(
|
ReconnectingClientFactory.clientConnectionLost(
|
||||||
self, connector, reason)
|
self, connector, reason)
|
||||||
|
|
||||||
def clientConnectionFailed(self, connector, reason):
|
def clientConnectionFailed(self, connector, reason):
|
||||||
log.err('Connection failed. Reason: %s' % reason)
|
log.err('Connection failed. Reason: %s' % reason)
|
||||||
ReconnectingClientFactory.clientConnectionFailed(
|
ReconnectingClientFactory.clientConnectionFailed(
|
||||||
self, connector, reason)
|
self, connector, reason)
|
||||||
|
|
||||||
# vim: set et ai sw=4 ts=4 sts=4:
|
# vim: set et ai sw=4 ts=4 sts=4:
|
||||||
|
|
|
@ -52,10 +52,10 @@ class FRNManagerClient(LineOnlyReceiver):
|
||||||
def loginDone(result):
|
def loginDone(result):
|
||||||
self.managerdata = parseSimpleXML(result)
|
self.managerdata = parseSimpleXML(result)
|
||||||
log.msg("Server login results: %s" % str(self.managerdata))
|
log.msg("Server login results: %s" % str(self.managerdata))
|
||||||
if int(self.managerdata['mc']) > 2009004:
|
if int(self.managerdata['MC']) > 2009004:
|
||||||
self.sendLine(responseToChallange(
|
self.sendLine(responseToChallange(
|
||||||
self.managerdata['kp']))
|
self.managerdata['KP']))
|
||||||
if self.managerdata['al'] != '0':
|
if self.managerdata['AL'] != '0':
|
||||||
self.transport.loseConnection()
|
self.transport.loseConnection()
|
||||||
else:
|
else:
|
||||||
self.pingtimer = LoopingCall(self.sendPing)
|
self.pingtimer = LoopingCall(self.sendPing)
|
||||||
|
|
|
@ -103,7 +103,7 @@ class FRNServer(BufferingLineReceiver, TimeoutMixin):
|
||||||
return (userId, "")
|
return (userId, "")
|
||||||
user.IP = self.clientAddress.host
|
user.IP = self.clientAddress.host
|
||||||
if self.factory.tracker.canLogin(user):
|
if self.factory.tracker.canLogin(user):
|
||||||
return self.factory.manager.clientLogin(user).addCallback(loginReturned)
|
return self.factory.manager.clientLogin(self.factory.serverAuth, user).addCallback(loginReturned)
|
||||||
else:
|
else:
|
||||||
log.msg("BLOCK %s" % repr(user))
|
log.msg("BLOCK %s" % repr(user))
|
||||||
return succeed(("BLOCK", ""))
|
return succeed(("BLOCK", ""))
|
||||||
|
@ -111,10 +111,10 @@ class FRNServer(BufferingLineReceiver, TimeoutMixin):
|
||||||
def disconnect(self):
|
def disconnect(self):
|
||||||
self.stopPinging()
|
self.stopPinging()
|
||||||
if self.user is not None:
|
if self.user is not None:
|
||||||
log.msg("Logging out client %s" % self.user)
|
log.msg("Logging out client %s" % self.user)
|
||||||
self.factory.manager.clientLogout(self.user)
|
self.factory.manager.clientLogout(self.factory.serverAuth, self.user)
|
||||||
self.factory.tracker.logout(self)
|
self.factory.tracker.logout(self)
|
||||||
self.transport.loseConnection()
|
self.transport.loseConnection()
|
||||||
|
|
||||||
def decodeCT(self, body):
|
def decodeCT(self, body):
|
||||||
def authReturned(result):
|
def authReturned(result):
|
||||||
|
@ -169,15 +169,15 @@ class FRNServer(BufferingLineReceiver, TimeoutMixin):
|
||||||
|
|
||||||
def decodeTM(self, body):
|
def decodeTM(self, body):
|
||||||
log.msg("TM: %s" % str(body))
|
log.msg("TM: %s" % str(body))
|
||||||
if body['id'] == '':
|
if body['ID'] == '':
|
||||||
msgtype = 'A'
|
msgtype = 'A'
|
||||||
else:
|
else:
|
||||||
msgtype = 'P'
|
msgtype = 'P'
|
||||||
for c in self.factory.tracker.getClientList(self.user.NT):
|
for c in self.factory.tracker.getClientList(self.user.NT):
|
||||||
if msgtype == 'A' or c.ID == body['id']:
|
if msgtype == 'A' or c.ID == body['ID']:
|
||||||
if c.ID != self.user.ID or msgtype == 'A':
|
if c.ID != self.user.ID or msgtype == 'A':
|
||||||
client = self.factory.tracker.getClientProtocol(c.ID)
|
client = self.factory.tracker.getClientProtocol(c.ID)
|
||||||
client.sendTextMessage(self.user.ID, body['ms'], msgtype)
|
client.sendTextMessage(self.user.ID, body['MS'], msgtype)
|
||||||
|
|
||||||
def decodeTX(self, body):
|
def decodeTX(self, body):
|
||||||
if body == '0':
|
if body == '0':
|
||||||
|
@ -190,53 +190,53 @@ class FRNServer(BufferingLineReceiver, TimeoutMixin):
|
||||||
|
|
||||||
def decodeMC(self, body):
|
def decodeMC(self, body):
|
||||||
if self.role in ["OWNER","ADMIN"]:
|
if self.role in ["OWNER","ADMIN"]:
|
||||||
self.factory.tracker.mute(self.user, body['ip'])
|
self.factory.tracker.mute(self.user, body['IP'])
|
||||||
if self.factory.tracker.isLoggedIn(body['ip']):
|
if self.factory.tracker.isLoggedIn(body['IP']):
|
||||||
self.factory.tracker.getClientProtocol(body['ip']).decodeRX('0')
|
self.factory.tracker.getClientProtocol(body['IP']).decodeRX('0')
|
||||||
|
|
||||||
def decodeUM(self, body):
|
def decodeUM(self, body):
|
||||||
if self.role in ["OWNER","ADMIN"]:
|
if self.role in ["OWNER","ADMIN"]:
|
||||||
self.factory.tracker.unMute(body['ip'])
|
self.factory.tracker.unMute(body['IP'])
|
||||||
|
|
||||||
def decodeBC(self, body):
|
def decodeBC(self, body):
|
||||||
if self.role in ["OWNER","ADMIN"]:
|
if self.role in ["OWNER","ADMIN"]:
|
||||||
self.factory.tracker.block(self.user, body['ip'])
|
self.factory.tracker.block(self.user, body['IP'])
|
||||||
self.factory.tracker.getClientProtocol(body['ip']).disconnect()
|
self.factory.tracker.getClientProtocol(body['IP']).disconnect()
|
||||||
|
|
||||||
def decodeUC(self, body):
|
def decodeUC(self, body):
|
||||||
if self.role in ["OWNER","ADMIN"]:
|
if self.role in ["OWNER","ADMIN"]:
|
||||||
self.factory.tracker.unBlock(body['ip'])
|
self.factory.tracker.unBlock(body['IP'])
|
||||||
|
|
||||||
def decodeAA(self, body):
|
def decodeAA(self, body):
|
||||||
if self.role == "OWNER":
|
if self.role == "OWNER":
|
||||||
self.factory.tracker.admin(body['ip'])
|
self.factory.tracker.admin(body['IP'])
|
||||||
|
|
||||||
def decodeDA(self, body):
|
def decodeDA(self, body):
|
||||||
if self.role == "OWNER":
|
if self.role == "OWNER":
|
||||||
self.factory.tracker.unAdmin(body['ip'])
|
self.factory.tracker.unAdmin(body['IP'])
|
||||||
|
|
||||||
def decodeETX(self, body):
|
def decodeETX(self, body):
|
||||||
log.msg("decodeETX(%s)" % str(body))
|
log.msg("decodeETX(%s)" % str(body))
|
||||||
if self.role == "OWNER":
|
if self.role == "OWNER":
|
||||||
self.factory.tracker.setAclTx(self.user.NT, body['ea'], True)
|
self.factory.tracker.setAclTx(self.user.NT, body['EA'], True)
|
||||||
self.sendAccessList(self.factory.tracker.getAcl(self.user.NT))
|
self.sendAccessList(self.factory.tracker.getAcl(self.user.NT))
|
||||||
|
|
||||||
def decodeRTX(self, body):
|
def decodeRTX(self, body):
|
||||||
log.msg("decodeRTX(%s)" % str(body))
|
log.msg("decodeRTX(%s)" % str(body))
|
||||||
if self.role == "OWNER":
|
if self.role == "OWNER":
|
||||||
self.factory.tracker.setAclTx(self.user.NT, body['ea'], False)
|
self.factory.tracker.setAclTx(self.user.NT, body['EA'], False)
|
||||||
self.sendAccessList(self.factory.tracker.getAcl(self.user.NT))
|
self.sendAccessList(self.factory.tracker.getAcl(self.user.NT))
|
||||||
|
|
||||||
def decodeDT(self, body):
|
def decodeDT(self, body):
|
||||||
log.msg("decodeDT(%s)" % str(body))
|
log.msg("decodeDT(%s)" % str(body))
|
||||||
if self.role == "OWNER":
|
if self.role == "OWNER":
|
||||||
self.factory.tracker.delAcl(self.user.NT, body['ea'])
|
self.factory.tracker.delAcl(self.user.NT, body['EA'])
|
||||||
self.sendAccessList(self.factory.tracker.getAcl(self.user.NT))
|
self.sendAccessList(self.factory.tracker.getAcl(self.user.NT))
|
||||||
|
|
||||||
def decodeAT(self, body):
|
def decodeAT(self, body):
|
||||||
log.msg("decodeAT(%s)" % str(body))
|
log.msg("decodeAT(%s)" % str(body))
|
||||||
if self.role == "OWNER":
|
if self.role == "OWNER":
|
||||||
self.factory.tracker.addAcl(self.user.NT, body['ea'])
|
self.factory.tracker.addAcl(self.user.NT, body['EA'])
|
||||||
self.sendAccessList(self.factory.tracker.getAcl(self.user.NT))
|
self.sendAccessList(self.factory.tracker.getAcl(self.user.NT))
|
||||||
|
|
||||||
def decodeTXR(self, body):
|
def decodeTXR(self, body):
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
From: GNURadioNetwork System Manager <admin@gnuradionetwork.org>
|
||||||
|
To: $EA
|
||||||
|
Subject: [GRN] $ON account data
|
||||||
|
|
||||||
|
Callsign and operator name: $ON
|
||||||
|
Password: $PW
|
||||||
|
Operating mode: $BC
|
||||||
|
Description: $DS
|
||||||
|
City and locator: $CT
|
||||||
|
Country: $NN
|
||||||
|
|
||||||
|
Registration date: $registration
|
||||||
|
Last login: $lastlogin
|
|
@ -68,7 +68,7 @@ class FRNStream(FRNClient):
|
||||||
|
|
||||||
def getClientName(self, client_id):
|
def getClientName(self, client_id):
|
||||||
if self.clientsById.has_key(client_id):
|
if self.clientsById.has_key(client_id):
|
||||||
return self.clientsById[client_id]['on']
|
return self.clientsById[client_id]['ON']
|
||||||
else:
|
else:
|
||||||
return client_id
|
return client_id
|
||||||
|
|
||||||
|
@ -77,11 +77,11 @@ class FRNStream(FRNClient):
|
||||||
self.pong()
|
self.pong()
|
||||||
|
|
||||||
def loginResponse(self, info):
|
def loginResponse(self, info):
|
||||||
log.msg("Login: %s" % info['al'])
|
log.msg("Login: %s" % info['AL'])
|
||||||
|
|
||||||
def clientsListUpdated(self, clients):
|
def clientsListUpdated(self, clients):
|
||||||
self.clients = clients
|
self.clients = clients
|
||||||
self.clientsById = dict([(i['id'], i) for i in clients])
|
self.clientsById = dict([(i['ID'], i) for i in clients])
|
||||||
|
|
||||||
|
|
||||||
class FRNStreamFactory(FRNClientFactory):
|
class FRNStreamFactory(FRNClientFactory):
|
||||||
|
|
|
@ -34,7 +34,7 @@ class FRNCrosslinkClient(FRNClient):
|
||||||
|
|
||||||
def getClientName(self, client_id):
|
def getClientName(self, client_id):
|
||||||
if self.clientsById.has_key(client_id):
|
if self.clientsById.has_key(client_id):
|
||||||
return self.clientsById[client_id]['on']
|
return self.clientsById[client_id]['ON']
|
||||||
else:
|
else:
|
||||||
return client_id
|
return client_id
|
||||||
|
|
||||||
|
@ -60,16 +60,16 @@ class FRNCrosslinkClient(FRNClient):
|
||||||
for server, port, u, factory in clients:
|
for server, port, u, factory in clients:
|
||||||
cl = []
|
cl = []
|
||||||
cl.append("<u>%s@%s:%d</u>" % (u.NT,server,port))
|
cl.append("<u>%s@%s:%d</u>" % (u.NT,server,port))
|
||||||
role = factory.connection.serverdata.get('al', None)
|
role = factory.connection.serverdata.get('AL', None)
|
||||||
if role in ['OK', 'ADMIN', 'OWNER']:
|
if role in ['OK', 'ADMIN', 'OWNER']:
|
||||||
for c in factory.connection.clients:
|
for c in factory.connection.clients:
|
||||||
ss = cStatus.get(c['s'], '?')
|
ss = cStatus.get(c['s'], '?')
|
||||||
if c['m'] != '0':
|
if c['M'] != '0':
|
||||||
ss = ss.lower()
|
ss = ss.lower()
|
||||||
cl.append(" %s%s %s " % (
|
cl.append(" %s%s %s " % (
|
||||||
cType.get(c['bc'], 'G'),
|
cType.get(c['BC'], 'G'),
|
||||||
ss,
|
ss,
|
||||||
c['on'].replace('<', '<'),
|
c['ON'].replace('<', '<'),
|
||||||
))
|
))
|
||||||
else:
|
else:
|
||||||
cl.append(" :!: DISCONNECTED :!: ")
|
cl.append(" :!: DISCONNECTED :!: ")
|
||||||
|
@ -100,7 +100,7 @@ class FRNCrosslinkClient(FRNClient):
|
||||||
global clients, talking, lastMessages
|
global clients, talking, lastMessages
|
||||||
if talking is None or talking == self:
|
if talking is None or talking == self:
|
||||||
talking = self
|
talking = self
|
||||||
talkingUser = self.clients[from_id-1]['on']
|
talkingUser = self.clients[from_id-1]['ON']
|
||||||
if len(lastMessages) > 0:
|
if len(lastMessages) > 0:
|
||||||
if lastMessages[0] == talkingUser:
|
if lastMessages[0] == talkingUser:
|
||||||
talkingUser = None
|
talkingUser = None
|
||||||
|
@ -126,15 +126,15 @@ class FRNCrosslinkClient(FRNClient):
|
||||||
self.pong()
|
self.pong()
|
||||||
|
|
||||||
def loginResponse(self, info):
|
def loginResponse(self, info):
|
||||||
log.msg("%s login: %s" % (self.user.ON, info['al']))
|
log.msg("%s login: %s" % (self.user.ON, info['AL']))
|
||||||
|
|
||||||
def clientsListUpdated(self, clients):
|
def clientsListUpdated(self, clients):
|
||||||
self.clients = clients
|
self.clients = clients
|
||||||
self.clientsById = dict([(i['id'], i) for i in clients])
|
self.clientsById = dict([(i['ID'], i) for i in clients])
|
||||||
if self.clientId is None:
|
if self.clientId is None:
|
||||||
for c in clients:
|
for c in clients:
|
||||||
if c['on'] == self.user.ON and c['bc'] == self.user.BC:
|
if c['ON'] == self.user.ON and c['BC'] == self.user.BC:
|
||||||
self.clientId = c['id']
|
self.clientId = c['ID']
|
||||||
|
|
||||||
class FRNCrosslinkClientFactory(FRNClientFactory):
|
class FRNCrosslinkClientFactory(FRNClientFactory):
|
||||||
protocol = FRNCrosslinkClient
|
protocol = FRNCrosslinkClient
|
||||||
|
|
|
@ -34,13 +34,13 @@ class FRNRecorder(FRNClient):
|
||||||
|
|
||||||
def getClientName(self, client_id):
|
def getClientName(self, client_id):
|
||||||
if self.clientsById.has_key(client_id):
|
if self.clientsById.has_key(client_id):
|
||||||
return self.clientsById[client_id]['on']
|
return self.clientsById[client_id]['ON']
|
||||||
else:
|
else:
|
||||||
return client_id
|
return client_id
|
||||||
|
|
||||||
def buildRecordingName(self, client_id):
|
def buildRecordingName(self, client_id):
|
||||||
ts = time.localtime()
|
ts = time.localtime()
|
||||||
opname = sanitizeFilename(self.clients[client_id-1]['on'])
|
opname = sanitizeFilename(self.clients[client_id-1]['ON'])
|
||||||
dirname = self.factory.recdir+"/"+time.strftime("%Y%m/%d/%H", ts)
|
dirname = self.factory.recdir+"/"+time.strftime("%Y%m/%d/%H", ts)
|
||||||
filename = time.strftime("%Y%m%d-%H%M%S-", ts) + opname + '.wav'
|
filename = time.strftime("%Y%m%d-%H%M%S-", ts) + opname + '.wav'
|
||||||
try:
|
try:
|
||||||
|
@ -82,16 +82,16 @@ class FRNRecorder(FRNClient):
|
||||||
|
|
||||||
def archiveRecording(self, from_id):
|
def archiveRecording(self, from_id):
|
||||||
log.msg("%s stopped talking" %
|
log.msg("%s stopped talking" %
|
||||||
self.clients[from_id-1]['on'])
|
self.clients[from_id-1]['ON'])
|
||||||
self.closeFile()
|
self.closeFile()
|
||||||
self.recordingFile = None
|
self.recordingFile = None
|
||||||
self.recordingOperator = None
|
self.recordingOperator = None
|
||||||
|
|
||||||
def audioFrameReceived(self, from_id, frames):
|
def audioFrameReceived(self, from_id, frames):
|
||||||
if self.recordingOperator != self.clients[from_id-1]['on']:
|
if self.recordingOperator != self.clients[from_id-1]['ON']:
|
||||||
if self.recordingOperator is not None:
|
if self.recordingOperator is not None:
|
||||||
self.closeFile()
|
self.closeFile()
|
||||||
self.recordingOperator = self.clients[from_id-1]['on']
|
self.recordingOperator = self.clients[from_id-1]['ON']
|
||||||
self.recordingFile = file(self.buildRecordingName(from_id), 'wb')
|
self.recordingFile = file(self.buildRecordingName(from_id), 'wb')
|
||||||
self.recordingFile.write(WAV_HEADER)
|
self.recordingFile.write(WAV_HEADER)
|
||||||
self.recordingFile.write(frames)
|
self.recordingFile.write(frames)
|
||||||
|
@ -99,20 +99,20 @@ class FRNRecorder(FRNClient):
|
||||||
self.parrot_timer.reset(AUDIO_TIMEOUT)
|
self.parrot_timer.reset(AUDIO_TIMEOUT)
|
||||||
except:
|
except:
|
||||||
log.msg("%s started talking" %
|
log.msg("%s started talking" %
|
||||||
self.clients[from_id-1]['on'])
|
self.clients[from_id-1]['ON'])
|
||||||
self.parrot_timer = self.factory.reactor.callLater(
|
self.parrot_timer = self.factory.reactor.callLater(
|
||||||
AUDIO_TIMEOUT, self.archiveRecording, from_id)
|
AUDIO_TIMEOUT, self.archiveRecording, from_id)
|
||||||
self.pong()
|
self.pong()
|
||||||
|
|
||||||
def loginResponse(self, info):
|
def loginResponse(self, info):
|
||||||
log.msg("Login: %s" % info['al'])
|
log.msg("Login: %s" % info['AL'])
|
||||||
self.setStatus(1)
|
self.setStatus(1)
|
||||||
self.recordingOperator = None
|
self.recordingOperator = None
|
||||||
self.recordingFile = None
|
self.recordingFile = None
|
||||||
|
|
||||||
def clientsListUpdated(self, clients):
|
def clientsListUpdated(self, clients):
|
||||||
self.clients = clients
|
self.clients = clients
|
||||||
self.clientsById = dict([(i['id'], i) for i in clients])
|
self.clientsById = dict([(i['ID'], i) for i in clients])
|
||||||
|
|
||||||
|
|
||||||
class FRNRecorderFactory(FRNClientFactory):
|
class FRNRecorderFactory(FRNClientFactory):
|
||||||
|
|
Loading…
Reference in New Issue