浏览代码

cdr events

Hal De 3 年之前
父节点
当前提交
791b4442c8
共有 3 个文件被更改,包括 64 次插入27 次删除
  1. 21 1
      app/app.py
  2. 38 20
      app/cel.py
  3. 5 6
      app0/cdr_test.py

+ 21 - 1
app/app.py

@@ -332,7 +332,27 @@ async def getCDR(start=None,
   return cdr
 
 async def getCallInfo(linked_id):
-    return []
+  _q = '''SELECT *
+          FROM cel 
+          WHERE linkedid=:linkedid and eventtype = :eventtype'''
+  _v = {'linkedid': linkedid, 'eventtype': 'ATTENDEDTRANSFER'}
+  _f = True
+  uniqueids = set(linkedid) #get ids of transferred calls
+  async for row in _db.iterate(query=_q, values=_v):
+    extra  = json.loads(row['extra'])
+    uniqueids.add(extra['channel2_uniqueid'])
+    
+  _q = '''SELECT *
+          FROM cdr 
+          WHERE linkedid=:linkedid or linkedid in (select distinct linkedid from cdr where uniqueid in :uniqueids)
+          ORDER BY sequence;'''
+  _v = {'linkedid': linkedid, 'uniqueids': uniqueids}
+  _f = True
+  unique_ids = set()
+  events = CdrEvents()
+  async for row in _db.iterate(query=_q, values=_v):
+    events.add(row)
+  return events.simple()
 
     
 async def getUserCDR(user,

+ 38 - 20
app/cel.py

@@ -35,34 +35,52 @@ class CdrEvent:
     return None
 
 class CdrEvents:
-  def __init__(self,linkedid):
+  def __init__(self):
     self._events = []
-    self._channels = []
-    self._dstchannels = []
+    self._channels = {}
+    self._dstchannels = {}
     self.start = 0
-    self.linkedid = linkedid
+    self._waitingchannel = None
     
   def add(self, event):
     if not isinstance(event, CdrEvent):
       event = CdrEvent(event)
     if not self.start:
         self.start = event.calldate
-    if event.channel not in self._channels:
-        self._channels[event.channel] = event
-    if event.dstchannel not in self._dstchannels:
-        self._dstchannels[event.dstchannel] = event.dst
+    if (event.channel.id not in self._channels):
+        self._channels[event.channel.id] = event
+    if (event.dstchannel.id not in self._dstchannels):
+        self._dstchannels[event.dstchannel.id] = event.dst
+    if (self._waitingchannel is not None) and (self._waitingchannel.id == event.channel.id): # if dial event after queue event
+        for e in self._events:
+          if (e.lastapp == 'Queue') and (e.dstchannel.id == event.channel.id):
+            e.duration = (event.calldate-e.calldate).total_seconds() +  event.duration 
+            e.billsec = event.billsec
+        self._waitingchannel = None
     if (event.lastapp == 'Queue'):
+      event.billsec = 0
+      queueevent = event 
       for e in self._events:
-        if (e.lastapp == 'Queue') and (e.uniqueid == event.uniqueid):
-          if (event.disposition == 'ANSWERED'):
-            e.disposition = 'ANSWERED'
-            if event.dstchannel in self._channels:
-              dialevent = self._channels[event.dstchannel]
-              e.duration = e.start-dialevent.start +  dialevent.duration 
-              e.billsec = dialevent.billsec
-          return # if it not fiars queue event - miss it
-    if (event.lastapp == 'Dial' and event.dstchannel in self._dstchannels):
-        event.dst = self._dstchannels[event.dstchannel]
+        if (e.lastapp == 'Queue') and (e.uniqueid == event.uniqueid):#find first queue event
+          queueevent = e
+      if (event.disposition == 'ANSWERED'): #if it answered - fill duration and waitng based on answered dial event
+        queueevent.disposition = 'ANSWERED'
+        queueevent.dstchannel = event.dstchannel
+        if (event.dstchannel.id in self._channels): # if dial event before queue event
+          dialevent = self._channels[event.dstchannel.id]
+          queueevent.duration = (dialevent.calldate-queueevent.calldate).total_seconds() +  dialevent.duration 
+          queueevent.billsec = dialevent.billsec
+        else:
+          self._waitingchannel = event.dstchannel # wait for dial event
+      else: 
+        if queueevent.disposition != 'ANSWERED': #count total queue duration
+          queueevent.duration = (event.calldate-queueevent.calldate).total_seconds() +  event.duration
+      if (event != queueevent):
+        return; # add only forst queue event
+    if (event.lastapp == 'Dial' and event.dstchannel.id in self._dstchannels):
+        event.dst = self._dstchannels[event.dstchannel.id] #get dst from fisrt event with rthis channel. for transfer
+    if (event.lastapp == 'Dial' and event.dstchannel.id in self._channels):
+        event.dst = self._channels[event.dstchannel.id].dst #for transfer to queue
     self.end = event.calldate + td(seconds=event.duration)
     self._events.append(event)
 
@@ -97,9 +115,9 @@ class CdrEvents:
         simple_event = {'start': event.calldate,
             'answered': event.disposition=='ANSWERED',
             'duration': event.billsec,
-            'waiting': event.duration = event.billsec,
+            'waiting': event.duration - event.billsec,
             'application': event.lastapp,
-            'src': event.src,
+            'caller': event.cnum,
             'dst': event.dst,
             'uniqueid': event.uniqueid,
             'file': event.recordingfile}

+ 5 - 6
app0/cdr_test.py

@@ -28,15 +28,14 @@ async def main():
   await _db.connect()
   _q = '''SELECT *
           FROM cel 
-          WHERE linkedid=:linkedid and eventtype = :eventtype
-          ORDER BY sequence;'''
+          WHERE linkedid=:linkedid and eventtype = :eventtype'''
   _v = {'linkedid': linkedid, 'eventtype': 'ATTENDEDTRANSFER'}
   _f = True
-  unique_ids = set()
+  uniqueids = set(linkedid) #get ids of transferred calls
   async for row in _db.iterate(query=_q, values=_v):
-    print('\t'.join([str(k) for k in row]))
+    #print('\t'.join([str(k) for k in row]))
     extra  = json.loads(row['extra'])
-    unique_ids.add(extra['channel2_uniqueid'])
+    uniqueids.add(extra['channel2_uniqueid'])
     
   _q = '''SELECT *
           FROM cdr 
@@ -47,7 +46,7 @@ async def main():
   unique_ids = set()
   events = CdrEvents()
   async for row in _db.iterate(query=_q, values=_v):
-    events.addEvent(row)
+    events.add(row)
   print(events.simple())
   await _db.disconnect()