120 lines
3.3 KiB
Python
Executable file
120 lines
3.3 KiB
Python
Executable file
#!/usr/bin/python3
|
|
import json
|
|
import logging
|
|
import os
|
|
import time
|
|
from urllib.parse import unquote
|
|
|
|
from tornado.httpserver import HTTPServer
|
|
from tornado.ioloop import IOLoop, PeriodicCallback
|
|
|
|
from tornado.web import StaticFileHandler, Application, HTTPError
|
|
import tornado.gen
|
|
import tornado.web
|
|
|
|
|
|
from recommendation_engine import Engine
|
|
from utils import json_dumps, run_async
|
|
|
|
|
|
BANNER_PUBLIC = 'DD recommondation engine'
|
|
BANNER = '%s - use POST at / to access JSON-RPC 2.0 endpoint' % BANNER_PUBLIC
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
@run_async
|
|
def api_task(request, engine, callback):
|
|
try:
|
|
if request['method'] == 'getVideos':
|
|
result = engine.get_videos(**request['params'])
|
|
elif request['method'] == 'getNext':
|
|
result = engine.get_next(**request['params'])
|
|
elif request['method'] == 'getRecommendations':
|
|
result = engine.state
|
|
elif request['method'] == 'setRecommendations':
|
|
result = engine.update_state(request['params'])
|
|
else:
|
|
result = {}
|
|
response = {
|
|
'result': result
|
|
}
|
|
except:
|
|
logger.error('api failed: %s', request, exc_info=True)
|
|
response = {'error': {'code': -32000, 'message': 'Server error'}}
|
|
callback(response)
|
|
|
|
|
|
class RPCHandler(tornado.web.RequestHandler):
|
|
|
|
def initialize(self, engine):
|
|
self.engine = engine
|
|
|
|
def get(self):
|
|
self.write(BANNER)
|
|
|
|
@tornado.gen.coroutine
|
|
def post(self):
|
|
error = None
|
|
request = None
|
|
try:
|
|
request = json.loads(self.request.body.decode())
|
|
if request['method'] not in ('getVideos', 'getNext', 'getRecommendations', 'setRecommendations'):
|
|
raise Exception('unknown method')
|
|
except:
|
|
error = {'error': {'code': -32700, 'message': 'Parse error'}}
|
|
if not error:
|
|
try:
|
|
response = yield tornado.gen.Task(api_task, request, self.engine)
|
|
except:
|
|
logger.error("ERROR: %s", request, exc_info=True)
|
|
error = {'error': {'code': -32000, 'message': 'Server error'}}
|
|
if error:
|
|
response = error
|
|
if request and 'id' in request:
|
|
response['id'] = request['id']
|
|
response['jsonrpc'] = '2.0'
|
|
response = json_dumps(response)
|
|
self.write(response)
|
|
|
|
|
|
def main(prefix='json/'):
|
|
settings = {
|
|
'debug': False,
|
|
'port': 8081,
|
|
'address': '',
|
|
'pandora': 'http://pandora.dmp/api/',
|
|
'pandora_ws': 'ws://pandora.dmp/api/ws/',
|
|
'username': 'dd.re',
|
|
'password': 'dd.re'
|
|
}
|
|
engine = Engine(prefix, **settings)
|
|
|
|
handlers = [
|
|
(r'/', RPCHandler, dict(engine=engine)),
|
|
]
|
|
options = {
|
|
'debug': settings['debug'],
|
|
'gzip': True,
|
|
}
|
|
if settings['debug']:
|
|
log_format = '%(asctime)s:%(levelname)s:%(name)s:%(message)s'
|
|
logging.basicConfig(level=logging.DEBUG, format=log_format)
|
|
|
|
app = Application(handlers, **options)
|
|
app.listen(settings['port'], settings['address'])
|
|
main = IOLoop.instance()
|
|
|
|
update_cb = PeriodicCallback(engine.update_async, 15*60*1000)
|
|
update_cb.start()
|
|
#main.spawn_callback(update, engine)
|
|
|
|
#fixme run periodically
|
|
try:
|
|
main.start()
|
|
except:
|
|
print('shutting down...')
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|