143 lines
4.7 KiB
Python
Executable File
143 lines
4.7 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
#
|
|
# Copyright 2010 Maurizio Porrato <maurizio.porrato@gmail.com>
|
|
# See LICENSE.txt for copyright info
|
|
|
|
from twisted.internet import reactor
|
|
from frn.protocol.client import FRNClient, FRNClientFactory
|
|
from frn.user import FRNUser
|
|
from twisted.python import log
|
|
|
|
clients = []
|
|
talking = None
|
|
|
|
class FRNCrosslinkClient(FRNClient):
|
|
|
|
def connectionMade(self):
|
|
self.txOk = False
|
|
self.txReq = False
|
|
self.clientId = None
|
|
FRNClient.connectionMade(self)
|
|
|
|
def getClientName(self, client_id):
|
|
if self.clientsById.has_key(client_id):
|
|
return self.clientsById[client_id]['on']
|
|
else:
|
|
return client_id
|
|
|
|
def textMessageReceived(self, client, message, target):
|
|
global clients
|
|
if target == 'A':
|
|
if client != self.clientId:
|
|
for _, _, _, factory in clients:
|
|
if factory != self.factory:
|
|
factory.connection.sendTextMessage('', message)
|
|
else:
|
|
if message.startswith('!'):
|
|
cmd = message[1:]
|
|
if cmd == "who":
|
|
for server, port, u, factory in clients:
|
|
cl = []
|
|
cl.append("[%s@%s:%d]" % (u.NT,server,port))
|
|
for c in factory.connection.clients:
|
|
cl.append("(%s)" % (c['on'],))
|
|
reply = ' '.join(cl)
|
|
self.sendTextMessage(client, reply)
|
|
|
|
def decodeTX(self, my_id):
|
|
log.msg("Got TX ack for %s" % self.user.ON)
|
|
self.txOk = True
|
|
|
|
def stopTransmission(self):
|
|
FRNClient.stopTransmission(self)
|
|
log.msg("Stopped TX on %s" % self.user.ON)
|
|
|
|
def goIdle(self):
|
|
global talking
|
|
self.txReq = False
|
|
self.txOk = False
|
|
talking = None
|
|
self.stopTransmission()
|
|
|
|
def audioFrameReceived(self, from_id, frames):
|
|
global clients, talking
|
|
if talking is None or talking == self:
|
|
talking = self
|
|
for _, _, _, factory in clients:
|
|
conn = factory.connection
|
|
if conn != self:
|
|
if conn.txOk:
|
|
conn.txReq = False
|
|
conn.sendAudioFrame(frames)
|
|
conn.busyTimer.reset(2.0)
|
|
else:
|
|
if not conn.txReq:
|
|
log.msg("Requesting TX for %s" % conn.user.ON)
|
|
conn.startTransmission()
|
|
conn.txReq = True
|
|
conn.busyTimer = conn.factory.reactor.callLater(
|
|
5.0, conn.goIdle)
|
|
self.pong()
|
|
|
|
def loginResponse(self, info):
|
|
log.msg("%s login: %s" % (self.user.ON, info['al']))
|
|
|
|
def clientsListUpdated(self, clients):
|
|
self.clients = clients
|
|
self.clientsById = dict([(i['id'], i) for i in clients])
|
|
if self.clientId is None:
|
|
for c in clients:
|
|
if c['on'] == self.user.ON and c['bc'] == self.user.BC:
|
|
self.clientId = c['id']
|
|
|
|
class FRNCrosslinkClientFactory(FRNClientFactory):
|
|
protocol = FRNCrosslinkClient
|
|
reactor = reactor
|
|
|
|
def buildProtocol(self, addr):
|
|
p = FRNClientFactory.buildProtocol(self, addr)
|
|
self.connection = p
|
|
return p
|
|
|
|
|
|
if __name__ == '__main__':
|
|
import sys
|
|
from os.path import dirname, join as pjoin
|
|
from ConfigParser import ConfigParser
|
|
|
|
log.startLogging(sys.stderr)
|
|
|
|
basedir = dirname(__file__)
|
|
|
|
acfg = ConfigParser()
|
|
acfg.read(['/etc/grn/accounts.conf',
|
|
pjoin(basedir,'accounts.conf'), 'accounts.conf'])
|
|
|
|
scfg = ConfigParser()
|
|
scfg.read(['/etc/grn/servers.conf',
|
|
pjoin(basedir,'servers.conf'), 'servers.conf'])
|
|
|
|
argc = len(sys.argv)
|
|
if argc > 1:
|
|
for client_data in sys.argv[1:]:
|
|
account_name, server_name, network_name = client_data.split(':',2)
|
|
account_cfg = acfg.items(account_name)+[('network', network_name)]
|
|
server_cfg = scfg.items(server_name)
|
|
server = scfg.get(server_name, 'server')
|
|
port = scfg.getint(server_name, 'port')
|
|
d = dict(account_cfg)
|
|
user = FRNUser(
|
|
EA=d['email'],
|
|
PW=d['password'], ON=d['operator'],
|
|
# BC=d['transmission'], DS=d['description'],
|
|
BC="Crosslink", DS=d['description'],
|
|
NN=d['country'], CT=d['city'], NT=d['network'])
|
|
factory = FRNCrosslinkClientFactory(user)
|
|
clients.append((server, port, user, factory))
|
|
reactor.connectTCP(server, port, factory)
|
|
reactor.run()
|
|
|
|
|
|
# vim: set et ai sw=4 ts=4 sts=4:
|