utils.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. import string
  2. import random
  3. import requests
  4. import json
  5. import logging
  6. import time
  7. import hashlib
  8. from captcha.image import ImageCaptcha
  9. from io import BytesIO
  10. import base64
  11. from datetime import datetime, timedelta
  12. import calendar
  13. from smartfarming.models.user import Role, UserPurview
  14. from kedong.tools import RedisPool
  15. from kedong import settings
  16. logger = logging.getLogger("other")
  17. redis_pool = RedisPool().get_redis_pool(settings.redis_db["jiankong"])
  18. def perms_pc_app(type_id=1000, perms_lst=[]):
  19. menu = "PC" if type_id == 1000 else "APP"
  20. parent_ids = []
  21. for p in perms_lst:
  22. # 先判断是否是父级菜单
  23. per_obj = UserPurview.objects.filter(id=int(p), menu=menu).first()
  24. if per_obj:
  25. if per_obj.parent_perm_id == 0:
  26. parent_ids.append(p)
  27. perm_lst = []
  28. for i in parent_ids:
  29. parent = UserPurview.objects.get(id=int(i), menu=menu)
  30. inner_parent = {
  31. "menu": parent.menu,
  32. "parent_perm_id": parent.parent_perm_id,
  33. "pur_id": parent.id,
  34. "purview_name": parent.purview_name,
  35. "url": parent.url
  36. }
  37. children_lst = []
  38. # 获取此父级菜单中所有的子菜单
  39. children = UserPurview.objects.filter(parent_perm_id=int(i), menu=menu)
  40. for child in children:
  41. if child.id in perms_lst:
  42. children_lst.append(
  43. {
  44. "menu": child.menu,
  45. "parent_perm_id": child.parent_perm_id,
  46. "pur_id": child.id,
  47. "purview_name": child.purview_name,
  48. "url": child.url
  49. }
  50. )
  51. if children_lst:
  52. inner_parent["children"] = children_lst
  53. perm_lst.append(inner_parent)
  54. return perm_lst
  55. def get_perm_list(device_user):
  56. id = device_user.role_id
  57. try:
  58. role = Role.objects.get(id=id)
  59. role_perm = role.role_perm
  60. perms_lst = [int(i) for i in role_perm.split(",")]
  61. pc_perm_lst = perms_pc_app(type_id=1000, perms_lst=perms_lst)
  62. app_perm_lst = perms_pc_app(type_id=2000, perms_lst=perms_lst)
  63. if pc_perm_lst and app_perm_lst:
  64. perm_lst = [
  65. {
  66. "menu": "",
  67. "parent_perm_id": 1000,
  68. "pur_id": 0,
  69. "purview_name": "登录PC端",
  70. "url": "",
  71. "children": pc_perm_lst
  72. },
  73. {
  74. "menu": "",
  75. "parent_perm_id": 2000,
  76. "pur_id": 0,
  77. "purview_name": "登录APP端",
  78. "url": "",
  79. "children": app_perm_lst
  80. }
  81. ]
  82. elif pc_perm_lst:
  83. perm_lst = [
  84. {
  85. "menu": "",
  86. "parent_perm_id": 1000,
  87. "pur_id": 0,
  88. "purview_name": "登录PC端",
  89. "url": "",
  90. "children": pc_perm_lst
  91. }
  92. ]
  93. elif app_perm_lst:
  94. perm_lst = [
  95. {
  96. "menu": "",
  97. "parent_perm_id": 2000,
  98. "pur_id": 0,
  99. "purview_name": "登录APP端",
  100. "url": "",
  101. "children": app_perm_lst
  102. }
  103. ]
  104. else:
  105. perm_lst = []
  106. mark = role.mark
  107. return perm_lst, mark
  108. except Exception as e:
  109. return [], ""
  110. def get_all_pers():
  111. role_perm = UserPurview.objects.all().values("id")
  112. perms_lst = []
  113. for i in role_perm:
  114. perms_lst.append(i.get("id"))
  115. pc_perm_lst = perms_pc_app(type_id=1000, perms_lst=perms_lst)
  116. app_perm_lst = perms_pc_app(type_id=2000, perms_lst=perms_lst)
  117. perm_lst = [
  118. {
  119. "menu": "",
  120. "parent_perm_id": 1000,
  121. "pur_id": 0,
  122. "purview_name": "登录PC端",
  123. "url": "",
  124. "children": pc_perm_lst
  125. },
  126. {
  127. "menu": "",
  128. "parent_perm_id": 2000,
  129. "pur_id": 0,
  130. "purview_name": "登录APP端",
  131. "url": "",
  132. "children": app_perm_lst
  133. }
  134. ]
  135. return perm_lst
  136. def get_captcha():
  137. """获取图片验证码
  138. return :
  139. 验证码字符串,验证码图片base64数据
  140. """
  141. chr_all = string.ascii_uppercase + string.digits
  142. chr_all = chr_all.replace('0', '').replace('1', '').replace('2', '').replace('O', '').replace('I', '')
  143. code_str = ''.join(random.sample(chr_all, 4))
  144. image = ImageCaptcha().generate_image(code_str)
  145. f = BytesIO()
  146. image.save(f, 'png')
  147. data = f.getvalue()
  148. f.close()
  149. encode_data = base64.b64encode(data)
  150. data = str(encode_data, encoding='utf-8')
  151. img_data = "data:image/jpeg;base64,{data}".format(data=data)
  152. return code_str, img_data
  153. def get_recent_month(num):
  154. # 获取最近N个月的时间戳
  155. end_time = datetime.now() # 结束时间,当前时间
  156. # 获取当前月份和年份
  157. current_month = end_time.month
  158. current_year = end_time.year
  159. # 计算开始时间
  160. start_month = current_month - num # 当前月份往前推N个月
  161. start_year = current_year
  162. if start_month <= 0: # 如果计算得到的月份为负数,则需要向前借位
  163. start_month += 12
  164. start_year -= 1
  165. # 获取开始时间所在月份的最后一天
  166. _, last_day = calendar.monthrange(start_year, start_month)
  167. start_time = datetime(start_year, start_month, last_day).timestamp()
  168. return start_time
  169. def get_addr_by_lag_lng(lat,lng):
  170. # 根据经纬度获取省市级
  171. is_success, province, city, district = False, "", "", ""
  172. try:
  173. # 使用腾讯接口
  174. url = "https://apis.map.qq.com/ws/geocoder/v1?location={},{}&get_poi=0&key=OA4BZ-FX43U-E5VV2-45M6S-C4HD3-NIFFI&output=json".format(lat,lng)
  175. requests.adapters.DEFAULT_RETRIES = 5 # 增加重连次数
  176. s = requests.session()
  177. s.keep_alive = False # 关闭多余连接
  178. ret = s.get(url)
  179. rest = json.loads(ret.text)
  180. province = rest["result"]["ad_info"]["province"]
  181. city = rest["result"]["ad_info"]["city"]
  182. district = rest["result"]["ad_info"]["district"]
  183. is_success = True
  184. except Exception as e:
  185. logger.error(f"获取腾讯地理位置接口失败 {e.args}")
  186. if not is_success:
  187. try:
  188. # 使用百度接口
  189. url = "http://api.map.baidu.com/geocoder?location=%s,%s&output=json"%(lat,lng)
  190. requests.adapters.DEFAULT_RETRIES = 5 # 增加重连次数
  191. s = requests.session()
  192. s.keep_alive = False # 关闭多余连接
  193. ret = s.get(url)
  194. addr = json.loads(ret.text)
  195. province = addr["result"]["addressComponent"]["province"]
  196. city = addr["result"]["addressComponent"]["city"]
  197. district = addr["result"]["addressComponent"]["district"]
  198. is_success = True
  199. except Exception as e:
  200. logger.error(f"获取百度地理位置接口失败 {e.args}")
  201. return is_success, province, city, district
  202. # 获取天气数据
  203. def get_address_by_lntlat(lng, lat):
  204. province, city, district = "", "", ""
  205. try:
  206. key = "78ce288400f4fc6d9458989875c833c2"
  207. adcode_url = "http://restapi.amap.com/v3/geocode/regeo?key={key}&location={lng},{lat}&poitype=&radius=&" \
  208. "extensions=all&batch=false&roadlevel=0".format(key=key, lng=lng, lat=lat)
  209. res = requests.get(adcode_url)
  210. rsp = res.json()
  211. address_info = rsp['regeocode']['addressComponent']
  212. adcode = address_info['adcode']
  213. if adcode != "900000":
  214. province, city, district = address_info['province'], address_info['city'], address_info['district']
  215. if (not city) and district:
  216. city = district
  217. except Exception as e:
  218. pass
  219. return province, city, district
  220. # 获取天气相关信息
  221. def get_weather_info(lng=None, lat=None):
  222. data = {}
  223. if lng and lat:
  224. try:
  225. url = "http://114.115.147.140:8080/weather"
  226. res = requests.post(url, {"lat": lat, "lng": lng})
  227. result = res.json()
  228. if result['status'] == 'true':
  229. data = result['data']
  230. except Exception as e:
  231. pass
  232. return data
  233. def md5value(appSecret):
  234. """sign加密"""
  235. times = int(time.time())
  236. # 随机生成32位字符串
  237. nonce = ''.join(random.sample(string.ascii_letters + string.digits, 32))
  238. sign = "time:{},nonce:{},appSecret:{}".format(times, nonce, appSecret)
  239. input_name = hashlib.md5()
  240. input_name.update(sign.encode("utf-8"))
  241. sign = (input_name.hexdigest()).lower()
  242. return times,nonce,sign
  243. def deviceAccessToken(appId, appSecret):
  244. """
  245. 乐橙云账号秘钥
  246. appSecret
  247. appId
  248. 使用乐橙云账号的appid和appSecret获取监控token
  249. 请求时数据格式
  250. {
  251. "id":"98a7a257-c4e4-4db3-a2d3-d97a3836b87c",
  252. "system":{
  253. "ver":"1.0",
  254. "appId":"lcdxxxxxxxxx",
  255. "sign":"b7e5bbcc6cc07941725d9ad318883d8e",
  256. "time":1599013514,
  257. "nonce":"fbf19fc6-17a1-4f73-a967-75eadbc805a2"},
  258. "params":{}
  259. }
  260. 签名原始串为:"time:1531401328,nonce:61f38836685b66f3201469543d8365f7,appSecret:12459ac547434b3ea83db5e6d56789"
  261. """
  262. # 先从redis 中获取token
  263. tokens = redis_pool.get(appId)
  264. if tokens and tokens !=None:
  265. redis_jk_data = eval(tokens)
  266. status = redis_jk_data.get("status",1)
  267. if status:
  268. # 查看到期时间
  269. expireTime = redis_pool.ttl(appId)
  270. # 设置到期时间 秒
  271. # redis_pool.expire('ttt', 10)
  272. redis_jk_data["result"]["data"]["expireTime"] = expireTime
  273. else:
  274. redis_jk_data = {"status":0}
  275. return redis_jk_data
  276. else:
  277. status = 0
  278. if not status:
  279. url = "http://172.100.91.30/openapi/openapi/accessToken"
  280. # 加密
  281. times,nonce,sign = md5value(appSecret)
  282. data = {
  283. "system":{
  284. "ver":"1.0",
  285. "appId":appId,
  286. "sign":sign,
  287. "time":times,
  288. "nonce":nonce
  289. },
  290. "id":nonce,
  291. "params":{
  292. }
  293. }
  294. token_data = requests.post(url,json=data)
  295. if token_data.status_code == 200:
  296. try:
  297. token_json_data = json.loads(token_data.text)
  298. expireTime = token_json_data["result"]["data"]["expireTime"]
  299. # status 1 代表获取token 成功 0失败
  300. token_json_data["status"] = 1
  301. except Exception as e:
  302. token_json_data = {"status":0}
  303. expireTime = 5
  304. else:
  305. token_json_data = {"status":0}
  306. expireTime = 5
  307. redis_pool.set(appId,token_json_data,expireTime)
  308. return token_json_data
  309. def device_config(appId,appSecret):
  310. """
  311. 配置项
  312. """
  313. time,nonce,sign = md5value(appSecret)
  314. token_data = deviceAccessToken(appId, appSecret)
  315. if token_data.get("status","0"):
  316. token = token_data["result"]["data"]["accessToken"]
  317. else:
  318. token = ""
  319. return time,nonce,sign,token
  320. def controlMove(appId,appSecret,deviceId,operation,channelId="0"):
  321. """
  322. 云台控制接口
  323. 请求样例:
  324. operation 0-上,1-下,2-左,3-右8-放大9-缩小10-停止
  325. {
  326. "id":"d5c287b4-5b2f-4f03-baf5-8032c5c354af",
  327. "system":{
  328. "ver":"1.0",
  329. "appId":"lcdxxxxxxxxx",
  330. "sign":"74bc756ebd53e9eef2836f8cf1730c10",
  331. "time":1599031074,
  332. "nonce":"8ec8a7bd1d1c95420de20d92422d457d"
  333. },
  334. "params":{
  335. "token":"At_00006acr3456d12312d3grf60147de7ec",
  336. "deviceId":"MEGREZ0000001842",
  337. "channelId":"0",
  338. "operation":"1",
  339. "duration":"1000" # 移动持续时间,单位毫秒
  340. }
  341. }
  342. """
  343. url = "http://172.100.91.30/openapi/openapi/controlMovePTZ"
  344. time,nonce,sign,token = device_config(appId, appSecret)
  345. if not token:
  346. return {"msg":"控制失败"}
  347. data = {
  348. "system":{
  349. "ver":"1.0",
  350. "appId":appId,
  351. "sign":sign,
  352. "time":time,
  353. "nonce":nonce
  354. },
  355. "id":nonce,
  356. "params":{
  357. "token":token,
  358. "deviceId":deviceId,
  359. "channelId":channelId,
  360. "operation":operation,
  361. "duration":"1000"
  362. }
  363. }
  364. control_Move = requests.post(url,json=data)
  365. return control_Move.json()
  366. def expire_time(times):
  367. data_time = datetime.datetime.now()
  368. cultivate_time_expire = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(times))
  369. time1 = datetime.datetime.strptime(cultivate_time_expire,"%Y-%m-%d %H:%M:%S")
  370. num=(time1-data_time).days
  371. print("设备到期天数---",num)
  372. if int(num) <=7 and int(num) >= 0:
  373. print("即将到期")
  374. status = 2
  375. elif int(num) < 0:
  376. print("已到期")
  377. status = 1
  378. else:
  379. print("未到期")
  380. status = 0
  381. return status
  382. if __name__ == "__main__":
  383. t = get_recent_month(1)
  384. print(t)