Jelajahi Sumber

New cache test

Hal De 4 tahun lalu
induk
melakukan
cca25ff356
1 mengubah file dengan 55 tambahan dan 37 penghapusan
  1. 55 37
      app/app.py

+ 55 - 37
app/app.py

@@ -65,9 +65,12 @@ app.config.update({
                                                             os.getenv('MYSQL_SERVER', 'db'),
                                                             os.getenv('APP_PORT_MYSQL', '3306'),
                                                             os.getenv('FREEPBX_CDRDBNAME', None)),
-  'EXTRA_API_URL':          os.getenv('APP_EXTRA_API_URL', None),
-  'STATE_CACHE':           {'user':{},
-                            'presence':{}}})
+  'EXTRA_API_URL':          os.getenv('APP_EXTRA_API_URL', None)})
+
+app.cache = {'devices':[],
+             'ustates':{},
+             'pstates':{},
+             'queues':{}}
 
 manager = Manager(
   loop=main_loop,
@@ -111,15 +114,17 @@ db = PintDB(app)
 
 @manager.register_event('FullyBooted')
 async def fullyBootedCallback(mngr: Manager, msg: Message):
+  await refreshDevicesCache()
   await refreshStatesCache()
+  await refreshQueuesCache()
 
 @manager.register_event('ExtensionStatus')
 async def extensionStatusCallback(mngr: Manager, msg: Message):
-  user = msg.exten #hint = msg.hint
+  user = msg.exten
   state = msg.statustext.lower()
-  if user in app.config['STATE_CACHE']['user']:
+  if user in app.cache['ustates']:
     prevState = getUserStateCombined(user)
-    app.config['STATE_CACHE']['user'][user] = state
+    app.cache['ustates'][user] = state
     combinedState = getUserStateCombined(user)
     if combinedState != prevState:
       await userStateChangeCallback(user, combinedState, prevState)
@@ -128,15 +133,15 @@ async def extensionStatusCallback(mngr: Manager, msg: Message):
 async def presenceStatusCallback(mngr: Manager, msg: Message):
   user = msg.exten #hint = msg.hint
   state = msg.status.lower()
-  if user in app.config['STATE_CACHE']['user']:
+  if user in app.cache['ustates']:
     prevState = getUserStateCombined(user)
-    app.config['STATE_CACHE']['presence'][user] = state
+    app.cache['pstates'][user] = state
     combinedState = getUserStateCombined(user)
     if combinedState != prevState:
       await userStateChangeCallback(user, combinedState, prevState)
 
 async def getCDR(start=None, end=None, **kwargs):
-  cdr = {}
+  _cdr = {}
   if end is None:
     end = dt.now()
   if start is None:
@@ -170,12 +175,15 @@ async def getCDR(start=None, end=None, **kwargs):
                                                 uniqueid;''',
                               values={'start':start,
                                       'end':end}):
-    call = {_k: str(_v) for _k, _v in row.items() if _k != 'linkedid' and _v != ''}
-    cdr.setdefault(row['linkedid'],[]).append(call)
+    event = {_k: str(_v) for _k, _v in row.items() if _k != 'linkedid' and _v != ''}
+    _cdr.setdefault(row['linkedid'],[]).append(event)
+  cdr = []
+  for _id in sorted(_cdr.keys()):
+    cdr.append({'id':_id,'events':_cdr[_id]})
   return cdr
 
 async def getCEL(start=None, end=None, **kwargs):
-  cel = {}
+  _cel = {}
   if end is None:
     end = dt.now()
   if start is None:
@@ -204,7 +212,10 @@ async def getCEL(start=None, end=None, **kwargs):
                               values={'start':start,
                                       'end':end}):
     event = {_k: str(_v) for _k, _v in row.items() if _k != 'linkedid' and _v != ''}
-    cel.setdefault(row['linkedid'],[]).append(event)
+    _cel.setdefault(row['linkedid'],[]).append(event)
+  cel = []
+  for _id in sorted(_cel.keys()):
+    cel.append({'id':_id,'events':_cel[_id]})
   return cel
 
 @app.before_first_request
@@ -506,8 +517,8 @@ async def amiDeviceChannel(device):
           return message.channel
   return None
 
-async def setQueueStates(queues, user, device, state):
-  for queue in [_q for _q, _ma in queues.items() for _m in _ma if _m.user == user]:
+async def setQueueStates(user, device, state):
+  for queue in [_q for _q, _ma in app.cache['queues'].items() for _m in _ma if _m.user == user]:
     await amiSetVar('DEVICE_STATE(Custom:QUEUE{}*{})'.format(device, queue), state)
 
 async def getDeviceUser(device):
@@ -531,7 +542,7 @@ async def setUserDevice(user, device):
   else:
     return await amiDBPut('AMPUSER', '{}/device'.format(user), device)
 
-async def unbindOtherDevices(user, newDevice, queues, ast):
+async def unbindOtherDevices(user, newDevice, ast):
   '''Unbinds user from all devices except newDevice and sets
   all required device states.
   '''
@@ -542,20 +553,20 @@ async def unbindOtherDevices(user, newDevice, queues, ast):
         if ast.FMDEVSTATE == 'TRUE':
           await amiSetVar('DEVICE_STATE(Custom:FOLLOWME{})'.format(_device), 'INVALID')
         if ast.QUEDEVSTATE == 'TRUE':
-          await setQueueStates(queues, user, _device, 'NOT_INUSE')
+          await setQueueStates(user, _device, 'NOT_INUSE')
         if ast.DNDDEVSTATE:
           await amiSetVar('DEVICE_STATE(Custom:DEVDND{})'.format(_device), 'NOT_INUSE')
         if ast.CFDEVSTATE:
           await amiSetVar('DEVICE_STATE(Custom:DEVCF{})'.format(_device), 'NOT_INUSE')
         await amiDBPut('DEVICE', '{}/user'.format(_device), 'none')
 
-async def setUserDeviceStates(user, device, queues, ast):
+async def setUserDeviceStates(user, device, ast):
   if ast.FMDEVSTATE == 'TRUE':
     _followMe = await amiDBGet('AMPUSER', '{}/followme/ddial'.format(user))
     if _followMe is not None:
       await amiSetVar('DEVICE_STATE(Custom:FOLLOWME{})'.format(device), followMe2DevState(_followMe))
   if ast.QUEDEVSTATE == 'TRUE':
-    await setQueueStates(queues, user, device, 'INUSE')
+    await setQueueStates(user, device, 'INUSE')
   if ast.DNDDEVSTATE:
     _dnd = await amiDBGet('DND', user)
     await amiSetVar('DEVICE_STATE(Custom:DEVDND{})'.format(device), 'INUSE' if _dnd == 'YES' else 'NOT_INUSE')
@@ -564,9 +575,18 @@ async def setUserDeviceStates(user, device, queues, ast):
     await amiSetVar('DEVICE_STATE(Custom:DEVCF{})'.format(device), 'INUSE' if _cf != '' else 'NOT_INUSE')
 
 async def refreshStatesCache():
-  app.config['STATE_CACHE']['user'] = await amiExtensionStateList()
-  app.config['STATE_CACHE']['presence'] = await amiPresenceStateList()
-  return len(app.config['STATE_CACHE']['user'])
+  app.cache['ustates'] = await amiExtensionStateList()
+  app.cache['pstates'] = await amiPresenceStateList()
+  return len(app.cache['ustates'])
+
+async def refreshDevicesCache():
+  aors = await amiPJSIPShowAors()
+  app.cache['devices'] = list(aors.keys())
+  return len(app.cache['devices'])
+
+async def refreshQueuesCache():
+  app.cache['queues'] = await amiQueues()
+  return len(app.cache['queues'])
 
 async def userStateChangeCallback(user, state, prevState = None):
   reply = None
@@ -581,12 +601,12 @@ async def userStateChangeCallback(user, state, prevState = None):
   return reply
 
 def getUserStateCombined(user):
-  _uCache = app.config['STATE_CACHE']['user']
-  _pCache = app.config['STATE_CACHE']['presence']
+  _uCache = app.cache['ustates']
+  _pCache = app.cache['pstates']
   return combinedStates[_uCache.get(user, 'unavailable')][_pCache.get(user, 'not_set')]
 
 def getUsersStatesCombined():
-  return {user:getUserStateCombined(user) for user in app.config['STATE_CACHE']['user']}
+  return {user:getUserStateCombined(user) for user in app.cache['ustates']}
 
 @app.route('/atxfer/<userA>/<userB>')
 class AtXfer(Resource):
@@ -635,7 +655,7 @@ class UserState(Resource):
     '''Returns user's combined state.
     One of: available, away, dnd, inuse, busy, unavailable, ringing
     '''
-    if user not in app.config['STATE_CACHE']['user']:
+    if user not in app.cache['ustates']:
       return noUser(user)
     return successReply({'user':user,'state':getUserStateCombined(user)})
 
@@ -648,9 +668,9 @@ class PresenceState(Resource):
     '''Returns user's presence state.
     One of: not_set, unavailable, available, away, xa, chat, dnd
     '''
-    if user not in app.config['STATE_CACHE']['user']:
+    if user not in app.cache['ustates']:
       return noUser(user)
-    return successReply({'user':user,'state':app.config['STATE_CACHE']['presence'].get(user, 'not_set')})
+    return successReply({'user':user,'state':app.cache['pstates'].get(user, 'not_set')})
 
 @app.route('/user/<user>/presence/<state>')
 class SetPresenceState(Resource):
@@ -666,7 +686,7 @@ class SetPresenceState(Resource):
     '''
     if state not in presenceStates:
       return invalidState(state)
-    if user not in app.config['STATE_CACHE']['user']:
+    if user not in app.cache['ustates']:
       return noUser(user)
     result = await amiSetVar('PRESENCE_STATE(CustomPresence:{})'.format(user), state)
     if result is not None:
@@ -682,7 +702,7 @@ class UsersDevices(Resource):
     Possible states are: available, away, dnd, inuse, busy, unavailable, ringing
     '''
     data = {}
-    for user in app.config['STATE_CACHE']['user']:
+    for user in app.cache['ustates']:
       device = await getUserDevice(user)
       if device in NONEs:
         device = None
@@ -702,7 +722,7 @@ class UserDeviceBind(Resource):
     Any device user was previously bound to, is unbound.
     Any user previously bound to device is unbound also.
     '''
-    if user not in app.config['STATE_CACHE']['user']:
+    if user not in app.cache['ustates']:
       return noUser(user)
     dial = await getDeviceDial(device) # Check if device exists in astdb
     if dial is None:
@@ -711,19 +731,18 @@ class UserDeviceBind(Resource):
     if currentUser == user:
       return alreadyBound(user, device)
     ast = await getGlobalVars()
-    queues = await amiQueues()
     if currentUser not in NONEs: # If any other user is bound to device, unbind him,
       await setUserDevice(currentUser, None)
       if ast.QUEDEVSTATE == 'TRUE': # set device states for previous user queues
-        await setQueueStates(queues, currentUser, device, 'NOT_INUSE')
+        await setQueueStates(currentUser, device, 'NOT_INUSE')
       await setUserHint(currentUser, None, ast) # set hints for previous user
     await setDeviceUser(device, user) # Bind user to device
     # If user is bound to some other devices, unbind him and set
     # device states for those devices
-    await unbindOtherDevices(user, device, queues, ast)
+    await unbindOtherDevices(user, device, ast)
     if not (await setUserHint(user, dial, ast)): # Set hints for user on new device
       return hintError(user, device)
-    await setUserDeviceStates(user, device, queues, ast) # Set device states for users new device
+    await setUserDeviceStates(user, device, ast) # Set device states for users new device
     if not (await setUserDevice(user, device)): # Bind device to user
       return bindError(user, device)
     return successfullyBound(user, device)
@@ -745,10 +764,9 @@ class DeviceUnBind(Resource):
       return noUserBound(device)
     else:
       ast = await getGlobalVars()
-      queues = await amiQueues()
       await setUserDevice(currentUser, None) # Unbind device from current user
       if ast.QUEDEVSTATE == 'TRUE': # set device states for current user queues
-        await setQueueStates(queues, currentUser, device, 'NOT_INUSE')
+        await setQueueStates(currentUser, device, 'NOT_INUSE')
       await setUserHint(currentUser, None, ast) # set hints for current user
     await setDeviceUser(device, 'none') # Unbind user from device
     return successfullyUnbound(currentUser, device)