File size: 3,121 Bytes
9d3cbac
 
58a7ac0
 
 
 
 
 
 
 
 
9d3cbac
 
 
 
 
58a7ac0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1c7b6d3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
from datetime import datetime
from zoneinfo import ZoneInfo
from typing import Any
from jose import jwt
import hashlib
import json
import uuid
import os


SECRET_KEY = os.environ.get("SECRET_KEY")


def beijing():
    """get beijing time"""
    return datetime.now(tz=ZoneInfo("Asia/Shanghai"))


def decode_jwt(token: str) -> dict[str, Any]:
    """get payload in the jwt token"""
    assert SECRET_KEY, "Please set the environment variable SECRET_KEY"
    return jwt.decode(token, SECRET_KEY, algorithms=["HS256"])


def parse_token(token: str | None) -> tuple[str, str]:
    """parse user token to get uid and username

    :param token (str): jwt token
    :return (str, str): (uid, username)
    """
    if not token:
        uid, username = "no_uid", "Anonymous"
    else:
        payload: dict = decode_jwt(token)
        uid = payload.get("uid", "no_uid")
        username = payload.get("username", "Anonymous")
    print(f"UID: {uid}")
    print(f"Username: {username}")
    return uid, username


def md5(text: list[str | bytes] | str | bytes | None = None) -> str:
    """generate the md5 hash code of the given text, if text is None,
    return a random md5"""
    code = hashlib.md5()
    if text:
        if isinstance(text, str):
            text = text.encode("utf-8")
            code.update(text)
        elif isinstance(text, list):
            for t in text:
                if isinstance(t, str):
                    t = t.encode("utf-8")
                code.update(t)
        else:
            code.update(text)
    else:
        code.update(uuid.uuid4().bytes)
    return code.hexdigest()


def json_to_str(obj: dict | list) -> str:
    return json.dumps(obj, separators=(",", ":"))


def validate_date_format(date_str: str, format_str: str = "%Y-%m-%d") -> bool:
    """
    验证日期字符串的格式是否正确

    :param date_str: 要验证的日期字符串
    :param format_str: 期望的日期格式(默认:YYYY-MM-DD)
    :return: 如果格式正确返回 True,否则返回 False
    """
    if not date_str:
        return True  # 空值被认为是有效的(可选参数)

    try:
        from datetime import datetime as dt
        dt.strptime(date_str, format_str)
        return True
    except ValueError:
        return False


def parse_date_range(from_date: str | None, to_date: str | None) -> tuple[str | None, str | None] | tuple[str, str]:
    """
    解析和验证日期范围

    :param from_date: 开始日期(格式:YYYY-MM-DD)
    :param to_date: 结束日期(格式:YYYY-MM-DD)
    :return: 验证后的日期范围元组 (from_date, to_date)
    :raises ValueError: 如果日期格式不正确或范围无效
    """
    if from_date and not validate_date_format(from_date):
        raise ValueError(f"Invalid from_date format: {from_date}")

    if to_date and not validate_date_format(to_date):
        raise ValueError(f"Invalid to_date format: {to_date}")

    if from_date and to_date and from_date > to_date:
        raise ValueError(f"from_date ({from_date}) cannot be after to_date ({to_date})")

    return from_date, to_date