You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

116 lines
3.6 KiB

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import with_statement
from frn.protocol.client import FRNClient, FRNClientFactory
from twisted.internet import reactor, task
from twisted.internet.defer import DeferredList
from twisted.python import log
import os, string
safe_chars = string.ascii_letters+string.digits+' :;.,+-=$@'
PARROT_AUDIO_DELAY = 5.0
def sanitizeFilename(name):
r = ''
for c in name:
if c in safe_chars:
r += c
return r
class FRNParrot(FRNClient):
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):
log.msg("Type %s message from %s: %s" %
(target, self.getClientName(client), message))
if target == 'P': # Only reply to private messages
if not message.startswith('play'):
self.sendTextMessage(client, message)
else:
cmd = message.split()
if len(cmd) > 1:
message = sanitizeFilename(cmd[1])
else:
message = 'monkeys'
filename = 'sounds/%s.wav' % message
if os.path.exists(filename):
log.msg("Streaming file %s" % filename)
with file(filename, 'rb') as sf:
sf.seek(0x3c) # Skip wav header
while True:
b = sf.read(325)
if len(b) < 325:
break
self.feedStreaming(b)
self.factory.reactor.callLater(0.5,
self.startStreaming)
else:
self.sendTextMessage(client, "File not found")
def stopTransmission(self):
FRNClient.stopTransmission(self)
log.msg("Stopped playback.")
def startRepeating(self, from_id):
log.msg("%s stopped talking: starting playback." %
self.clients[from_id-1]['on'])
self.startStreaming()
def audioFrameReceived(self, from_id, frames):
recname = sanitizeFilename(self.clients[from_id-1]['on'])
with file('recordings/%s.gsm' % recname, 'ab') as f:
f.write(frames)
self.feedStreaming(frames)
try:
self.parrot_timer.reset(PARROT_AUDIO_DELAY)
except:
log.msg("%s started talking" %
self.clients[from_id-1]['on'])
self.parrot_timer = self.factory.reactor.callLater(
PARROT_AUDIO_DELAY, self.startRepeating, from_id)
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 FRNParrotFactory(FRNClientFactory):
protocol = FRNParrot
reactor = reactor
if __name__ == '__main__':
import sys
from ConfigParser import ConfigParser
log.startLogging(sys.stderr)
cfg = ConfigParser()
cfg.read('stations.conf')
if len(sys.argv) > 1:
station = sys.argv[1]
else:
stations = cfg.sections()
stations.sort()
station = cfg.sections()[0]
log.msg("Profile not specified: using '%s'" % station)
station_conf = dict(cfg.items(station))
reactor.connectTCP('master.freeradionetwork.it', 10024,
FRNParrotFactory(**station_conf))
reactor.run()
# vim: set et ai sw=4 ts=4 sts=4: