コード例 #1
0
 def reload_module(self, module):
     """
     Realiza reload de configuracion de Asterisk usando AMI
     ATENCION: El comando parece estar blacklisted.
     """
     manager = AMIManagerConnector()
     manager._ami_manager('command', 'module reload {0}'.format(module))
コード例 #2
0
 def reload_music_on_hold_config(self):
     """Realiza reload de configuracion de Asterisk usando AMI
     """
     # TODO: Actualmente  el comando  manager.command(content) del metodo _ami_action
     #       esta devolviendo estos headers:
     #       {'Response': 'Error', 'ActionID': 'xxx', 'Message': 'Command blacklisted'}
     manager = AMIManagerConnector()
     manager.connect()
     manager._ami_manager('command', 'module unload res_musiconhold.so')
     time.sleep(2)
     manager._ami_manager('command', 'module load res_musiconhold.so')
     manager.disconnect()
コード例 #3
0
 def reload_asterisk(self):
     """Realiza reload de configuracion de Asterisk usando AMI
     """
     manager = AMIManagerConnector()
     manager.connect()
     manager._ami_manager('command', 'module reload')
     manager.disconnect()
コード例 #4
0
class SupervisorActivityAmiManager(object):

    EXTENSIONES = [
        "AGENTLOGOUT", "AGENTUNPAUSE", "AGENTPAUSE", "CHANTAKECALL",
        "CHANSPYWISHPER", "CHANSPY", "CHANCONFER"
    ]

    manager = AMIManagerConnector()

    def originate_call(self, originate_data):
        content = originate_data
        data_returned = self.manager._ami_manager('originate', content)
        return data_returned

    def _obtener_agentes_activos(self):
        agentes_parseados = AgentesParsing()
        agentes_activos = []
        data_returned, error = self.manager._ami_manager(
            "command", "database show OML/AGENT")
        agentes_activos = agentes_parseados._parsear_datos_agentes(
            data_returned)
        return agentes_activos

    def ejecutar_accion_sobre_agente(self, supervisor, agente_id, exten):
        agente_profile = AgenteProfile.objects.get(id=agente_id)
        agent_activity = AgentActivityAmiManager()
        supervisor_activity = SupervisorActivityAmiManager()
        if exten not in self.EXTENSIONES:
            return _("La acción indicada no existe")
        channel = "PJSIP/{0}".format(supervisor.sip_extension)
        channel_vars = {
            'OMLAGENTID': str(agente_id),
        }
        originate_data = [channel, exten, 'oml-sup-actions', channel_vars]
        # Genero la llamada via originate por AMI
        if exten == "AGENTLOGOUT":
            agente_profile.force_logout()
            agent_activity.logout_agent(agente_profile)
        elif exten == "AGENTPAUSE":
            agent_activity.pause_agent(agente_profile, '00')
        elif exten == "AGENTUNPAUSE":
            agent_activity.unpause_agent(agente_profile, '00')
        else:
            supervisor_activity.originate_call(originate_data)
