<commit_before>############################################################################
# Copyright (C) 2013 tele <<EMAIL>>
#
# Numbering module
# This file is part of RCCN
#
# RCCN is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# RCCN is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero Public License for more details.
#
# You should have received a copy of the GNU Affero Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
############################################################################

import sys
sys.path.append("..")
from config import *
from ESL import *

class NumberingException(Exception):
    pass

class Numbering:

    def is_number_sip_connected(self, session, number):
        try:
            session.execute('set', "sofia_contact_=${sofia_contact("+number+")}")
            _sofia_contact = session.getVariable("sofia_contact_")
            if _sofia_contact == 'error/user_not_registered':
                session.execute('set', "sofia_contact_=${sofia_contact(*/"+number+"@"+wan_ip_address+")}")
                _sofia_contact = session.getVariable("sofia_contact_")
            log.info('Sofia Contact: %s' % _sofia_contact)
            if _sofia_contact == '' or _sofia_contact == 'error/user_not_registered':
                return False
            return _sofia_contact
        except Exception as ex:
            log.info('Exception: %s' % ex)
            return False

    def is_number_sip_connected_no_session(self, number):
        # Carefult with this, seems to lock up FS console if called from chatplan.
        # That is to say, don't connect back via ESL from the chatplan.
        try:
            con = ESLconnection("127.0.0.1", "8021", "ClueCon")
            esl = con.api("sofia_contact "+str(number))
            _sofia_contact = esl.getBody()
            if _sofia_contact == 'error/user_not_registered':
                esl = con.api("sofia_contact */" + str(number) + "@" + str(wan_ip_address))
                _sofia_contact = esl.getBody()
            log.info('Sofia Contact: %s' % _sofia_contact)
            if _sofia_contact == '' or _sofia_contact == 'error/user_not_registered':
                return False
            return _sofia_contact
        except Exception as ex:
            log.info('Exception: %s' % ex)

    def is_number_intl(self, destination_number):
        if (destination_number[0] == '+' or
                destination_number[:2] == '00'):
            log.debug('Called number is an international call')
            return True
        return False

    def detect_mx_short_dial(self, destination_number):
        """
        Try to acertain if a mexican number dialled as
        10 digits is celular based on the data rates we
        got from upstream Voip.

        """
        try:
            if (len(destination_number) != 10 or
                    re.search(r'^(00|\+)', destination_number) is not None):
                return destination_number
            if self.is_number_mxcel(destination_number):
                destination_number = '00521' + destination_number
            else:
                destination_number = '0052' + destination_number
            log.info('Translated dialled 10 digit number to %s' % destination_number)
            return destination_number
        except NumberingException as _ex:
            log.error(_ex)

    def is_number_did(self, destination_number):
        try:
            cur = db_conn.cursor()
            cur.execute("SELECT phonenumber FROM dids WHERE phonenumber=%(number)s", {'number': destination_number})
            did = cur.fetchone()
            #log.debug("Value of did var: %s" % did)
            if did != None:
                return True
            else:
                return False
        except psycopg2.DatabaseError as e:
            raise NumberingException('Database error checking DID: %s' % e)

    def fivetoeleven(self, source_number, destination_number):
        """ Convert a five digit extension to 11 digits based on the caller. """
        if len(destination_number) != 5:
            return destination_number
        elevendigit_number = source_number[:6] + destination_number
        log.info('5 digit destination : %s->%s' % (destination_number, elevendigit_number))
        return elevendigit_number

    def is_number_local(self, destination_number):
        # check if extension if yes add internal_prefix
        if len(destination_number) == 5:
            destination_number = config['internal_prefix'] + destination_number

        try:
            cur = db_conn.cursor()
            cur.execute('SELECT msisdn FROM subscribers WHERE msisdn=%(number)s', {'number': destination_number})
            dest = cur.fetchone()
            if dest != None:
                destn = dest[0]
                # check if number is local to the site
                if destn[:6] == config['internal_prefix']:
                    return True
            else:
                return False
        except psycopg2.DatabaseError as e:
            raise NumberingException('Database error checking if number is local:' % e)

    def is_number_known(self, number):
        try:
            cur = db_conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
            cur.execute('SELECT * FROM hlr WHERE msisdn=%(msisdn)s', {'msisdn': number})
            subscriber = cur.fetchone()
            if subscriber != None:
                return True
            return False
        except psycopg2.DatabaseError as e:
            raise NumberingException('PG_HLR error checking if number is known:' % e)

    def is_number_internal(self, destination_number):
        siteprefix = destination_number[:6]
        if siteprefix == config['internal_prefix']:
            return False
        # Try to avoid going to RIAK here
        cur = db_conn.cursor()
        cur.execute('SELECT DISTINCT home_bts FROM hlr WHERE msisdn like %(prefix)s', {'prefix': siteprefix+'%'})
        test = cur.fetchall()
        if len(test) > 1:
            log.warn('!!FIX THIS!! Got more than one home_bts from hlr for %s' % siteprefix)
            sites = riak_client.bucket('sites')
            if sites.get(siteprefix).exists == True:
                return True
            else:
                return False
        elif len(test) == 1:
            return True
        else:
            return False

    def is_number_here(self, number):
        log.info('%s %s %s %s' % (self.calling_host, mncc_ip_address, number[:6], config['internal_prefix']))
        if self.calling_host == mncc_ip_address and number[:6] == config['internal_prefix']:
            # If we are here and are a local number, then we can't be roaming
            log.warn('%s is here' % number)<commit_msg>code verbesserung<commit_after>############################################################################
