You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
111 lines
3.2 KiB
111 lines
3.2 KiB
# coding=utf-8
|
|
import hashlib
|
|
import os
|
|
from pathlib import Path
|
|
import re
|
|
from .logger_utils import create_logger
|
|
import json
|
|
from typing import Any, Union
|
|
from datetime import datetime
|
|
|
|
|
|
def parse_nested_json(
|
|
json_str: str,
|
|
default: Any = None,
|
|
recursive: bool = True
|
|
) -> Union[dict, list, Any]:
|
|
"""
|
|
解析多层嵌套的JSON字符串
|
|
|
|
:param json_str: 要解析的JSON字符串
|
|
:param default: 解析失败时返回的默认值
|
|
:param recursive: 是否递归解析嵌套的JSON字符串
|
|
:return: 解析后的Python对象
|
|
"""
|
|
|
|
def _parse(obj: Any) -> Any:
|
|
# 递归解析嵌套结构
|
|
if isinstance(obj, dict):
|
|
return {k: _parse(v) for k, v in obj.items()}
|
|
elif isinstance(obj, list):
|
|
return [_parse(elem) for elem in obj]
|
|
elif recursive and isinstance(obj, str):
|
|
try:
|
|
parsed = json.loads(obj)
|
|
return _parse(parsed) # 递归解析新对象
|
|
except json.JSONDecodeError:
|
|
return obj
|
|
else:
|
|
return obj
|
|
|
|
# 处理空输入
|
|
if not json_str:
|
|
return default if default is not None else {}
|
|
|
|
try:
|
|
# 首次解析外层JSON
|
|
parsed = json.loads(json_str)
|
|
# 递归处理嵌套结构
|
|
return _parse(parsed)
|
|
except (TypeError, json.JSONDecodeError) as e:
|
|
# 处理解码错误和类型错误
|
|
return default if default is not None else {}
|
|
except Exception as e:
|
|
# 其他异常处理(可选记录日志)
|
|
return default if default is not None else {}
|
|
|
|
|
|
def convert_timestamp(timestamp):
|
|
"""
|
|
自动识别时间戳是秒级还是毫秒级,并转换为 datetime 对象。
|
|
|
|
参数:
|
|
timestamp -- 时间戳(整数或浮点数)
|
|
|
|
返回:
|
|
datetime 对象
|
|
"""
|
|
# 如果时间戳大于 1e10,认为是毫秒级时间戳
|
|
if timestamp > 1e10:
|
|
timestamp /= 1000.0 # 转换为秒级时间戳
|
|
return datetime.fromtimestamp(timestamp)
|
|
|
|
def make_sha256_hash(file_path: str) -> str:
|
|
"""
|
|
计算文件的哈希值
|
|
:param file_path: 文件路径
|
|
:return: 哈希值的十六进制字符串
|
|
"""
|
|
hash_obj = hashlib.new("sha256")
|
|
with open(file_path, "rb") as f:
|
|
while chunk := f.read(8192): # 分块读取避免大文件内存溢出
|
|
hash_obj.update(chunk)
|
|
return hash_obj.hexdigest()
|
|
|
|
|
|
def css_to_dict(css_line):
|
|
"""
|
|
将单行CSS变量声明转换为Python字典
|
|
|
|
参数:
|
|
css_line (str): 包含CSS变量声明的字符串,例如:
|
|
'--ds-button-color: #fff; -button-text-color: #4c4c4c; button-border-color: rgba(0, 0, 0, 0.12);'
|
|
|
|
返回:
|
|
dict: 包含CSS变量名和值的字典
|
|
"""
|
|
# 使用正则表达式匹配所有变量声明
|
|
# 匹配格式:可能带有1-2个横线的变量名,然后是冒号和值
|
|
pattern = r'(-{0,2}[a-zA-Z0-9-]+)\s*:\s*([^;]+);?'
|
|
matches = re.findall(pattern, css_line)
|
|
|
|
# 将匹配结果转换为字典
|
|
result = {}
|
|
for match in matches:
|
|
var_name = match[0] # 保留原始横线数量
|
|
var_value = match[1].strip()
|
|
result[var_name] = var_value
|
|
|
|
return result
|
|
|
|
|