-
Notifications
You must be signed in to change notification settings - Fork 4
/
cichang.py
198 lines (177 loc) · 7 KB
/
cichang.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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
import argparse
import hashlib
import json
from base64 import b64decode
import os
from random import shuffle, choice
import time
import tempfile
import requests
import telebot
import pendulum
from openai import OpenAI
from rich import print
import telegramify_markdown
if api_base := os.environ.get("OPENAI_API_BASE"):
client = OpenAI(base_url=api_base, api_key=os.environ.get("OPENAI_API_KEY"))
else:
client = OpenAI()
TIMEZONE = "Asia/Shanghai"
KEY = "NDVmZDE3ZTAyMDAzZDg5YmVlN2YwNDZiYjQ5NGRlMTM="
LOGIN_URL = "https://pass.hujiang.com/Handler/UCenter.json?action=Login&isapp=true&language=zh_CN&password={password}&timezone=8&user_domain=hj&username={user_name}"
COVERT_URL = "https://pass-cdn.hjapi.com/v1.1/access_token/convert"
# added in 2023.06.08
XIAOD_LIST_URL = "https://vocablist.hjapi.com/notebook/notebooklist?lastSyncDate=2000-01-01T00:00:00.000&lastSyncVer=0&syncVer=1"
XIAOD_ONE_NOTE_URL = "https://vocablist.hjapi.com/notebook/notewords?lastSyncDate=2000-01-01T00:00:00.000&lastSyncVer=0&nbookid={nbook_id}&oldnbookid=0&syncVer=1"
def md5_encode(string):
m = hashlib.md5()
m.update(string.encode())
return m.hexdigest()
####### XIAOD #######
def get_xiaod_notes_dict(s):
r = s.get(XIAOD_LIST_URL)
if not r.ok:
raise Exception("Can not note books info from hujiang")
d = {}
node_list = r.json()["data"]["noteList"]
for n in node_list:
d[n["nbookId"]] = n["nbookName"]
return d
def get_xiaod_words(s, nbook_id):
r = s.get(XIAOD_ONE_NOTE_URL.format(nbook_id=nbook_id))
if not r.ok:
raise Exception(f"Can not get words for nbook_id: {nbook_id}")
return r.json()
def login(user_name, password):
s = requests.Session()
password_md5 = md5_encode(password)
r = s.get(LOGIN_URL.format(user_name=user_name, password=password_md5))
if not r.ok:
raise Exception(f"Someting is wrong to login -- {r.text}")
club_auth_cookie = r.json()["Data"]["Cookie"]
data = {"club_auth_cookie": club_auth_cookie}
HJKEY = b64decode(KEY).decode()
headers = {"hj_appkey": HJKEY, "Content-Type": "application/json"}
# real login to get real token
r = s.post(COVERT_URL, headers=headers, data=json.dumps(data))
if not r.ok:
raise Exception(f"Get real token failed -- {r.text}")
access_token = r.json()["data"]["access_token"]
headers["Access-Token"] = access_token
s.headers = headers
return s
def make_xiaod_note(s):
now = pendulum.now(TIMEZONE)
note_dict = get_xiaod_notes_dict(s)
new_words = []
new_words_define = []
symbol_list = []
yesterday_words = []
yesterday_words_define = []
yesterday_symbol_list = []
for k, v in note_dict.items():
data = get_xiaod_words(s, k)
word_list = data["data"]["wordList"]
if not word_list:
continue
for word in word_list:
add_date = word["clientDateUpdated"]
add_date = pendulum.parse(add_date)
if add_date.day == now.day and add_date.month == now.month:
new_words.append(word["word"])
new_words_define.append(word["definition"])
symbol_list.append(word["symbol1"])
if (
add_date.day == now.subtract(days=1).day
and add_date.month == now.subtract(days=1).month
):
yesterday_words.append(word["word"])
yesterday_words_define.append(word["definition"])
yesterday_symbol_list.append(word["symbol1"])
if not new_words:
print("No new words today")
return yesterday_words, yesterday_words_define, yesterday_symbol_list
return new_words, new_words_define, symbol_list
def main(user_name, password, token, tele_token, tele_chat_id):
bot = telebot.TeleBot(tele_token)
try:
s = requests.Session()
HJKEY = b64decode(KEY).decode()
headers = {"hj_appkey": HJKEY, "Content-Type": "application/json"}
s.headers = headers
headers["Access-Token"] = token
word_list, word_define_list, symbol_list = make_xiaod_note(s)
except Exception as e:
bot.send_message(
tele_chat_id,
"toekn is invalid, try to login, please change the token in GitHub secret",
)
s = login(user_name, password)
word_list, word_define_list, symbol_list = make_xiaod_note(s)
# word
bot.send_message(tele_chat_id, "Today's words:\n" "\n".join(word_list))
# symbol
bot.send_message(tele_chat_id, "Symbol:\n" "\n".join(symbol_list))
# define
bot.send_message(tele_chat_id, "Definition:\n" "\n".join(word_define_list))
# ten words combine make a story using openai
shuffle(word_list)
words_chunk = [word_list[i : i 20] for i in range(0, len(word_list), 20)]
make_story_prompt = "Make a story using these words the story should be written in Japanese words: `{}`"
for chunk in words_chunk:
words = ",".join(chunk)
prompt = make_story_prompt.format(words)
try:
completion = client.chat.completions.create(
messages=[{"role": "user", "content": prompt}],
model="gpt-4o-2024-05-13",
)
head = "Words: " words "\n"
story = completion.choices[0].message.content.encode("utf8").decode()
audio = client.audio.speech.create(
model="tts-1",
voice=choice(["alloy", "echo", "fable", "onyx", "nova", "shimmer"]),
input=story,
)
print("Audio created")
# make all word in words to be bold
for word in chunk:
story = story.replace(word, f"*{word}*")
# create a temp mp3 file
with tempfile.NamedTemporaryFile(
prefix=f"words_{pendulum.now().to_date_string()}",
suffix=".mp3",
delete=False,
) as f:
speech_file_path = f.name
audio.write_to_file(speech_file_path)
content = head story
bot.send_audio(
tele_chat_id,
open(speech_file_path, "rb"),
caption=telegramify_markdown.convert(content),
)
# spdier rule
time.sleep(1)
except Exception as e:
print(str(e))
print("Can not make story")
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("user_name", help="hujiang_user_name")
parser.add_argument("password", help="hujiang_password")
parser.add_argument("token", help="token", default=None, nargs="?")
parser.add_argument(
"--tele_token", help="tele_token", nargs="?", default="", const=""
)
parser.add_argument(
"--tele_chat_id", help="tele_chat_id", nargs="?", default="", const=""
)
options = parser.parse_args()
main(
options.user_name,
options.password,
options.token,
options.tele_token,
options.tele_chat_id,
)