# Copyright (C) 2013 tele <<EMAIL>>
#
# Numbering module
# This file is part of RCCN
#
# RCCN is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# RCCN is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero Public License for more details.
#
# You should have received a copy of the GNU Affero Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
############################################################################

import sys
sys.path.append("..")
from config import *
from ESL import *

class NumberingException(Exception):
    pass

class Numbering:

    def is_number_sip_connected(self, session, number):
        try:
            session.execute('set', "sofia_contact_=${sofia_contact("+number+")}")
            _sofia_contact = session.getVariable("sofia_contact_")
            if _sofia_contact == 'error/user_not_registered':
                session.execute('set', "sofia_contact_=${sofia_contact(*/"+number+"@"+wan_ip_address+")}")
                _sofia_contact = session.getVariable("sofia_contact_")
            log.info('Sofia Contact: %s' % _sofia_contact)
            if _sofia_contact == '' or _sofia_contact == 'error/user_not_registered':
                return False
            return _sofia_contact
        except Exception as ex:
            log.info('Exception: %s' % ex)
            return False

    def is_number_sip_connected_no_session(self, number):
        # Carefult with this, seems to lock up FS console if called from chatplan.
        # That is to say, don't connect back via ESL from the chatplan.
        try:
            con = ESLconnection("127.0.0.1", "8021", "ClueCon")
            esl = con.api("sofia_contact "+str(number))
            _sofia_contact = esl.getBody()
            if _sofia_contact == 'error/user_not_registered':
                esl = con.api("sofia_contact */" + str(number) + "@" + str(wan_ip_address))
                _sofia_contact = esl.getBody()
            log.info('Sofia Contact: %s' % _sofia_contact)
            if _sofia_contact == '' or _sofia_contact == 'error/user_not_registered':
                return False
            return _sofia_contact
        except Exception as ex:
            log.info('Exception: %s' % ex)

    def is_number_intl(self, destination_number):
        if (destination_number[0] == '+' or
                destination_number[:2] == '00'):
            log.debug('Called number is an international call')
            return True
        return False

    def detect_mx_short_dial(self, destination_number):
        """
        Try to acertain if a mexican number dialled as
        10 digits is celular based on the data rates we
        got from upstream Voip.

        """
        try:
            if (len(destination_number) != 10 or
                    re.search(r'^(00|\+)', destination_number) is not None):
                return destination_number
            if self.is_number_mxcel(destination_number):
                destination_number = '00521' + destination_number
            else:
                destination_number = '0052' + destination_number
            log.info('Translated dialled 10 digit number to %s' % destination_number)
            return destination_number
        except NumberingException as _ex:
            log.error(_ex)

    def is_number_did(self, destination_number):
        try:
            cur = db_conn.cursor()
            cur.execute("SELECT phonenumber FROM dids WHERE phonenumber=%(number)s", {'number': destination_number})
            did = cur.fetchone()
            #log.debug("Value of did var: %s" % did)
            return bool(did)
        except psycopg2.DatabaseError as e:
            raise NumberingException('Database error checking DID: %s' % e)

    def fivetoeleven(self, source_number, destination_number):
        """ Convert a five digit extension to 11 digits based on the caller. """
        if len(destination_number) != 5:
            return destination_number
        elevendigit_number = source_number[:6] + destination_number
        log.info('5 digit destination : %s->%s' % (destination_number, elevendigit_number))
        return elevendigit_number

    def is_number_local(self, destination_number):
        # check if extension if yes add internal_prefix
        if len(destination_number) == 5:
            destination_number = config['internal_prefix'] + destination_number

        try:
            cur = db_conn.cursor()
            cur.execute('SELECT msisdn FROM subscribers WHERE msisdn=%(number)s', {'number': destination_number})
            dest = cur.fetchone()
            if dest != None:
                destn = dest[0]
                # check if number is local to the site
                if destn[:6] == config['internal_prefix']:
                    return True
            else:
                return False
        except psycopg2.DatabaseError as e:
            raise NumberingException('Database error checking if number is local:' % e)

    def is_number_known(self, number):
        try:
            cur = db_conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
            cur.execute('SELECT * FROM hlr WHERE msisdn=%(msisdn)s', {'msisdn': number})
            subscriber = cur.fetchone()
            if subscriber != None:
                return True
            return False
        except psycopg2.DatabaseError as e:
            raise NumberingException('PG_HLR error checking if number is known:' % e)

    def is_number_internal(self, destination_number):
        siteprefix = destination_number[:6]
        if siteprefix == config['internal_prefix']:
            return False
        # Try to avoid going to RIAK here
        cur = db_conn.cursor()
        cur.execute('SELECT DISTINCT home_bts FROM hlr WHERE msisdn like %(prefix)s', {'prefix': siteprefix+'%'})
        test = cur.fetchall()
        if len(test) > 1:
            log.warn('!!FIX THIS!! Got more than one home_bts from hlr for %s' % siteprefix)
            sites = riak_client.bucket('sites')
            return bool(sites.get(siteprefix).exists)
        elif len(test) == 1:
            return True
        else:
            return False

    def is_number_here(self, number):
        log.info('%s %s %s %s' % (self.calling_host, mncc_ip_address, number[:6], config['internal_prefix']))
        if self.calling_host == mncc_ip_address and number[:6] == config['internal_prefix']:
            # If we are here and are a local number, then we can't be roaming
            log.warn('%s is here' % number)
{'fraction_non_alphanumeric': 0.11455813291589582, 'fraction_numerical': 0.007542336701295005, 'mean_word_length': 2.3932882665379043, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1276890', 'n_tokens_mistral': 3979, 'n_tokens_neox': 3837, 'n_words': 1150}