-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
155 lines (135 loc) · 4.43 KB
/
main.py
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import os
import requests
import config
import sys
from concurrent.futures import ThreadPoolExecutor
from my_decorator import time_cal
ANKI_CONNECT_URL = "http://localhost:8765"
IMAGE_PATH = config.img_path
DECK_NAME = config.deck_name # 牌组名
def invoke(session: requests.Session, action: str, params: dict) -> dict:
"""
向anki connect 发送请求
"""
return session.post(
ANKI_CONNECT_URL, json={"action": action, "version": 6, "params": params}
).json()
def check_anki_connect(session: requests.Session) -> None:
"""
检查与anki connect插件的连接
"""
try:
response = invoke(session, "version", {})
if response.get("error") is None:
print(f"AnkiConnect 连接正常,版本:{response['result']}")
else:
print(f"AnkiConnect 连接失败: {response['error']}")
except requests.exceptions.ConnectionError:
print("AnkiConnect 连接失败,请确保Anki正在运行并启用了AnkiConnect插件。")
sys.exit(1)
def create_deck(session: requests.Session, deck_name: str) -> None:
"""
创建新的牌组
"""
result = invoke(session, "createDeck", {"deck": deck_name})
print(
f"成功创建牌组: {deck_name}"
if result.get("error") is None
else f"创建牌组失败: {result['error']}"
)
def check_template(session: requests.Session, template_name: str) -> None:
"""
检查anki中存不存在Baisc模板,不存在创建一个
"""
result = invoke(session, "modelNames", {})
if result.get("error") is not None:
print(f"获取模板名失败: {result['error']}")
sys.exit(1)
if "Basic" in result["result"]:
print(f"模板 {template_name} 已存在, 继续导入")
return
# 模板不存在, 创建模板
result = invoke(
session,
"createModel",
{
"modelName": "Basic",
"inOrderFields": ["Front", "Back"],
"css": """
.card {
font-family: arial;
font-size: 20px;
text-align: center;
color: black;
background-color: white;
}
""",
"cardTemplates": [
{
"Name": "Card 1",
"Front": "{{Front}}",
"Back": "{{FrontSide}}<hr id='answer'>{{Back}}",
}
],
},
)
print(
"成功创建模板: Basic"
if result.get("error") is None
else f"创建模板失败: {result['error']}"
)
def add_note_to_anki(
session: requests.Session, deck_name: str, image_file_name: str
) -> None:
note = {
"deckName": deck_name,
"modelName": "Basic",
"fields": {
"Front": f"<img src='{image_file_name}'>", # 只显示图片作为问题
"Back": "", # 答案为空
},
"options": {"allowDuplicate": False},
"tags": ["confusing_points"],
"picture": [
{
"filename": image_file_name,
"path": os.path.join(IMAGE_PATH, image_file_name),
"fields": ["Front"], # 图片应用于卡片的正面
}
],
}
result = invoke(session, "addNote", {"note": note})
if result.get("error") is None:
print(f"成功添加卡片: {image_file_name}")
else:
print(f"添加卡片失败: {result['error']}")
def import_image_to_anki(
session: requests.Session, deck_name: str, image_directory: str
):
"""
导入图片到anki牌组
"""
with ThreadPoolExecutor() as executor:
futures = []
try:
for image_file_name in os.listdir(image_directory):
if image_file_name.endswith(".jpg") or image_file_name.endswith(".png"):
futures.append(
executor.submit(
add_note_to_anki, session, deck_name, image_file_name
)
)
for future in futures:
future.result()
except OSError as e:
print(f"读取目录时出错: {e}")
sys.exit(1)
@time_cal
def main() -> None:
with requests.Session() as session:
check_anki_connect(session)
create_deck(session, DECK_NAME)
check_template(session, "Basic")
import_image_to_anki(session, DECK_NAME, IMAGE_PATH)
if __name__ == "__main__":
main()