diff --git a/recorder.py b/recorder.py new file mode 100755 index 0000000..c97d595 --- /dev/null +++ b/recorder.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2010 Maurizio Porrato +# See LICENSE.txt for copyright info + +from __future__ import with_statement +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, time +safe_chars = string.ascii_letters+string.digits+' :;.,+-=$@' + +AUDIO_TIMEOUT = 5.0 + +def sanitizeFilename(name): + r = '' + for c in name: + if c in safe_chars: + r += c + return r + + +class FRNRecorder(FRNClient): + + def getClientName(self, client_id): + if self.clientsById.has_key(client_id): + return self.clientsById[client_id]['on'] + else: + return client_id + + def buildRecordingName(self, client_id): + ts = time.localtime() + opname = sanitizeFilename(self.clients[client_id-1]['on']) + dirname = "/var/spool/grn/recordings/"+time.strftime("%Y%m/%d/%H", ts) + filename = time.strftime("%Y%m%d%H%M%S-", ts) + opname + '.gsm' + try: + os.makedirs(dirname) + except OSError: pass + return dirname+'/'+filename + + def textMessageReceived(self, client, message, target): + pass + + def archiveRecording(self, from_id): + log.msg("%s stopped talking: starting playback." % + self.clients[from_id-1]['on']) + self.recordingFile.close() + self.recordingFile = None + self.recordingOperator = None + + def audioFrameReceived(self, from_id, frames): + if self.recordingOperator != self.clients[from_id-1]['on']: + if self.recordingOperator is not None: + self.recordingFile.close() + self.recordingOperator = self.clients[from_id-1]['on'] + self.recordingFile = file(self.buildRecordingName(from_id), 'wb') + self.recordingFile.write(frames) + try: + self.parrot_timer.reset(AUDIO_TIMEOUT) + except: + log.msg("%s started talking" % + self.clients[from_id-1]['on']) + self.parrot_timer = self.factory.reactor.callLater( + AUDIO_TIMEOUT, self.archiveRecording, from_id) + self.pong() + + def loginResponse(self, info): + log.msg("Login: %s" % info['al']) + self.setStatus(1) + self.recordingOperator = None + self.recordingFile = None + + def clientsListUpdated(self, clients): + self.clients = clients + self.clientsById = dict([(i['id'], i) for i in clients]) + + +class FRNRecorderFactory(FRNClientFactory): + protocol = FRNRecorder + 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, FRNRecorderFactory(user)) + reactor.run() + + +# vim: set et ai sw=4 ts=4 sts=4: