#!/usr/bin/env python # -*- coding: utf-8 -*- # # Copyright 2010 Maurizio Porrato # See LICENSE.txt for copyright info import subprocess from frn.protocol.client import FRNClient, FRNClientFactory from frn.user import FRNUser from twisted.internet import reactor, task from twisted.internet.defer import DeferredList from twisted.python import log import os, string from Queue import Queue from twisted.internet.task import LoopingCall import fcntl from twisted.internet.protocol import ProcessProtocol class StreamingProtocol(ProcessProtocol): _silenceFrame = open("sounds/silence-gsm.gsm", "rb").read() def __init__(self): self._frames = Queue() self._streamTimer = LoopingCall.withCount(self.sendStreamFrame) def connectionMade(self): log.msg("Streaming process started") self._streamTimer.start(0.20) def inConnectionLost(self): log.msg("connection lost") self._streamTimer.stop() def processExited(self, status): log.msg("Streaming process exited (%s)" % str(status)) def sendStreamFrame(self, count): for i in range(count): if self._frames.empty(): frames = self._silenceFrame else: frames = self._frames.get_nowait() self.transport.write(frames) def feed(self, frame): self._frames.put_nowait(frame) def eof(self): self.transport.closeStdin() STREAM_CMD="""tools/gsmstream.sh""" class FRNStream(FRNClient): def __init__(self): self._stream = StreamingProtocol() def connectionMade(self): FRNClient.connectionMade(self) reactor.spawnProcess(self._stream, "bash", ["bash", "-c", STREAM_CMD], os.environ) def connectionLost(self, reason): FRNClient.connectionLost(self, reason) self._stream.eof() def getClientName(self, client_id): if self.clientsById.has_key(client_id): return self.clientsById[client_id]['ON'] else: return client_id def audioFrameReceived(self, from_id, frames): self._stream.feed(frames) self.pong() def loginResponse(self, info): log.msg("Login: %s" % info['AL']) def clientsListUpdated(self, clients): self.clients = clients self.clientsById = dict([(i['ID'], i) for i in clients]) class FRNStreamFactory(FRNClientFactory): protocol = FRNStream reactor = reactor 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 >= 3: server_name, network_name = sys.argv[2].split(':',1) account_cfg = acfg.items(sys.argv[1])+[('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'], NN=d['country'], CT=d['city'], NT=d['network']) reactor.connectTCP(server, port, FRNStreamFactory(user)) reactor.run() # vim: set et ai sw=4 ts=4 sts=4: