2019-11-12 13:59:34 +08:00

484 lines
18 KiB
Python

# -*- coding: utf-8 -*-
# from __future__ import absolute_import
from ops.mtga import GetTgaConfig, FromTga
#from ops.minterface import MpInterface
import os
from flask import Flask, render_template, request, jsonify
from flask_mail import Mail, Message
from threading import Thread
from collections import defaultdict
from ops.plog import define_logger
import logging
import datetime
import requests
define_logger("/data/logs/ops/daily_report.log")
import pdb
log = logging.getLogger(__name__)
sender = "ops@kingsome.cn"
app = Flask(__name__)
app.config['MAIL_SERVER'] = 'smtp.exmail.qq.com'
app.config['MAIL_PORT'] = '465'
app.config['MAIL_USE_SSL'] = True
app.config['MAIL_USE_TLS'] = False ## 默认就是 false, 加上警示自己
app.config['MAIL_USERNAME'] = sender
app.config['MAIL_PASSWORD'] = 'bX8cfBAyj9MBqH22'
mail = Mail(app)
# recipients_mini = ["pengtao@kingsome.cn", "tangwenjing@kingsome.cn"]
recipients_mini = ["pengtao@kingsome.cn", "tangwenjing@kingsome.cn", "yuexin@kingsome.cn", "yuetao@kingsome.cn"]
# recipients_2001 = ["pengtao@kingsome.cn", "chenliang@kingsome.cn"]
recipients_2001 = ["pengtao@kingsome.cn", "chenliang@kingsome.cn", "yuexin@kingsome.cn", "yuetao@kingsome.cn"]
# FROMAPPID_CN = {"wxdb103a128e118619": "拯救熊猫泡泡", "wxc137c93eedeab6f2": "爆冰达人"}
class MpInterface:
def __init__(self):
self.base_url = "https://mp.kingsome.cn/api/open/cfg/all?"
def get_data(self, url):
import requests
r = requests.get(url)
if r.status_code == requests.codes.ok:
return r.json().get('result')
else:
return None
def get_fromappid_cn(self, gameid, channelid):
key = "fromappid_cn"
url = f"{self.base_url}channelid={channelid}&gameid={gameid}&key={key}"
return self.get_data(url)
def send_async_email(app, msg):
with app.app_context():
mail.send(msg)
@app.route('/send-dailyreport')
def send_dailyreport():
title = "OPS报表"
day = request.args.get('day')
project = request.args.get('project') or 'mini_games'
if not (project and day):
return jsonify("PLS input arfs")
if str(project) == '2001':
recipients = recipients_2001
else:
recipients = recipients_mini
msg = Message(title, sender=sender, recipients=recipients)
rp = Report(day, project)
data = rp.run()
print(data)
#data[day] = day
if str(project) == '2001':
msg.subject = f"求生之岛_{day}_游戏日报"
else:
msg.subject = f"休闲游戏_{day}_游戏日报"
if data:
msg.html = render_template('report.html', data=data, day=day)
thread = Thread(target=send_async_email, args=[app, msg])
thread.start()
return jsonify("邮件发送成功")
else:
return jsonify("get Data Failed!")
class Report:
def __init__(self, day, project):
self.day = day
self.project = project
self.not_minigames = (2001, 2002)
def get_all_data(self, **args):
activa_sql = f"""SELECT
count(distinct "#account_id")
FROM
v_event_{args['suffix']}
where
gameid='{args['gameid']}'
and "channel"='{args['channelid']}'
and "$part_event"='event_11_1'
and "$part_date"='{self.day}'"""
new_sql = f"""SELECT
count(distinct "#account_id")
FROM
v_event_{args['suffix']}
where
gameid='{args['gameid']}'
and "channel"='{args['channelid']}'
and "$part_event"='event_11_1'
and account_register_date between timestamp'{self.day} 00:00:00' and timestamp'{self.day} 23:59:59'"""
share_sql = f"""SELECT
count(distinct \"#account_id\")
FROM
v_event_{args['suffix']}
where
"$part_event"='event_11_10'
and gameid='{args['gameid']}'
and "channel"='{args['channelid']}'
and "$part_event"='event_11_1'
and "$part_date"='{self.day}'"""
# byshare_sql = f"""SELECT
# count(distinct \"#account_id\")
# FROM
# v_event_{args['suffix']}
# where
# "$part_event"='event_11_11'
# and gameid='{args['gameid']}'
# and channel='{args['channelid']}'
# and "$part_event"='event_11_1'
# and "$part_date"='{self.day}'"""
timeonlie_sql = f"""SELECT
sum(cast(online_duration as int))
FROM
v_event_{args['suffix']}
where
"$part_event"='event_21_2'
and gameid='{args['gameid']}'
and "channel"='{args['channelid']}'
and "$part_date"='{self.day}' """
ad_101_sql = f"""SELECT
count(1)
FROM
v_event_{args['suffix']}
WHERE
"$part_event"='event_11_21'
and gameid='{args['gameid']}'
and "channel"='{args['channelid']}'
AND activity_id=101
AND adv_id_state='0'
and "$part_date"='{self.day}' """
ad_1_sql = f"""SELECT
count(1)
FROM
v_event_{args['suffix']}
WHERE
"$part_event"='event_11_21'
and gameid='{args['gameid']}'
and "channel"='{args['channelid']}'
AND activity_id=1
AND adv_id_state='0'
and "$part_date"='{self.day}' """
ad_201_sql = f"""SELECT
count(1)
FROM
v_event_{args['suffix']}
WHERE
"$part_event"='event_11_21'
and gameid='{args['gameid']}'
and "channel"='{args['channelid']}'
AND activity_id=201
and "$part_date"='{self.day}' """
if args['gameid'] not in self.not_minigames:
jumpout_sql = f"""SELECT
count(distinct "#account_id")
FROM
v_event_{args['suffix']}
where
"$part_event"='event_1_4'
and gameid='{args['gameid']}'
and "channel"='{args['channelid']}'
and "$part_date"='{self.day}'
and "jump_result"=1 """
else:
jumpout_sql = f"""SELECT
count(distinct "#account_id")
FROM
v_event_{args['suffix']}
where
"$part_event"='event_11_31'
and gameid='{args['gameid']}'
and "channel"='{args['channelid']}'
and "$part_date"='{self.day}'
and "button_name" like 'wx%_success'"""
try:
activa = args['tga'].get_data(activa_sql)[0][0] or 0
new = args['tga'].get_data(new_sql)[0][0] or 0
share = args['tga'].get_data(share_sql)[0][0] or 0
timeonlie = round(int(args['tga'].get_data(timeonlie_sql)[0][0] or 0) / activa, 2)
jumpout = args['tga'].get_data(jumpout_sql)[0][0] or 0
jump_per = round((100 * jumpout) / activa, 2)
if args['gameid'] not in self.not_minigames:
ad_101 = args['tga'].get_data(ad_101_sql)[0][0] or 0
ad_1 = args['tga'].get_data(ad_1_sql)[0][0] or 0
ad_201 = args['tga'].get_data(ad_201_sql)[0][0] or 0
else:
ad_101 = ad_1 = ad_201 = 0
return [activa, new, share, timeonlie, ad_1, ad_101, ad_201, jump_per]
except Exception:
log.error(f"get data from tga failed ,{args['gameid']}", exc_info=True)
return None
def get_input_fromappid(self, **args):
activa_sql = f"""SELECT
count(distinct "#account_id")
FROM
v_event_{args['suffix']}
where
gameid='{args['gameid']}'
and "channel"='{args['channelid']}'
and "$part_event"='event_11_1'
and "$part_date"='{self.day}'
and from_appid='{args['fromappid']}'"""
new_sql = f"""SELECT
count(distinct "#account_id")
FROM
v_event_{args['suffix']}
where
gameid='{args['gameid']}'
and "channel"='{args['channelid']}'
and "$part_event"='event_11_1'
and account_register_date between timestamp'{self.day} 00:00:00' and timestamp'{self.day} 23:59:59'
and from_appid='{args['fromappid']}' """
share_sql = f"""SELECT
count(distinct \"#account_id\")
FROM
v_event_{args['suffix']}
where
"$part_event"='event_11_10'
and gameid='{args['gameid']}'
and "channel"='{args['channelid']}'
and "$part_event"='event_11_1'
and "$part_date"='{self.day}'
and from_appid='{args['fromappid']}' """
byshare_sql = f"""SELECT
count(distinct \"#account_id\")
FROM
v_event_{args['suffix']}
where
"$part_event"='event_11_11'
and gameid='{args['gameid']}'
and "channel"='{args['channelid']}'
and "$part_event"='event_11_1'
and "$part_date"='{self.day}'
and from_appid='{args['fromappid']}' """
try:
activa = args['tga'].get_data(activa_sql)[0][0] or 0
new = args['tga'].get_data(new_sql)[0][0] or 0
share = args['tga'].get_data(share_sql)[0][0] or 0
byshare = args['tga'].get_data(byshare_sql)[0][0] or 0
if activa == 0:
k = 0
else:
k = round((100 * byshare / (activa - byshare)), 2)
return (args['fromappid_cn'], activa, new, share, k)
except Exception:
log.error(f"collect input failed {args['gameid']} {args['fromappid']}", exc_info=True)
return None
def get_output_fromappid(self, **args):
if args['gameid'] not in self.not_minigames:
jump_sql = f"""SELECT
count("#account_id"),count(distinct "#account_id")
FROM
v_event_{args['suffix']}
where
"$part_event"='event_1_4'
and gameid='{args['gameid']}'
and "channel"='{args['channelid']}'
and "$part_date"='{self.day}'
and "jump_appid"='{args['fromappid']}'
and "jump_result"=1 """
else:
jump_sql = f"""SELECT
count("#account_id"),count(distinct "#account_id")
FROM
v_event_{args['suffix']}
where
"$part_event"='event_11_31'
and gameid='{args['gameid']}'
and "channel"='{args['channelid']}'
and "$part_date"='{self.day}'
and "button_name"='{args['fromappid']}_success'"""
data = args['tga'].get_data(jump_sql)
if data:
try:
jump_num, jump_pre = data[0]
return (args['fromappid_cn'], jump_num, jump_pre)
except Exception:
log.error(f"get data from output by {args['gameid']} {args['fromappid']} failed", exc_info=True)
return None
else:
return None
def get_args_cn(self):
gameids_cn = dict()
channel_cn = dict()
url = "http://10.10.5.4:2333/api/open/games/list"
r = requests.get(url)
if r.status_code == requests.codes.ok:
data = r.json().get('gameList')
for line in data:
try:
gameids_cn[line.get('game_id')] = line.get('game')
channel_cn[line.get('platform_id')] = line.get('platform_name')
except Exception:
log.error(f"split {line} failed!", exc_info=True)
return (gameids_cn, channel_cn)
else:
return None
def get_ss_input_fromappid(self, args):
if args['gameid'] not in self.not_minigames:
sql = f"""select distinct from_appid FROM
v_event_{args['suffix']}
where
"$part_event"='event_11_1'
and gameid='{args['gameid']}'
and "channel"='{args['channelid']}'
and "$part_date"='{self.day}'"""
data = args['tga'].get_data(sql)
input_fromappids = list()
if data:
try:
for line in data:
if line and line[0] != '':
input_fromappids.append(line[0])
except Exception:
log.error(f"split {line} error", exc_info=True)
return input_fromappids
else:
return None
def get_ss_output_fromappid(self, args):
output_fromappids = list()
if args['gameid'] not in self.not_minigames:
sql = f"""select distinct jump_appid FROM
v_event_{args['suffix']}
where
"$part_event"='event_1_4'
and gameid='{args['gameid']}'
and "channel"='{args['channelid']}'
and "jump_result"=1
and "$part_date"='{self.day}'"""
data = args['tga'].get_data(sql)
if data:
try:
for line in data:
if line and line[0] != '':
output_fromappids.append(line[0].split('_success')[0])
except Exception:
log.error(f"split {line} error", exc_info=True)
return output_fromappids
else:
sql = f"""select distinct button_name FROM
v_event_{args['suffix']}
where
"$part_event"='event_11_31'
and gameid='{args['gameid']}'
and "channel"='{args['channelid']}'
and "$part_date"='{self.day}'
and button_name like 'wx%_success'"""
data = args['tga'].get_data(sql)
if data:
try:
for line in data:
if line and line[0] != '':
output_fromappids.append(line[0])
except Exception:
log.error(f"split {line} error", exc_info=True)
return output_fromappids
def run(self):
if self.project == 'mini_games':
parms = [(1004, 6001), (1011, 6001), (1001, 6001), (1013, 6001)]
elif self.project == '2001':
parms = [(2001, 6001), (2002, 6001)]
else:
return None
cn = self.get_args_cn()
if not cn:
return None
else:
game_cn, chanel_cn = cn
data = list()
for item in parms:
args = {}
args['gameid'], args['channelid'] = item
temp = {}
temp['gameid'] = game_cn.get(args['gameid'], None)
temp['channelid'] = chanel_cn.get(args['channelid'], None)
temp['input'] = defaultdict(list)
temp['output'] = defaultdict(list)
temp['input'] = []
temp['output'] = []
g = GetTgaConfig()
item = g.get_api_key(args['gameid'])
url = item['url']
args['suffix'] = item.get('suffix', 0)
api_key = item.get('api_key', None)
tga = FromTga(url, api_key)
args['tga'] = tga
temp['all'] = self.get_all_data(**args)
ss_input_fromappids = self.get_ss_input_fromappid(args)
ss_output_fromappids = self.get_ss_output_fromappid(args)
mp = MpInterface()
fromappids = mp.get_fromappid_cn(args['gameid'], args['channelid'])
log.info(f"1={fromappids} 2={ss_input_fromappids} 3={ss_output_fromappids}")
if fromappids and ss_input_fromappids:
for item in ss_input_fromappids:
args['fromappid'] = item
args['fromappid_cn'] = fromappids.get(item, None) or item
temp['input'].append(self.get_input_fromappid(**args))
if fromappids and ss_output_fromappids:
for item in ss_output_fromappids:
if args['gameid'] in self.not_minigames:
args['fromappid'] = item.split('_success')[0]
else:
args['fromappid'] = item
args['fromappid_cn'] = fromappids.get(item.split('_success')[0], None) or item
temp['output'].append(self.get_output_fromappid(**args))
data.append(temp)
return data
def main():
day = (datetime.date.today() - datetime.timedelta(days=1)).strftime('%Y-%m-%d')
project = 'mini_games'
cc = Report(day, project)
data = cc.run()
print(data)
if __name__ == "__main__":
#main()
app.run(host='0.0.0.0', port=6700, debug=False)