promotion/ad_interface_tornado.py
2019-10-30 16:24:18 +08:00

215 lines
8.9 KiB
Python

# -*- coding: utf-8 -*-
# 推广系统对外接口,提供与客户端之间的广告信息接口及每分钟执行一次的缓存变更操作
# http://ad.kingsome.cn/webapp/index.php?c=Ops&a=getAdList&body={"gameid":1004,"locationid":1001}
# http://ad.kingsome.cn/webapp/index.php?c=Ops&a=upAdRecording&adid=1002
# python ad_interface_tornado.py --port=6013
import tornado.ioloop
import tornado.web
import tornado.options
import json
from myredis.myredis import my_redis
import datetime
from mysql.mmysql import MysqlBase
from prod_config import mysql_promotion_config
from log.mylog import define_logger
import logging
from prod_config import BEGIN, END, ad_list_interface_port
from tornado import gen
import pdb
from urllib.parse import unquote
from ops.mtga import FromTga, GetTgaConfig
define_logger("/data/logs/ad_interface_tornado.log")
log = logging.getLogger(__name__)
tornado.options.define("port", default=ad_list_interface_port, type=int, help="run server on the given port.")
limit = 100
class DispatchHandler(tornado.web.RequestHandler):
@gen.coroutine
def get(self):
if self.get_query_argument('c') == 'Ops' and self.get_query_argument('a') == 'selfChecking':
self._selfCheckingHandler()
elif self.get_query_argument('c') == 'Ops' and self.get_query_argument('a') == 'getAdList':
yield self._selfGetAdList()
elif self.get_query_argument('c') == 'Ops' and self.get_query_argument('a') == 'upAdRecording':
yield self._upAdRecording()
elif self.get_query_argument('c') == 'Ops' and self.get_query_argument('a') == 'getLocation':
yield self._selfGetLocation()
else:
self.write("pls check args!")
@gen.coroutine
def post(self):
if self.get_query_argument('c') == 'Ops' and self.get_query_argument('a') == 'upJumpRecording':
self._selfupJumpRecording()
def _selfupJumpRecording(self):
try:
post_data = self.request.body_arguments
post_data = {x: post_data.get(x)[0].decode("utf-8") for x in post_data.keys()}
if not post_data:
post_data = self.request.body.decode('utf-8')
post_data = json.loads(post_data)
post_data['time']=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
today = datetime.datetime.now().strftime("%Y%m%d")
redis_key = f"ad::jumpRecording::{today}"
try:
my_redis.lpush(redis_key, json.dumps(post_data))
return self.write({'errcode': 0, "errmsg": ''})
except:
return self.write({'errcode': 1, "errmsg": 'Failed'})
except Exception as e:
result = {'errcode': 2, "errmsg": f"get args failed,{str(e)}"}
log.error(result)
return self.write({'errcode': 2, "errmsg": 'Failed'})
def _selfGetLocation(self):
try:
input = json.loads(self.get_query_argument('body'))
gameid = input['gameid']
channelid = input.get('channelid', None) or 6001
except Exception as e:
result = {'errcode': 2, "errmsg": f"get args failed,{str(e)}"}
log.error(result)
return self.write_error(2)
mydb = MysqlBase(**mysql_promotion_config)
sql = f"select gameid,channelid,id,area,type,mode from location where gameid={gameid} and channelid={channelid} and in_used=1;"
try:
data = mydb.query(sql)
except Exception:
log.error("get data from location failed!", exc_info=True)
return self.write({'errcode': 2, "errmsg": f"get mysql data failed!"})
all_data = []
log.debug(f"get data from localtion was {data}")
if data:
for line in data:
if line:
localtion = {}
localtion['gameid'], localtion['channelid'], localtion['id'], localtion['area'], localtion['type'], \
localtion['mode'] = line
all_data.append(localtion)
del localtion
return self.write({'errcode': 0, "errmsg": '', "message": all_data})
def _upAdRecording(self):
try:
adid = unquote(self.get_query_argument('adid'), 'utf-8')
localtionid = self.get_query_argument('locationid')
log.info(f" get adid was {adid}")
ids = json.loads(adid)
except Exception:
result = {'errcode': 2, "errmsg": f"get args failed`"}
log.error(result, exc_info=True)
self.write({'errcode': 1, "errmsg": 'get adid failed!'})
if not localtionid:
self.write({'errcode': 1, "errmsg": 'get localtionid failed!'})
if localtionid:
if ids:
for id in ids:
if id:
key = f"adnum::{id}_{localtionid}::num"
my_redis.incr(key, amount=1)
self.write({'errcode': 0, "errmsg": '', "message": f"{ids} incr success!"})
else:
self.write({'errcode': 1, "errmsg": 'get adid failed!'})
else:
self.write({'errcode': 1, "errmsg": 'get localtionid failed!'})
def _selfCheckingHandler(self):
cron_time = 2 * 60 + 5
ad_produce_time = my_redis.get("ad_produce_time") or 0
ad_produce_status = my_redis.get("ad_produce") or 0
now_stamp = int(datetime.datetime.timestamp(datetime.datetime.now()))
timediff = now_stamp - int(ad_produce_time)
if ad_produce_status != str(1) or timediff > cron_time:
self.write(json.dumps(
{'errcode': 1, 'errmsg': f'timediff ={timediff},status={ad_produce_status}', 'healthy': 1,
'max_rundelay': 10}, separators=(',', ':')))
else:
self.write(
json.dumps({'errcode': 0, 'errmsg': '', 'healthy': 1, 'max_rundelay': 10}, separators=(',', ':')))
def _selfGetAdList(self):
try:
input = json.loads(self.get_query_argument('body'))
gameid = input['gameid']
channelid=input.get('channelid',None) or 6001
area = input.get('area', None)
locationid = input.get('locationid',0)
except Exception as e:
result = {'errcode': 2, "errmsg": f"get args failed,{str(e)}"}
log.error(result)
return self.write_error(2)
if area == 0 or area == str(0):
return self.write({'errcode': 2, "errmsg": f"area != 0 "})
if gameid and locationid:
key_word = f"adlist::{gameid}_*::{channelid}::*::{locationid}"
elif gameid and area:
key_word = f"adlist::{gameid}_*::{channelid}::{area}::*"
else:
pass
ad_keys = my_redis.keys(key_word)
ids = []
if ad_keys:
for ad_key in ad_keys:
adlists = my_redis.get(ad_key)
try:
for key in json.loads(adlists):
ids.append(key)
except Exception:
log.error(f"get redis data failed!", exc_info=True)
return self.write({'errcode': 2, "errmsg": f"get redis data failed!"})
dist_ids = list(set(ids))
info = []
if not dist_ids:
result = {'errcode': 0, "errmsg": '', "message": {"totoal": len(info), "result": info}}
else:
try:
# 如果取得的记录条数大于预设,扔掉多余的记录,当前采用的是随机选择,以后可能需要添加加权选择
id_list = []
if limit < len(dist_ids):
nums = limit
else:
nums = len(dist_ids)
for i in range(nums):
while 1:
# new = my_redis.srandmember(key)
import random
new = random.choice(dist_ids)
if new not in id_list:
id_list.append(new)
break
for id in id_list:
temp = my_redis.hgetall(f"adinfo::{id}::info")
if temp:
info.append(temp)
# info_new = sorted(info, key=lambda s: int(s.get('ad_sort', 9999)))
# result = {'errcode': 0, "errmsg": '', "message": {"totoal": len(info_new),
# "result": info_new}}
result = {'errcode': 0, "errmsg": '', "message": {"totoal": len(info), "result": info}}
except Exception as e:
result = {'errcode': 1, "errmsg": e}
return self.write(result)
def make_app():
return tornado.web.Application([(r"/webapp/index[\.]php", DispatchHandler)])
if __name__ == "__main__":
print('start!')
tornado.options.parse_command_line()
app = make_app()
app.listen(tornado.options.options.port)
tornado.ioloop.IOLoop.current().start()