Browse Source

callback template implementaion

Hal De 4 years ago
parent
commit
7b1f45c140
1 changed files with 24 additions and 9 deletions
  1. 24 9
      app/app.py

+ 24 - 9
app/app.py

@@ -40,6 +40,9 @@ class PintDB:
   def __init__(self, app: Optional[Pint] = None) -> None:
     self.init_app(app)
     self._db = Database(app.config["DB_URI"])
+    await self._db.connect()
+    await database.execute(query='CREATE TABLE IF NOT EXISTS callback_urls (device VARCHAR(16) PRIMARY KEY, url VARCHAR(255))')
+    await self._db.disconnect()
 
   def init_app(self, app: Pint) -> None:
     app.before_serving(self._before_serving)
@@ -89,6 +92,7 @@ app.config.update({
 
 app.cache = {'devices':{},
              'usermap':{},
+             'devicemap':{},
              'ustates':{},
              'pstates':{},
              'queues':{}}
@@ -628,6 +632,7 @@ async def refreshQueuesCache():
 
 async def rebindLostDevices():
   app.cache['usermap'] = {}
+  app.cache['devicemap'] = {}
   ast = await getGlobalVars()
   for device in app.cache['devices']:
     user = await getDeviceUser(device)
@@ -641,16 +646,20 @@ async def rebindLostDevices():
         await setUserDeviceStates(user, device, ast) # Set device states for users device
         await setUserDevice(user, device)            # Bind device to user
     app.cache['usermap'][device] = user
+    if user != 'none':
+      app.cache['devicemap'][user] = device
 
 async def userStateChangeCallback(user, state, prevState = None):
   reply = None
-  if ((app.config['STATE_CALLBACK_URL'] not in NONEs) and
-      ('HTTP_CLIENT' in app.config)):
-    reply = await app.config['HTTP_CLIENT'].post(app.config['STATE_CALLBACK_URL'],
+  if ('HTTP_CLIENT' in app.config) and (user in app.cache['devicemap']):
+    url = await db.fetch_one(query='SELECT url FROM callback_urls WHERE device = :device',
+                             values={'device': app.cache['devicemap'][user]})
+    app.logger.warning(pformat(url))
+    reply = await app.config['HTTP_CLIENT'].post(url,
                                                  json={'user': user,
                                                        'state': state,
                                                        'prev_state':prevState})
-  else:
+
     app.logger.warning('{} changed state to: {}'.format(user, state))
   return reply
 
@@ -899,6 +908,7 @@ class UserDeviceBind(Resource):
     if not (await setUserDevice(user, device)): # Bind device to user
       return bindError(user, device)
     app.cache['usermap'][device] = user
+    app.cache['devicemap'][user] = device
     return successfullyBound(user, device)
 
 @app.route('/device/<device>/off')
@@ -927,6 +937,7 @@ class DeviceUnBind(Resource):
       await setUserHint(currentUser, None, ast) # set hints for current user
     await setDeviceUser(device, 'none') # Unbind user from device
     del app.cache['usermap'][device]
+    del app.cache['devicemap'][currentUser]
     return successfullyUnbound(currentUser, device)
 
 @app.route('/cdr')
@@ -1006,7 +1017,7 @@ class UserCalls(Resource):
   @app.param('limit', 'Max number of returned records, defaults to unlimited. Use offset parameter together with limit', 'query')
   @app.param('offset', 'If limit is specified use offset parameter to request more results', 'query')
   @app.param('order', 'Calls sort order for datetime field. ASC or DESC. Defaults to ASC', 'query')
-  @app.response(HTTPStatus.OK, 'JSON data {"user":user,"state":state}')
+  @app.response(HTTPStatus.OK, 'JSON data {"status":status,"data":data,"message":message}')
   @app.response(HTTPStatus.UNAUTHORIZED, 'Authorization required')
   async def get(self, user):
     '''Returns user's call stats.
@@ -1028,17 +1039,21 @@ class UserCalls(Resource):
 class DeviceCallback(Resource):
   @authRequired
   @app.param('device', 'Device to get/set the callback url for', 'path')
-  @app.param('url', 'Callback url', 'query')
+  @app.param('url', 'used to set the Callback url for the device', 'query')
   @app.response(HTTPStatus.OK, 'JSON data {"user":user,"state":state}')
   @app.response(HTTPStatus.UNAUTHORIZED, 'Authorization required')
   async def get(self, device):
-    '''Returns device's callback url.
+    '''Returns and sets device's callback url.
     '''
     if (device != request.device) and (not request.admin):
       abort(401)
     url = request.args.get('url', None)
-    if url is None:
-      url = 'http://127.0.0.1:65535/status'
+    if url is not None:
+      await db.execute(query='REPLACE INTO callback_urls (device, url) VALUES (:device, :url)',
+                       values={'device': device,'url': url})
+    else:
+      url = await db.fetch_one(query='SELECT url FROM callback_urls WHERE device = :device',
+                               values={'device': device})
     return successCallbackURL(device, url)
 
 manager.connect()