浏览代码

New cache test

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