Browse Source

Fix regressions introduced by new simple XML parser.

master
Maurizio Porrato 8 years ago
parent
commit
17eb5f0ca3

+ 5
- 2
frn/manager/database.py View File

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

+ 1
- 1
frn/manager/remote.py View File

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)

+ 306
- 306
frn/protocol/client.py View File

# -*- coding: utf-8 -*-
#
# Copyright 2010 Maurizio Porrato <maurizio.porrato@gmail.com>
# See LICENSE.txt for copyright info
from Queue import Queue
from twisted.internet.protocol import ReconnectingClientFactory
from twisted.protocols.policies import TimeoutMixin
from twisted.internet.task import LoopingCall
from twisted.python import log
from frn.protocol import versions
from frn.user import FRNUser
from frn.protocol.common import BufferingLineReceiver
from frn.utility import *
class FRNClient(BufferingLineReceiver, TimeoutMixin):
def connectionMade(self):
BufferingLineReceiver.connectionMade(self)
self.user.VX = versions.client
# -*- coding: utf-8 -*-
#
# Copyright 2010 Maurizio Porrato <maurizio.porrato@gmail.com>
# See LICENSE.txt for copyright info
from Queue import Queue
from twisted.internet.protocol import ReconnectingClientFactory
from twisted.protocols.policies import TimeoutMixin
from twisted.internet.task import LoopingCall
from twisted.python import log
from frn.protocol import versions
from frn.user import FRNUser
from frn.protocol.common import BufferingLineReceiver
from frn.utility import *
class FRNClient(BufferingLineReceiver, TimeoutMixin):
def connectionMade(self):
BufferingLineReceiver.connectionMade(self)
self.user.VX = versions.client
self.serverdata = {} self.serverdata = {}
self.txq = Queue()
self.setTimeout(25.0)
self.login()
self.txq = Queue()
self.setTimeout(25.0)
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):
self.status = 'READY'
self.msgbuffer = []
self.phase = 0
self.expectRawData(1)
def startMultiLineMessage(self, msgtype):
self.status = msgtype
self.phase = None
self.setLineMode()
def stopMultiLineMessage(self):
handler = getattr(self, 'decode'+self.status, None)
status = self.status
message = self.msgbuffer
self.ready()
if handler is not None:
handler(message)
else:
self.unimplemented(status, message)
def collectMultiLineMessage(self, line):
if self.phase is None:
self.expected_lines = int(line.strip())
self.msgbuffer = []
self.phase = 0
else:
self.msgbuffer.append(line)
self.phase += 1
if self.phase >= self.expected_lines:
self.stopMultiLineMessage()
def lineReceived(self, line):
if self.status == 'AUTH':
if self.phase == 0:
self.latest_client_version = int(line.strip())
self.phase = 1
else:
self.serverdata = parseSimpleXML(line.strip())
if int(self.serverdata['sv']) > 2009004:
self.sendLine(responseToChallange(
self.serverdata['kp']))
self.ready()
self.setTimeout(10.0)
self.factory.resetDelay()
self.loginResponse(self.serverdata)
else:
self.collectMultiLineMessage(line)
def expectedReceived(self, data):
self.resetTimeout()
if self.status == 'READY':
packet_type = ord(data[0])
if packet_type == 0: # Keepalive
self.ready()
self.pong()
elif packet_type == 1: # TX ack
self.status = 'TX'
self.expectRawData(2)
elif packet_type == 2: # Audio
self.status = 'AUDIO'
self.expectRawData(327) # Two ID bytes + 10 GSM frames
elif packet_type == 3: # Client list
self.status = 'CLIENTS'
self.expectRawData(2) # Discard two null bytes
elif packet_type == 4: # Text
self.startMultiLineMessage('TEXT')
elif packet_type == 5: # Channel list
self.startMultiLineMessage('NETWORKS')
elif packet_type == 6: # Admin list
self.startMultiLineMessage('ADMIN')
elif packet_type == 7: # Access list
self.startMultiLineMessage('ACCESS')
elif packet_type == 8: # Block list
self.startMultiLineMessage('BLOCK')
elif packet_type == 9: # Mute list
self.startMultiLineMessage('MUTE')
elif packet_type == 10: # Access list flags
self.startMultiLineMessage('ACCESSFLAGS')
else:
log.err("Unknown packet type %d" % packet_type)
elif self.status == 'CLIENTS':
self.startMultiLineMessage('CLIENTS')
elif self.status == 'AUDIO':
self.ready()
self.decodeAUDIO(ord(data[0])*256+ord(data[1]), data[2:])
elif self.status == 'TX':
self.ready()
self.decodeTX(ord(data[0])*256+ord(data[1]))
def login(self):
ap = "CT:"+self.user.asXML(
'VX','EA','PW','ON','BC','DS','NN','CT','NT')
self.status = 'AUTH'
self.phase = 0
self.sendLine(ap)
def pong(self):
self.sendLine('P')
def setStatus(self, status):
self.sendLine('ST:%s' % str(status))
def stopTransmission(self):
self.sendLine('RX0')
def startTransmission(self):
self.sendLine('TX0')
def sendAudioFrame(self, frame):
self.resetTimeout()
self.sendLine('TX1')
self.transport.write(frame)
def streamStep(self, count):
if count > 1:
log.msg("WARNING: lost %d ticks" % (count-1))
for i in range(count):
self.sendAudioFrame(self.txq.get_nowait())
def stopStreaming(self):
self.txtimer.stop()
def _streamAck(self):
self.txtimer = LoopingCall.withCount(self.streamStep)
self.txtimer.start(0.20).addCallback(
lambda _: self.stopTransmission()).addErrback(
lambda _: self.stopTransmission())
def feedStreaming(self, frames):
if type(frames) == list:
for frame in frames:
self.txq.put_nowait(frame)
else:
self.txq.put_nowait(frames)
def startStreaming(self):
self.startTransmission()
def sendTextMessage(self, dest, text):
self.sendLine('TM:'+formatSimpleXML(dict(ID=dest, MS=text)))
def addAdmin(self, client_ip):
self.sendLine("AA:"+formatSimpleXML(dict(IP=client_ip)))
def removeAdmin(self, client_ip):
self.sendLine("DA:"+formatSimpleXML(dict(IP=client_ip)))
def addMute(self, client_ip):
self.sendLine("MC:"+formatSimpleXML(dict(IP=client_ip)))
def removeMute(self, client_ip):
self.sendLine("UM:"+formatSimpleXML(dict(IP=client_ip)))
def addBlock(self, client_ip):
self.sendLine("BC:"+formatSimpleXML(dict(IP=client_ip)))
def removeBlock(self, client_ip):
self.sendLine("UC:"+formatSimpleXML(dict(IP=client_ip)))
def addAccess(self, email):
self.sendLine("AT:"+formatSimpleXML(dict(EA=email)))
def removeAccess(self, email):
self.sendLine("DT:"+formatSimpleXML(dict(EA=email)))
def addTalk(self, email):
self.sendLine("ETX:"+formatSimpleXML(dict(EA=email)))
def removeTalk(self, email):
self.sendLine("RTX:"+formatSimpleXML(dict(EA=email)))
def accessFlagEnable(self, enable):
if enable:
v = 1
else:
v = 0
self.sendLine("ENA:%d" % v)
def accessFlagTalk(self, enable):
if enable:
v = 1
else:
v = 0
self.sendLine("TXR:%d" % v)
def unimplemented(self, status, msg):
log.msg("Unimplemented: %s: %s" % (status, msg))
def decodeAUDIO(self, from_id, frames):
self.audioFrameReceived(from_id, frames)
def decodeTX(self, my_id):
self._streamAck()
def decodeTEXT(self, msg):
self.textMessageReceived(msg[0], msg[1], msg[2])
def decodeCLIENTS(self, msg):
self.clientsListUpdated([parseSimpleXML(x) for x in msg])
def decodeNETWORKS(self, msg):
self.networksListUpdated(msg)
def decodeADMIN(self, msg):
self.adminListUpdated([parseSimpleXML(x) for x in msg])
def decodeACCESS(self, msg):
self.accessListUpdated([parseSimpleXML(x) for x in msg])
def decodeBLOCK(self, msg):
self.blockListUpdated([parseSimpleXML(x) for x in msg])
def decodeMUTE(self, msg):
self.muteListUpdated([parseSimpleXML(x) for x in msg])
def decodeACCESSFLAGS(self, msg):
self.accessFlagsUpdated(msg[0], msg[1])
def decodeUNKNOWN(self, code, msg):
log.msg("%s: %s" % (code, msg))
def loginResponse(self, info):
pass
def audioFrameReceived(self, from_id, frame):
pass
def textMessageReceived(self, client, message, target):
pass
def clientsListUpdated(self, clients):
pass
def networksListUpdated(self, networks):
pass
def adminListUpdated(self, admins):
pass
def accessListUpdated(self, access):
pass
def blockListUpdated(self, blocks):
pass
def muteListUpdated(self, mutes):
pass
def accessFlagsUpdated(self, access, talk):
pass
class FRNClientFactory(ReconnectingClientFactory):
protocol = FRNClient
maxRetries = 10
def __init__(self, user):
self.user = user
def startedConnecting(self, connector):
log.msg('Started to connect')
def buildProtocol(self, addr):
log.msg('Connected')
p = ReconnectingClientFactory.buildProtocol(self, addr)
p.user = self.user
return p
def clientConnectionLost(self, connector, reason):
log.msg('Lost connection. Reason: %s' % reason)
ReconnectingClientFactory.clientConnectionLost(
self, connector, reason)
def clientConnectionFailed(self, connector, reason):
log.err('Connection failed. Reason: %s' % reason)
ReconnectingClientFactory.clientConnectionFailed(
self, connector, reason)
# vim: set et ai sw=4 ts=4 sts=4:
def ready(self):
self.status = 'READY'
self.msgbuffer = []
self.phase = 0
self.expectRawData(1)
def startMultiLineMessage(self, msgtype):
self.status = msgtype
self.phase = None
self.setLineMode()
def stopMultiLineMessage(self):
handler = getattr(self, 'decode'+self.status, None)
status = self.status
message = self.msgbuffer
self.ready()
if handler is not None:
handler(message)
else:
self.unimplemented(status, message)
def collectMultiLineMessage(self, line):
if self.phase is None:
self.expected_lines = int(line.strip())
self.msgbuffer = []
self.phase = 0
else:
self.msgbuffer.append(line)
self.phase += 1
if self.phase >= self.expected_lines:
self.stopMultiLineMessage()
def lineReceived(self, line):
if self.status == 'AUTH':
if self.phase == 0:
self.latest_client_version = int(line.strip())
self.phase = 1
else:
self.serverdata = parseSimpleXML(line.strip())
if int(self.serverdata['SV']) > 2009004:
self.sendLine(responseToChallange(
self.serverdata['KP']))
self.ready()
self.setTimeout(10.0)
self.factory.resetDelay()
self.loginResponse(self.serverdata)
else:
self.collectMultiLineMessage(line)
def expectedReceived(self, data):
self.resetTimeout()
if self.status == 'READY':
packet_type = ord(data[0])
if packet_type == 0: # Keepalive
self.ready()
self.pong()
elif packet_type == 1: # TX ack
self.status = 'TX'
self.expectRawData(2)
elif packet_type == 2: # Audio
self.status = 'AUDIO'
self.expectRawData(327) # Two ID bytes + 10 GSM frames
elif packet_type == 3: # Client list
self.status = 'CLIENTS'
self.expectRawData(2) # Discard two null bytes
elif packet_type == 4: # Text
self.startMultiLineMessage('TEXT')
elif packet_type == 5: # Channel list
self.startMultiLineMessage('NETWORKS')
elif packet_type == 6: # Admin list
self.startMultiLineMessage('ADMIN')
elif packet_type == 7: # Access list
self.startMultiLineMessage('ACCESS')
elif packet_type == 8: # Block list
self.startMultiLineMessage('BLOCK')
elif packet_type == 9: # Mute list
self.startMultiLineMessage('MUTE')
elif packet_type == 10: # Access list flags
self.startMultiLineMessage('ACCESSFLAGS')
else:
log.err("Unknown packet type %d" % packet_type)
elif self.status == 'CLIENTS':
self.startMultiLineMessage('CLIENTS')
elif self.status == 'AUDIO':
self.ready()
self.decodeAUDIO(ord(data[0])*256+ord(data[1]), data[2:])
elif self.status == 'TX':
self.ready()
self.decodeTX(ord(data[0])*256+ord(data[1]))
def login(self):
ap = "CT:"+self.user.asXML(
'VX','EA','PW','ON','BC','DS','NN','CT','NT')
self.status = 'AUTH'
self.phase = 0
self.sendLine(ap)
def pong(self):
self.sendLine('P')
def setStatus(self, status):
self.sendLine('ST:%s' % str(status))
def stopTransmission(self):
self.sendLine('RX0')
def startTransmission(self):
self.sendLine('TX0')
def sendAudioFrame(self, frame):
self.resetTimeout()
self.sendLine('TX1')
self.transport.write(frame)
def streamStep(self, count):
if count > 1:
log.msg("WARNING: lost %d ticks" % (count-1))
for i in range(count):
self.sendAudioFrame(self.txq.get_nowait())
def stopStreaming(self):
self.txtimer.stop()
def _streamAck(self):
self.txtimer = LoopingCall.withCount(self.streamStep)
self.txtimer.start(0.20).addCallback(
lambda _: self.stopTransmission()).addErrback(
lambda _: self.stopTransmission())
def feedStreaming(self, frames):
if type(frames) == list:
for frame in frames:
self.txq.put_nowait(frame)
else:
self.txq.put_nowait(frames)
def startStreaming(self):
self.startTransmission()
def sendTextMessage(self, dest, text):
self.sendLine('TM:'+formatSimpleXML(dict(ID=dest, MS=text)))
def addAdmin(self, client_ip):
self.sendLine("AA:"+formatSimpleXML(dict(IP=client_ip)))
def removeAdmin(self, client_ip):
self.sendLine("DA:"+formatSimpleXML(dict(IP=client_ip)))
def addMute(self, client_ip):
self.sendLine("MC:"+formatSimpleXML(dict(IP=client_ip)))
def removeMute(self, client_ip):
self.sendLine("UM:"+formatSimpleXML(dict(IP=client_ip)))
def addBlock(self, client_ip):
self.sendLine("BC:"+formatSimpleXML(dict(IP=client_ip)))
def removeBlock(self, client_ip):
self.sendLine("UC:"+formatSimpleXML(dict(IP=client_ip)))
def addAccess(self, email):
self.sendLine("AT:"+formatSimpleXML(dict(EA=email)))
def removeAccess(self, email):
self.sendLine("DT:"+formatSimpleXML(dict(EA=email)))
def addTalk(self, email):
self.sendLine("ETX:"+formatSimpleXML(dict(EA=email)))
def removeTalk(self, email):
self.sendLine("RTX:"+formatSimpleXML(dict(EA=email)))
def accessFlagEnable(self, enable):
if enable:
v = 1
else:
v = 0
self.sendLine("ENA:%d" % v)
def accessFlagTalk(self, enable):
if enable:
v = 1
else:
v = 0
self.sendLine("TXR:%d" % v)
def unimplemented(self, status, msg):
log.msg("Unimplemented: %s: %s" % (status, msg))
def decodeAUDIO(self, from_id, frames):
self.audioFrameReceived(from_id, frames)
def decodeTX(self, my_id):
self._streamAck()
def decodeTEXT(self, msg):
self.textMessageReceived(msg[0], msg[1], msg[2])
def decodeCLIENTS(self, msg):
self.clientsListUpdated([parseSimpleXML(x) for x in msg])
def decodeNETWORKS(self, msg):
self.networksListUpdated(msg)
def decodeADMIN(self, msg):
self.adminListUpdated([parseSimpleXML(x) for x in msg])
def decodeACCESS(self, msg):
self.accessListUpdated([parseSimpleXML(x) for x in msg])
def decodeBLOCK(self, msg):
self.blockListUpdated([parseSimpleXML(x) for x in msg])
def decodeMUTE(self, msg):
self.muteListUpdated([parseSimpleXML(x) for x in msg])
def decodeACCESSFLAGS(self, msg):
self.accessFlagsUpdated(msg[0], msg[1])
def decodeUNKNOWN(self, code, msg):
log.msg("%s: %s" % (code, msg))
def loginResponse(self, info):
pass
def audioFrameReceived(self, from_id, frame):
pass
def textMessageReceived(self, client, message, target):
pass
def clientsListUpdated(self, clients):
pass
def networksListUpdated(self, networks):
pass
def adminListUpdated(self, admins):
pass
def accessListUpdated(self, access):
pass
def blockListUpdated(self, blocks):
pass
def muteListUpdated(self, mutes):
pass
def accessFlagsUpdated(self, access, talk):
pass
class FRNClientFactory(ReconnectingClientFactory):
protocol = FRNClient
maxRetries = 10
def __init__(self, user):
self.user = user
def startedConnecting(self, connector):
log.msg('Started to connect')
def buildProtocol(self, addr):
log.msg('Connected')
p = ReconnectingClientFactory.buildProtocol(self, addr)
p.user = self.user
return p
def clientConnectionLost(self, connector, reason):
log.msg('Lost connection. Reason: %s' % reason)
ReconnectingClientFactory.clientConnectionLost(
self, connector, reason)
def clientConnectionFailed(self, connector, reason):
log.err('Connection failed. Reason: %s' % reason)
ReconnectingClientFactory.clientConnectionFailed(
self, connector, reason)
# vim: set et ai sw=4 ts=4 sts=4:

