Advertisement
Guest User

Untitled

a guest
Jul 25th, 2016
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 11.19 KB | None | 0 0
  1. from flask import Flask, render_template, jsonify, session, redirect, url_for
  2. import os, sys
  3. import ConfigParser
  4. import json
  5. import model
  6. from distutils.util import strtobool
  7. from werkzeug.serving import run_simple
  8. from werkzeug.wsgi import DispatcherMiddleware
  9. from datetime import date
  10.  
  11. # get current names for directory and file
  12. dirname, filename = os.path.split(os.path.abspath(__file__))
  13.  
  14. # py-asterisk
  15. sys.path.append(os.path.join(dirname,  'libs','py-asterisk'))
  16. from Asterisk.Manager import *
  17.  
  18.  
  19. # sqlalchemy
  20. sys.path.append(os.path.join(dirname,  'libs','sqlalchemy', 'lib'))
  21. from sqlalchemy.orm import sessionmaker
  22. from sqlalchemy.orm.exc import NoResultFound
  23.  
  24. # session db mysql
  25. Session_MySQL = sessionmaker(bind=model.engine_mysql)
  26. session_mysql = Session_MySQL()
  27. # session db freepbx
  28. Session_FreePBX = sessionmaker(bind=model.engine_freepbx)
  29. session_freepbx = Session_FreePBX()
  30.  
  31.  
  32.  
  33. # config file
  34. cfg_file = 'config.ini'
  35. cfg = ConfigParser.ConfigParser()
  36. try:
  37.     with open(os.path.join(dirname, cfg_file))  as f:
  38.         cfg.readfp(f)
  39. except IOError:
  40.     print 'Error open file config. Check if config.ini exists'
  41.     sys.exit()
  42.  
  43.  
  44. def init_day(d = date.today()):
  45.     return datetime.datetime(d.year, d.month, d.day, 0, 0, 0)
  46.  
  47. def __connect_manager():
  48.     host = cfg.get('manager', 'host')
  49.     port = int(cfg.get('manager', 'port'))
  50.     user = cfg.get('manager', 'user')
  51.     password = cfg.get('manager', 'password')
  52.     try:
  53.         manager = Manager((host, port), user, password)
  54.         return manager
  55.     except:
  56.         app.logger.info('Error to connect to Asterisk Manager. Check config.ini and manager.conf of asterisk')
  57.  
  58. def is_debug():
  59.     try:
  60.         var = cfg.get('general', 'debug')
  61.         v = True if strtobool(var) == 1 else False
  62.     except:
  63.         return False
  64.     return v
  65.  
  66. def port_bind():
  67.     return int(__get_entry_ini_default('general', 'port', 5000))
  68.  
  69. def host_bind():
  70.     return __get_entry_ini_default('general', 'host', '0.0.0.0')
  71.  
  72. def get_hide_config():
  73.     tmp = __get_entry_ini_default('general', 'hide', '')
  74.     tmp = tmp.replace('\'', '')
  75.     return tmp.split(',')
  76.  
  77.  
  78. def __get_entry_ini_default(section, var, default):
  79.     try:
  80.         var = cfg.get(section, var)
  81.         v = var
  82.     except:
  83.         return default
  84.     return v
  85.  
  86. def __get_data_queues_manager():
  87.     manager = __connect_manager()
  88.     try:
  89.         data = manager.QueueStatus()
  90.     except:
  91.         app.logger.info('Error to connect to Asterisk Manager. Check config.ini and manager.conf of asterisk')
  92.         data = []
  93.     return data
  94.  
  95.  
  96. def get_data_queues(queue = None):
  97.     data = parser_data_queue(__get_data_queues_manager())
  98.     if queue is not None:
  99.         data = data[queue]
  100.     if is_debug():
  101.         app.logger.debug(data)
  102.     return data
  103.  
  104. def hide_queue(data):
  105.     tmp_data = {}
  106.     hide = get_hide_config()
  107.     for q in data:
  108.         if q not in hide:
  109.             tmp_data[q] = data[q]
  110.     return tmp_data
  111.  
  112. def rename_queue(data):
  113.     tmp_data = {}
  114.     for q in data:
  115.         rename = __get_entry_ini_default('rename', q, None)
  116.         if rename is not None:
  117.             tmp_data[rename] = data[q]
  118.         else:
  119.             tmp_data[q] = data[q]
  120.     return tmp_data
  121.  
  122.  
  123. def set_global_queues_freepbx():
  124.     queues = {}
  125.     try:
  126.         data = session_freepbx.query(model.QueuesConfig).all()
  127.     except NoResultFound, e:
  128.         data = None
  129.     for q in data:
  130.         queues[q.extension] = q.descr
  131.     session['queues'] = queues
  132.  
  133. def if_need_set_queue_globals():
  134.     try:
  135.         if len(session['queues']) == 0:
  136.             set_global_queues_freepbx()
  137.     except:
  138.             set_global_queues_freepbx()
  139.  
  140.  
  141. def parser_data_queue(data):
  142.     data = hide_queue(data)
  143.     data = rename_queue(data)
  144.     # convert references manager to string
  145.     for q in data:
  146.         for e in data[q]['entries']:
  147.             tmp = data[q]['entries'].pop(e)
  148.             data[q]['entries'][str(e)] = tmp
  149.             tmp = data[q]['entries'][str(e)]['Channel']
  150.             data[q]['entries'][str(e)]['Channel']  = str(tmp)
  151.         for m in data[q]['members']:
  152.             #Asterisk 1.8 dont have StateInterface
  153.             if 'StateInterface' not in data[q]['members'][m]:
  154.                 data[q]['members'][m]['StateInterface'] = m
  155.         try:
  156.             if q in session['queues']:
  157.                 data[q]['long_name'] = session['queues'][q]
  158.             else:
  159.                 data[q]['long_name'] = None
  160.         except:
  161.             data[q]['long_name'] = None
  162.  
  163.     return data
  164.  
  165. def first_queue():
  166.     data = get_data_queues()
  167.     if data:
  168.         return data.keys()[0]
  169.     else:
  170.         return ''
  171.  
  172.  
  173. def events_queuelog_data_type(from_date, to_date, events=None, agent=None, queue=None):
  174.     try:
  175.         q = session_mysql.query(model.QueueLog)
  176.  
  177.         if from_date:
  178.             q = q.filter(model.QueueLog.created >= from_date)
  179.         if to_date:
  180.             q = q.filter(model.QueueLog.created <= to_date)
  181.         if events:
  182.             q = q.filter(model.QueueLog.event.in_(events))
  183.         if agent:
  184.             q = q.filter(model.QueueLog.agent.in_(agent))
  185.         if queue:
  186.             q = q.filter(model.QueueLog.queuename == queue)
  187.         return q.all()
  188.         return q.order_by(model.QueueLog.id.asc()).all()
  189.     except NoResultFound, e:
  190.         return None
  191.  
  192.  
  193. def count_answered(from_date, to_date, agent=None, queue=None):
  194. #    events = ['COMPLETECALLER', 'COMPLETEAGENT']
  195.     events = ['CONNECT']
  196.     data =  events_queuelog_data_type(from_date, to_date, events, agent, queue)
  197.     return len(data)
  198.  
  199. def count_inbound(from_date, to_date, agent=None, queue=None):
  200.     events = ['ENTERQUEUE']
  201.     calls = []
  202.     data =  events_queuelog_data_type(from_date, to_date, events, agent, queue)
  203.  
  204.     for call in data:
  205.         if call.callid not in calls:
  206.             calls.append(call.callid)
  207.     return len(calls)
  208.  
  209. def count_voicemail(from_date, to_date, agent=None, queue=None):
  210.     events = ['VOICEMAIL']
  211.     data =  events_queuelog_data_type(from_date, to_date, events, agent, queue)
  212.     return len(data)
  213.  
  214. def count_abandon(from_date, to_date, agent=None, queue=None):
  215.     events = ['ABANDON']
  216.     data =  events_queuelog_data_type(from_date, to_date, events, agent, queue)
  217.     return len(data)
  218.  
  219.  
  220. def seconds_wait_abandon(from_date, to_date, agent=None, queue=None):
  221.     events = ['ABANDON']
  222.     seconds = 0
  223.     data =  events_queuelog_data_type(from_date, to_date, events, agent, queue)
  224.     for call in data:
  225.         seconds = seconds + int(call.data3)
  226.  
  227.     return seconds
  228.  
  229. def seconds_wait(from_date, to_date, agent=None, queue=None):
  230.     events = ['CONNECT']
  231.     seconds = 0
  232.     data =  events_queuelog_data_type(from_date, to_date, events, agent, queue)
  233.     for call in data:
  234.         seconds = seconds + int(call.data1)
  235.  
  236.     return seconds
  237.  
  238.  
  239.  
  240. def seconds_talking(from_date, to_date, agent=None, queue=None):
  241.     events = ['COMPLETECALLER', 'COMPLETEAGENT']
  242.     seconds = 0
  243.     data =  events_queuelog_data_type(from_date, to_date, events, agent, queue)
  244.     for call in data:
  245.         seconds = seconds + int(call.data2)
  246.     return seconds
  247.  
  248.  
  249. def data_queue(from_date, to_date, agent=None, queue=None):
  250.     data = {}
  251.     data['answered'] = count_answered(from_date, to_date, agent, queue)
  252.     data['inbound'] = count_inbound(from_date, to_date, agent, queue)
  253.     data['count_abandon'] = count_abandon(from_date, to_date, agent, queue)
  254.     data['voicemail'] = count_voicemail(from_date, to_date, agent, queue)
  255.     data['seconds_wait'] = seconds_wait(from_date, to_date, agent, queue)
  256.     data['seconds_talking'] = seconds_talking(from_date, to_date, agent, queue)
  257.     data['seconds_wait_abandon'] = seconds_wait_abandon(from_date, to_date, agent, queue)
  258.     return data
  259.  
  260. # Flask env
  261. APPLICATION_ROOT = __get_entry_ini_default('general', 'base_url', '/')
  262. app = Flask(__name__)
  263. app.secret_key = 'CHANGEME'
  264. app.config.from_object(__name__)
  265.  
  266. @app.before_first_request
  267. def setup_logging():
  268.   # issue https://github.com/benoitc/gunicorn/issues/379
  269.   if not app.debug:
  270.     app.logger.addHandler(logging.StreamHandler())
  271.     app.logger.setLevel(logging.INFO)
  272.  
  273.  
  274. #Utilities helpers
  275. @app.context_processor
  276. def utility_processor():
  277.     def format_id_agent(value):
  278.         v = value.replace('/', '-')
  279.         return v.replace('@', '_')
  280.     return dict(format_id_agent=format_id_agent)
  281.  
  282. @app.context_processor
  283. def utility_processor():
  284.     def str_status_agent(value):
  285.         try:
  286.             value = int(value)
  287.         except:
  288.             value = 0
  289.         unavailable = [0, 4, 5]
  290.         free = [1]
  291.  
  292.         if value in unavailable:
  293.             return 'unavailable'
  294.         elif value in free:
  295.             return 'free'
  296.         else:
  297.             return 'busy'
  298.     return dict(str_status_agent=str_status_agent)
  299.  
  300. @app.context_processor
  301. def utility_processor():
  302.     def request_interval():
  303.         return int(__get_entry_ini_default('general', 'interval', 5)) * 1000
  304.     return dict(request_interval=request_interval)
  305.  
  306.  
  307. # ---------------------
  308. # ---- Routes ---------
  309. # ---------------------
  310. # home
  311. @app.route('/')
  312. def home():
  313.     data = get_data_queues()
  314.     return render_template('index.html', queues = data)
  315.  
  316.  
  317.  
  318. @app.route('/queue/<name>')
  319. def queue(name = None):
  320.     data = get_data_queues(name)
  321.     return render_template('queue.html', data = data, name = name)
  322.  
  323.  
  324. @app.route('/queue/<name>.json')
  325. def queue_json(name = None):
  326.     data = get_data_queues(name)
  327.     return jsonify(
  328.         name = name,
  329.         data = data,
  330.         current_time = time.strftime("%Y-%m-%d %H:%M:%S")
  331.     )
  332.  
  333. # data queue
  334. @app.route('/queues')
  335. def queues():
  336.     data = get_data_queues()
  337.     return jsonify(
  338.         data = data
  339.     )
  340.  
  341.  
  342. @app.route('/qstatus')
  343. def init_route_qstatus():
  344.     return redirect(url_for('qstatus', name=first_queue()))
  345.  
  346. @app.route('/qstatus/<name>')
  347. def qstatus(name):
  348.     if_need_set_queue_globals()
  349.     queues = get_data_queues()
  350.     data = queues[name]
  351.     return render_template('qstatus.html', data = data, queues = queues,  name = name)
  352.  
  353.  
  354. @app.route('/qoper/<name>.json')
  355. def qoper_json(name = None):
  356.     queue_values = data_queue(init_day(), None, None, name)
  357.     data = get_data_queues(name)
  358.     return jsonify(
  359.         name = name,
  360.         data = data,
  361.         values = queue_values,
  362.         current_time = time.strftime("%Y-%m-%d %H:%M:%S")
  363.     )
  364.  
  365.  
  366. @app.route('/qoper')
  367. def init_route_qoper():
  368.     return redirect(url_for('qoper', name=first_queue()))
  369.  
  370. @app.route('/qoper/<name>')
  371. def qoper(name):
  372.     if_need_set_queue_globals()
  373.     queues = get_data_queues()
  374.     data = queues[name]
  375.     return render_template('qoper.html', data = data, queues = queues,  name = name)
  376.  
  377. # ---------------------
  378. # ---- Main  ----------
  379. # ---------------------
  380. if __name__ == '__main__':
  381.  
  382.     if is_debug():
  383.         app.config['DEBUG'] = True
  384.  
  385.     app.logger.debug(APPLICATION_ROOT)
  386.     if APPLICATION_ROOT == '/':
  387.         app.run(host=host_bind(), port=port_bind())
  388.     else:
  389.         application = DispatcherMiddleware(Flask('dummy_app'), {
  390.             app.config['APPLICATION_ROOT']: app,
  391.         })
  392.         run_simple(host_bind(), port_bind(), application, use_reloader=True)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement