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 | |
| 
 | |
| 
 |