DeviceDataController.py 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. # -*- encoding: utf-8 -*-
  2. """
  3. @File : UserDataController.py
  4. @Time : 2022/8/16 10:44
  5. @Author : peng
  6. @Email : zhangdongming@asj6.wecom.work
  7. @Software: PyCharm
  8. """
  9. import datetime
  10. import requests
  11. from django.db.models import Count, Q, Sum
  12. from django.views.generic.base import View
  13. from Model.models import Device_Info, CountryModel, UidSetModel, DeviceTypeModel, VideoPlaybackTimeModel, \
  14. DeviceInfoSummary
  15. from Service.CommonService import CommonService
  16. # 设备数据
  17. class DeviceDataView(View):
  18. def get(self, request, *args, **kwargs):
  19. request.encoding = 'utf-8'
  20. operation = kwargs.get('operation')
  21. return self.validation(request.GET, request, operation)
  22. def post(self, request, *args, **kwargs):
  23. request.encoding = 'utf-8'
  24. operation = kwargs.get('operation')
  25. return self.validation(request.POST, request, operation)
  26. def validation(self, request_dict, request, operation):
  27. token_code, user_id, response = CommonService.verify_token_get_user_id(request_dict, request)
  28. if token_code != 0:
  29. return response.json(token_code)
  30. if operation == 'type': # 统计设备类型
  31. return self.type_statistics(response)
  32. if operation == 'regional': # 设备地区分布
  33. return self.regional_statistics(response)
  34. if operation == 'addDevice': # 查询设备增长数据(数据有些许差异)
  35. return self.add_device(request_dict, response)
  36. if operation == 'active': # 设备活跃数据
  37. return self.device_active(request_dict, response)
  38. if operation == 'global/regional': # 全球设备分布
  39. return self.global_regional(request, request_dict, response)
  40. if operation == 'global/type': # 全球设备类型
  41. return self.golbal_type(request, request_dict, response)
  42. if operation == 'global/active': # 全球设备活跃分布
  43. return self.golbal_active(request, request_dict, response)
  44. if operation == 'global/addDevice': # 全球新增设备数据
  45. return self.golbal_add_device(request, request_dict, response)
  46. if operation == 'ip/country': #
  47. return self.ip_country(response)
  48. else:
  49. return response.json(414)
  50. @staticmethod
  51. def ip_country(response):
  52. uid_set_qs = UidSetModel.objects.filter(~Q(ip='') & Q(tb_country=0)).values('ip')
  53. for uid_set in uid_set_qs:
  54. ip = uid_set['ip']
  55. ipInfo = CommonService.getIpIpInfo(ip, 'CN')
  56. country_qs = CountryModel.objects.filter(country_code=ipInfo['country_code']).values('id')
  57. if country_qs.exists():
  58. country = country_qs[0]['id']
  59. uid_set_qs.filter(ip=ip).update(tb_country=country)
  60. return response.json(0)
  61. @classmethod
  62. def golbal_add_device(cls, request, request_dict, response):
  63. """
  64. 全球新增设备数据
  65. @param request:请求
  66. @param request_dict:请求参数
  67. @param response: 响应对象
  68. """
  69. url_list = CommonService.get_domain_name()
  70. try:
  71. headers = {
  72. 'Authorization': request.META.get('HTTP_AUTHORIZATION')
  73. }
  74. device_list = []
  75. device_count = 0
  76. type_list = []
  77. type_count = 0
  78. region_list = []
  79. region_count = 0
  80. order_list = []
  81. order_count = 0
  82. for url in url_list:
  83. url = url + request.path.replace('global/', '')
  84. res = requests.get(url=url, params=request_dict, headers=headers)
  85. result = res.json()
  86. if result['result_code'] == 0:
  87. for item in result['result']['addDevice']:
  88. flag = 0
  89. for each in device_list:
  90. if item['startTime'] == each['startTime'] and item['endTime'] == each['endTime']:
  91. each['count'] += item['count']
  92. device_count += item['count']
  93. flag = 1
  94. break
  95. if flag == 0:
  96. device_list.append(item)
  97. device_count += item['count']
  98. for item in device_list:
  99. if device_count != 0:
  100. item['rate'] = round(item['count'] / device_count * 100, 2)
  101. else:
  102. break
  103. for item in result['result']['region']:
  104. flag = 0
  105. for each in region_list:
  106. if item['countryName'] == each['countryName']:
  107. each['count'] += item['count']
  108. region_count += item['count']
  109. flag = 1
  110. break
  111. if flag == 0:
  112. region_list.append(item)
  113. region_count += item['count']
  114. for item in region_list:
  115. if region_count != 0:
  116. item['rate'] = round(item['count'] / region_count * 100, 2)
  117. else:
  118. break
  119. for item in result['result']['type']:
  120. flag = 0
  121. for each in type_list:
  122. if item['type'] == each['type']:
  123. each['count'] += item['count']
  124. type_count += item['count']
  125. flag = 1
  126. break
  127. if flag == 0:
  128. type_list.append(item)
  129. type_count += item['count']
  130. for item in type_list:
  131. if type_count != 0:
  132. item['rate'] = round(item['count'] / type_count * 100, 2)
  133. else:
  134. break
  135. for item in result['result']['version']:
  136. flag = 0
  137. for each in order_list:
  138. if item['type'] == each['type']:
  139. each['count'] += item['count']
  140. order_count += item['count']
  141. flag = 1
  142. break
  143. if flag == 0:
  144. order_list.append(item)
  145. order_count += item['count']
  146. for item in order_list:
  147. if order_count != 0:
  148. item['rate'] = round(item['count'] / order_count * 100, 2)
  149. else:
  150. break
  151. else:
  152. return response.json(result['result_code'])
  153. res = {
  154. 'device': device_list,
  155. 'type': type_list,
  156. 'region': CommonService.list_sort(region_list),
  157. 'version': order_list
  158. }
  159. return response.json(0, res)
  160. except Exception as e:
  161. print(e)
  162. return response.json(500, repr(e))
  163. @classmethod
  164. def golbal_active(cls, request, request_dict, response):
  165. """
  166. 全球设备活跃分布
  167. @param request:请求
  168. @param request_dict:请求参数
  169. @param response: 响应对象
  170. """
  171. url_list = CommonService.get_domain_name()
  172. try:
  173. headers = {
  174. 'Authorization': request.META.get('HTTP_AUTHORIZATION')
  175. }
  176. type_list = []
  177. type_count = 0
  178. region_list = []
  179. region_count = 0
  180. for url in url_list:
  181. url = url + request.path.replace('global/', '')
  182. res = requests.get(url=url, params=request_dict, headers=headers)
  183. result = res.json()
  184. if result['result_code'] == 0:
  185. for item in result['result']['vodHls']:
  186. flag = 0
  187. for each in type_list:
  188. if item['startTime'] == each['startTime'] and item['endTime'] == each['endTime']:
  189. each['count'] += item['count']
  190. type_count += item['count']
  191. flag = 1
  192. break
  193. if flag == 0:
  194. type_list.append(item)
  195. type_count += item['count']
  196. for item in type_list:
  197. if type_count != 0:
  198. item['rate'] = round(item['count'] / type_count * 100, 2)
  199. else:
  200. break
  201. for item in result['result']['region']:
  202. flag = 0
  203. for each in region_list:
  204. if item['countryName'] == each['countryName']:
  205. each['count'] += item['count']
  206. region_count += item['count']
  207. flag = 1
  208. break
  209. if flag == 0:
  210. region_list.append(item)
  211. region_count += item['count']
  212. for item in region_list:
  213. if region_count != 0:
  214. item['rate'] = round(item['count'] / region_count * 100, 2)
  215. else:
  216. break
  217. else:
  218. return response.json(result['result_code'])
  219. res = {
  220. 'device': type_list,
  221. 'region': CommonService.list_sort(region_list)
  222. }
  223. return response.json(0, res)
  224. except Exception as e:
  225. print(e)
  226. return response.json(500, repr(e))
  227. @classmethod
  228. def golbal_type(cls, request, request_dict, response):
  229. """
  230. 全球设备类型分布
  231. @param request:请求
  232. @param request_dict:请求参数
  233. @param response: 响应对象
  234. """
  235. url_list = CommonService.get_domain_name()
  236. try:
  237. headers = {
  238. 'Authorization': request.META.get('HTTP_AUTHORIZATION')
  239. }
  240. type_list = []
  241. type_count = 0
  242. for url in url_list:
  243. url = url + request.path.replace('global/', '')
  244. res = requests.get(url=url, params=request_dict, headers=headers)
  245. result = res.json()
  246. if result['result_code'] == 0:
  247. for item in result['result']['type']:
  248. flag = 0
  249. for each in type_list:
  250. if item['type'] == each['type']:
  251. each['count'] += item['count']
  252. type_count += item['count']
  253. flag = 1
  254. break
  255. if flag == 0:
  256. type_list.append(item)
  257. type_count += item['count']
  258. for item in type_list:
  259. item['rate'] = round(item['count'] / type_count * 100, 2)
  260. else:
  261. return response.json(result['result_code'])
  262. res = {
  263. 'type': CommonService.list_sort(type_list)
  264. }
  265. return response.json(0, res)
  266. except Exception as e:
  267. print(e)
  268. return response.json(500)
  269. @classmethod
  270. def global_regional(cls, request, request_dict, response):
  271. """
  272. 全球设备分布
  273. @param request:请求
  274. @param request_dict:请求参数
  275. @param response:响应对象
  276. @return:
  277. """
  278. url_list = CommonService.get_domain_name()
  279. try:
  280. headers = {
  281. 'Authorization': request.META.get('HTTP_AUTHORIZATION')
  282. }
  283. device_list = []
  284. device_count = 0
  285. region_list = []
  286. region_count = 0
  287. for url in url_list:
  288. url = url + request.path.replace('global/', '')
  289. res = requests.get(url=url, params=request_dict, headers=headers)
  290. result = res.json()
  291. if result['result_code'] == 0:
  292. # 处理地区
  293. for item in result['result']['countries']:
  294. flag = 0
  295. for each in device_list:
  296. if each['countryName'] == item['countryName']:
  297. each['count'] += int(item['count'])
  298. device_count += int(item['count'])
  299. flag = 1
  300. break
  301. if flag == 0:
  302. device_list.append(item)
  303. device_count += int(item['count'])
  304. for item in device_list:
  305. rate = round(item['count'] / device_count * 100, 2)
  306. item['rate'] = rate
  307. for item in result['result']['continent']:
  308. flag = 0
  309. for each in region_list:
  310. if each['continentName'] == item['continentName']:
  311. each['count'] += item['count']
  312. region_count += item['count']
  313. flag = 1
  314. break
  315. if flag == 0:
  316. region_list.append(item)
  317. region_count += item['count']
  318. for item in region_list:
  319. item['rate'] = round(item['count'] / region_count * 100, 2)
  320. else:
  321. return response.json(result['result_code'])
  322. res = {
  323. 'countries': CommonService.list_sort(device_list[:20]),
  324. 'continent': region_list
  325. }
  326. return response.json(0, res)
  327. except Exception as e:
  328. return response.json(500, repr(e))
  329. @classmethod
  330. def device_active(cls, request_dict, response):
  331. """
  332. 设备活跃数据
  333. @param request_dict:请求参数
  334. @request_dict starTime:开始时间
  335. @request_dict endTime:结束时间
  336. @param response:响应对象
  337. """
  338. start_time = request_dict.get('startTime', None) # 时间戳
  339. end_time = request_dict.get('endTime', None)
  340. unit_time = request_dict.get('timeUnit', None)
  341. if not all([start_time, end_time, unit_time]):
  342. return response.json(444, {'error param': 'startTime or endTime or timeUnit'})
  343. s_time = datetime.datetime.fromtimestamp(int(start_time))
  344. e_time = datetime.datetime.fromtimestamp(int(end_time))
  345. time_list = CommonService.cutting_time(s_time, e_time, unit_time)
  346. try:
  347. device_info_summary_qs = DeviceInfoSummary.objects.filter(
  348. time__range=(start_time, end_time), query_type=1).values('country', 'count')
  349. null_list = []
  350. if not device_info_summary_qs.exists():
  351. return response.json(0, null_list)
  352. count_all = device_info_summary_qs.aggregate(total=Sum('count'))['total']
  353. res = {}
  354. video_list = []
  355. region_list = []
  356. for item in time_list:
  357. deivce_type_qs = device_info_summary_qs.filter(time__range=(item[0], item[1])).values('count')
  358. if deivce_type_qs.exists():
  359. count = deivce_type_qs.aggregate(total=Sum('count'))['total']
  360. else:
  361. count = deivce_type_qs.count()
  362. vod_dict = {
  363. 'count': count,
  364. 'rate': round(count / count_all * 100, 2),
  365. 'startTime': item[0],
  366. 'endTime': item[1]
  367. }
  368. video_list.append(vod_dict)
  369. res['vodHls'] = video_list
  370. for type_country in device_info_summary_qs:
  371. country_temp_dict = eval(type_country['country'])
  372. for k, v in country_temp_dict.items():
  373. flag = 0
  374. for each in region_list:
  375. if k == each['countryName']:
  376. each['count'] += v
  377. flag = 1
  378. break
  379. if flag == 0:
  380. region_list.append({
  381. 'countryName': k,
  382. 'count': v
  383. })
  384. for item in region_list:
  385. item['rate'] = round(item['count'] / count_all * 100, 2) if count_all else 0
  386. res['region'] = region_list
  387. return response.json(0, res)
  388. except Exception as e:
  389. print(e)
  390. return response.json(500)
  391. @classmethod
  392. def add_device(cls, request_dict, response):
  393. """
  394. 查询设备增长数据
  395. @param request_dict:请求参数
  396. @request_dict starTime:开始时间
  397. @request_dict endTime:结束时间
  398. @param response:响应对象
  399. """
  400. start_time = request_dict.get('startTime', None) # 时间戳
  401. end_time = request_dict.get('endTime', None)
  402. unit_time = request_dict.get('timeUnit', None)
  403. if not all([start_time, end_time, unit_time]):
  404. return response.json(444, {'error param': 'startTime or endTime or timeUnit'})
  405. try:
  406. uid_set_qs = DeviceInfoSummary.objects.filter(time__range=(start_time, end_time), query_type=0)
  407. null_list = []
  408. if not uid_set_qs.exists():
  409. return response.json(0, null_list)
  410. count_all = uid_set_qs.aggregate(total=Sum('count'))['total']
  411. # 统计该时间段的设备数量(已去重)
  412. res = {
  413. 'addDevice': '',
  414. 'region': '',
  415. 'type': '',
  416. 'version': '',
  417. }
  418. info_list = []
  419. region_list = []
  420. type_list = []
  421. version_list = []
  422. start_time = datetime.datetime.fromtimestamp(int(start_time))
  423. end_time = datetime.datetime.fromtimestamp(int(end_time))
  424. time_list = CommonService.cutting_time(start_time, end_time, unit_time)
  425. for item in time_list:
  426. device_uid_qs = uid_set_qs.filter(time__range=(item[0], item[1]), query_type=0)
  427. if device_uid_qs.exists():
  428. count = device_uid_qs.aggregate(total=Sum('count'))['total']
  429. else:
  430. count = device_uid_qs.count()
  431. rate = round(count / count_all * 100, 2)
  432. info_dict = {
  433. 'startTime': item[0],
  434. 'endTime': item[1],
  435. 'count': count,
  436. 'rate': rate
  437. }
  438. info_list.append(info_dict)
  439. res['addDevice'] = info_list
  440. # 统计地区设备数量
  441. device_info_country_qs = uid_set_qs.values('country')
  442. for item in device_info_country_qs:
  443. country_temp_dict = eval(item['country'])
  444. for x, y in country_temp_dict.items():
  445. flag = 0
  446. for each in region_list:
  447. if x == each['countryName']:
  448. each['count'] += y
  449. flag = 1
  450. break
  451. if flag == 0:
  452. region_list.append({
  453. 'countryName': x,
  454. 'count': y
  455. })
  456. for item in region_list:
  457. item['rate'] = round(item['count'] / count_all * 100, 2) if count_all else 0
  458. res['region'] = CommonService.list_sort(region_list)
  459. # 统计设备类型数量
  460. device_type_qs = uid_set_qs.values('device_type')
  461. for item in device_type_qs:
  462. country_temp_dict = eval(item['device_type'])
  463. for x, y in country_temp_dict.items():
  464. flag = 0
  465. for each in type_list:
  466. if x == each['type']:
  467. each['count'] += y
  468. flag = 1
  469. break
  470. if flag == 0:
  471. type_list.append({
  472. 'type': x,
  473. 'count': y
  474. })
  475. for item in type_list:
  476. item['rate'] = round(item['count'] / count_all * 100, 2) if count_all else 0
  477. res['type'] = CommonService.list_sort(type_list)
  478. # 云存版本数量
  479. cloud_type_qs = uid_set_qs.values('vod_service')
  480. for cloud_type in cloud_type_qs:
  481. country_temp_dict = eval(cloud_type['vod_service'])
  482. for x, y in country_temp_dict.items():
  483. flag = 0
  484. for each in version_list:
  485. if x == each['type']:
  486. each['count'] += y
  487. flag = 1
  488. break
  489. if flag == 0:
  490. version_list.append({
  491. 'type': x,
  492. 'count': y
  493. })
  494. for item in version_list:
  495. item['rate'] = round(item['count'] / count_all * 100, 2) if count_all else 0
  496. res['version'] = CommonService.list_sort(version_list)
  497. return response.json(0, res)
  498. except Exception as e:
  499. print(e)
  500. return response.json(500, repr(e))
  501. @classmethod
  502. def regional_statistics(cls, response):
  503. """
  504. 统计地区设备数量
  505. @param response:响应对象
  506. """
  507. all_device_qs = DeviceInfoSummary.objects.all()
  508. if not all_device_qs.exists():
  509. return response.json(173)
  510. all_country_qs = all_device_qs.values('count', 'country')
  511. all_continent_qs = all_device_qs.values('continent')
  512. country_count = all_country_qs.aggregate(total=Sum('count'))['total']
  513. res = {}
  514. try:
  515. continent_list = []
  516. region_list = []
  517. for item in all_country_qs:
  518. country_temp_dict = eval(item['country'])
  519. for x, y in country_temp_dict.items():
  520. flag = 0
  521. for each in region_list:
  522. if x == each['countryName']:
  523. each['count'] += y
  524. flag = 1
  525. break
  526. if flag == 0:
  527. region_list.append({
  528. 'countryName': x,
  529. 'count': y
  530. })
  531. for item in region_list:
  532. item['rate'] = round(item['count'] / country_count * 100, 2) if country_count else 0
  533. for item in all_continent_qs:
  534. continent_temp_dict = eval(item['continent'])
  535. for x, y in continent_temp_dict.items():
  536. flag = 0
  537. for each in continent_list:
  538. if x == each['continentName']:
  539. each['count'] += y
  540. flag = 1
  541. break
  542. if flag == 0:
  543. continent_list.append({
  544. 'continentName': x,
  545. 'count': y
  546. })
  547. for item in continent_list:
  548. item['rate'] = round(item['count'] / country_count * 100, 2) if country_count else 0
  549. res['countries'] = CommonService.list_sort(region_list)
  550. res['continent'] = CommonService.list_sort(continent_list)
  551. return response.json(0, res)
  552. except Exception as e:
  553. print(e)
  554. return response.json(500)
  555. @classmethod
  556. def type_statistics(cls, response):
  557. """
  558. 统计设备类型
  559. @param response:响应对象
  560. @return:
  561. """
  562. all_device_qs = DeviceInfoSummary.objects.filter().values('device_type', 'count')
  563. if not all_device_qs.exists():
  564. return response.json(173)
  565. country_count = all_device_qs.aggregate(total=Sum('count'))['total']
  566. res = {}
  567. try:
  568. device_type_list = []
  569. for item in all_device_qs:
  570. country_temp_dict = eval(item['device_type'])
  571. for t, c in country_temp_dict.items():
  572. flag = 0
  573. for each in device_type_list:
  574. if t == each['type']:
  575. each['count'] += c
  576. flag = 1
  577. break
  578. if flag == 0:
  579. device_type_list.append({
  580. 'type': t,
  581. 'count': c
  582. })
  583. for item in device_type_list:
  584. item['rate'] = round(item['count'] / country_count * 100, 2) if country_count else 0
  585. res['type'] = device_type_list
  586. return response.json(0, res)
  587. except Exception as e:
  588. print(e)
  589. return response.json(500)