DeviceDataController.py 24 KB

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