コード例 #5
0
class AgentActivityAmiManager(object):

    manager = AMIManagerConnector()

    def login_agent(self, agente_profile):

        error = self._close_open_session(agente_profile)
        # Inicio nueva sesión
        if not error:
            error = self.queue_add_remove(agente_profile, 'QueueAdd')
        if not error:
            error = self._insert_astb_status(agente_profile, 'login')
        return error

    def logout_agent(self, agente_profile):
        queue_remove_error = self.queue_add_remove(agente_profile,
                                                   'QueueRemove')
        insert_astdb_error = self._insert_astb_status(agente_profile, 'logout')
        return queue_remove_error, insert_astdb_error

    def pause_agent(self, agente_profile, pause_id):
        pause_name = ''
        queue_pause_error = self.queue_pause_unpause(agente_profile, pause_id,
                                                     'pause')
        if pause_id == '0':
            pause_name = 'ACW'
        elif pause_id == '00':
            pause_name = 'Supervision'
        else:
            pause_name = Pausa.objects.activa_by_pauseid(pause_id).nombre
        insert_astdb_error = self._insert_astb_status(
            agente_profile, 'PAUSE-' + str(pause_name))
        # TODO: Refactorizar para hacer todo en la misma session del AMIManagerConnector
        if not insert_astdb_error:
            insert_astdb_error = self.insert_astdb_pause_id(
                agente_profile, pause_id)
        return queue_pause_error, insert_astdb_error

    def unpause_agent(self, agente_profile, pause_id):
        queue_unpause_error = self.queue_pause_unpause(agente_profile,
                                                       pause_id, 'unpause')
        insert_astdb_error = self._insert_astb_status(agente_profile,
                                                      'unpause')
        return queue_unpause_error, insert_astdb_error

    def get_pause_id(self, pause_id):
        return pause_id

    def _get_family(self, agente_profile):
        agente_family = AgenteFamily()
        return agente_family._get_nombre_family(agente_profile)

    def _get_astdb_status_data(self, agente_profile, action):
        family = self._get_family(agente_profile)
        tiempo_actual = int(time.time())
        key = 'STATUS'
        if action == 'login' or action == 'unpause':
            value = 'READY:' + str(tiempo_actual)
        elif action == 'logout':
            value = 'OFFLINE:' + str(tiempo_actual)
        elif 'PAUSE' in action:
            value = action + ':' + str(tiempo_actual)
        content = [family, key, value]
        return content

    def get_queue_data(self, agente_profile):
        agent_id = agente_profile.id
        member_name = agente_profile.get_asterisk_caller_id()
        queues = QueueMember.objects.obtener_queue_por_agent(agent_id)
        penalties = QueueMember.objects.obtener_penalty_por_agent(agent_id)
        sip_extension = agente_profile.sip_extension
        interface = "PJSIP/" + str(sip_extension).strip('[]')
        content = [agent_id, member_name, queues, penalties, interface]
        return content

    def queue_add_remove(self, agente_profile, action):
        content = self.get_queue_data(agente_profile)
        data_returned, error = self.manager._ami_manager(action, content)
        return error

    def queue_pause_unpause(self, agente_profile, pause_id, action):
        if action == 'unpause':
            pause_state = 'false'
        elif action == 'pause':
            pause_state = 'true'
        content = self.get_queue_data(agente_profile)
        content.append(pause_id)
        content.append(pause_state)
        data_returned, error = self.manager._ami_manager('QueuePause', content)

    def _insert_astb_status(self, agente_profile, action):
        content = self._get_astdb_status_data(agente_profile, action)
        data_returned, error = self.manager._ami_manager('dbput', content)
        return error

    def insert_astdb_pause_id(self, agente_profile, pause_id):
        family = self._get_family(agente_profile)
        key = 'PAUSE_ID'
        value = pause_id
        content = [family, key, value]
        data_returned, error = self.manager._ami_manager('dbput', content)
        return error

    def _close_open_session(self, agente_profile):
        status, error = self._get_astdb_agent_status(agente_profile)
        if not error and not status == 'OFFLINE':
            # Finalizo posibles pausas en curso.
            error = self.queue_pause_unpause(agente_profile, '', 'unpause')
            # Finalizo posible sesión en curso.
            if not error:
                error = self.queue_add_remove(agente_profile, 'QueueRemove')
        return error

    def _get_astdb_agent_status(self, agente_profile):
        family = self._get_family(agente_profile)
        data_returned, error = self.manager._ami_manager(
            "command", "database show {0}".format(family))
        if not error:
            parser = AgentesParsing()
            agent_data = parser.parsear_datos_agente(data_returned)
            status = agent_data.get('status', 'OFFLINE')
        return status, error
コード例 #6
0
 def __init__(self, *args, **kwargs):
     self.manager = AMIManagerConnector()
