215 lines
8.9 KiB
Python
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()
|