diff --git a/switchio/models.py b/switchio/models.py index 251854a..6f9862e 100644 --- a/switchio/models.py +++ b/switchio/models.py @@ -10,6 +10,7 @@ import multiprocessing as mp from concurrent import futures from pprint import pprint +import warnings from . import utils @@ -229,7 +230,7 @@ def getvar(self, var): def setvar(self, var, value): """Set variable to value """ - self.broadcast("set::{}={}".format(var, value)) + self.execute('set', '='.join((var, value))) def setvars(self, params): """Set all variables in map `params` with a single command @@ -241,7 +242,7 @@ def setvars(self, params): def unsetvar(self, var): """Unset a channel var. """ - self.broadcast("unset::{}".format(var)) + return self.execute("unset", var) def answer(self): self.con.api("uuid_answer {}".format(self.uuid)) @@ -302,15 +303,13 @@ def playback(self, args, start_sample=None, endless=False, else: # set a stream file delimiter self.setvar('playback_delimiter', delim) - self.broadcast( - '{app}::{varset}{streams}{start} {leg}'.format( - app=app, + varset = '{{{vars}}}'.format(','.join(pairs)) if pairs else '' + args = '{streams}{start}'.format( streams=delim.join(args), start='@@{}'.format(start_sample) if start_sample else '', - leg=leg, - varset='{{{vars}}}'.format(','.join(pairs)) if pairs else '', + # leg=leg, ) - ) + self.execute(app, args, params=varset) def start_record(self, path, rx_only=False, stereo=False, rate=16000): '''Record audio from this session to a local file on the slave filesystem @@ -326,7 +325,7 @@ def start_record(self, path, rx_only=False, stereo=False, rate=16000): self.setvar('RECORD_STEREO', 'true') self.setvar('record_sample_rate', '{}'.format(rate)) - self.broadcast('record_session::{}'.format(path)) + self.execute('record_session', path) def stop_record(self, path='all', delay=0): '''Stop recording audio from this session to a local file on the slave @@ -336,13 +335,13 @@ def stop_record(self, path='all', delay=0): https://freeswitch.org/confluence/display/FREESWITCH/mod_dptools%3A+stop_record_session ''' if delay: - self.con.api( - "sched_api +{delay} none uuid_broadcast {sessid} " - "stop_record_session::{path}". - format(sessid=self.uuid, delay=delay, path=path) + self.execute( + "sched_api", + "+{delay} none stop_record_session {path}". + format(delay=delay, path=path) ) else: - self.broadcast('stop_record_session::{}'.format(path)) + self.execute('stop_record_session', path) def record(self, action, path, rx_only=True): '''Record audio from this session to a local file on the slave filesystem @@ -356,9 +355,9 @@ def record(self, action, path, rx_only=True): self.con.api('uuid_record {} {} {}'.format(self.uuid, action, path)) def echo(self): - '''Echo back all audio recieved + '''Echo back all audio recieved. ''' - self.broadcast('echo::') + self.execute('echo') def bypass_media(self, state): '''Re-invite a bridged node out of the media path for this session @@ -383,6 +382,12 @@ def park(self): self.con.api('uuid_park {}'.format(self.uuid)) return self.recv('CHANNEL_PARK') + def execute(self, cmd, arg='', params='', loops=1): + """Execute an application async. + """ + return self.con.execute( + self.uuid, cmd, arg, params=params, loops=loops) + def broadcast(self, path, leg='', delay=None, hangup_cause=None): """Execute an application async on a chosen leg(s) with optional hangup afterwards. If provided tell FS to schedule the app ``delay`` seconds @@ -394,6 +399,11 @@ def broadcast(self, path, leg='', delay=None, hangup_cause=None): .. _sched_broadcast: https://freeswitch.org/confluence/display/FREESWITCH/mod_commands#mod_commands-sched_broadcast """ + warnings.warn(( + "`Session.broadcast()` has been deprecated due to unreliable\ + `uuid_broadcast` behaviour in FreeSWITCH core. Use\ + `Session.execute()` instead."), + DeprecationWarning) if not delay: return self.con.api( 'uuid_broadcast {} {} {}'.format(self.uuid, path, leg)) @@ -414,8 +424,9 @@ def bridge(self, dest_url=None, profile=None, gateway=None, proxy=None, if gateway: profile = 'gateway/{}'.format(gateway) - self.broadcast( - "bridge::{{{varset}}}sofia/{}/{}{dest}".format( + self.execute( + 'bridge', + "{{{varset}}}sofia/{}/{}{dest}".format( profile if profile else self['variable_sofia_profile_name'], dest_url if dest_url else self['variable_sip_req_uri'], varset=','.join(pairs), @@ -455,7 +466,7 @@ def respond(self, response): .. _respond: https://freeswitch.org/confluence/display/FREESWITCH/mod_dptools%3A+respond """ - self.broadcast('respond::{}'.format(response)) + self.execute('respond', response) def deflect(self, uri): """Send a refer to the client. @@ -464,7 +475,13 @@ def deflect(self, uri): """ - self.broadcast("deflect::{}".format(uri)) + self.execute("deflect", uri) + + def speak(self, text, engine='flite', voice='kal', timer_name=''): + """Speak, young switch (alpha). + """ + return self.execute( + 'speak', '|'.join((engine, voice, text, timer_name))) def is_inbound(self): """Return bool indicating whether this is an inbound session