コード例 #7
0
class AgentActivityAmiManager(object):
    redis_connection = None

    def __init__(self, *args, **kwargs):
        self.manager = AMIManagerConnector()

    def connect_manager(self):
        self.manager.connect()

    def disconnect_manager(self):
        self.manager.disconnect()

    def login_agent(self, agente_profile, manage_connection=False):
        if manage_connection:
            self.connect_manager()
        error = self._close_open_session(agente_profile)
        # Inicio nueva sesión
        if not error:
            error = self._queue_add_remove(agente_profile, 'QueueAdd')
        if not error:
            error = self._set_agent_redis_status(agente_profile, 'login')
        if manage_connection:
            self.disconnect_manager()
        return error

    def logout_agent(self, agente_profile, manage_connection=False):
        if manage_connection:
            self.connect_manager()
        queue_remove_error = self._queue_add_remove(agente_profile, 'QueueRemove')
        if manage_connection:
            self.disconnect_manager()
        insert_redis_error = self._set_agent_redis_status(agente_profile, 'logout')
        return queue_remove_error, insert_redis_error

    def set_agent_ringing(self, agente_profile, ringing, manage_connection=False):
        if manage_connection:
            self.connect_manager()
        if ringing:
            insert_redis_error = self._set_agent_redis_status(agente_profile, 'RINGING')
        else:
            insert_redis_error = self._set_agent_redis_status(agente_profile, 'READY')
        return insert_redis_error

    def pause_agent(self, agente_profile, pause_id, manage_connection=False):
        pause_name = ''
        if pause_id == '0':
            pause_name = 'ACW'
        elif pause_id == '00':
            pause_name = 'Supervision'
        else:
            pause_name = Pausa.objects.activa_by_pauseid(pause_id).nombre

        if manage_connection:
            self.connect_manager()
        queue_pause_error = self._queue_pause_unpause(agente_profile, pause_id, 'pause')
        if manage_connection:
            self.disconnect_manager()

        insert_redis_error = self._set_agent_pause_redis_status(
            agente_profile, pause_name, pause_id)

        return queue_pause_error, insert_redis_error

    def unpause_agent(self, agente_profile, pause_id, manage_connection=False):
        # Me aseguro q exista la pausa activa:
        if pause_id not in ('0', '00'):
            pause_id = Pausa.objects.activa_by_pauseid(pause_id).id

        if manage_connection:
            self.connect_manager()
        queue_unpause_error = self._queue_pause_unpause(agente_profile, pause_id, 'unpause')
        if manage_connection:
            self.disconnect_manager()
        insert_redis_error = self._set_agent_redis_status(agente_profile, 'unpause')
        return queue_unpause_error, insert_redis_error

    def set_agent_as_unavailable(self, agente_profile):
        self._set_agent_redis_status(agente_profile, 'UNAVAILABLE')

    def get_pause_id(self, pause_id):
        return pause_id

    def _get_family(self, agente_profile):
        agente_family = AgenteFamily()
        return agente_family._get_nombre_family(agente_profile)

    def _get_redis_status_data(self, action):
        status = action
        if action == 'login' or action == 'unpause':
            status = 'READY'
        elif action == 'logout':
            status = 'OFFLINE'
        elif 'PAUSE' in action:
            status = action
        elif 'UNAVAILABLE' in action:
            status = action

        return {
            'STATUS': status,
            'TIMESTAMP': str(int(time.time()))
        }

    def _get_queue_data(self, agente_profile):
        agent_id = agente_profile.id
        member_name = agente_profile.get_asterisk_caller_id()
        queues = QueueMember.objects.obtener_queue_por_agent(agent_id)
        penalties = QueueMember.objects.obtener_penalty_por_agent(agent_id)
        sip_extension = agente_profile.sip_extension
        interface = "PJSIP/" + str(sip_extension).strip('[]')
        content = [agent_id, member_name, queues, penalties, interface]
        return content

    def _queue_add_remove(self, agente_profile, action):
        content = self._get_queue_data(agente_profile)
        data_returned, error = self.manager._ami_manager(action, content)
        return error

    def _queue_pause_unpause(self, agente_profile, pause_id, action):
        if action == 'unpause':
            pause_state = 'false'
        elif action == 'pause':
            pause_state = 'true'
        content = self._get_queue_data(agente_profile)
        content.append(pause_id)
        content.append(pause_state)
        data_returned, error = self.manager._ami_manager('QueuePause', content)

    def _close_open_session(self, agente_profile):
        status, error = self._get_redis_agent_status(agente_profile)
        if not error and not status == 'OFFLINE':
            # Finalizo posibles pausas en curso.
            error = self._queue_pause_unpause(agente_profile, '', 'unpause')
            # Finalizo posible sesión en curso.
            if not error:
                error = self._queue_add_remove(agente_profile, 'QueueRemove')
        return error

    def get_redis_connection(self):
        if self.redis_connection is None:
            self.redis_connection = redis.Redis(
                host=settings.REDIS_HOSTNAME,
                port=settings.CONSTANCE_REDIS_CONNECTION['port'],
                decode_responses=True)
        return self.redis_connection

    def _save_agent_data(self, agente_profile, data):
        error = False
        family = self._get_family(agente_profile)
        redis_connection = self.get_redis_connection()
        try:
            redis_connection.hset(family, mapping=data)
        except redis.exceptions.RedisError:
            error = True
        return error

    def _set_agent_redis_status(self, agente_profile, action):
        data = self._get_redis_status_data(action)
        if data['STATUS'] == 'READY' or (('PAUSE' in data['STATUS'])
                                         and ('ACW' not in data['STATUS'])):
            data['CAMPAIGN'] = ''
            data['CONTACT_NUMBER'] = ''
        return self._save_agent_data(agente_profile, data)

    def _set_agent_pause_redis_status(self, agente_profile, pause_name, pause_id):
        action = 'PAUSE-' + pause_name
        data = self._get_redis_status_data(action)
        data['PAUSE_ID'] = pause_id
        return self._save_agent_data(agente_profile, data)

    def _get_redis_agent_status(self, agente_profile):
        family = self._get_family(agente_profile)
        redis_connection = self.get_redis_connection()
        status = None
        error = False
        try:
            status = redis_connection.hget(family, 'STATUS')
            if status is None:
                error = True
        except redis.exceptions.RedisError:
            error = True

        return status, error
