#!/usr/bin/python  
 | 
# -*- coding: utf-8 -*-  
 | 
#  
 | 
##@package  
 | 
#  
 | 
# @todo: 基于头条广告API对接广告点击 激活 注册 付费信息交互  
 | 
#  
 | 
# @author: Alee  
 | 
# @date 2018-5-4 22:10:51  
 | 
# @version 1.0  
 | 
#  
 | 
# @note: 中文必须传utf8,收到的为urlencode内容  .decode('gbk').encode('utf8')  
 | 
# !!!注意大小写区分  
 | 
#  
 | 
#---------------------------------------------------------------------  
 | 
  
 | 
from bottle import Bottle, request  
 | 
from lib import mylog, CommFunc  
 | 
import ADDB  
 | 
import json  
 | 
import md5  
 | 
import time  
 | 
  
 | 
myapp = Bottle()  
 | 
  
 | 
Def_URLPARAM_STR = "__"  # 参数两边用两个下划线包裹  
 | 
  
 | 
#====================  
 | 
# 参数adid cid timestamp callback_url mac1 ua1 idfa androidid1 imei ip  
 | 
#====================  
 | 
  
 | 
  
 | 
#center.secondworld.net.cn:53004/ad/feedback/2001?adid=__AID__&cid=__CID__&csite=__CSITE__&ctype=__CTYPE__&mac1=__MAC1__&ua1=__UA1__&androidid1=__ANDROIDID1__&imei=__IMEI__&os=__OS__&ip=__IP__&ts=__TS__&callback_url=__CALLBACK_URL__  
 | 
#接口1   
 | 
# 点击广告记录,通过广告ID、包体ID和唯一标识(IMEI或MAC等)匹配对应后续的激活注册付费操作  
 | 
# 情况1-重复:同一用户多次点击同一个广告ID下载  
 | 
# 情况2-重复:同一用户多次点击不同广告ID下载  
 | 
# 情况3-无点击: 不是从广告进入的用户  
 | 
@myapp.route('/ad/feedback/:packid')  
 | 
def ADFeedback(packid):  
 | 
    getDict = request.GET  
 | 
      
 | 
    #print "---------"  
 | 
    for key in getDict:  
 | 
        mylog.debug("feedback: %s-%s"%(key, getDict[key]))  
 | 
          
 | 
    adid = getDict.get("adid", "")  
 | 
    if not adid:  
 | 
        mylog.error("no adid")  
 | 
        return json.dumps({"status":-1}, ensure_ascii=False)  
 | 
      
 | 
    if adid == "__AID__":  
 | 
        return  
 | 
    dbController = ADDB.GetDBEventCon()  
 | 
    if not dbController:  
 | 
        # 无法获取数据库  
 | 
        mylog.debug("no dbController")  
 | 
        return json.dumps({"status":-1}, ensure_ascii=False)  
 | 
      
 | 
    #adid 和 包ID为唯一标识  
 | 
          
 | 
    result, findDict = FindUserFromAD(dbController, getDict, packid, adid)  
 | 
    mylog.debug("result:%s-%s"%(result, findDict))  
 | 
    newDict = {"adid":adid}     # 广告计划ID  
 | 
    newDict["cid"] = getDict.get("cid", "") # 广告创意ID  
 | 
    newDict["csite"] = getDict.get("csite", "") # 广告投放位置  
 | 
    newDict["ctype"] = getDict.get("ctype", "") # 创意样式  
 | 
    newDict["mac1"] = getDict.get("mac1", "") # 入网硬件地址 eth0 MAC    md5  
 | 
    newDict["ua1"] = getDict.get("ua1", "") # user-agent  
 | 
    newDict["idfa"] = getDict.get("idfa", "")   # 苹果的idfa  
 | 
    newDict["androidid1"] = getDict.get("androidid1", "")  
 | 
    newDict["imei"] = getDict.get("imei", "")  # md5  
 | 
    newDict["os"] = getDict.get("os", "")  
 | 
    newDict["ip"] = getDict.get("ip", "")  
 | 
    newDict["ts"] = int(getDict.get("ts", time.time()*1000))   # 时间戳毫秒 点击和激活最长7天  
 | 
    newDict["callback_url"] = getDict.get("callback_url", "")  
 | 
  
 | 
    newDict["packid"] = packid  #包ID  
 | 
    if not result:  
 | 
        newDict["clickcnt"] = 1 # 重复点击数  
 | 
        newDict["event_type"] = 0  
 | 
        #插入新数据  
 | 
        dbController.insert(ADDB.AdColName, newDict)  
 | 
    else:  
 | 
        # 更新数据  
 | 
        newDict["clickcnt"] = result[0].get("clickcnt", 0) + 1 # 重复点击数  
 | 
        newDict["event_type"] = result[0].get("event_type", 0)  
 | 
        dbController.update(ADDB.AdColName, findDict, newDict)  
 | 
          
 | 
    return json.dumps({"status":0}, ensure_ascii=False)  
 | 
  
 | 
  
 | 
  
 | 
