tornado_api.py 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669
  1. from wechat_action.sql_models import DB
  2. from settings import using_config
  3. import tornado.log
  4. import tornado.ioloop
  5. import tornado.web
  6. from logging import handlers
  7. from wechat_action.login_ad import LogIn
  8. from wechat_action import sql_tools
  9. import threading
  10. from web_module import user_action
  11. from sqlalchemy import Table
  12. import json
  13. import pickle
  14. from datetime import datetime
  15. # TODO:需要添加上supervisor,来维护进程
  16. # TODO:有时间需要对tornado进行改进
  17. # TODO:需要有一套上线工具,来维持线上稳定
  18. db = DB(config=using_config)
  19. wechat_cookies_table = Table('wechat_cookies', db.metadata,
  20. autoload=True, autoload_with=db.engine)
  21. layout_typesetting_table = Table('layout_typesetting', db.metadata,
  22. autoload=True, autoload_with=db.engine)
  23. ad_plan_typesetting_table = Table('ad_plan_typesetting', db.metadata,
  24. autoload=True, autoload_with=db.engine)
  25. action_record_table = Table('action_record', db.metadata,
  26. autoload=True, autoload_with=db.engine)
  27. layout_create_action = 'create_ad_layout'
  28. ad_plan_create_action = 'create_ad_plan'
  29. refresh_wechat_action = 'refresh_wechat_info'
  30. # 1.实现本机服务
  31. # 2.实现线上docker-selenium服务
  32. class BaseHandler(tornado.web.RequestHandler):
  33. def options(self):
  34. pass
  35. def set_default_headers(self):
  36. self.set_header('Access-Control-Allow-Origin', '*')
  37. self.set_header('Access-Control-Allow-Headers', '*')
  38. self.set_header('Access-Control-Max-Age', 1000)
  39. self.set_header('Content-type', '*')
  40. self.set_header('Access-Control-Allow-Methods', '*')
  41. class create_ad_plan_local(BaseHandler):
  42. def post(self):
  43. request_dict = json.loads(self.request.body, encoding='utf-8')
  44. user_id = request_dict['user_id']
  45. ad_plan_list = request_dict['plan_list']
  46. sql_session = db.DBSession()
  47. if user_id is None or ad_plan_list is None:
  48. self.write({'status': {'msg': 'url parameter error', "RetCode": 400}})
  49. return
  50. # 落地页名字精确到毫秒,默认是全局唯一
  51. for _ in ad_plan_list:
  52. ad_plan_name = _['title']
  53. ad_plan_typesetting_info = {'user_id': user_id, 'name': ad_plan_name,
  54. 'typesetting': json.dumps(_, ensure_ascii=False)}
  55. ad_plan_typesetting_inserte = sql_tools.save_ad_plan_typesetting_info(
  56. ad_plan_typesetting_info=ad_plan_typesetting_info,
  57. table_ad_plan_typesetting=ad_plan_typesetting_table)
  58. sql_session.execute(ad_plan_typesetting_inserte)
  59. sql_session.commit()
  60. self.write({'status': {'msg': 'success', "RetCode": 200}})
  61. class create_ad_plan(BaseHandler):
  62. # TODO:只要tornado开着就不允许修改数据库,------想好之后上线如何操作
  63. @staticmethod
  64. def check_task(user_id):
  65. sql_session = db.DBSession()
  66. result = sql_tools.get_task_in_hand_num(user_id, sql_session)
  67. return result
  68. def save_task_info(self, user_id, ad_plan_list, sql_session, task_name):
  69. # 2.数据存入数据库
  70. if user_id is None or ad_plan_list is None:
  71. self.write({'status': {'msg': 'url parameter error', "RetCode": 400}})
  72. return
  73. # 2.1存计划数据
  74. for _ in ad_plan_list:
  75. ad_plan_name = _['title']
  76. ad_plan_typesetting_info = {'user_id': user_id, 'name': ad_plan_name,
  77. 'typesetting': json.dumps(_, ensure_ascii=False)}
  78. ad_plan_typesetting_inserte = sql_tools.save_ad_plan_typesetting_info(
  79. ad_plan_typesetting_info=ad_plan_typesetting_info,
  80. table_ad_plan_typesetting=ad_plan_typesetting_table)
  81. sql_session.execute(ad_plan_typesetting_inserte)
  82. sql_session.commit()
  83. for _ in ad_plan_list:
  84. for action_type in [layout_create_action, ad_plan_create_action]:
  85. object_name = _['title'] if action_type == ad_plan_create_action else \
  86. _['idea']['jump_type_page_type'][
  87. 'layout_name']
  88. action_info = {'user_id': user_id, 'service_name': _['service_name'],
  89. 'wechat_name': _['wechat_name'],
  90. 'action_type': action_type, 'object_name': object_name, 'task_name': task_name,
  91. 'status': 'todo'}
  92. record_insert = sql_tools.save_action_record(action_record_info=action_info,
  93. table_action_record=action_record_table)
  94. sql_session.execute(record_insert)
  95. sql_session.commit()
  96. def post(self):
  97. sql_session = db.DBSession()
  98. log_ad = None
  99. try:
  100. request_dict = json.loads(self.request.body, encoding='utf-8')
  101. ad_plan_list = request_dict['planList']
  102. user_id = request_dict['userId']
  103. # 2.2存行为记录
  104. task_name = 'user_id: {user_id} time:{time_sign} action:create_plan'.format(user_id=user_id,
  105. time_sign=datetime.now().strftime(
  106. "%Y-%m-%d, %H:%M:%S"))
  107. # 4.开始运行
  108. if not self.check_task(user_id=user_id):
  109. # 1.查看是否cookie可用
  110. log_ad, cookie_canuse = ad_human_info.refresh_wechat_cookies(self, user_id=user_id)
  111. self.save_task_info(user_id, ad_plan_list, sql_session, task_name)
  112. threading.Thread(target=user_action.carry_plan,
  113. args=(user_id, ad_plan_list, log_ad, db, cookie_canuse, task_name)).start()
  114. else:
  115. self.save_task_info(user_id, ad_plan_list, sql_session, task_name)
  116. self.write({'status': {'msg': 'success', "RetCode": 200}})
  117. except Exception as e:
  118. if log_ad:
  119. log_ad.driver.quit()
  120. logging.error(str(e))
  121. # TODO:这部分需要处理,,之后换成flask
  122. self.write('error')
  123. finally:
  124. sql_session.commit()
  125. class get_ad_plan_local(BaseHandler):
  126. def get(self):
  127. user_id = self.get_argument('user_id', None)
  128. layout_name = self.get_argument('plan_name', None)
  129. sql_session = db.DBSession()
  130. if user_id is None:
  131. self.write({'status': {'msg': 'url parameter error', "RetCode": 400}})
  132. return
  133. # 落地页名字精确到毫秒,默认是全局唯一
  134. if layout_name:
  135. result = sql_tools.get_plan_typesetting_rough(sql_session=sql_session, user_id=user_id,
  136. typesetting_name=layout_name)
  137. else:
  138. # TODO:之后修改一下,让其查询效率高点,like效率过低
  139. layout_name = ''
  140. result = sql_tools.get_plan_typesetting_rough(sql_session=sql_session, user_id=user_id,
  141. typesetting_name=layout_name)
  142. result_ = []
  143. for i in range(len(result)):
  144. typesetting, name, create_time, update_time = result[i]
  145. _ = {}
  146. _['typesetting'] = json.loads(typesetting)
  147. _['ad_plan_name'] = name
  148. _['id'] = i
  149. _['create_time'] = create_time.strftime("%Y-%m-%d %H:%M:%S")
  150. _['update_time'] = update_time.strftime("%Y-%m-%d %H:%M:%S")
  151. result_.append(_)
  152. self.write({'status': {'msg': 'success', "RetCode": 200},
  153. 'local_ad_plan_info': result_})
  154. class create_ad_layout_local(BaseHandler):
  155. def post(self):
  156. # TODO:返回一个layout_name重复的一个信息
  157. request_dict = json.loads(self.request.body)
  158. user_id = request_dict['user_id']
  159. layout_typesetting = request_dict['layout_typesetting']
  160. layout_name = request_dict['layout_name']
  161. sql_session = db.DBSession()
  162. if user_id is None or layout_name is None or layout_typesetting is None:
  163. self.write({'status': {'msg': 'url parameter error', "RetCode": 400}})
  164. return
  165. # 落地页名字精确到毫秒,默认是全局唯一
  166. layout_typesetting_info = {'user_id': user_id, 'name': layout_name,
  167. 'typesetting': layout_typesetting}
  168. layout_typesetting_inserte = sql_tools.save_layout_typesetting_info(
  169. layout_typesetting_info=layout_typesetting_info,
  170. table_layout_typesetting=layout_typesetting_table)
  171. sql_session.execute(layout_typesetting_inserte)
  172. sql_session.commit()
  173. self.write({'status': {'msg': 'success', "RetCode": 200}})
  174. class get_ad_layout_local(BaseHandler):
  175. def get(self):
  176. user_id = self.get_argument('user_id', None)
  177. layout_name = self.get_argument('layout_name', None)
  178. sql_session = db.DBSession()
  179. if user_id is None:
  180. self.write({'status': {'msg': 'url parameter error', "RetCode": 400}})
  181. return
  182. # 落地页名字精确到毫秒,默认是全局唯一
  183. if layout_name:
  184. result = sql_tools.get_layout_typesetting_rough(sql_session=sql_session, user_id=user_id,
  185. typesetting_name=layout_name)
  186. else:
  187. # TODO:之后修改一下,让其查询效率高点,like效率过低
  188. layout_name = ''
  189. result = sql_tools.get_layout_typesetting_rough(sql_session=sql_session, user_id=user_id,
  190. typesetting_name=layout_name)
  191. result_ = []
  192. for i in range(len(result)):
  193. typesetting, name, create_time, update_time = result[i]
  194. _ = {}
  195. _['typesetting'] = json.loads(typesetting)
  196. _['layout_name'] = name
  197. _['id'] = i
  198. _['create_time'] = create_time.strftime("%Y-%m-%d %H:%M:%S")
  199. _['update_time'] = update_time.strftime("%Y-%m-%d %H:%M:%S")
  200. result_.append(_)
  201. self.write({'status': {'msg': 'success', "RetCode": 200},
  202. 'local_layout_info': result_})
  203. class get_scan_status(BaseHandler):
  204. # 获取到扫码状态
  205. def get(self):
  206. sql_session = db.DBSession()
  207. user_id = self.get_argument("user_id", None)
  208. status = sql_tools.get_scan_action_status(user_id, sql_session)
  209. if user_id is None:
  210. self.write({'status': {'msg': 'url parameter error', "RetCode": 400}})
  211. return
  212. self.write({'status': {'msg': 'success', "RetCode": 200},
  213. 'scan_action_status': status})
  214. # TODO:wechat_info,human_info 这两张表有空时需要进行对应改进
  215. class ad_human_info(BaseHandler):
  216. @staticmethod
  217. def refresh_wechat_cookies(tornado_web, user_id):
  218. # 1.返回二维码链接
  219. # ----1.查看cookie是否可用
  220. sql_session = db.DBSession()
  221. cookie_db = sql_tools.get_wechat_cookies(sql_session, user_id=user_id)
  222. # 进行登录操作
  223. log_ad = LogIn(user_id=user_id)
  224. # 使driver可以使用
  225. cookie_canuse = False
  226. if cookie_db:
  227. cookie_db = pickle.loads(cookie_db)
  228. if not log_ad.wechat_cookies_check_alive(cookie_db):
  229. # cookie 不能使用
  230. wechat_code = log_ad.log_in()
  231. sql_tools.update_user_scan_action(user_id, sql_session)
  232. tornado_web.write({'status': {'msg': 'success', "RetCode": 200},
  233. 'wechat_code': wechat_code})
  234. logging.info('cookie can not use')
  235. else:
  236. # cookie 可以继续使用
  237. cookie_canuse = True
  238. log_ad.driver.get('https://a.weixin.qq.com/index.html')
  239. tornado_web.write({'status': {'msg': 'success', "RetCode": 200}})
  240. else:
  241. # cookie 不能使用
  242. wechat_code = log_ad.log_in()
  243. sql_tools.update_user_scan_action(user_id, sql_session)
  244. tornado_web.write({'status': {'msg': 'success', "RetCode": 200},
  245. 'wechat_code': wechat_code})
  246. return log_ad, cookie_canuse
  247. # 1.人群包获取
  248. def get(self):
  249. sql_session = db.DBSession()
  250. log_ad = None
  251. try:
  252. # 0.是否刷新
  253. # 1.获取userid,以及是否刷新
  254. user_id = self.get_argument("user_id", None)
  255. human_package_name = self.get_argument('human_package_name', None)
  256. is_refresh = self.get_argument("is_refresh", None)
  257. wechat_name = self.get_argument('wechat_name', None)
  258. service_name = self.get_argument('service_name', None)
  259. if user_id is None or is_refresh is None or wechat_name is None or service_name is None:
  260. self.write({'status': {'msg': 'url parameter error', "RetCode": 400}})
  261. return
  262. # TODO:一个涉及到selenium-driver的请求-生命周期.----看一下tornado是怎么处理请求的生命周期
  263. if int(is_refresh) == 1:
  264. log_ad, cookie_canuse = self.refresh_wechat_cookies(self, user_id=user_id)
  265. if not create_ad_plan.check_task(user_id=user_id):
  266. task_name = 'user_id: {user_id} time:{time_sign} action:refresh_wechat_info'.format(
  267. user_id=user_id,
  268. time_sign=datetime.now().strftime(
  269. "%Y-%m-%d, %H:%M:%S"))
  270. # 行为记录
  271. action_type = refresh_wechat_action
  272. object_name = ''
  273. service_name = ''
  274. wechat_name = ''
  275. action_info = {'user_id': user_id, 'service_name': service_name, 'wechat_name': wechat_name,
  276. 'action_type': action_type, 'object_name': object_name, 'task_name': task_name,
  277. 'status': 'todo'}
  278. record_insert = sql_tools.save_action_record(action_record_info=action_info,
  279. table_action_record=action_record_table)
  280. sql_session.execute(record_insert)
  281. sql_session.commit()
  282. threading.Thread(target=user_action.get_human_info,
  283. args=(
  284. user_id, log_ad, db, cookie_canuse, task_name)).start()
  285. else:
  286. logging.info('任务有堆积')
  287. return
  288. self.write({'status': {'msg': '任务有堆积', "RetCode": 200}})
  289. else:
  290. # 1.查看是否在刷新,
  291. # 在刷新中,
  292. # 返回正在刷新
  293. # -------不管上面逻辑让他们多刷新几次
  294. # 不在刷新
  295. # 返回对应数据
  296. # 2.获取userid对应数据
  297. result = sql_tools.get_human_info(sql_session=sql_session,
  298. service_name=service_name, wechat_name=wechat_name)
  299. result = json.loads(result)
  300. if human_package_name:
  301. result = [_ for _ in result if human_package_name in _['name']]
  302. result_ = []
  303. for i in range(len(result)):
  304. _ = result[i]
  305. _['id'] = i
  306. result_.append(_)
  307. self.write({'status': {'msg': 'success', "RetCode": 200},
  308. 'human_info': result})
  309. except Exception as e:
  310. if log_ad:
  311. log_ad.driver.quit()
  312. logging.error(str(e))
  313. finally:
  314. sql_session.commit()
  315. class refresh_wechat_info(BaseHandler):
  316. # TODO:刷新以及创建,限时3分钟
  317. @staticmethod
  318. def refresh_wechat_cookies(tornado_web, user_id):
  319. # 1.返回二维码链接
  320. # ----1.查看cookie是否可用
  321. sql_session = db.DBSession()
  322. cookie_db = sql_tools.get_wechat_cookies(sql_session, user_id=user_id)
  323. # 进行登录操作
  324. log_ad = LogIn(user_id=user_id)
  325. # 使driver可以使用
  326. cookie_canuse = False
  327. if cookie_db:
  328. cookie_db = pickle.loads(cookie_db)
  329. if not log_ad.wechat_cookies_check_alive(cookie_db):
  330. # cookie 不能使用
  331. wechat_code = log_ad.log_in()
  332. sql_tools.update_user_scan_action(user_id, sql_session)
  333. tornado_web.write({'status': {'msg': 'success', "RetCode": 200},
  334. 'wechat_code': wechat_code})
  335. logging.info('cookie can not use')
  336. else:
  337. # cookie 可以继续使用
  338. cookie_canuse = True
  339. log_ad.driver.get('https://a.weixin.qq.com/index.html')
  340. tornado_web.write({'status': {'msg': 'success', "RetCode": 200}})
  341. else:
  342. # cookie 不能使用
  343. wechat_code = log_ad.log_in()
  344. sql_tools.update_user_scan_action(user_id, sql_session)
  345. tornado_web.write({'status': {'msg': 'success', "RetCode": 200},
  346. 'wechat_code': wechat_code})
  347. return log_ad, cookie_canuse
  348. def get(self):
  349. sql_session = db.DBSession()
  350. log_ad = None
  351. try:
  352. user_id = self.get_argument("user_id", None)
  353. log_ad, cookie_canuse = self.refresh_wechat_cookies(self, user_id=user_id)
  354. task_name = 'user_id: {user_id} time:{time_sign} action:refresh_wechat_info'.format(
  355. user_id=user_id,
  356. time_sign=datetime.now().strftime(
  357. "%Y-%m-%d, %H:%M:%S"))
  358. # 行为记录
  359. action_type = refresh_wechat_action
  360. object_name = ''
  361. service_name = ''
  362. wechat_name = ''
  363. action_info = {'user_id': user_id, 'service_name': service_name, 'wechat_name': wechat_name,
  364. 'action_type': action_type, 'object_name': object_name, 'task_name': task_name,
  365. 'status': 'todo'}
  366. record_insert = sql_tools.save_action_record(action_record_info=action_info,
  367. table_action_record=action_record_table)
  368. sql_session.execute(record_insert)
  369. sql_session.commit()
  370. if not create_ad_plan.check_task(user_id=user_id):
  371. threading.Thread(target=user_action.get_human_info,
  372. args=(
  373. user_id, log_ad, db, cookie_canuse, task_name)).start()
  374. else:
  375. return
  376. self.write({'status': {'msg': '任务有堆积', "RetCode": 200}})
  377. except:
  378. pass
  379. class ad_wechat_info(BaseHandler):
  380. # 1.公众号相关信息获取
  381. def get(self):
  382. sql_session = db.DBSession()
  383. log_ad = None
  384. try:
  385. # 0.是否刷新
  386. # 1.获取userid,以及是否刷新
  387. user_id = self.get_argument("userId", None)
  388. is_refresh = self.get_argument("isRefresh", None)
  389. if user_id is None or is_refresh is None:
  390. self.write({'status': {'msg': 'url parameter error', "RetCode": 400}})
  391. return
  392. if int(is_refresh) == 1:
  393. # 检查有无其他任务在处理中,有则等待
  394. log_ad, cookie_canuse = ad_human_info.refresh_wechat_cookies(self, user_id=user_id)
  395. if not create_ad_plan.check_task(user_id=user_id):
  396. task_name = 'user_id: {user_id} time:{time_sign} action:refresh_wechat_info'.format(
  397. user_id=user_id,
  398. time_sign=datetime.now().strftime(
  399. "%Y-%m-%d, %H:%M:%S"))
  400. # 行为记录
  401. action_type = refresh_wechat_action
  402. object_name = ''
  403. service_name = ''
  404. wechat_name = ''
  405. action_info = {'user_id': user_id, 'service_name': service_name, 'wechat_name': wechat_name,
  406. 'action_type': action_type, 'object_name': object_name, 'task_name': task_name,
  407. 'status': 'todo'}
  408. record_insert = sql_tools.save_action_record(action_record_info=action_info,
  409. table_action_record=action_record_table)
  410. sql_session.execute(record_insert)
  411. sql_session.commit()
  412. threading.Thread(target=user_action.get_human_info,
  413. args=(
  414. user_id, log_ad, db, cookie_canuse, task_name)).start()
  415. else:
  416. return
  417. self.write({'status': {'msg': '任务有堆积', "RetCode": 200}})
  418. else:
  419. result = sql_tools.get_wechat_info(sql_session=sql_session, user_id=user_id)
  420. result_list = []
  421. for _ in result:
  422. service_name, wechat_name = _
  423. result_list.append({'service_name': service_name, 'wechat_name': wechat_name})
  424. self.write({'status': {'msg': 'success', "RetCode": 200},
  425. 'wechat_info': result_list})
  426. except Exception as e:
  427. if log_ad:
  428. log_ad.driver.quit()
  429. logging.error(str(e))
  430. finally:
  431. sql_session.commit()
  432. class delete_ad_layout(BaseHandler):
  433. def get(self):
  434. user_id = self.get_argument('user_id', None)
  435. layout_name = self.get_argument('layout_name', None)
  436. sql_session = db.DBSession()
  437. if user_id is None or layout_name is None:
  438. self.write({'status': {'msg': 'url parameter error', "RetCode": 400}})
  439. return
  440. # 落地页名字精确到毫秒,默认是全局唯一
  441. sql_tools.delete_layout_typesetting_vir(sql_session=sql_session, user_id=user_id,
  442. typesetting_name=layout_name)
  443. self.write({'status': {'msg': 'success', "RetCode": 200}})
  444. class delete_ad_plan(BaseHandler):
  445. def get(self):
  446. user_id = self.get_argument('user_id', None)
  447. plan_name = self.get_argument('plan_name', None)
  448. service_name = self.get_argument('service_name', None)
  449. wechat_name = self.get_argument('wechat_name', None)
  450. sql_session = db.DBSession()
  451. if user_id is None or plan_name is None:
  452. self.write({'status': {'msg': 'url parameter error', "RetCode": 400}})
  453. return
  454. # 落地页名字精确到毫秒,默认是全局唯一
  455. sql_tools.delete_ad_plan_typesetting_vir(sql_session=sql_session, user_id=user_id,
  456. typesetting_name=plan_name, wechat_name=wechat_name,
  457. service_name=service_name)
  458. self.write({'status': {'msg': 'success', "RetCode": 200}})
  459. class get_ad_wechat_service_name(BaseHandler):
  460. def get(self):
  461. user_id = self.get_argument('user_id', None)
  462. sql_session = db.DBSession()
  463. if user_id is None:
  464. self.write({'status': {'msg': 'url parameter error', "RetCode": 400}})
  465. return
  466. result = sql_tools.get_wechat_info_service_name(sql_session=sql_session, user_id=user_id)
  467. result_list = []
  468. for _ in result:
  469. service_name = _
  470. result_list.append({'service_name': service_name})
  471. self.write({'status': {'msg': 'success', "RetCode": 200},
  472. 'wechat_info': result_list})
  473. class get_ad_wechat_wechat_name(BaseHandler):
  474. def get(self):
  475. user_id = self.get_argument('user_id', None)
  476. service_name = self.get_argument('service_name', None)
  477. sql_session = db.DBSession()
  478. if user_id is None or service_name is None:
  479. self.write({'status': {'msg': 'url parameter error', "RetCode": 400}})
  480. return
  481. result = sql_tools.get_wechat_info_wechat_name(sql_session=sql_session, user_id=user_id,
  482. service_name=service_name)
  483. result_list = []
  484. for _ in result:
  485. service_name, wechat_name = _
  486. result_list.append({'service_name': service_name, 'wechat_name': wechat_name})
  487. self.write({'status': {'msg': 'success', "RetCode": 200},
  488. 'wechat_info': result_list})
  489. class get_plan_action_record(BaseHandler):
  490. def get(self):
  491. user_id = self.get_argument('user_id', None)
  492. service_name = self.get_argument('service_name', None)
  493. wechat_name = self.get_argument('wechat_name', None)
  494. status = self.get_argument('status', None)
  495. plan_name = self.get_argument('plan_name', None)
  496. sql_session = db.DBSession()
  497. if user_id is None:
  498. self.write({'status': {'msg': 'url parameter error', "RetCode": 400}})
  499. return
  500. # 落地页名字精确到毫秒,默认是全局唯一
  501. result = sql_tools.get_plan_record(sql_session=sql_session, user_id=user_id,
  502. service_name=service_name, wechat_name=wechat_name,
  503. status=status, plan_name=plan_name)
  504. result_ = []
  505. for i in range(len(result)):
  506. user_id, name, service_name, wechat_name, create_time, status, typesetting, wechat_id_info = result[i]
  507. _ = {}
  508. _['typesetting'] = json.loads(typesetting)
  509. _['ad_plan_name'] = name
  510. _['id'] = i
  511. _['create_time'] = create_time.strftime("%Y-%m-%d %H:%M:%S")
  512. _['service_name'] = service_name
  513. _['wechat_name'] = wechat_name
  514. _['wechat_id_info'] = wechat_id_info
  515. _['status'] = status
  516. result_.append(_)
  517. self.write({'status': {'msg': 'success', "RetCode": 200},
  518. 'local_ad_plan_info': result_})
  519. class get_all_ad_task(BaseHandler):
  520. def get(self):
  521. user_id = self.get_argument('user_id', None)
  522. sql_session = db.DBSession()
  523. if user_id is None:
  524. self.write({'status': {'msg': 'url parameter error', "RetCode": 400}})
  525. return
  526. # 落地页名字精确到毫秒,默认是全局唯一
  527. result = sql_tools.get_ad_task(sql_session=sql_session, user_id=user_id)
  528. task_dict = {}
  529. localtion = ['wechat', '']
  530. for _ in result:
  531. task_name, status, task_status_num, create_time, typesetting = _
  532. typesetting = json.loads(typesetting)
  533. if typesetting['plan_base'][1] == 'pyq':
  534. localtion[1] = 'pyq'
  535. create_time = create_time.strftime("%Y-%m-%d %H:%M:%S")
  536. if task_name not in task_dict.keys():
  537. task_dict[task_name] = {}
  538. task_dict[task_name][status] = (task_status_num, create_time)
  539. result_ = []
  540. num = 0
  541. for k, v in task_dict.items():
  542. # TODO:修改为dict的sort
  543. sum_num = 0
  544. new_dict = {}
  545. create_time = None
  546. for k_, v_ in v.items():
  547. task_status_num, create_time = v_
  548. sum_num = sum_num + task_status_num
  549. new_dict[k_] = task_status_num
  550. status = 'todo' if 'todo' in new_dict.keys() else 'done'
  551. task_dict[k]['sum_num'] = sum_num
  552. new_dict['sum_num'] = sum_num
  553. result_.append(
  554. {'task_name': k, 'task_info': new_dict, 'create_time': create_time, 'channel': localtion[0],
  555. 'localtion': localtion[1], 'id': num, 'status': status})
  556. num = num + 1
  557. self.write({'status': {'msg': 'success', "RetCode": 200},
  558. 'local_ad_plan_info': result_})
  559. def heart_jump():
  560. # TODO:tornado 心跳检测,下周做----线程不断检查,线程生命周期60分钟
  561. pass
  562. def make_app():
  563. return tornado.web.Application([
  564. ("/get_all_ad_task", get_all_ad_task), # 获取所有任务状态,
  565. ("/create_ad_plan", create_ad_plan), #
  566. ("/get_ad_wechat_service_name", get_ad_wechat_service_name),
  567. ("/get_ad_wechat_wechat_name", get_ad_wechat_wechat_name),
  568. # ("/create_ad_plan_local", create_ad_plan_local),
  569. ("/create_ad_layout_local", create_ad_layout_local),
  570. ("/get_layout_local", get_ad_layout_local),
  571. ("/get_ad_plan_local", get_ad_plan_local),
  572. ("/delete_layout_local", delete_ad_layout),
  573. ("/delete_ad_plan_local", delete_ad_plan),
  574. ("/get_scan_status", get_scan_status),
  575. # ("/create_ad_layout_remote", create_ad_layout_remote),
  576. ("/ad_human_info", ad_human_info),
  577. ("/ad_wechat_info", ad_wechat_info),
  578. ("/get_plan_action_record", get_plan_action_record),
  579. ], debug=True, autoreload=True)
  580. if __name__ == "__main__":
  581. import logging
  582. logging.basicConfig(
  583. handlers=[
  584. logging.handlers.RotatingFileHandler('./tornado.log',
  585. maxBytes=10 * 1024 * 1024,
  586. backupCount=5,
  587. encoding='utf-8')
  588. , logging.StreamHandler() # 供输出使用
  589. ],
  590. level=logging.INFO,
  591. format="%(asctime)s - %(levelname)s %(filename)s %(funcName)s %(lineno)s - %(message)s"
  592. )
  593. handler = logging.FileHandler('tornado.log')
  594. logger = logging.getLogger()
  595. logger.addHandler(handler)
  596. logger.setLevel(logging.INFO)
  597. app = make_app()
  598. app.listen(8888)
  599. tornado.ioloop.IOLoop.current().start()