Jelajahi Sumber

Very basic CDR aggregation draft

Hal De 4 tahun lalu
induk
melakukan
68f0b7d6c8
2 mengubah file dengan 67 tambahan dan 0 penghapusan
  1. 52 0
      app/app.py
  2. 15 0
      app/utils.py

+ 52 - 0
app/app.py

@@ -804,5 +804,57 @@ class CEL(Resource):
     cel = await getCEL(start, end)
     return successReply(cel)
 
+@app.route('/calls')
+class Calls(Resource):
+  @app.param('end', 'End of datetime range. Defaults to now. Allowed formats are: timestamp, ISO 8601 and ddmmyyyyHHMMSS', 'query')
+  @app.param('start', 'Start of datetime range. Defaults to end-24h. Allowed formats are: timestamp, ISO 8601 and ddmmyyyyHHMMSS', 'query')
+  @app.response(HTTPStatus.OK, 'JSON reply')
+  @app.response(HTTPStatus.UNAUTHORIZED, 'Authorization required')
+  async def get(self):
+    '''Returns aggregated call data JSON.
+    All request arguments are optional.
+    '''
+    calls = []
+    start = parseDatetime(request.args.get('start'))
+    end = parseDatetime(request.args.get('end'))
+    cdr = await getCDR(start, end)
+    for _call in cdr:
+      _call0 = _call['id'][0]
+      context = _call0['dcontext']
+      call = {'id':_call['id'],
+              'start':_call0['calldate'],
+              'type': None,
+              'numberA': None,
+              'numberB': None,
+              'line': None,
+              'duration': None,
+              'waiting': None,
+              'status':'NO ANSWER',
+              'url': None }
+      for _c, _r in (('disposition','status'),
+                     ('src','numberA'),
+                     ('recordingfile','url')):
+        if _c in  _call0:
+          call[_r] = _call0[_c]
+      src = _call0['src'] if 'src' in _call0 else None
+      dst = _call0['dst'] if 'dst' in _call0 else None
+      if src in (*app.cache['ustates'].keys(), *app.cache['devices']):
+        if dst in (*app.cache['ustates'].keys(),
+                   *app.cache['devices'],
+                   *app.cache['queues'].keys()):
+          call['type'] = 'local'
+        else:
+          call['type'] = 'out'
+          call['numberB'] = _call0['dst']
+      else:
+        call['type'] = 'in'
+        if 'did' in _call0:
+          call['line'] = _call0['did']
+      if len(_call['id'] > 1):
+        for step in _call['id'][1:]:
+          pass
+      calls.append(call)
+    return successReply(calls)
+
 manager.connect()
 app.run(loop=main_loop, host='0.0.0.0', port=app.config['PORT'])

+ 15 - 0
app/utils.py

@@ -6,6 +6,13 @@ from datetime import timedelta as td
 
 TRUEs = ('true', '1', 'y', 'yes')
 NONEs = (None,'none','')
+externalContexts = ('ext-group',
+                    'ext-queues',
+                    'ext-local',
+                    'from-trunk',
+                    'from-digital',
+                    'from-pstn',
+                    'from-did-direct')
 # userstate presencestate maping:
 _ustates = ['idle',       'inuse', 'busy', 'unavailable', 'ringing', 'inuse&ringing','hold', 'inuse&hold'] #presence:
 _states = [['available',   'busy', 'busy', 'unavailable', 'ringing', 'busy',         'busy', 'busy'],      #not_set
@@ -71,6 +78,14 @@ def parseDatetime(dateString):
         pass
   return _dt
 
+def freepbxExternalContext(context):
+  if ((context in externalContexts) or
+      (context.startswith('from-trunk')) or
+      (context.startswith('from-did')) or
+      (context.startswith('ivr-'))):
+    return True
+  return False
+
 def followMe2DevState(followMeState):
   if followMeState == 'DIRECT':
     return 'INUSE'