#center.secondworld.net.cn:53004/ad/eventtype/包id?mac1=xxx....event_type=0  
 | 
# 客户端激活 注册 付费  
 | 
# MAC1 UA IDFA ANDROIDID1 IMEI IP  event_type  
 | 
@myapp.route('/ad/eventtype/:packid')  
 | 
def ClientActive(packid):  
 | 
    getDict = request.GET  
 | 
      
 | 
    #print "---------"  
 | 
    for key in getDict:  
 | 
        mylog.debug("ClientActive: %s-%s"%(key, getDict[key]))  
 | 
      
 | 
    mylog.info("ClientActive - IMEI:%s ANDROIDID1: %s event_type: %s"%(  
 | 
            getDict.get("IMEI", ""), getDict.get("ANDROIDID1", ""), getDict.get("event_type", "")))  
 | 
           
 | 
    event_type = getDict.get("event_type", "")  
 | 
    if event_type == "":  
 | 
        mylog.error("no event_type")  
 | 
        return  
 | 
    event_type = CommFunc.ToIntDef(event_type, 0)  
 | 
          
 | 
    dbController = ADDB.GetDBEventCon()  
 | 
    if not dbController:  
 | 
        # 无法获取数据库  
 | 
        mylog.debug("no dbController")  
 | 
        return  
 | 
           
 | 
    # 理论上adid和packid是唯一对应,此处最多只能找到一个  
 | 
    result, findDict = FindUserFromClient(dbController, getDict, packid)  
 | 
    if not result:  
 | 
        # 非广告用户  
 | 
        return  
 | 
      
 | 
    if len(result) > 1:  
 | 
        mylog.warn("more result:%s-%s"%(len(result), findDict))  
 | 
      
 | 
    dbEvent = result[0]['event_type']  
 | 
    clientEvent = pow(2, event_type)  
 | 
    if dbEvent&clientEvent != 0:  
 | 
        # 已设置过,不处理  
 | 
        return  
 | 
      
 | 
    if dbEvent == 0 and event_type > 0:  
 | 
        # 未设置过激活不设置注册和付费  
 | 
        return  
 | 
      
 | 
    callback_url = result[0]['callback_url']  
 | 
      
 | 
    # 发送给头条广告  
 | 
    try:  
 | 
        result = CommFunc.DoGet(callback_url + "&event_type=%s"%event_type)  
 | 
    except:  
 | 
        mylog.warn("toutiao no answer")  
 | 
        result = None  
 | 
      
 | 
    if result:  
 | 
        resultDict = json.loads(result)  
 | 
        mylog.debug("%s"%resultDict)  
 | 
        if resultDict.get("ret", -1) == 0:  
 | 
            dbController.update(ADDB.AdColName, findDict, {"$set":{'event_type':dbEvent|clientEvent}})  
 | 
    return  
 | 
  
 | 
@myapp.route('/ad/getip')  
 | 
def GetIP():  
 | 
    return request.environ.get("REMOTE_ADDR", "0.0.0.0")  
 | 
  
 | 
  
 | 
# !!!注意大小写区分  
 | 
# 同类型手机在同wifi网络下 ip和ua可能相同,放最后判断  
 | 