コード例 #8
0
 def __init__(self, *args, **kwargs):
     self.manager = AMIManagerConnector()
     self.agent_activity = AgentActivityAmiManager()
コード例 #9
0
class SupervisorActivityAmiManager(object):

    EXTENSIONES = [
        "AGENTLOGOUT", "AGENTUNPAUSE", "AGENTPAUSE", "CHANTAKECALL",
        "CHANSPYWISHPER", "CHANSPY", "CHANCONFER"
    ]

    def __init__(self, *args, **kwargs):
        self.manager = AMIManagerConnector()
        self.agent_activity = AgentActivityAmiManager()

    def _originate_call(self, originate_data):
        self.manager.connect()
        content = originate_data
        data_returned = self.manager._ami_manager('originate', content)
        self.manager.disconnect()
        return data_returned

    def obtener_agentes_activos(self):
        agentes_parseados = AgentesParsing()
        agentes_activos = []
        self.manager.connect()
        data_returned, error = self.manager._ami_manager(
            "command", "database show OML/AGENT")
        self.manager.disconnect()
        agentes_activos = agentes_parseados._parsear_datos_agentes(
            data_returned)
        return agentes_activos

    def ejecutar_accion_sobre_agente(self, supervisor, agente_id, exten):
        agente_profile = AgenteProfile.objects.get(id=agente_id)
        if exten not in self.EXTENSIONES:
            return _("La acción indicada no existe")
        channel = "PJSIP/{0}".format(supervisor.sip_extension)
        channel_vars = {
            'OMLAGENTID': str(agente_id),
        }
        originate_data = [channel, exten, 'oml-sup-actions', channel_vars]
        # Genero la llamada via originate por AMI
        if exten == "AGENTLOGOUT":
            agente_profile.force_logout()
            self.agent_activity.logout_agent(agente_profile,
                                             manage_connection=True)
        elif exten == "AGENTPAUSE":
            self.agent_activity.pause_agent(agente_profile,
                                            '00',
                                            manage_connection=True)
        elif exten == "AGENTUNPAUSE":
            self.agent_activity.unpause_agent(agente_profile,
                                              '00',
                                              manage_connection=True)
        else:
            self._originate_call(originate_data)

    def escribir_agentes_unavailable_astdb(self):
        """ Abre una conexion para setear a los agentes como UNAVAILABLE en ASTDB  """
        self.agent_activity.connect_manager()
        agentes_profiles = []
        # Nota: Accedo al manager del agent_activity para no crear otra conexion
        user_activity_list, error = self.agent_activity.manager._ami_manager(
            'command', 'queue show')
        for activity_line in user_activity_list.splitlines():
            if activity_line.find("Unavailable") != -1:
                fields_activity = activity_line.split()
                agente_id = fields_activity[1].split('_')[0]
                agente_profile = AgenteProfile.objects.get(id=agente_id)
                if agente_profile not in agentes_profiles:
                    agentes_profiles.append(agente_profile)
        if agentes_profiles:
            for agente_profile in agentes_profiles:
                self.agent_activity.set_agent_as_unavailable(
                    agente_profile, manage_connection=False)
        self.agent_activity.disconnect_manager()
コード例 #10
0
class SupervisorActivityAmiManager(object):

    EXTENSIONES = [
        "AGENTLOGOUT", "AGENTUNPAUSE", "AGENTPAUSE", "CHANTAKECALL",
        "CHANSPYWISHPER", "CHANSPY", "CHANCONFER"
    ]

    def __init__(self, *args, **kwargs):
        self.manager = AMIManagerConnector()
        self.agent_activity = AgentActivityAmiManager()

    def _originate_call(self, originate_data):
        self.manager.connect()
        content = originate_data
        data_returned = self.manager._ami_manager('originate', content)
        self.manager.disconnect()
        return data_returned

    def obtener_agentes_activos(self):
        agentes_activos = []
        redis_connection = redis.Redis(
            host=settings.REDIS_HOSTNAME,
            port=settings.CONSTANCE_REDIS_CONNECTION['port'],
            decode_responses=True)
        # TODO: cambiar a usar el metodo 'scan' que es mas eficiente con datos muy grandes
        # y realiza una especie de paginación
        keys_agentes = redis_connection.keys('OML:AGENT*')
        agentes_activos = []
        for key in keys_agentes:
            agente_info = redis_connection.hgetall(key)
            status = agente_info.get('STATUS', '')
            id_agente = key.split(':')[-1]
            if status != '' and len(agente_info) >= LONGITUD_MINIMA_HEADERS:
                agente_info['nombre'] = agente_info['NAME']
                agente_info['status'] = status
                agente_info['sip'] = agente_info['SIP']
                agente_info['pause_id'] = agente_info.get('PAUSE_ID', '')
                agente_info['campana_llamada'] = agente_info.get(
                    'CAMPAIGN', '')
                agente_info['contacto'] = agente_info.get('CONTACT_NUMBER', '')
                tiempo_actual = int(time())
                tiempo_estado = tiempo_actual - int(agente_info['TIMESTAMP'])
                agente_info['tiempo'] = tiempo_estado
                del agente_info['NAME']
                del agente_info['STATUS']
                del agente_info['TIMESTAMP']
                del agente_info['SIP']
                agente_info['id'] = int(id_agente)
                agentes_activos.append(agente_info)
        return agentes_activos

    def ejecutar_accion_sobre_agente(self, supervisor, agente_id, exten):
        agente_profile = AgenteProfile.objects.get(id=agente_id)
        if exten not in self.EXTENSIONES:
            return _("La acción indicada no existe")
        channel = "PJSIP/{0}".format(supervisor.sip_extension)
        channel_vars = {
            'OMLAGENTID': str(agente_id),
        }
        originate_data = [channel, exten, 'oml-sup-actions', channel_vars]
        # Genero la llamada via originate por AMI
        if exten == "AGENTLOGOUT":
            agente_profile.force_logout()
            self.agent_activity.logout_agent(agente_profile,
                                             manage_connection=True)
        elif exten == "AGENTPAUSE":
            self.agent_activity.pause_agent(agente_profile,
                                            '00',
                                            manage_connection=True)
        elif exten == "AGENTUNPAUSE":
            self.agent_activity.unpause_agent(agente_profile,
                                              '00',
                                              manage_connection=True)
        else:
            self._originate_call(originate_data)

    def escribir_estado_agentes_unavailable(self):
        """ Busca en el queue de Asterisk si hay agentes Unavailable para reportarlo en Redis"""
        self.manager.connect()
        user_activity_list, error = self.manager._ami_manager(
            'command', 'queue show')
        self.manager.disconnect()

        agentes_profiles = []
        for activity_line in user_activity_list.splitlines():
            if activity_line.find("Unavailable") != -1:
                fields_activity = activity_line.split()
                agente_id = fields_activity[1].split('_')[0]
                agente_profile = AgenteProfile.objects.get(id=agente_id)
                if agente_profile not in agentes_profiles:
                    agentes_profiles.append(agente_profile)

        if agentes_profiles:
            for agente_profile in agentes_profiles:
                self.agent_activity.set_agent_as_unavailable(agente_profile)