Files
Incidents-Data-Portal/backend/app/utils.py
T

115 lines
3.7 KiB
Python
Raw Normal View History

2026-07-10 18:55:55 +08:00
import base64
from datetime import datetime, timezone
import math
from zoneinfo import ZoneInfo
from flask import current_app, json
import numpy as np
from werkzeug.security import generate_password_hash, check_password_hash
import threading # 用于线程安全
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
# --- 全局状态管理 ---
# 使用一个简单的标志和锁来确保线程安全
cluster_ensured_running = False
cluster_check_lock = threading.Lock()
def encrypt_password(raw_password: str) -> str:
"""加密密码(使用pbkdf2:sha256算法)"""
return generate_password_hash(raw_password, method="pbkdf2:sha256", salt_length=16)
def verify_password(encrypted_password: str, raw_password: str) -> bool:
"""验证密码"""
return check_password_hash(encrypted_password, raw_password)
def convert_incident_time_format(data_list):
for item in data_list:
# 原始数据是Timestamp类型,直接获取
original_ts = item["incident_time"]
print('original_ts',type(original_ts))
# 1. 为Timestamp添加原时区(假设原时间是Asia/Shanghai时区,且原始Timestamp无时区)
# 注意:如果Timestamp已有时区,直接跳过localize,用tz_convert即可
if original_ts.tz is None: # 检查是否已有时区
original_tz_ts = original_ts.tz_localize(ZoneInfo("Asia/Shanghai"))
else:
original_tz_ts = original_ts # 已有时区则直接使用
# 2. 转换为UTC时区
utc_ts = original_tz_ts.tz_convert(ZoneInfo("UTC"))
# 3. 格式化输出目标格式(添加T、毫秒和时区标识)
target_str = utc_ts.strftime("%Y-%m-%dT%H:%M:%S") + ".000+0000"
# 更新字段
item["incident_time"] = target_str
# 处理NaN的值
# processed_data = {}
for key, value in item.items():
# 检查当前值是否为NaN(仅针对数值类型)
if isinstance(value, (int, float)): # 确保是数值类型
# 判断是否为NaN(同时兼容math.nan和np.nan
if math.isnan(value) or np.isnan(value):
item[key] = None
else:
item[key] = value
else:
# 非数值类型(如字符串、None等)直接保留
item[key] = value
return data_list
# gen5的车码查询前替换为真实的车码
def mask_vin(real_vin):
id_str = real_vin[-6:]
if not id_str.isdigit():
print('The last six digits of vin:%s are not numbers!' % real_vin)
return real_vin
masked_id = ''
add = 0
total = 0
mapping = {
73: 88,
79: 89,
81: 90,
}
for i in id_str:
total += int(i)
for i in id_str:
add += total + 2
c = int(i) + 65 + add % 13
if c in [73, 79, 81]:
c = mapping[c]
masked_id += chr(c)
masked_vin = real_vin[:-6] + masked_id[::-1]
return masked_vin
def decrypt_code(encrypted_data):
try:
raw_key=current_app.config['HEADERS_SECRET_KEY']
key_bytes=raw_key.encode('utf-8')[:16]
if len(key_bytes)<16:
key_bytes=key_bytes.ljust(16,b"0")
combined=base64.b64decode(encrypted_data)
iv_byte=combined[:16]
ct_byte=combined[16:]
ciper=AES.new(key_bytes,AES.MODE_CBC,iv=iv_byte)
des_padd=ciper.decrypt(ct_byte)
desrypt_res=unpad(des_padd,AES.block_size)
return desrypt_res.decode('utf-8')
except Exception as e:
print('解析失败')
return None