Files
flaskProject/app/utils/__init__.py
T
YanLongChangAn 74fb9698cd refactor(book_service): 重构书籍服务以使用Pathlib路径处理
- 移除os模块导入,改用pathlib.Path进行路径操作
- 添加find_project_root工具函数用于查找项目根目录
- 将文件夹创建方法重构为使用Path对象的create_folder函数
- 更新下载路径构建方式,使用pathlib路径拼接替代os.path.join
- 优化download_file方法,改进异常处理和内容类型检查逻辑
- 修改get_post_date方法为静态方法,提升代码结构清晰度
2026-05-12 13:38:37 +08:00

114 lines
3.7 KiB
Python

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 # 没找到则返回当前文件所在目录