def FindUserFromAD(dbController, getDict, packid, adid):  
 | 
    if "idfa" in getDict:  
 | 
        # 苹果  
 | 
        if getDict.get("idfa", ""):  
 | 
            findDict = {"adid":adid, "packid":packid, "idfa":getDict.get("idfa", "")}  
 | 
            result = dbController.find(ADDB.AdColName, findDict)  
 | 
            if result[1]:  
 | 
                return result[1], findDict  
 | 
          
 | 
        if getDict.get("mac1", ""):  
 | 
            findDict = {"adid":adid, "packid":packid, "mac1":getDict.get("mac1", "")}  
 | 
            result = dbController.find(ADDB.AdColName, findDict)  
 | 
            if result[1]:  
 | 
                return result[1], findDict  
 | 
  
 | 
        if (getDict.get("ip", "") and getDict.get("ua1", "")):  
 | 
            findDict = {"adid":adid, "packid":packid, "ip":getDict.get("ip", ""), "ua1":getDict.get("ua1", "")}  
 | 
            result = dbController.find(ADDB.AdColName, findDict)  
 | 
            if result[1]:  
 | 
                return result[1], findDict  
 | 
              
 | 
  
 | 
    else:  
 | 
        # 安卓  
 | 
          
 | 
        if getDict.get("imei", ""):  
 | 
            findDict = {"adid":adid, "packid":packid, "imei":getDict.get("imei", "")}  
 | 
            result = dbController.find(ADDB.AdColName, findDict)  
 | 
            if result[1]:  
 | 
                return result[1], findDict  
 | 
          
 | 
        if getDict.get("androidid1", ""):  
 | 
            findDict = {"adid":adid, "packid":packid, "androidid1":getDict.get("androidid1", "")}  
 | 
            result = dbController.find(ADDB.AdColName, findDict)  
 | 
            if result[1]:  
 | 
                return result[1], findDict  
 | 
              
 | 
        if getDict.get("mac1", ""):  
 | 
            findDict = {"adid":adid, "packid":packid, "mac1":getDict.get("mac1", "")}  
 | 
            result = dbController.find(ADDB.AdColName, findDict)  
 | 
            if result[1]:  
 | 
                return result[1], findDict  
 | 
  
 | 
        if (getDict.get("ip", "") and getDict.get("ua1", "")):  
 | 
            findDict = {"adid":adid, "packid":packid, "ip":getDict.get("ip", ""), "ua1":getDict.get("ua1", "")}  
 | 
            result = dbController.find(ADDB.AdColName, findDict)  
 | 
            if result[1]:  
 | 
                return result[1], findDict  
 | 
          
 | 
    return None, None  
 | 
  
 | 
# MAC1 UA IDFA ANDROIDID1 IMEI IP  event_type  
 | 
# !!!注意大小写区分  
 | 
# 同类型手机在同wifi网络下 ip和ua可能相同,放最后判断  
 | 
def FindUserFromClient(dbController, getDict, packid):  
 | 
    intime = int(time.time()*1000 - 7*24*60*60*1000)   # 查找7天内的数据  
 | 
      
 | 
    if "IDFA" in getDict:  
 | 
        # 苹果  
 | 
        if getDict.get("IDFA", ""):  
 | 
            findDict = {"packid":packid, "idfa":getDict.get("IDFA", ""), "ts":{'$gt':intime}}  
 | 
            result = dbController.find(ADDB.AdColName, findDict)  
 | 
            if result[1]:  
 | 
                return result[1], findDict  
 | 
          
 | 
        if getDict.get("MAC1", ""):  
 | 
            findDict = {"packid":packid, "mac1":md5.md5(getDict.get("MAC1", "")).hexdigest(), "ts":{'$gt':intime}}  
 | 
            result = dbController.find(ADDB.AdColName, findDict)  
 | 
            if result[1]:  
 | 
                return result[1], findDict  
 | 
  
 | 
        if (getDict.get("IP", "") and getDict.get("UA", "")):  
 | 
            findDict = {"packid":packid, "ip":getDict.get("IP", ""), "ua1":getDict.get("UA", ""), "ts":{'$gt':intime}}  
 | 
            result = dbController.find(ADDB.AdColName, findDict)  
 | 
            if result[1]:  
 | 
                return result[1], findDict  
 | 
              
 | 
  
 | 
    else:  
 | 
        # 安卓  
 | 
        if getDict.get("IMEI", ""):  
 | 
            findDict = {"packid":packid, "imei":md5.md5(getDict.get("IMEI", "")).hexdigest(), "ts":{'$gt':intime}}  
 | 
            result = dbController.find(ADDB.AdColName, findDict)  
 | 
            if result[1]:  
 | 
                return result[1], findDict  
 | 
          
 | 
        if getDict.get("ANDROIDID1", ""):  
 | 
            findDict = {"packid":packid, "androidid1":getDict.get("ANDROIDID1", ""), "ts":{'$gt':intime}}  
 | 
            result = dbController.find(ADDB.AdColName, findDict)  
 | 
            if result[1]:  
 | 
                return result[1], findDict  
 | 
              
 | 
        if getDict.get("MAC1", ""):  
 | 
            findDict = {"packid":packid, "mac1":md5.md5(getDict.get("MAC1", "")).hexdigest(), "ts":{'$gt':intime}}  
 | 
            result = dbController.find(ADDB.AdColName, findDict)  
 | 
            if result[1]:  
 | 
                return result[1], findDict  
 | 
  
 | 
        if (getDict.get("IP", "") and getDict.get("UA", "")):  
 | 
            findDict = {"packid":packid, "ip":getDict.get("IP", ""), "ua1":getDict.get("UA", ""), "ts":{'$gt':intime}}  
 | 
            result = dbController.find(ADDB.AdColName, findDict)  
 | 
            if result[1]:  
 | 
                return result[1], findDict  
 | 
          
 | 
    return None, None  
 | 
  
 | 
  
 | 
  
 |