# -*- 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)