| #!/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  | 
|   | 
|   | 
|   |