pymecli 0.2.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/dou_dict.py ADDED
@@ -0,0 +1,172 @@
1
+ from pathlib import Path
2
+ from typing import Dict
3
+
4
+ text_map: Dict[str, str] = dict(
5
+ D="JOKER", # 大王
6
+ X="JOKER",
7
+ dizhu="地主",
8
+ jiaodizhu_btn="叫地主",
9
+ qiangdizhu_btn="抢地主",
10
+ jiabei_btn="加倍",
11
+ chaojijiabei_btn="超级加倍",
12
+ bujiabei_btn="不加倍",
13
+ liantian_btn="聊天",
14
+ start_btn="开始游戏",
15
+ chat_btn="聊天",
16
+ chupai_btn="出牌",
17
+ buchu_btn="不出",
18
+ yaobuqi_btn="要不起",
19
+ mingpai_btn="明牌",
20
+ mingpaistart_btn="明牌开始",
21
+ jixuyouxi_btn="继续游戏",
22
+ )
23
+
24
+ region_map: Dict[str, tuple] = dict(
25
+ general_btn=(210, 450, 1000, 120), # 叫地主、抢地主、加倍按钮截图区域
26
+ # pass_btn=(200, 450, 1000, 120), # 要不起截图区域
27
+ # # 出牌区
28
+ my_hand_cards=(210, 560, 1000, 180), # 我的手牌截图区域
29
+ left_played_cards=(320, 320, 400, 120), # 左边出牌截图区域
30
+ right_played_cards=(720, 320, 400, 120), # 右边出牌截图区域
31
+ my_played_cards=(320, 422, 800, 120), # 我的出牌截图区域
32
+ # # 过牌区
33
+ three_cards=(600, 33, 220, 103), # 地主底牌截图区域
34
+ # left_pass=(360, 360, 120, 80), # 左边不出截图区域
35
+ # right_pass=(940, 360, 120, 80), # 右边不出截图区域
36
+ # my_pass=(636, 469, 152, 87), # 我的不出截图区域
37
+ # 豆子区域
38
+ # bean=(308, 204, 254, 60),
39
+ # bean1=(295, 474, 264, 60),
40
+ # bean2=(882, 203, 230, 60),
41
+ chat_btn=(1302, 744, 117, 56),
42
+ # landlord_cards=(602, 88, 218, 104),
43
+ end_btn=(800, 610, 510, 80),
44
+ landlord_flag_left=(114, 236, 70, 70),
45
+ landlord_flag_right=(1226, 236, 70, 70),
46
+ cards_num_left=(273, 388, 33, 42),
47
+ cards_num_right=(1117, 387, 33, 44),
48
+ # my_pass=(636, 469, 152, 87),
49
+ right_animation=(720, 210, 360, 100), # 下家动画位置
50
+ left_animation=(360, 210, 360, 100), # 上家动画位置
51
+ my_animation=(540, 340, 350, 120), # 自己上方动画位置
52
+ # (1440, 810)
53
+ weile_test=(130, 600, 2000, 380),
54
+ weile_test_three=(990, 16, 300, 80),
55
+ )
56
+
57
+ draw_rect_map = dict(
58
+ # c1=(270, 600, 1900, 380),
59
+ weile_test=region_map["weile_test"],
60
+ weile_test_three=region_map["weile_test_three"],
61
+ # left_played_cards=rect_map["left_played_cards"],
62
+ # right_played_cards=rect_map["right_played_cards"],
63
+ # my_played_cards=rect_map["my_played_cards"],
64
+ # three_cards=rect_map["three_cards"],
65
+ # cards_num_left=rect_map["cards_num_left"],
66
+ # cards_num_right=rect_map["cards_num_right"],
67
+ # general_btn=rect_map["general_btn"],
68
+ # rect_map["right_animation"], # 下家动画位置
69
+ # rect_map["left_animation"], # 上家动画位置
70
+ # rect_map["my_animation"], # 自己上方动画位置
71
+ # right_animation=rect_map["right_animation"],
72
+ # left_animation=rect_map["left_animation"],
73
+ # my_animation=rect_map["my_animation"],
74
+ # all=(5, 5, 1430, 800),
75
+ # my_pass=rect_map["my_pass"],
76
+ )
77
+
78
+ threshold_map: Dict[str, float | tuple[float, float]] = dict(
79
+ jiaodizhu=-0.68, # 叫地主阈值
80
+ fanqiangdizhu=0.3, # 反抢地主阈值
81
+ qiangdizhu=0.12, # 抢地主阈值
82
+ landlord_jiabei=(0.4, 0.01),
83
+ # landlord_jiabei=(0.37, -0.4),
84
+ qiang_landlord_jiabei=(0.45, 0.12),
85
+ farmer_jaibei=(2, 1.22),
86
+ farmer_jaibei_low=(1.22, 0.45),
87
+ mingpai=1.14,
88
+ # jiabei1=0.37,
89
+ # jiabei2=-0.4,
90
+ # jiabei3=0.45,
91
+ # jiabei4=0.12,
92
+ # jiabei5=2,
93
+ # jiabei6=1.22,
94
+ # jiabei7=1.22,
95
+ # jiabei8=0.45,
96
+ )
97
+ to_card_map = {
98
+ 30: "D",
99
+ 20: "X",
100
+ 17: "2",
101
+ 14: "A",
102
+ 13: "K",
103
+ 12: "Q",
104
+ 11: "J",
105
+ 10: "T",
106
+ 9: "9",
107
+ 8: "8",
108
+ 7: "7",
109
+ 6: "6",
110
+ 5: "5",
111
+ 4: "4",
112
+ 3: "3",
113
+ }
114
+ to_env_card_map = {
115
+ "D": 30,
116
+ "X": 20,
117
+ "2": 17,
118
+ "A": 14,
119
+ "K": 13,
120
+ "Q": 12,
121
+ "J": 11,
122
+ "T": 10,
123
+ "9": 9,
124
+ "8": 8,
125
+ "7": 7,
126
+ "6": 6,
127
+ "5": 5,
128
+ "4": 4,
129
+ "3": 3,
130
+ }
131
+
132
+ module_dir = Path(__file__).resolve().parent.parent
133
+
134
+ model_path_map = {
135
+ "landlord": str(module_dir / "baselines/resnet/resnet_landlord.ckpt"),
136
+ "landlord_up": str(module_dir / "baselines/resnet/resnet_landlord_up.ckpt"),
137
+ "landlord_down": str(module_dir / "baselines/resnet/resnet_landlord_down.ckpt"),
138
+ }
139
+
140
+ weights_path_map = {
141
+ "bid_weights": str(module_dir / "douzero/weights/bid_weights.pkl"),
142
+ "farmer_weights": str(module_dir / "douzero/weights/farmer_weights.pkl"),
143
+ "landlord_down_weights": str(
144
+ module_dir / "douzero/weights/landlord_down_weights.pkl"
145
+ ),
146
+ "landlord_up_weights": str(module_dir / "douzero/weights/landlord_up_weights.pkl"),
147
+ "landlord_weights": str(module_dir / "douzero/weights/landlord_weights.pkl"),
148
+ }
149
+
150
+ position_name_map = {
151
+ "landlord": "地主",
152
+ "landlord_up": "地主上家",
153
+ "landlord_down": "地主下家",
154
+ }
155
+
156
+ TYPE_PRIORITY = {
157
+ 0: 0, # PASS
158
+ 1: 1, # SINGLE
159
+ 2: 1, # PAIR
160
+ 3: 1, # TRIPLE
161
+ 4: 2, # BOMB
162
+ 5: 3, # KING_BOMB
163
+ 6: 1, # 3+1
164
+ 7: 1, # 3+2
165
+ 8: 1, # SERIAL_SINGLE
166
+ 9: 1, # SERIAL_PAIR
167
+ 10: 1, # SERIAL_TRIPLE
168
+ 11: 1, # SERIAL_3+1
169
+ 12: 1, # SERIAL_3+2
170
+ 13: 1, # 4+2
171
+ 14: 1, # 4+2+2
172
+ }
data/dou_list.py ADDED
@@ -0,0 +1,93 @@
1
+ # card识别列表
2
+ card_rec_list: list[str] = [
3
+ "JOKER",
4
+ "JOK",
5
+ "JO", # 表示JOKER
6
+ "2",
7
+ "A",
8
+ "K",
9
+ "Q",
10
+ "J",
11
+ "10",
12
+ "9",
13
+ "8",
14
+ "7",
15
+ "6",
16
+ "5",
17
+ "4",
18
+ "3",
19
+ ]
20
+
21
+ bombs = [
22
+ [3, 3, 3, 3],
23
+ [4, 4, 4, 4],
24
+ [5, 5, 5, 5],
25
+ [6, 6, 6, 6],
26
+ [7, 7, 7, 7],
27
+ [8, 8, 8, 8],
28
+ [9, 9, 9, 9],
29
+ [10, 10, 10, 10],
30
+ [11, 11, 11, 11],
31
+ [12, 12, 12, 12],
32
+ [13, 13, 13, 13],
33
+ [14, 14, 14, 14],
34
+ [17, 17, 17, 17],
35
+ [20, 30],
36
+ ]
37
+
38
+ all_env_card = [
39
+ 3,
40
+ 3,
41
+ 3,
42
+ 3,
43
+ 4,
44
+ 4,
45
+ 4,
46
+ 4,
47
+ 5,
48
+ 5,
49
+ 5,
50
+ 5,
51
+ 6,
52
+ 6,
53
+ 6,
54
+ 6,
55
+ 7,
56
+ 7,
57
+ 7,
58
+ 7,
59
+ 8,
60
+ 8,
61
+ 8,
62
+ 8,
63
+ 9,
64
+ 9,
65
+ 9,
66
+ 9,
67
+ 10,
68
+ 10,
69
+ 10,
70
+ 10,
71
+ 11,
72
+ 11,
73
+ 11,
74
+ 11,
75
+ 12,
76
+ 12,
77
+ 12,
78
+ 12,
79
+ 13,
80
+ 13,
81
+ 13,
82
+ 13,
83
+ 14,
84
+ 14,
85
+ 14,
86
+ 14,
87
+ 17,
88
+ 17,
89
+ 17,
90
+ 17,
91
+ 20,
92
+ 30,
93
+ ]
data/main.py ADDED
@@ -0,0 +1,5 @@
1
+ from pathlib import Path
2
+
3
+ if __name__ == "__main__":
4
+ module_dir = Path(__file__).resolve().parent.parent
5
+ print(module_dir)
data/template.yaml ADDED
@@ -0,0 +1,150 @@
1
+ mixed-port: 7890
2
+ allow-lan: false
3
+ mode: rule
4
+ log-level: warning
5
+ external-controller: "127.0.0.1:9097"
6
+ global-client-fingerprint: chrome
7
+ unified-delay: true
8
+ ipv6: false
9
+ profile:
10
+ store-selected: true
11
+ tun:
12
+ mtu: 1500
13
+ dns:
14
+ enable: true
15
+ ipv6: false
16
+ use-system-hosts: false
17
+ listen: "127.0.0.1:5335"
18
+ enhanced-mode: fake-ip
19
+ fake-ip-range: 198.18.0.1/16
20
+ fake-ip-filter:
21
+ [
22
+ "*.lan",
23
+ "stun.*.*.*",
24
+ "stun.*.*",
25
+ time.windows.com,
26
+ time.nist.gov,
27
+ time.apple.com,
28
+ time.asia.apple.com,
29
+ "*.ntp.org.cn",
30
+ "*.openwrt.pool.ntp.org",
31
+ time1.cloud.tencent.com,
32
+ time.ustc.edu.cn,
33
+ pool.ntp.org,
34
+ ntp.ubuntu.com,
35
+ ntp.aliyun.com,
36
+ ntp1.aliyun.com,
37
+ ntp2.aliyun.com,
38
+ ntp3.aliyun.com,
39
+ ntp4.aliyun.com,
40
+ ntp5.aliyun.com,
41
+ ntp6.aliyun.com,
42
+ ntp7.aliyun.com,
43
+ time1.aliyun.com,
44
+ time2.aliyun.com,
45
+ time3.aliyun.com,
46
+ time4.aliyun.com,
47
+ time5.aliyun.com,
48
+ time6.aliyun.com,
49
+ time7.aliyun.com,
50
+ "*.time.edu.cn",
51
+ time1.apple.com,
52
+ time2.apple.com,
53
+ time3.apple.com,
54
+ time4.apple.com,
55
+ time5.apple.com,
56
+ time6.apple.com,
57
+ time7.apple.com,
58
+ time1.google.com,
59
+ time2.google.com,
60
+ time3.google.com,
61
+ time4.google.com,
62
+ music.163.com,
63
+ "*.music.163.com",
64
+ "*.126.net",
65
+ musicapi.taihe.com,
66
+ music.taihe.com,
67
+ songsearch.kugou.com,
68
+ trackercdn.kugou.com,
69
+ "*.kuwo.cn",
70
+ api-jooxtt.sanook.com,
71
+ api.joox.com,
72
+ joox.com,
73
+ y.qq.com,
74
+ "*.y.qq.com",
75
+ streamoc.music.tc.qq.com,
76
+ mobileoc.music.tc.qq.com,
77
+ isure.stream.qqmusic.qq.com,
78
+ dl.stream.qqmusic.qq.com,
79
+ aqqmusic.tc.qq.com,
80
+ amobile.music.tc.qq.com,
81
+ "*.xiami.com",
82
+ "*.music.migu.cn",
83
+ music.migu.cn,
84
+ "*.msftconnecttest.com",
85
+ "*.msftncsi.com",
86
+ localhost.ptlogin2.qq.com,
87
+ "*.*.*.srv.nintendo.net",
88
+ "*.*.stun.playstation.net",
89
+ "xbox.*.*.microsoft.com",
90
+ "*.ipv6.microsoft.com",
91
+ "*.*.xboxlive.com",
92
+ speedtest.cros.wr.pvp.net,
93
+ ]
94
+ default-nameserver:
95
+ [
96
+ system,
97
+ 180.76.76.76,
98
+ 182.254.118.118,
99
+ 8.8.8.8,
100
+ 180.184.2.2,
101
+ "2400:3200::1",
102
+ ]
103
+ nameserver:
104
+ [
105
+ "https://223.5.5.5/dns-query#skip-cert-verify=true",
106
+ "https://doh.pub/dns-query#skip-cert-verify=true",
107
+ "https://dns.alidns.com/dns-query#skip-cert-verify=true",
108
+ "tls://223.5.5.5#skip-cert-verify=true",
109
+ "tls://dot.pub#skip-cert-verify=true",
110
+ "tls://dns.alidns.com#skip-cert-verify=true",
111
+ "https://223.6.6.6/dns-query#skip-cert-verify=true&h3=true",
112
+ "https://cloudflare-dns.com/dns-query#skip-cert-verify=true",
113
+ ]
114
+ proxy-server-nameserver:
115
+ [
116
+ "https://223.5.5.5/dns-query#skip-cert-verify=true",
117
+ "https://doh.pub/dns-query#skip-cert-verify=true",
118
+ "https://dns.alidns.com/dns-query#skip-cert-verify=true",
119
+ "tls://223.5.5.5#skip-cert-verify=true",
120
+ "tls://dot.pub#skip-cert-verify=true",
121
+ "tls://dns.alidns.com#skip-cert-verify=true",
122
+ "https://223.6.6.6/dns-query#skip-cert-verify=true&h3=true",
123
+ "https://cloudflare-dns.com/dns-query#skip-cert-verify=true",
124
+ ]
125
+ fallback-filter:
126
+ {
127
+ geoip: true,
128
+ ipcidr: [240.0.0.0/4, 0.0.0.0/32, 127.0.0.1/32],
129
+ domain:
130
+ [
131
+ +.google.com,
132
+ +.facebook.com,
133
+ +.twitter.com,
134
+ +.youtube.com,
135
+ +.xn--ngstr-lra8j.com,
136
+ +.google.cn,
137
+ +.googleapis.cn,
138
+ +.googleapis.com,
139
+ +.gvt1.com,
140
+ ],
141
+ }
142
+ external-controller-cors:
143
+ allow-private-network: true
144
+ allow-origins:
145
+ - "*"
146
+ proxies: []
147
+ proxy-providers: {}
148
+ proxy-groups: []
149
+ rule-providers: {}
150
+ rules: []
models/__init__.py ADDED
File without changes
@@ -0,0 +1,45 @@
1
+ from typing import Literal
2
+
3
+ from pydantic import BaseModel, Field, field_validator
4
+
5
+
6
+ class BidScoreRequest(BaseModel):
7
+ cards: str = Field(..., min_length=17, max_length=17, description="cards str")
8
+
9
+
10
+ class PreGameScoreRequest(BaseModel):
11
+ cards: str = Field(..., description="cards str")
12
+ three: str = Field(..., min_length=3, max_length=3, description="三张底牌")
13
+ position_code: Literal["0", "1", "2"] = Field(
14
+ ...,
15
+ description="0:我是地主上家,1:我是地主,2:我是地主下家",
16
+ )
17
+
18
+ @field_validator("cards")
19
+ def validate_cards_length(cls, v):
20
+ if len(v) not in [17, 20]:
21
+ raise ValueError("cards length must be either 17 or 20")
22
+ return v
23
+
24
+
25
+ class PlayRequest(BaseModel):
26
+ cards: str = Field(..., description="开局前的手牌,17或20张")
27
+ other_cards: str | None = Field("", description="开局前其他玩家手牌,34张或37张")
28
+ played_list: list[str] = Field([], description="played list")
29
+ three: str = Field(..., min_length=3, max_length=3, description="三张底牌")
30
+ position_code: Literal[0, 1, 2] = Field(
31
+ ...,
32
+ description="0:地主在右边;1:我是地主;2:地主在左边",
33
+ )
34
+
35
+ @field_validator("cards")
36
+ def validate_cards_length(cls, v):
37
+ if len(v) not in [17, 20]:
38
+ raise ValueError("cards length must be either 17 or 20")
39
+ return v
40
+
41
+ @field_validator("other_cards")
42
+ def validate_other_cards_length(cls, v):
43
+ if len(v) not in [37, 34, 0] and v is not None:
44
+ raise ValueError("cards length must be either 37 or 34")
45
+ return v
models/ocr_model.py ADDED
@@ -0,0 +1,57 @@
1
+ from typing import List, Literal, Optional
2
+
3
+ from pydantic import BaseModel, Field
4
+
5
+
6
+ class FindCardsRequest(BaseModel):
7
+ img: str = Field(..., min_length=100, description="img base64 string")
8
+ region: Optional[List[int]] = Field(
9
+ None, min_length=4, max_length=4, description="识别区域[x,y,w,h]"
10
+ )
11
+ is_align_y: bool = Field(False, description="是否对齐Y轴")
12
+ is_preprocess: bool = Field(
13
+ True, description="是否预处理图片,如何识别效果不好,可以预处理"
14
+ )
15
+
16
+
17
+ class FindOneRequest(BaseModel):
18
+ img: str = Field(..., min_length=100, description="img base64 string")
19
+ target: str | None = Field(None, description="需识别的目标文本")
20
+ region: Optional[List[int]] = Field(
21
+ None, min_length=4, max_length=4, description="识别区域[x,y,w,h]"
22
+ )
23
+ is_preprocess: bool = Field(
24
+ True, description="是否预处理图片,如何识别效果不好,可以预处理"
25
+ )
26
+
27
+
28
+ class FindNRequest(BaseModel):
29
+ img: str = Field(..., min_length=100, description="img base64 string")
30
+ target_list: List[str] = Field(..., description="需识别的N个目标列表")
31
+ region: Optional[List[int]] = Field(
32
+ None, min_length=4, max_length=4, description="识别区域[x,y,w,h]"
33
+ )
34
+ is_preprocess: bool = Field(
35
+ True, description="是否预处理图片,如何识别效果不好,可以预处理"
36
+ )
37
+
38
+
39
+ class Region(BaseModel):
40
+ region: List[int] = Field(
41
+ ..., min_length=4, max_length=4, description="识别区域[x,y,w,h]"
42
+ )
43
+ type: Literal["list", "text", "cards"] = Field(..., description="识别类型")
44
+ is_align_y: bool = Field(False, description="是否对齐Y轴")
45
+ target_list: List[str] = Field([], description="需识别的目标文本列表")
46
+ target: str = Field("", description="需识别的目标文本")
47
+ is_preprocess: bool = Field(
48
+ False, description="是否预处理图片,如何识别效果不好,可以预处理"
49
+ )
50
+
51
+
52
+ class FindRegionsRequest(BaseModel):
53
+ img: str = Field(..., min_length=100, description="img base64 string")
54
+ regions: List[Region] = Field(..., description="识别区域配置")
55
+ is_preprocess: bool = Field(
56
+ False, description="是否预处理图片,如何识别效果不好,可以预处理"
57
+ )
models/response.py ADDED
@@ -0,0 +1,37 @@
1
+ from typing import Any, Generic, Optional, TypeVar
2
+
3
+ from pydantic import BaseModel
4
+
5
+ T = TypeVar("T")
6
+
7
+
8
+ class StandardResponse(BaseModel, Generic[T]):
9
+ """标准API响应模型"""
10
+
11
+ success: bool = True
12
+ data: Optional[T] = None
13
+ error: Optional[str] = None
14
+
15
+ class Config:
16
+ json_schema_extra = {
17
+ "example": {
18
+ "success": True,
19
+ "data": {},
20
+ "error": None,
21
+ }
22
+ }
23
+
24
+
25
+ # 定义常用的具体响应类型
26
+ class SuccessResponse(StandardResponse[T]):
27
+ """成功响应"""
28
+
29
+ success: bool = True
30
+
31
+
32
+ class ErrorResponse(StandardResponse):
33
+ """错误响应"""
34
+
35
+ success: bool = False
36
+ error: Optional[str] = None
37
+ data: Optional[Any] = None
@@ -0,0 +1,45 @@
1
+ Metadata-Version: 2.4
2
+ Name: pymecli
3
+ Version: 0.2.5
4
+ Summary: My CLI
5
+ Project-URL: Homepage, https://pypi.org/project/pymecli
6
+ Project-URL: Repository, https://github.com/meme2046/pymecli
7
+ License: MIT
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Requires-Python: <=3.12,>=3.10
12
+ Requires-Dist: arrow>=1.4.0
13
+ Requires-Dist: babel>=2.17.0
14
+ Requires-Dist: cowsay>=6.1
15
+ Requires-Dist: dotenv>=0.9.9
16
+ Requires-Dist: fastapi>=0.127.0
17
+ Requires-Dist: numpy<2.0.0
18
+ Requires-Dist: pandas>=2.3.3
19
+ Requires-Dist: pydantic-settings>=2.12.0
20
+ Requires-Dist: pymysql>=1.1.2
21
+ Requires-Dist: pytz>=2025.2
22
+ Requires-Dist: pyyaml>=6.0.3
23
+ Requires-Dist: redis[hiredis]>=7.1.0
24
+ Requires-Dist: requests[socks]>=2.32.5
25
+ Requires-Dist: sqlalchemy>=2.0.45
26
+ Requires-Dist: toml>=0.10.2
27
+ Requires-Dist: typer>=0.20.1
28
+ Requires-Dist: uvicorn>=0.40.0
29
+ Description-Content-Type: text/markdown
30
+
31
+ # typer example
32
+
33
+ ```shell
34
+ uv run example hello
35
+ uv run example hello Xiaoming
36
+ uv run example goodbye
37
+ uv run example goodbye Xiaoming
38
+ uv run example goodbye Xiaoming -f
39
+ ```
40
+
41
+ # fastapi server
42
+
43
+ ```shell
44
+ uv run fast --port 8877
45
+ ```
@@ -0,0 +1,39 @@
1
+ api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ api/v1/__init__.py,sha256=qaYn2kAw041YfY2rQEu6l3n_WlKaxi2ON-dJy5wxaW8,277
3
+ api/v1/clash.py,sha256=S-QpEhCq-9WI_rvS5Hk74noCBVnzzgAIzKyTihrF7k0,1238
4
+ api/v1/redis.py,sha256=Ble6mrt23nx-4hdccMta-8ATVolrWyTvNPui-x_6VAQ,625
5
+ cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ cli/bitget.py,sha256=J5dwhYY3AivYQ24SufbMHoMUZMRpU2R6VegQhlW6-HY,1447
7
+ cli/example.py,sha256=eV-vuFfjy0K-AUiJNzcjqt-tcDsW1NIypCzB0Gpwphw,617
8
+ cli/fast.py,sha256=rSlouCDbzY1Kwn7MRbxIvYuPMxqBFUYaMZYrRIT1urg,4545
9
+ cli/gate.py,sha256=m9eDevnQVWoMXbZDZruDm1H4frHblW69FBx-tQgLlNM,410
10
+ cli/util.py,sha256=nGEQDbDnNc74Ce0te7uaI3dazahSevWFQRfkywXHvFw,2600
11
+ core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
+ core/clash.py,sha256=qoolygkEK4jqhTZdgq8K7S4G8BvQ7bTKh2-mPHdO32A,9648
13
+ core/config.py,sha256=HQidRndTPnVXMt1Q54Mydb8i1LTsemKxZ_ZOuWtXe18,957
14
+ core/redis_client.py,sha256=FWVkbzjrNy98yPSUOhyjtxQF9mS31OM4FOW4q9Qgfl0,3886
15
+ crypto/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ crypto/bitget.py,sha256=96M3n7NOP0H7L_wbUaVczis1bGEA-LKgY6upsblF8Co,4293
17
+ crypto/gate.py,sha256=PnoFjag5LQ1i9oKaZsi2IKcI9bNE5W1BB5XI40E4brc,1537
18
+ data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
+ data/dou_dict.py,sha256=CPqAfjx0YgBnRvy2aiJZl9Hcqe5gbRDVz3oarVId3OA,5287
20
+ data/dou_list.py,sha256=DKAs0YyFQ7izNacaWmaX9Tjh-IP3h6IE7gPP9maQvNw,1019
21
+ data/main.py,sha256=r3JVMaI_wi_NnnlyM8nlfIDtc_Cjpnz3HUlFIKlAxtw,136
22
+ data/template.yaml,sha256=t7l0sIZyBOb0zMNsRaKRCZc0ADnFQ9I2kXQgCQjSeJA,3953
23
+ models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
+ models/douzero_model.py,sha256=XmM1QIP6rnfoSBcQsZvdCUjhWB3uEjlEA_GqagOHgGU,1670
25
+ models/ocr_model.py,sha256=UZP1S2hvl0K3eEoRMh6gRHo8xVBp9PTfRtE0_zd09Mw,2358
26
+ models/response.py,sha256=itUfkxm9W6XC6YuGAzZdkuKr7jxTibuph5OBeebsaQQ,781
27
+ utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
+ utils/elapsed.py,sha256=pCPQcf1U9gx4gLPqLf32HDLmQqVcy5yqGzplD5spf2A,410
29
+ utils/helper.py,sha256=787H45n_zZdjKe-HnSRSuqDAKoXRSyfob6kM0_TszDw,240
30
+ utils/logger.py,sha256=yscf2nU8XO1LqgvU31m1ipcmfZj5b6BaQtEqaLCm03Y,1084
31
+ utils/mysql.py,sha256=P2-gkdOuaa2aZ0ElRPqexfCEHozmjbe0oGkTtV9aIy4,2315
32
+ utils/pd.py,sha256=IRI9t7N_Vdbeylx_9iDxLuAwe-26AJ57-JJ6CWszJvg,582
33
+ utils/sleep.py,sha256=l-e316xdAS5ha83C4bm8anieeut7qaA_a7C2yoXzB00,438
34
+ utils/text.py,sha256=9_pMIrRzIfEOoj7TZpt1eZfTWI_1g8D5a6joaWEBUXw,877
35
+ utils/toml.py,sha256=8bN_At6Ajlq6frqk67LqXctU-Hw0YmpRTh0jlT4SbA4,119
36
+ pymecli-0.2.5.dist-info/METADATA,sha256=Vz3fBENCs8zFk-Eydz2_7XZFXwS__TxqNlMXcO1lI8A,1166
37
+ pymecli-0.2.5.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
38
+ pymecli-0.2.5.dist-info/entry_points.txt,sha256=sIgdM6PVsx6ZBaTecV3oA0NO8_kiEHzih9SRY8fK64A,134
39
+ pymecli-0.2.5.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.28.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,6 @@
1
+ [console_scripts]
2
+ bitget = cli.bitget:app
3
+ example = cli.example:app
4
+ fast = cli.fast:typer_app
5
+ gate = cli.gate:app
6
+ util = cli.util:app
utils/__init__.py ADDED
File without changes
utils/elapsed.py ADDED
@@ -0,0 +1,18 @@
1
+ import time
2
+ from functools import wraps
3
+
4
+ from utils.logger import get_logger
5
+
6
+ logger = get_logger(__name__)
7
+
8
+
9
+ def timeit(func):
10
+ @wraps(func)
11
+ def wrapper(*args, **kwargs):
12
+ t0 = time.perf_counter()
13
+ res = func(*args, **kwargs)
14
+ t1 = time.perf_counter()
15
+ logger.info(f"{func.__name__} 执行时间: {t1 - t0:.3f} 秒")
16
+ return res
17
+
18
+ return wrapper
utils/helper.py ADDED
@@ -0,0 +1,9 @@
1
+ import numpy as np
2
+
3
+
4
+ def process_bounding_box(box_data):
5
+ """处理边界框数据的辅助函数"""
6
+ try:
7
+ return np.asarray(box_data).reshape(4, 2).tolist()
8
+ except (ValueError, AttributeError):
9
+ return []