CommonFunction.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. import requests
  2. from utils.UrlConfig import headers
  3. import json
  4. import pandas as pd
  5. import datetime
  6. from utils.DataBaseConfig import *
  7. import traceback
  8. from concurrent_log import ConcurrentTimedRotatingFileHandler
  9. import logging
  10. log_formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s', '%m/%d/%Y %I:%M:%S %p')
  11. log_handler = ConcurrentTimedRotatingFileHandler("logs/commonfunction.log", when="midnight", backupCount=100)
  12. log_handler.setFormatter(log_formatter)
  13. logger = logging.getLogger('common_function_logger')
  14. logger.addHandler(log_handler)
  15. logger.setLevel(logging.DEBUG)
  16. print('id of common_function_logger %s' % id(logger))
  17. logger.info("common_function_logger started!")
  18. def get_lower_case_name(name):
  19. lst = []
  20. for index, char in enumerate(name):
  21. if char.isupper() and index != 0:
  22. lst.append("_")
  23. lst.append(char)
  24. return "".join(lst).lower()
  25. def get_app_list(account_id,url):
  26. """
  27. 获取应用详情
  28. url:http://192.168.1.8:8080/jeecg-boot/ai/aiKuaiShouAppInfo/list
  29. 请求方式:post
  30. 入参:accountId 账户id
  31. appId 应用id
  32. 返回参数:
  33. {
  34. "code": 0,
  35. "data": [{
  36. "id": 413,
  37. "accountId": 9864909,
  38. "appVersion": "ksjyrlyn-人类一脑涂地大败",
  39. "appName": "233乐园",
  40. "packageName": "com.meta.box",
  41. "platform": 1,
  42. "url": "https://www.233leyuan.com/apiserv/api/deliveryTest/ABTest?id=ksjyrlyn",
  43. "useSdk": 0,
  44. "appPrivacyUrl": "https://webcdn.233leyuan.com/app/useragreement/metax/privacyagreement.html",
  45. "trackUrl": "https://lnk0.com/kYZxds?chn=451&imei_md5=__IMEI2__&androidid_md5_1=__ANDROIDID2__&oaid=__OAID__&adcampaign=__DNAME__&adcreative=__CID__&adgroup=__AID__&did=__DID__&accountid=__ACCOUNTID__&platform=__OS__&clicktime=__TS__&ip=__IP__&useragent=__UA__&channelapp=__CSITE__&callback_url=__CALLBACK__&action=none",
  46. "appMd5": "0b2314c738956dc159ed38dc584ef214",
  47. "imageToken": "marketb3e98f5f68a74870b8d8d814499d6189.jpg",
  48. "status": 2,
  49. "remark": "创建应用成功",
  50. "appId": 3543665,
  51. "createTime": "2021-02-03 16:40:53",
  52. "updateTime": "2021-02-03 16:42:52"}],
  53. "message": "success"
  54. }
  55. """
  56. request_data = {"accountId": account_id}
  57. logger.info("aiKuaiShouAppInfo/list the request_data is %s" % request_data)
  58. try:
  59. request = requests.post(url=url, headers=headers, data=json.JSONEncoder().encode(request_data)).text
  60. request_json = json.loads(request)
  61. if request_json["code"] != 0:
  62. logger.info("account_id=%s, the res of list is %s" % (account_id, request_json['message']))
  63. except:
  64. logger.error('account_id=%s, the res of list is %s, the traceback is %s ' %
  65. (account_id, request, traceback.format_exc()))
  66. return {"code": -1}
  67. return request_json
  68. def get_app_detail(account_id, url, app_id):
  69. """
  70. 获取应用详情
  71. url:http://192.168.1.8:8080/jeecg-boot/ai/aiKuaiShouAppInfo/getAppDetail
  72. 请求方式:post
  73. 入参:accountId 账户id
  74. appId 应用id
  75. 返回参数:
  76. {
  77. "code": 0,
  78. "data": {
  79. "id": 413,
  80. "accountId": 9864909,
  81. "appVersion": "ksjyrlyn-人类一脑涂地大败",
  82. "appName": "233乐园",
  83. "packageName": "com.meta.box",
  84. "platform": 1,
  85. "url": "https://www.233leyuan.com/apiserv/api/deliveryTest/ABTest?id=ksjyrlyn",
  86. "useSdk": 0,
  87. "appPrivacyUrl": "https://webcdn.233leyuan.com/app/useragreement/metax/privacyagreement.html",
  88. "trackUrl": "https://lnk0.com/kYZxds?chn=451&imei_md5=__IMEI2__&androidid_md5_1=__ANDROIDID2__&oaid=__OAID__&adcampaign=__DNAME__&adcreative=__CID__&adgroup=__AID__&did=__DID__&accountid=__ACCOUNTID__&platform=__OS__&clicktime=__TS__&ip=__IP__&useragent=__UA__&channelapp=__CSITE__&callback_url=__CALLBACK__&action=none",
  89. "appMd5": "0b2314c738956dc159ed38dc584ef214",
  90. "imageToken": "marketb3e98f5f68a74870b8d8d814499d6189.jpg",
  91. "status": 2,
  92. "remark": "创建应用成功",
  93. "appId": 3543665,
  94. "createTime": "2021-02-03 16:40:53",
  95. "updateTime": "2021-02-03 16:42:52"},
  96. "message": "success"
  97. }
  98. """
  99. request_data = {"accountId": account_id, "appId": app_id}
  100. logger.info("/getAppDetail the request_data is %s" % request_data)
  101. try:
  102. request = requests.post(url=url, headers=headers, data=json.JSONEncoder().encode(request_data)).text
  103. request_json = json.loads(request)
  104. if request_json["code"] != 0:
  105. logger.info("account_id=%s, appId=%s, the res of getAppDetail is %s" % (account_id, app_id, request_json['message']))
  106. except:
  107. logger.error('account_id=%s, appId=%s, the res of getAppDetail is %s, the traceback is %s ' %
  108. (account_id, app_id, request, traceback.format_exc()))
  109. return {"code": -1}
  110. return request_json
  111. def get_history_video_info(account_id, url, start_time, end_time, video_cnt, related_creative_max_cnt, app_version=None):
  112. """
  113. url:http://192.168.1.8:8080/jeecg-boot/kuaishou/material/getHistoryVideoList
  114. 请求方式:POST
  115. remark: 见入参
  116. 入参:accountId 账户id
  117. startDate 开始时间 --(视频的upload_time)
  118. endDate 结束时间 --(视频的upload_time)
  119. createCount 关联创意数 (小于该值)
  120. num 获取数量 (随机num个)
  121. """
  122. if not app_version:
  123. request_data = {"accountId": account_id,
  124. "startDate": start_time,
  125. "endDate": end_time,
  126. "num": video_cnt,
  127. "createCount": related_creative_max_cnt}
  128. else:
  129. request_data = {"accountId": account_id,
  130. "startDate": start_time,
  131. "endDate": end_time,
  132. "num": video_cnt,
  133. "createCount": related_creative_max_cnt,
  134. "appVersion": app_version}
  135. try:
  136. logger.info("getHistoryVideoList the request_data is %s" % request_data)
  137. request = requests.post(url, headers=headers, data=json.JSONEncoder().encode(request_data)).text
  138. request_json = json.loads(request)
  139. if request_json["code"] != 0:
  140. logger.info("account_id=%s, app_version=%s, the res of getHistoryVideoList is %s" %
  141. (account_id, app_version, request_json['message']))
  142. except Exception:
  143. logger.error('account_id=%s, app_version=%s, the res of getHistoryVideoList is %s, the traceback is %s ' %
  144. (account_id, app_version, request, traceback.format_exc()))
  145. return {"code": -1}
  146. return request_json
  147. def refresh_video(account_id, url):
  148. """
  149. 需要调用刷新快手素材的接口 http://192.168.1.8:8080/jeecg-boot/kuaishou/material/getKuaiShouVideoList
  150. (请求方式 POST 入参:accountId 返回结果:成功或失败)
  151. remark: 自动上新之前,需要调用该接口,注意是账户层级的调用,不是app_id层级的调用
  152. """
  153. try:
  154. request = requests.post(url=url, headers=headers,
  155. data=json.JSONEncoder().encode({"accountId": account_id})).text
  156. request_json = json.loads(request)
  157. logger.info('account_id=%s, the res of getKuaiShouVideoList is %s' % (account_id, request_json))
  158. except Exception:
  159. logger.error('account_id=%s, the res of getKuaiShouVideoList is %s, traceback is %s ' %
  160. (account_id, request, traceback.format_exc()))
  161. def get_new_video_info(account_id, url, app_version=None):
  162. """
  163. url:http://192.168.1.8:8080/jeecg-boot/kuaishou/material/getNewVideoList
  164. 请求方式:POST
  165. remark:
  166. 1、返回 upload_time 在上次调用时间到本次调用时间内的素材(第一次调用返回5分钟前到本次调用时间的素材)
  167. 入参:accountId
  168. """
  169. if not app_version:
  170. request_data = {"accountId": account_id}
  171. else:
  172. request_data = {"accountId": account_id, 'appVersion': app_version}
  173. try:
  174. logger.info("getNewVideoList the request_data is %s" % request_data)
  175. request = requests.post(url, headers=headers, data=json.JSONEncoder().encode(request_data)).text
  176. request_json = json.loads(request)
  177. if request_json["code"] != 0:
  178. logger.info("account_id=%s, app_version=%s, the res of getNewVideoList is %s" %
  179. (account_id, app_version, request_json['message']))
  180. except Exception:
  181. logger.error('account_id=%s, app_version=%s, the res of getNewVideoList is %s, the traceback is %s ' %
  182. (account_id, app_version, request, traceback.format_exc()))
  183. return {"code": -1}
  184. return request_json
  185. def get_missing_video_info(account_id, cnt, url, start_time, end_time, app_version=None):
  186. """
  187. url:"http://192.168.1.8:8080/jeecg-boot/kuaishou/material/getCreateZeroVideoList"
  188. 请求方式:POST
  189. remark: 视频的upload_time 在startTime 和 endTime 之间,创意关联个数为0,order by upload_time asc limit videoCnt
  190. 入参:
  191. accountId: 账户id
  192. videoCnt: 查询数量
  193. startTime: 开始时间
  194. endTime: 结束时间
  195. """
  196. if not app_version:
  197. request_data = {"accountId": account_id, "videoCnt": cnt, "startTime": start_time, "endTime": end_time}
  198. else:
  199. request_data = {"accountId": account_id, "videoCnt": cnt, "startTime": start_time, "endTime": end_time,
  200. 'appVersion': app_version}
  201. try:
  202. logger.info("getCreateZeroVideoList the request_data is %s" % request_data)
  203. request = requests.post(url, headers=headers, data=json.JSONEncoder().encode(request_data)).text
  204. request_json = json.loads(request)
  205. if request_json["code"] != 0:
  206. logger.info("account_id=%s, app_version=%s, the res of getCreateZeroVideoList is %s" %
  207. (account_id, app_version, request_json['message']))
  208. except Exception:
  209. logger.error('account_id=%s, app_version=%s, the res of getCreateZeroVideoList is %s, the traceback is %s ' %
  210. (account_id, app_version, request, traceback.format_exc()))
  211. return {"code": -1}
  212. return request_json
  213. def get_top_video_info(account_id, cnt, start_time, end_time, url, app_version=None):
  214. """
  215. url:http://192.168.1.8:8080/jeecg-boot/kuaishou/material/getHistoryTopVideoList
  216. 请求方式:POST
  217. remark: ctop_kuaishou_report_daily_material
  218. 整个项目维度 stat_date 在 startTime 和 endTime, order by sum(charge) desc limit num
  219. 入参:
  220. accountId: 账户id
  221. startTime: 开始时间
  222. endTime: 结束时间
  223. num: 查询数量
  224. remark: 返回结果中 "photo_name" == "all",表示为通用视频,反之为app_id对应的特定视频("photo_name": "ksjytdrca-糖豆人冲啊")
  225. 返回:
  226. {
  227. "code": 0,
  228. "data": [
  229. {
  230. "material_type": 1,
  231. "charge": 154229.670,
  232. "video_url": "http://alimov2.a.yximgs.com/upic/2021/02/03/18/BMjAyMTAyMDMxODU3MjlfMjI0NTY2OTI5MF80MzUxMjc4MTgzNV8wXzM=_b_B142e1ddc44705f978fe2a7fa4f4e9eb1.mp4?tag=1-1613958443-unknown-0-nbzw9am7cu-465420c6c3fe0f27&clientCacheKey=3xeh2gxd84qg462_b.mp4&tt=b&di=8bba1b60&bp=13890",
  233. "photo_id": "5249789835088957477",
  234. "photo_name": "ksjytdrca-糖豆人冲啊",
  235. "signature": "e160cc10d73031a48895a32834b54c46",
  236. "channel_type": 0,
  237. "imageList": [
  238. "3267a05ef40ca8180b87428bcc324628",
  239. "1e5cb59e588a6dd489a9c0c36b7e52cd",
  240. "c0a199395614c5204a2f9a5aa9457fdf",
  241. "659c1865be2e9b561475d204ebf363b4",
  242. "7b85a1262a59e22ff2e82a3374d8beb0",
  243. "2e5542b2b39191219c33e278ccae0bdf",
  244. "45d2d11e052aca20c2a5e546e2ffda30",
  245. "8902152d887dfc119a2ba32d970683d9",
  246. "7becab0d75b2cbec66ea18fbabd33b59",
  247. "e1ba0f57d3abe2822ab3fc02d9ea7ba3",
  248. "9676c587837df85df4aba76a5ce3b8c1",
  249. "1b42543b0b31613740dfaa8fd861136c",
  250. "8a1c95ecf4af672d2f7a1acef36bce15",
  251. "5e6d8d8f0339ab7d2b3e1de533111606",
  252. "8b5b6c6d63e62e04a92d84fe175c05fd"
  253. ]
  254. },
  255. {
  256. "material_type": 1,
  257. "charge": 92135.125,
  258. "video_url": "http://txmov2.a.yximgs.com/upic/2021/02/03/18/BMjAyMTAyMDMxODU3MzhfMjI0NTY2OTI5MF80MzUxMjc5MzU0MV8wXzM=_b_Bd0dab20fe03c02e76080340c66341573.mp4?tag=1-1613958443-unknown-0-9romi5xmpo-d5161ea63e200cde&clientCacheKey=3xu33qupdka3h5y_b.mp4&tt=b&di=8bba1b60&bp=13890",
  259. "photo_id": "5192368941898812785",
  260. "photo_name": "all",
  261. "signature": "fc4004dc82f44f765aa7a0150e3aad8a",
  262. "channel_type": 0,
  263. "imageList": [
  264. "8cc3de1612ced3a6dbdf8e9e054c6ec1",
  265. "7a2e7c070c25e6d06460e9fe62f139c7",
  266. "43dcb78211d4d6d8bdb5a398a57d9d1d",
  267. "14118f0ecd4a86e35165e6130ba69c6b",
  268. "eec697ea33e3ddaaf0e77e65749a6f23",
  269. "da6e9648da85204c717e8beb87b19328",
  270. "0839fffc60203f1ba13bc89c26d437c4",
  271. "feabdeaab2e264e521be06c5fc4c0457"
  272. ]
  273. },
  274. {
  275. "material_type": 1,
  276. "charge": 70956.941,
  277. "video_url": "http://txmov2.a.yximgs.com/upic/2021/02/03/18/BMjAyMTAyMDMxODIwMzdfMjI0NTY2OTI5MF80MzUxMDIxMDg2OF8wXzM=_b_Bfea5219f9c40bdf34f8420429c59434c.mp4?tag=1-1613958443-unknown-0-rk05fpbcb3-7dbb4cb30a941643&clientCacheKey=3x3xi88nniq6m6i_b.mp4&tt=b&di=8bba1b60&bp=13890",
  278. "photo_id": "5219390536383350388",
  279. "photo_name": "all",
  280. "signature": "0ec9b0bac40463d18f151be605682dc8",
  281. "channel_type": 0,
  282. "imageList": [
  283. "9b71f206b6ca9d2f89712b79ebd0d699",
  284. "c802325b325cf67c5c7c13872572642d",
  285. "e79ca1b5dde8709e794b53582e40dbdd",
  286. "37b529460cbebcba259a412dce40bd9c",
  287. "b7b37d27e33d21923c7ade475e7d0ffb",
  288. "b4ebac5da9e624aae208f2d8d9ab6b0e",
  289. "0675ef5a12e9ed01954e40309ff226c1",
  290. "04ed3651b233aad5a1f7e76b1ead48e4",
  291. "6a954e0ecfce38ad854c715c4e0d3a26",
  292. "516a957c2c80a4a74a24d1073412647f",
  293. "95f1a42d06657c4b8b8554b81583db5f",
  294. "30ba9f8a90539f3afe43f3046c54f488",
  295. "e48236f0509398412efac2f9ee258c6d",
  296. "a9f21f3731b653784fcf2dca6d4ca427",
  297. "014383e5b7c33cb9e0a515bf11e9a786"
  298. ]
  299. }
  300. ],
  301. "message": "SUCCESS"
  302. }
  303. """
  304. if not app_version:
  305. request_data = {"accountId": account_id, "num": cnt, "startTime": start_time, "endTime": end_time}
  306. else:
  307. request_data = {"accountId": account_id, "num": cnt, "startTime": start_time, "endTime": end_time,
  308. 'appVersion': app_version}
  309. try:
  310. logger.info("getHistoryTopVideoList the request_data is %s" % request_data)
  311. request = requests.post(url, headers=headers, data=json.JSONEncoder().encode(request_data)).text
  312. request_json = json.loads(request)
  313. if request_json["code"] != 0:
  314. logger.info("account_id=%s, app_version=%s, the res of getHistoryTopVideoList is %s" %
  315. (account_id, app_version, request_json['message']))
  316. except Exception:
  317. logger.error('account_id=%s, app_version=%s, the res of getHistoryTopVideoList is %s, the traceback is %s ' %
  318. (account_id, app_version, request, traceback.format_exc()))
  319. return {"code": -1}
  320. return request_json
  321. def get_campaign_and_group_name_rule(account_id):
  322. sql = """select campaign_name, group_name
  323. from ctop_ai_kuaishou_advertiser_strategy
  324. where account_id = %s
  325. order by create_time desc
  326. limit 1
  327. """ % account_id
  328. df = pd.read_sql(sql, engine)
  329. if df.empty:
  330. return None, None
  331. campaign_name = df['campaign_name'].values[0]
  332. group_name = df['group_name'].values[0]
  333. return campaign_name, group_name
  334. def get_request_data(account_id, campaign_id, video_info, campaign_name, group_name,
  335. ai_strategy_remark, name_replace='',
  336. unit_type=4, click_track_url=None, app_id=None, creative_name=None):
  337. res = {
  338. "video": video_info,
  339. "operation_type": 1,
  340. "account_id": account_id,
  341. "ai_strategy_remark": ai_strategy_remark,
  342. "campaign_info":
  343. {"campaign_id": campaign_id,
  344. "campaign_name": (campaign_name.replace('自定义', name_replace) + str(datetime.datetime.now()))
  345. if name_replace else campaign_name},
  346. 'group_info':
  347. {'group_name': (group_name.replace('自定义', name_replace) + str(datetime.datetime.now()))
  348. if name_replace else (group_name + str(datetime.datetime.now())),
  349. 'begin_time': str(datetime.date.today()),
  350. 'unit_type': unit_type,
  351. 'app_id': app_id},
  352. 'creative_info': {'is_sticky': 0,
  353. 'click_track_url': click_track_url,
  354. 'creative_name': creative_name}
  355. }
  356. return res