+ 3
- 3
frn/protocol/manager.py View File

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']))
if self.managerdata['al'] != '0':
self.managerdata['KP']))
if self.managerdata['AL'] != '0':
self.transport.loseConnection() self.transport.loseConnection()
else: else:
self.pingtimer = LoopingCall(self.sendPing) self.pingtimer = LoopingCall(self.sendPing)

+ 21
- 21
frn/protocol/server.py View File

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", ""))
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)
self.factory.manager.clientLogout(self.user)
self.factory.tracker.logout(self)
self.transport.loseConnection()
log.msg("Logging out client %s" % self.user)
self.factory.manager.clientLogout(self.factory.serverAuth, self.user)
self.factory.tracker.logout(self)
self.transport.loseConnection()


def decodeCT(self, body): def decodeCT(self, body):
def authReturned(result): def authReturned(result):


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':


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'])
if self.factory.tracker.isLoggedIn(body['ip']):
self.factory.tracker.getClientProtocol(body['ip']).decodeRX('0')
self.factory.tracker.mute(self.user, body['IP'])
if self.factory.tracker.isLoggedIn(body['IP']):
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.getClientProtocol(body['ip']).disconnect()
self.factory.tracker.block(self.user, body['IP'])
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):

+ 13
- 0
mailtemplate.txt View File

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

+ 3
- 3
stream.py View File



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


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

+ 10
- 10
twisted/plugins/frncrosslink.py View File



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


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('<', '&lt;'),
c['ON'].replace('<', '&lt;'),
)) ))
else: else:
cl.append(" :!: DISCONNECTED :!: ") cl.append(" :!: DISCONNECTED :!: ")
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
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:
self.clientId = c['id']
if c['ON'] == self.user.ON and c['BC'] == self.user.BC:
self.clientId = c['ID']


class FRNCrosslinkClientFactory(FRNClientFactory): class FRNCrosslinkClientFactory(FRNClientFactory):
protocol = FRNCrosslinkClient protocol = FRNCrosslinkClient

+ 8
- 8
twisted/plugins/frnrecorder.py View File



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:


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)
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…
Cancel
Save