mapper.py - Hero-Development/snippets GitHub Wiki

#!/apps/bin/python-service

import csv, datetime, json, logging, os, sys, tempfile from sqlalchemy import distinct, func #, and_, distinct, or_, select

from voex.native import ServiceError from voex.extensions import Service from voex.pooling import Task, ThreadPool

from common import SAConnection, ScriptCommand, ScriptRunner

class Mapper( ScriptCommand ): FIELD_NAMES = [ 'CustomerID', 'SAP_ID', 'SegmentID', 'routingProfileName', 'DID', 'DID Count', 'TF', 'TF Count', 'RP Type', 'Trunks' ]

def __init__( self, service ):
    super( Mapper, self ).__init__( service )

    self.package_details = {}
    self.csv_pool = ThreadPool( 1, target=self.write_csv )
    self.rp_pool = ThreadPool( 3, target=self.process_rp )


def write_csv( self, *args, **kwargs ):
    queue = args[0]

    report_path = 'routes_{0}.csv'.format( datetime.datetime.now().strftime( '%Y-%m-%d_%H%M%S' ) )
    logging.info( report_path )
    with open( report_path, 'wb' ) as fp_writer:
        csv_writer = csv.DictWriter( fp_writer, fieldnames=self.FIELD_NAMES)

        try:
            # 2.7+
            csv_writer.writeheader()
        except Exception as ex:
            # < 2.7
            header = dict(zip( self.FIELD_NAMES, self.FIELD_NAMES ))
            csv_writer.writerow( header )


        while True:
            task = queue.get()
            if Task.is_empty( task ):
                queue.task_done()
                self.running = False
                break


            try:
                segmentID = task.request
                details = self.package_details[ segmentID ]
                if details[ 'Trunks' ]:
                    details[ 'Trunks' ] = ','.join( details[ 'Trunks' ] )
                csv_writer.writerow( details )                   

            except Exception as ex:
                task.exception = ex
                logging.exception( ex )

            finally:
                queue.task_done()
                task.set()

        fp_writer.flush()


def process_rp( self, *args, **kwargs ):
    queue = args[0]

    while True:
        task = queue.get()
        if Task.is_empty( task ):
            queue.task_done()
            self.running = False
            break


        try:
            task.response = self.get_rp( task.request )

        except Exception as ex:
            task.exception = ex
            logging.exception( ex )

        finally:
            queue.task_done()
            task.set()


def get_rp( self, segmentID ):
    package = self.package_details[ segmentID ]
    if package['routingProfileName']:
        first, second = package['routingProfileName'].split( '_', 1 )
    else:
        first = package['SAP_ID']
        second = package['SegmentID']

    try:
        res = Service.TaquaRoutingProfileDatabase().getRoutingProfileDetails( SAP_ID=first, routingProfileEpName=second )
    except:
        pass

    if res:
        logging.info( res )
        if res.isFieldSet( 'tgNames' ):
            self.package_details[ segmentID ][ 'Trunks' ] = res.getAll( 'tgNames' )

        if res.isFieldSet( 'selectionTypeId' ):
            typeID = res.get( 'selectionTypeId' ).getInt32()
            if typeID == 1:
                self.package_details[ segmentID ][ 'RP Type' ] = 'Round Robin'
            elif typeID == 2:
                self.package_details[ segmentID ][ 'RP Type' ] = 'Sequential'
            elif typeID == 3:
                self.package_details[ segmentID ][ 'RP Type' ] = 'Proportional'

    self.csv_pool.put( segmentID )



def start( self ):
    self.rp_pool.start()
    self.csv_pool.start()

    self.rp_pool.stop().join_threads()
    self.csv_pool.stop().join_threads()

if name == 'main': sys.argv.pop(0)

level = sys.argv.pop(0).upper() if sys.argv else None
if level in ( 'DEBUG', 'INFO', 'WARNING', 'ERROR' ):
    LOG_LEVEL = level
else:
    LOG_LEVEL = logging.INFO
    if level:
        logging.warning( "Log level '{0}' is not supported".format( level ) )

'''
if 'DEBUG' == level:
    LOG_LEVEL = logging.DEBUG
elif 'INFO' == level:
    LOG_LEVEL = logging.INFO
elif 'WARNING' == level:
    LOG_LEVEL = logging.WARNING
elif 'ERROR' == level:
    LOG_LEVEL = logging.ERROR
else:
    LOG_LEVEL = logging.INFO
    if level:
        logging.warning( "Log level '{0}' is not supported".format( level ) )
'''

formatter = logging.Formatter( '[%(asctime)s] %(levelname)-8s %(filename)12.12s:%(lineno)3d %(message)s' )

handler = logging.StreamHandler(sys.stdout)
handler.setLevel( LOG_LEVEL )
handler.setFormatter(formatter)

logger = logging.getLogger()
logger.setLevel( LOG_LEVEL )
logger.addHandler(handler)

#TODO: CLI args?
base_path = os.path.dirname(os.path.realpath(__file__))
config_path = os.path.join( base_path, 'tn-tg-mapper.xml' )

try:
    with ScriptRunner( handler, config_path ) as service:
        handler.setLevel( LOG_LEVEL )
        logger.setLevel( LOG_LEVEL )

        with Mapper( service ) as mapper:
            mapper.start()

except ServiceError as sEx:
    logging.exception( sEx.getMessage() )
    raise sEx

except Exception as ex:
    logging.exception( ex )
    raise ex