def queue_status(): MANAGER = Manager(loop=asyncio.get_event_loop(), host='127.0.0.1', username='******', secret='password') yield from MANAGER.connect() queues_details = yield from MANAGER.send_action({'Action': 'QueueStatus', 'Queue': 'queue_name'}) pprint(queues_details)
def main(): """Função principal da aplicação.""" manager = Manager( loop=asyncio.get_event_loop(), host=ASTERISK_IP, port=ASTERISK_PORT, username=ASTERISK_USER, secret=ASTERISK_PASSWORD, ) @manager.register_event("QueueCallerLeave") @manager.register_event("AgentCalled") @manager.register_event("AgentConnect") @manager.register_event("AgentComplete") @manager.register_event("AgentDump") # @manager.register_event("AgentRingNoAnswer") @manager.register_event("MessageWaiting") # @manager.register_event('UserEvent') async def callback_agent(manager, message): fire(message) @manager.register_event("Hangup") async def callback_hangup(manager, message): # hangup from queue, external only if message.context == "ext-queues": fire(message) manager.connect() try: manager.loop.run_forever() except KeyboardInterrupt: manager.loop.close()
def attach(self, amihost): """ attach amihost to a ChannelManager. Args: amihost (dict): A dictionary containing the connection settings for an AMI host. """ # Create Panoramisk asterisk AMI manager. amimgr = Manager(loop=self.loop, host=amihost['host'], port=amihost['port'], username=amihost['username'], secret=amihost['password'], ssl=False, encoding='utf8', log=self.logger) # Create our own channel manager. channel_manager = self.channel_manager(reporter=self.reporter, ) # Tell Panoramisk to which events we want to listen. for event_name in channel_manager.INTERESTING_EVENTS: amimgr.register_event(event_name, self.on_event) # Record them for later use. self.amimgrs[amimgr] = channel_manager # Tell asyncio what to work on. asyncio.ensure_future(amimgr.connect())
def extension_status(): manager = Manager(loop=asyncio.get_event_loop(), host='127.0.0.1', username='******', secret='password') yield from manager.connect() extension = yield from manager.send_action_via_manager({'Action': 'ExtensionState', 'Exten': '2001', 'Context': 'default'}) pprint(extension)
def attach(self, amihost): """ attach amihost to a ChannelManager. Args: amihost (dict): A dictionary containing the connection settings for an AMI host. """ # Create Panoramisk asterisk AMI manager. amimgr = Manager( loop=self.loop, host=amihost['host'], port=amihost['port'], username=amihost['username'], secret=amihost['password'], ssl=False, encoding='utf8') # Create our own channel manager. channel_manager = self.channel_manager( reporter=self.reporter, ) # Tell Panoramisk to which events we want to listen. channel_manager._pre_connect(amimgr) # Record them for later use. self.amimgrs.append(amimgr) self.channel_managers.append(channel_manager) # Tell asyncio what to work on. asyncio.async(amimgr.connect())
class Bridge: def __init__(self, options, filters, push_configs): self.loop = asyncio.get_event_loop() max_queues = options.pop("max_size", DEFAULT_MAX_QUEUES) max_queue_size = options.pop("max_queue_size", DEFAULT_MAX_QUEUE_SIZE) self.controller = Controller(self.loop, max_queues, max_queue_size) self.controller.load_configs(filters, push_configs) options.pop("loop", None) # discard invalid argument self.manager = Manager(loop=self.loop, **options) self.manager.log.addHandler(logging.NullHandler()) self.manager.register_event("*", self.handle_events) @asyncio.coroutine def handle_events(self, manager, message): wrapper = MessageWrapper(message) yield from self.controller.handle(wrapper) @asyncio.coroutine def connect(self): yield from self.manager.connect() def run(self): try: self.loop.run_until_complete(self.connect()) self.loop.run_forever() finally: self.loop.close()
def queue_status(): manager = Manager(loop=asyncio.get_event_loop(), host='127.0.0.1', port=5039, username='******', secret='mysecret') yield from manager.connect() queues_details = yield from manager.send_action({'Action': 'QueueStatus', 'Queue': 'queue_name'}) manager.close() pprint(queues_details)
def extension_status(): manager = Manager(loop=asyncio.get_event_loop(), host='127.0.0.1', port=5039, username='******', secret='password') yield from manager.connect() extension = yield from manager.send_action({'Action': 'ExtensionState', 'Exten': '2001', 'Context': 'default'}) manager.close() pprint(extension)
def originate(): manager = Manager(loop=asyncio.get_event_loop(), host='127.0.0.1', username='******', secret='password') yield from manager.connect() result = yield from manager.send_action_via_manager({'Action': 'Originate', 'Channel': 'SIP/gawel', 'WaitTime': 20, 'CallerID': 'gawel', 'Exten': '0299999999', 'Context': 'default', 'Priority': 1,}) pprint(result)
def ping(lp, username, secret): manager = Manager(loop=lp, host='127.0.0.1', port=5038, username=username, secret=secret, forgetable_actions=('login',)) yield from manager.connect() while True: p = yield from manager.send_action({'Action': 'ping'}) # p = yield from manager.send_action({'Action': 'SIPpeers'}) pprint(p) yield from asyncio.sleep(1) manager.close()
def queue_status(): MANAGER = Manager(loop=asyncio.get_event_loop(), host='127.0.0.1', username='******', secret='password') yield from MANAGER.connect() queues_details = yield from MANAGER.send_action_via_manager({ 'Action': 'QueueStatus', 'Queue': 'queue_name' }) pprint(queues_details)
def ping(lp, username, secret): manager = Manager(loop=lp, host='127.0.0.1', port=5038, username=username, secret=secret, forgetable_actions=('login', )) yield from manager.connect() while True: p = yield from manager.send_action({'Action': 'ping'}) # p = yield from manager.send_action({'Action': 'SIPpeers'}) pprint(p) yield from asyncio.sleep(1) manager.close()
def test_reconnection_without_lost(event_loop, unused_tcp_port_factory): unused_tcp_port = unused_tcp_port_factory() print('Start server on %s' % unused_tcp_port) manager = Manager(loop=event_loop, host='127.0.0.1', port=unused_tcp_port, username='******', secret='secret') server = Asterisk(event_loop, unused_tcp_port) yield from server.start() yield from manager.connect() yield from server.data_received() login = server.actions[0] assert login['action'] == 'Login' unused_tcp_port = unused_tcp_port_factory() print('Restart server on %s' % unused_tcp_port) server.port = unused_tcp_port manager.config['port'] = unused_tcp_port yield from server.stop() manager.send_action({'Action': 'Ping'}) f = manager.send_action({'Action': 'Test', 'Command': 'test'}) fully_booted = Event('FullyBooted') yield from asyncio.sleep(.1) assert manager.awaiting_actions yield from server.start() yield from asyncio.sleep(2) assert manager.awaiting_actions manager.dispatch(fully_booted) yield from asyncio.sleep(.5) assert not manager.awaiting_actions resp = yield from f yield from server.stop() login2 = server.actions[0] assert login2['action'] == 'Login' assert login['actionid'] != login2['actionid'] test_action = server.actions[-1] assert test_action.id == resp.id assert test_action['action'] == 'Test'
def test_reconnection_without_lost(event_loop): unused_tcp_port = unused_tcp_port_factory() print('Start server on %s' % unused_tcp_port) manager = Manager(loop=event_loop, host='127.0.0.1', port=unused_tcp_port, username='******', secret='secret') server = Asterisk(event_loop, unused_tcp_port) yield from server.start() yield from manager.connect() yield from server.data_received() login = server.actions[0] assert login['action'] == 'Login' unused_tcp_port = unused_tcp_port_factory() print('Restart server on %s' % unused_tcp_port) server.port = unused_tcp_port manager.config['port'] = unused_tcp_port yield from server.stop() manager.send_action({'Action': 'Ping'}) f = manager.send_action({'Action': 'Test', 'Command': 'test'}) fully_booted = Event('FullyBooted') yield from asyncio.sleep(.1) assert manager.awaiting_actions yield from server.start() yield from asyncio.sleep(2) assert manager.awaiting_actions manager.dispatch(fully_booted) yield from asyncio.sleep(.5) assert not manager.awaiting_actions resp = yield from f yield from server.stop() login2 = server.actions[0] assert login2['action'] == 'Login' assert login['actionid'] != login2['actionid'] test_action = server.actions[-1] assert test_action.id == resp.id assert test_action['action'] == 'Test'
def attach(self, asterisk): """ Set up a connection to the specified Asterisk Args: asterisk (str): A connection string """ ami_host = urlparse(asterisk) # Create Panoramisk asterisk AMI manager. manager = Manager(loop=self.loop, host=ami_host.hostname, port=ami_host.port, username=ami_host.username, secret=ami_host.password, ssl=ami_host.scheme in ('ssl', 'tls'), encoding='utf8', log=self.logger) # Create our own channel manager. event_handler = self.event_handler( reporter=self.reporter, hostname=ami_host.hostname, logger=self.logger, ) # Tell Panoramisk to which events we want to listen. if event_handler.FILTER_EVENTS: for event_name in event_handler.event_handlers().keys(): manager.register_event(event_name, self.on_event) else: manager.register_event('*', self.on_event) # Record them for later use. self.ami_managers[manager] = event_handler # Tell asyncio what to work on. asyncio.ensure_future(manager.connect())
def putCids(lp, args, config): auth = HTTPBasicAuth(config['carddav']['user'], config['carddav']['pass']) url = config['carddav']['url'] # connect to asterisk ami = Manager(host=config['ami']['host'], port=config['ami']['port'], username=config['ami']['user'], secret=config['ami']['pass']) yield from ami.connect() # get phone numbers from vcard for vurl in getAllVcardLinks(url, auth): r = requests.request("GET", vurl, auth=auth) try: vcard = vobject.readOne(r.text) except ParseError as e: print(e) continue if "tel" in vcard.contents: for telno in vcard.contents['tel']: num = tidyPhoneNumber(config, telno.value) if num and "fn" in vcard.contents: name = vcard.fn.value print("Adding/updating Number: %s Name: %s" % (num, name), end="... ") if not args.no_update: ami_result = yield from ami.send_action({ "Action": "DBPut", "Family": "cidname", "Key": num, "Val": name }) print(ami_result.Response) else: print("no-update") ami.close()
class Asterisk(object): requires = ['irc3.plugins.command'] def __init__(self, bot): self.bot = bot self.bot.asterirc = self self.config = config = dict( host='127.0.0.1', port=5038, http_port='8088', protocol='http', debug=True, ) config.update(bot.config.get('asterisk', {})) self.log = logging.getLogger('irc3.ast') self.ilog = logging.getLogger('irc.asterirc') self.ilog.set_irc_targets(bot, self.config['channel']) self.log.info('Channel is set to {channel}'.format(**config)) self.rooms = defaultdict(dict) self.http = None self.resolver = irc3.utils.maybedotted(self.config['resolver']) self.manager = Manager(log=logging.getLogger('irc3.ast.manager'), **config) self.manager.register_event('Shutdown', self.handle_shutdown) self.manager.register_event('Meet*', self.handle_meetme) if config.get('debug'): self.manager.register_event('*', self.handle_event) if isinstance(self.resolver, type): self.resolver = self.resolver(bot) def connection_made(self): self.bot.loop.call_later(1, self.connect) def post_connect(self): self.log.debug('post_connect') resp = self.send_action({'Action': 'Status'}) if resp.success: self.update_meetme() else: # pragma: no cover self.log.error(resp.text) self.bot.loop.call_later(1, self.post_connect) def update_meetme(self): resp = self.send_command('meetme list') if resp.success: if 'No active MeetMe conferences.' in resp.text: self.rooms = defaultdict(dict) for line in resp.lines[1:-2]: room = line.split(' ', 1)[0] if not room or not room.isdigit(): continue resp = self.send_command('meetme list ' + room) if resp.success and resp.iter_lines(): room = self.rooms[room] for line in resp.lines: if not line.startswith('User '): continue line = line.split('Channel:')[0] splited = [s for s in line.split() if s][2:] uid = splited.pop(0) caller = ' '.join(splited[1:]) if 'external call ' in caller.lower(): e, c, n = caller.split(' ')[:4] caller = ' '.join([e, c, n[:6]]) room[caller] = uid def connect(self): if self.manager is not None: self.manager.close() self.bot.loop.call_later(5, self.post_connect) try: self.manager.connect() except Exception as e: self.log.exception(e) self.log.info('connect retry in 5s') self.bot.loop.call_later(1, self.connect) return False else: return True def handle_shutdown(self, event, manager): self.manager.close() self.bot.loop.call_later(2, self.connect) def handle_event(self, event, manager): self.log.debug('handle_event %s %s', event, '') # , event.headers) def handle_meetme(self, event, manager): self.log.debug('handle_meetme %s %s', event, event.headers) lower_header_keys(event) name = event.name.lower() room = event['meetme'] if name == 'meetmeend': if room in self.rooms: # pragma: no cover del self.rooms[room] self.ilog.info('room {} is closed.'.format(room)) return action = None caller = event['calleridname'] if 'external call ' in caller.lower(): e, c, n = caller.split(' ')[:4] caller = ' '.join([e, c, n[:6]]) elif 'external call' in caller.lower(): # pragma: no cover caller += event['calleridnum'][:6] if 'join' in name: action = 'join' self.rooms[room][caller] = event['usernum'] elif 'leave' in name: action = 'leave' if caller in self.rooms.get(room, []): del self.rooms[room][caller] if action: # log args = dict(caller=caller, action=action, room=room, total=len(self.rooms[room])) self.ilog.info(( '{caller} has {action} room {room} ' '(total in this room: {total})').format(**args)) def send_action(self, *args, **kwargs): try: res = self.manager.send_action(*args, **kwargs) return res except Exception as e: self.log.error('send_action(%r, **%r)', args, kwargs) self.log.exception(e) return Message('response', 'Sorry an error occured. ({})'.format(repr(e)), headers={'Response': 'Failed'}) def send_command(self, command, debug=False): resp = self.send_action({'Action': 'Command', 'Command': command}) if debug: # pragma: no cover self.log.debug('Command "%s" => Succeed: %s, Data:\n%s', command, resp.success, getattr(resp, 'text', resp)) if resp.success: resp.lines = [] if resp['response'].lower() == 'follows': resp.lines = resp.text.split('\n') return resp @command(permission='voip') def call(self, mask, target, args): """Call someone. Destination and from can't contains spaces. %%call <destination> [<from>] """ if 'nick' not in args: args['nick'] = mask.nick callee = self.resolver(mask, args['<destination>']) if args['<from>']: caller = self.resolver(mask, args['<from>']) else: caller = self.resolver(mask, mask.nick) if caller is None or caller.get('channel') is None: return '{nick}: Your caller is invalid.'.format(**args) if callee is None or callee.get('exten') is None: return '{nick}: Your destination is invalid.'.format(**args) action = { 'Action': 'Originate', 'Channel': caller['channel'], 'WaitTime': 20, 'CallerID': caller.get('fullname', caller['channel']), 'Exten': callee['exten'], 'Context': caller.get('context', 'default'), 'Priority': 1, } resp = self.send_action(action) if resp.success: return '{nick}: Call to {<destination>} done.'.format(**args) else: return resp.text @command(permission='voip') def room(self, mask, target, args): """Invite/kick someone in a room. You can use more than one destination. Destinations can't contains spaces. %%room (list|invite|kick) [<room>] [<destination>...] """ args['nick'] = mask.nick room = args['<room>'] if args['invite']: callees = args['<destination>'] message = '{nick}: {<from>} has been invited to room {<room>}.' if not callees: # self invite callees = [mask.nick] message = '{nick}: You have been invited to room {<room>}.' resolved = [self.resolver(mask, c) for c in callees] if None in resolved: # show invalid arguments and quit callees = zip(resolved, callees) invalid = [c for r, c in callees if r is None] yield ( "{0}: I'm not able to resolve {1}. Please fix it!" ).format(mask.nick, ', '.join(invalid)) raise StopIteration() for callee in callees: # call each args['<destination>'] = args['<room>'] args['<from>'] = callee msg = self.call(mask, target, args) if 'Call to' in msg: yield message.format(**args) else: yield msg if room and room not in self.rooms: yield 'Invalid room' raise StopIteration() if args['list']: def fmt(room, users): amount = len(users) users = ', '.join([u for u in sorted(users)]) return 'Room {0} ({1}): {2}'.format(room, amount, users) if room: yield fmt(room, self.rooms[room]) elif self.rooms: for room, users in self.rooms.items(): yield fmt(room, self.rooms[room]) else: yield 'Nobody here.' elif args['kick']: users = self.rooms[room] commands = [] for victim in args['<destination>']: for user in users: if victim.lower() in user.lower(): peer = users[user] commands.append(( user, 'meetme kick {0} {1}'.format(room, peer))) if not commands: yield 'No user matching query' raise StopIteration() for user, cmd in commands: resp = self.send_command(cmd) if resp.success: del self.rooms[room][user] if not self.rooms[room]: del self.rooms[room] yield '{0} kicked from {1}.'.format(user, room) else: # pragma: no cover yield 'Failed to kick {0} from {1}.'.format(user, room) @command(permission='voip') def asterisk(self, mask, target, args): """Show voip status %%asterisk status [<id>] """ self.log.info('voip %s %s %s', mask, target, args) args['nick'] = mask.nick if args['<id>']: peer = self.resolver(mask.nick, args['<id>']) else: peer = self.resolver(mask, mask.nick) if peer is None: return '{nick}: Your id is invalid.'.format(**args) action = {'Action': 'SIPshowpeer', 'peer': peer['login']} resp = self.send_action(action) if resp.success: print(resp.lheaders) return ('{nick}: Your VoIP phone is registered. ' '(User Agent: {sip-useragent} on {address-ip})' ).format(nick=mask.nick, **resp.lheaders) @command(permission='admin', venusian_category='irc3.debug') def asterisk_command(self, mask, target, args): # pragma: no cover """Send a raw command to asterisk. Use "help" to list core commands. %%asterisk_command <command>... """ cmd = ' '.join(args['<command>']) cmd = dict( help='core show help', ).get(cmd, cmd) resp = self.send_command(cmd, debug=True) return resp.success @command(permission='admin', venusian_category='irc3.debug') def asterisk_originate(self, mask, target, args): # pragma: no cover """Send raw originate %%asterisk_originate <Channel> <CallerID> <Exten> <Context> """ action = { 'Action': 'Originate', 'WaitTime': 20, 'Priority': 1, } for k, v in list(args.items()): if k.startswith('<'): action[k.strip('<>')] = v self.send_action(action) return 'Action {} sent'.format(repr(action)) def SIGINT(self): if self.manager is not None: self.manager.close() self.log.info('SIGINT: connection closed')
class Asterisk(object): requires = ['irc3.plugins.command'] def __init__(self, bot): self.bot = bot self.bot.asterirc = self self.config = config = dict( host='127.0.0.1', port=5038, http_port='8088', protocol='http', debug=True, ) config.update(bot.config.get('asterisk', {})) self.log = logging.getLogger('irc3.ast') self.ilog = logging.getLogger('irc.asterirc') self.ilog.set_irc_targets(bot, self.config['channel']) self.log.info('Channel is set to {channel}'.format(**config)) self.rooms = defaultdict(dict) self.http = None self.resolver = irc3.utils.maybedotted(self.config['resolver']) self.manager = Manager(log=logging.getLogger('irc3.ast.manager'), **config) self.manager.register_event('Shutdown', self.handle_shutdown) self.manager.register_event('Meet*', self.handle_meetme) if config.get('debug'): self.manager.register_event('*', self.handle_event) if isinstance(self.resolver, type): self.resolver = self.resolver(bot) def connection_made(self): self.bot.loop.call_later(1, self.connect) def post_connect(self): self.log.debug('post_connect') resp = self.send_action({'Action': 'Status'}) if resp.success: self.update_meetme() else: # pragma: no cover self.log.error(resp.text) self.bot.loop.call_later(1, self.post_connect) def update_meetme(self): resp = self.send_command('meetme list') if resp.success: if 'No active MeetMe conferences.' in resp.text: self.rooms = defaultdict(dict) for line in resp.lines[1:-2]: room = line.split(' ', 1)[0] if not room or not room.isdigit(): continue resp = self.send_command('meetme list ' + room) if resp.success and resp.iter_lines(): room = self.rooms[room] for line in resp.lines: if not line.startswith('User '): continue line = line.split('Channel:')[0] splited = [s for s in line.split() if s][2:] uid = splited.pop(0) caller = ' '.join(splited[1:]) if 'external call ' in caller.lower(): e, c, n = caller.split(' ')[:4] caller = ' '.join([e, c, n[:6]]) room[caller] = uid def connect(self): if self.manager is not None: self.manager.close() self.bot.loop.call_later(5, self.post_connect) try: self.manager.connect() except Exception as e: self.log.exception(e) self.log.info('connect retry in 5s') self.bot.loop.call_later(1, self.connect) return False else: return True def handle_shutdown(self, event, manager): self.manager.close() self.bot.loop.call_later(2, self.connect) def handle_event(self, event, manager): self.log.debug('handle_event %s %s', event, '') # , event.headers) def handle_meetme(self, event, manager): self.log.debug('handle_meetme %s %s', event, event.headers) lower_header_keys(event) name = event.name.lower() room = event['meetme'] if name == 'meetmeend': if room in self.rooms: # pragma: no cover del self.rooms[room] self.ilog.info('room {} is closed.'.format(room)) return action = None caller = event['calleridname'] if 'external call ' in caller.lower(): e, c, n = caller.split(' ')[:4] caller = ' '.join([e, c, n[:6]]) elif 'external call' in caller.lower(): # pragma: no cover caller += event['calleridnum'][:6] if 'join' in name: action = 'join' self.rooms[room][caller] = event['usernum'] elif 'leave' in name: action = 'leave' if caller in self.rooms.get(room, []): del self.rooms[room][caller] if action: # log args = dict(caller=caller, action=action, room=room, total=len(self.rooms[room])) self.ilog.info(('{caller} has {action} room {room} ' '(total in this room: {total})').format(**args)) def send_action(self, *args, **kwargs): try: res = self.manager.send_action(*args, **kwargs) return res except Exception as e: self.log.error('send_action(%r, **%r)', args, kwargs) self.log.exception(e) return Message('response', 'Sorry an error occured. ({})'.format(repr(e)), headers={'Response': 'Failed'}) def send_command(self, command, debug=False): resp = self.send_action({'Action': 'Command', 'Command': command}) if debug: # pragma: no cover self.log.debug('Command "%s" => Succeed: %s, Data:\n%s', command, resp.success, getattr(resp, 'text', resp)) if resp.success: resp.lines = [] if resp['response'].lower() == 'follows': resp.lines = resp.text.split('\n') return resp @command(permission='voip') def call(self, mask, target, args): """Call someone. Destination and from can't contains spaces. %%call <destination> [<from>] """ if 'nick' not in args: args['nick'] = mask.nick callee = self.resolver(mask, args['<destination>']) if args['<from>']: caller = self.resolver(mask, args['<from>']) else: caller = self.resolver(mask, mask.nick) if caller is None or caller.get('channel') is None: return '{nick}: Your caller is invalid.'.format(**args) if callee is None or callee.get('exten') is None: return '{nick}: Your destination is invalid.'.format(**args) action = { 'Action': 'Originate', 'Channel': caller['channel'], 'WaitTime': 20, 'CallerID': caller.get('fullname', caller['channel']), 'Exten': callee['exten'], 'Context': caller.get('context', 'default'), 'Priority': 1, } resp = self.send_action(action) if resp.success: return '{nick}: Call to {<destination>} done.'.format(**args) else: return resp.text @command(permission='voip') def room(self, mask, target, args): """Invite/kick someone in a room. You can use more than one destination. Destinations can't contains spaces. %%room (list|invite|kick) [<room>] [<destination>...] """ args['nick'] = mask.nick room = args['<room>'] if args['invite']: callees = args['<destination>'] message = '{nick}: {<from>} has been invited to room {<room>}.' if not callees: # self invite callees = [mask.nick] message = '{nick}: You have been invited to room {<room>}.' resolved = [self.resolver(mask, c) for c in callees] if None in resolved: # show invalid arguments and quit callees = zip(resolved, callees) invalid = [c for r, c in callees if r is None] yield ( "{0}: I'm not able to resolve {1}. Please fix it!").format( mask.nick, ', '.join(invalid)) raise StopIteration() for callee in callees: # call each args['<destination>'] = args['<room>'] args['<from>'] = callee msg = self.call(mask, target, args) if 'Call to' in msg: yield message.format(**args) else: yield msg if room and room not in self.rooms: yield 'Invalid room' raise StopIteration() if args['list']: def fmt(room, users): amount = len(users) users = ', '.join([u for u in sorted(users)]) return 'Room {0} ({1}): {2}'.format(room, amount, users) if room: yield fmt(room, self.rooms[room]) elif self.rooms: for room, users in self.rooms.items(): yield fmt(room, self.rooms[room]) else: yield 'Nobody here.' elif args['kick']: users = self.rooms[room] commands = [] for victim in args['<destination>']: for user in users: if victim.lower() in user.lower(): peer = users[user] commands.append( (user, 'meetme kick {0} {1}'.format(room, peer))) if not commands: yield 'No user matching query' raise StopIteration() for user, command in commands: resp = self.send_command(command) if resp.success: del self.rooms[room][user] if not self.rooms[room]: del self.rooms[room] yield '{0} kicked from {1}.'.format(user, room) else: # pragma: no cover yield 'Failed to kick {0} from {1}.'.format(user, room) @command(permission='voip') def asterisk(self, mask, target, args): """Show voip status %%asterisk status [<id>] """ self.log.info('voip %s %s %s', mask, target, args) args['nick'] = mask.nick if args['<id>']: peer = self.resolver(mask.nick, args['<id>']) else: peer = self.resolver(mask, mask.nick) if peer is None: return '{nick}: Your id is invalid.'.format(**args) action = {'Action': 'SIPshowpeer', 'peer': peer['login']} resp = self.send_action(action) if resp.success: print(resp.lheaders) return ('{nick}: Your VoIP phone is registered. ' '(User Agent: {sip-useragent} on {address-ip})').format( nick=mask.nick, **resp.lheaders) @command(permission='admin', venusian_category='irc3.debug') def asterisk_command(self, mask, target, args): # pragma: no cover """Send a raw command to asterisk. Use "help" to list core commands. %%asterisk_command <command>... """ cmd = ' '.join(args['<command>']) cmd = dict(help='core show help', ).get(cmd, cmd) resp = self.send_command(cmd, debug=True) return resp.success @command(permission='admin', venusian_category='irc3.debug') def asterisk_originate(self, mask, target, args): # pragma: no cover """Send raw originate %%asterisk_originate <Channel> <CallerID> <Exten> <Context> """ action = { 'Action': 'Originate', 'WaitTime': 20, 'Priority': 1, } for k, v in list(args.items()): if k.startswith('<'): action[k.strip('<>')] = v self.send_action(action) return 'Action {} sent'.format(repr(action)) def SIGINT(self): if self.manager is not None: self.manager.close() self.log.info('SIGINT: connection closed')
server_side=True) try: server.serve_forever() except Exception as e: print("error on starting web server {0}".format(e)) if __name__ == '__main__': if DEBUG: print('DEBUG enabled') if DEBUG: handler = logging.StreamHandler(sys.stdout) # handler.setLevel(logging.DEBUG) formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) logger.addHandler(handler) else: logging.basicConfig(level=logging.INFO) Thread(target=serve_on_port, args=[SERVE_PORT]).start() bx24 = Bitrix24(BX_INC_HOOK) bx_users = grab_bx_users(bx24) manager.on_connect = on_connect manager.on_login = on_login manager.on_disconnect = on_disconnect manager.connect(run_forever=True, on_startup=on_startup, on_shutdown=on_shutdown)
class AsteriskClient: def __init__(self, loop): self.manager = Manager(loop=loop, host='178.248.87.116', port=1709, username='******', secret='100') self.callManager = CallBaseManager() self.httpclient = HttpClientTornado() self.manager.register_event('FullyBooted', self.FullyBooted) self.manager.register_event('BridgeEnter', self.BridgeEnter) self.manager.register_event('Hangup', self.Hangup) self.manager.connect() try: self.manager.loop.run_forever() except KeyboardInterrupt: self.manager.loop.close() def FullyBooted(self, manager, message): print(message) resp = yield from manager.send_action({'Action': 'SIPpeers'}) self.callManager.FillSIPpeers(resp) resp = yield from manager.send_action({'Action': 'QueueStatus'}) pprint(resp) result = self.httpclient.QueueStatus(resp, method='connect') self.httpclient.SendRequest(result) def BridgeEnter(self, manager, message): # global isDial # isDial=False print(message) Bridge = self.callManager.CallBegin( CallerNumber=message.CallerIDNum, ConnectedNumber=message.ConnectedLineNum) if isinstance(Bridge, dict): resp = yield from manager.send_action({'Action': 'QueueStatus'}) pprint(resp) result = self.httpclient.QueueStatus(resp, method='call_begin', call=Bridge) self.httpclient.SendRequest(result) def Hangup(self, manager, message): print(message) Call = self.callManager.CallEnd(CallerNumber=message.CallerIDNum) if isinstance(Call, dict): resp = yield from manager.send_action({'Action': 'QueueStatus'}) pprint(resp) result = self.httpclient.QueueStatus(resp, method='call_end', call=Call) self.httpclient.SendRequest(result) def ChanSpy(self, channel_from: str, channel_to: str, type: str): call = yield from self.manager.send_action({ 'Action': 'Originate', 'Channel': 'SIP/' + channel_from, 'Application': 'ChanSpy', 'Data': 'SIP/' + channel_to + ',' + type, 'Priority': 1, 'Callerid': 'Spy-{%s} <{%s}>'.format(channel_to), 'Variable': 'SIPADDHEADER="Call-Info:\;answer-after=0"', }) pprint(call) def PickUp(self, channel: str): call = yield from self.manager.send_action({ 'Action': 'Originate', 'Channel': 'SIP/' + channel, 'Application': 'PickupChan', 'Data': 'SIP/' + channel, 'Priority': 1, 'Callerid': channel, 'Variable': 'SIPADDHEADER="Call-Info:\;answer-after=0"', }) pprint(call) def Originate(self, channel_from, channel_to): call = yield from self.manager.send_action({ 'Action': 'Originate', 'Channel': 'SIP/' + channel_from, 'Exten': channel_to, 'Priority': 1, 'Callerid': channel_from, 'Variable': 'SIPADDHEADER="Call-Info:\;answer-after=0"', }) pprint(call) def Redirect(self, channel_from, channel_to): call = yield from self.manager.send_action({ 'Action': 'Redirect', # 'Channel': 'SIP/' + channel_from, # 'Exten': channel_to, 'Priority': 1, 'Context': 'from-internal', }) pprint(call) def QueueAdd(self, channel): call = yield from self.manager.send_action({ 'Action': 'QueueAdd', 'Queue': 'operator', 'Interface': 'SIP/' + channel, 'Penalty': 0, }) pprint(call) def QueueRemove(self, channel): call = yield from self.manager.send_action({ 'Action': 'QueueRemove', 'Queue': 'operator', 'Interface': 'SIP/' + channel, }) pprint(call) def Queue(self, worker: str, action: int): if action == 1: self.QueueAdd(worker) else: self.QueueRemove(worker) def Parse(self, message: dict): method = message['method'] if method == 'call_abonent': self.Originate(message['from'], message['to']) elif method == 'transfer_call': self.Redirect(message['from'], message['to']) elif method == 'connect_with_abonent': self.ChanSpy(message['from'], message['to'], 'qBx') elif method == 'connect_without_abonent': self.ChanSpy(message['from'], message['to'], 'wx') elif method == 'connect_without_microphone': self.ChanSpy(message['from'], message['to'], 'qx') elif method == 'queue': self.Queue(message['worker'], message['action']) # if __name__ == '__main__': # main()