import json import time import ctypes from collections import defaultdict from pathlib import Path from typing import List from datetime import datetime from functools import cmp_to_key def windows_sort_unicode(items: List[str]) -> List[str]: """ 使用Windows API实现字符串列表的排序。 该函数通过调用Windows的Shlwapi.dll库中的StrCmpLogicalW函数进行字符串的比较,以实现自然排序。 自然排序是指在排序数字和字母组合的字符串时,数字按照数值来比较,而不是按照字符的ASCII值来比较。 :param items: List[str] - 需要排序的字符串列表。 :return: List[str] - 排序后的字符串列表。 """ shlwapi = ctypes.windll.LoadLibrary('Shlwapi.dll') StrCmpLogicalW = shlwapi.StrCmpLogicalW StrCmpLogicalW.argtypes = [ctypes.c_wchar_p, ctypes.c_wchar_p] StrCmpLogicalW.restype = ctypes.c_int def compare(a: str, b: str) -> int: """ 比较两个字符串的函数,用于在排序时调用。 :param a: str - 第一个字符串。 :param b: str - 第二个字符串。 :return: int - StrCmpLogicalW函数的返回值,表示两个字符串的比较结果。 """ return StrCmpLogicalW(str(a), str(b)) return sorted(items, key=cmp_to_key(compare)) def read_json_file(json_path): # 读取json文件 with open(json_path, 'r', encoding='utf-8') as file: data = json.load(file) return data def write_json_file(json_path, data): # 写入json文件 with open(json_path, 'w') as file: json.dump(data, file, sort_keys=False, indent=4) def datetime_to_timestamp(date) -> int: """ 日期转时间戳 :param date: 需要转换的日期 :return: """ return int(datetime.strptime(date, "%Y-%m-%d").timestamp()) def timestamp_to_datetime(timestamp): """ 时间戳转日期 :param timestamp: 需要转换的时间戳 :return: """ return datetime.fromtimestamp(timestamp).strftime("%Y-%m-%d") def get_today_timestamp(): """ 获取今日时间戳 :return: """ return datetime_to_timestamp(datetime.now().strftime("%Y-%m-%d")) def show_delay_progress(delay_time: float) -> None: """在控制台显示延迟进度条""" total_blocks = 30 # 进度条总长度 start_time = time.time() end_time = start_time + delay_time print(f"\n等待 {delay_time:.1f} 秒... [{' ' * total_blocks}]", end='', flush=True) while time.time() < end_time: elapsed = time.time() - start_time progress = min(1.0, elapsed / delay_time) filled = int(progress * total_blocks) remaining = end_time - time.time() print(f"\r等待 {delay_time:.1f} 秒... [{'=' * filled}>{' ' * (total_blocks - filled - 1)}]" f" 剩余: {remaining:.1f}s", end='', flush=True) time.sleep(0.1) print("\r" + " " * 80 + "\r", end='', flush=True) # 清空进度行 def to_json_serializable(obj): """递归将 defaultdict 和 set 转换为 JSON 可序列化的类型""" if isinstance(obj, defaultdict): # 转为普通字典,并递归处理每个值 obj = dict(obj) if isinstance(obj, dict): return {k: to_json_serializable(v) for k, v in obj.items()} if isinstance(obj, set): return list(obj) # 集合转列表 # 其他基本类型(str, int, float, list, tuple, None)直接返回 return obj def find_project_root(marker_files=('requirements.txt', 'run.py')): current = Path(__file__).resolve().parent for parent in current.parents: if any((parent / marker).exists() for marker in marker_files): return parent return current # 没找到则返回当前文件所在目录