efb-qq-plugin-go-cqhttp/efb_qq_plugin_go_cqhttp/Utils.py

781 lines
17 KiB
Python
Raw Normal View History

2021-02-15 15:32:47 +00:00
import logging
import tempfile
import urllib.request
from gettext import translation
2022-02-05 12:58:20 +00:00
from urllib.error import ContentTooShortError, HTTPError, URLError
2021-02-15 15:32:47 +00:00
2022-03-06 08:48:26 +00:00
import pilk
import pydub
2021-02-15 15:32:47 +00:00
from ehforwarderbot import Message, coordinator
from pkg_resources import resource_filename
2022-02-05 12:58:20 +00:00
# created by JogleLew and jqqqqqqqqqq, optimized based on Tim's emoji support, updated by xzsk2 to mobileqq v8.8.11
qq_emoji_list = {
0: "😮",
1: "😣",
2: "😍",
3: "😳",
4: "😎",
5: "😭",
6: "☺️",
7: "😷",
8: "😴",
9: "😭",
10: "😰",
11: "😡",
12: "😝",
13: "😃",
14: "🙂",
15: "🙁",
16: "🤓",
17: "[Empty]",
18: "😤",
19: "😨",
20: "😏",
21: "😊",
22: "🙄",
23: "😕",
24: "🤤",
25: "😪",
26: "😨",
27: "😓",
28: "😬",
29: "🤑",
30: "",
31: "😤",
32: "🤔",
33: "🤐",
34: "😵",
35: "😩",
36: "💣",
37: "💀",
38: "🔨",
39: "👋",
40: "[Empty]",
41: "😮",
42: "💑",
43: "🕺",
44: "[Empty]",
45: "[Empty]",
46: "🐷",
47: "[Empty]",
48: "[Empty]",
49: "🤷",
50: "[Empty]",
51: "[Empty]",
52: "[Empty]",
53: "🎂",
54: "",
55: "💣",
56: "🔪",
57: "⚽️",
58: "[Empty]",
59: "💩",
60: "☕️",
61: "🍚",
62: "[Empty]",
63: "🌹",
64: "🥀",
65: "[Empty]",
66: "❤️",
67: "💔️",
68: "[Empty]",
69: "🎁",
70: "[Empty]",
71: "[Empty]",
72: "[Empty]",
73: "[Empty]",
74: "🌞️",
75: "🌃",
76: "👍",
77: "👎",
78: "🤝",
79: "✌️",
80: "[Empty]",
81: "[Empty]",
82: "[Empty]",
83: "[Empty]",
84: "[Empty]",
85: "🥰",
86: "[怄火]",
87: "[Empty]",
88: "[Empty]",
89: "🍉",
90: "[Empty]",
91: "[Empty]",
92: "[Empty]",
93: "[Empty]",
94: "[Empty]",
95: "[Empty]",
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: "[Empty]",
136: "[双喜]",
137: "🧨",
138: "🏮",
139: "💰",
140: "[K歌]",
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: "[doge]",
180: "[惊喜]",
181: "[骚扰]",
182: "😹",
183: "[我最美]",
184: "🦀",
185: "[羊驼]",
186: "[Empty]",
187: "👻",
188: "🥚",
189: "[Empty]",
190: "🌼",
191: "[Empty]",
192: "🧧",
193: "😄",
194: "😞",
195: "[Empty]",
196: "[Empty]",
197: "[冷漠]",
198: "[呃]",
199: "👍",
200: "👋",
201: "👍",
202: "[无聊]",
203: "[托脸]",
204: "[吃]",
205: "💐",
206: "😨",
207: "[花痴]",
208: "[小样儿]",
209: "[Empty]",
210: "😭",
211: "[我不看]",
212: "[托腮]",
213: "[Empty]",
214: "😙",
215: "[糊脸]",
216: "[拍头]",
217: "[扯一扯]",
218: "[舔一舔]",
219: "[蹭一蹭]",
220: "[拽炸天]",
221: "[顶呱呱]",
222: "🤗",
223: "[暴击]",
224: "🔫",
225: "[撩一撩]",
226: "[拍桌]",
227: "👏",
228: "[恭喜]",
229: "🍻",
230: "[嘲讽]",
231: "[哼]",
232: "[佛系]",
233: "[掐一掐]",
234: "😮",
235: "[颤抖]",
236: "[啃头]",
237: "[偷看]",
238: "[扇脸]",
239: "[原谅]",
240: "[喷脸]",
241: "🎂",
242: "[头撞击]",
243: "[甩头]",
244: "[扔狗]",
245: "[加油必胜]",
246: "[加油抱抱]",
247: "[口罩护体]",
248: "[Empty]",
249: "[Empty]",
250: "[Empty]",
251: "[Empty]",
252: "[Empty]",
253: "[Empty]",
254: "[Empty]",
255: "[Empty]",
256: "😲",
257: "😟",
258: "😍",
259: "😳",
260: "[搬砖中]",
261: "[忙到飞起]",
262: "[脑阔疼]",
263: "[沧桑]",
264: "[捂脸]",
265: "[辣眼睛]",
266: "[哦哟]",
267: "[头秃]",
268: "[问号脸]",
269: "[暗中观察]",
270: "[emm]",
271: "[吃瓜]",
272: "[呵呵哒]",
273: "[我酸了]",
274: "[太南了]",
275: "[Empty]",
276: "[辣椒酱]",
277: "[汪汪]",
278: "[汗]",
279: "[打脸]",
280: "[击掌]",
281: "[无眼笑]",
282: "[敬礼]",
283: "[狂笑]",
284: "[面无表情]",
285: "[摸鱼]",
286: "[魔鬼笑]",
287: "[哦]",
288: "[请]",
289: "[睁眼]",
290: "[敲开心]",
291: "[震惊]",
292: "[让我康康]",
293: "[摸锦鲤]",
294: "[期待]",
295: "[拿到红包]",
296: "[真好]",
297: "[拜谢]",
298: "[元宝]",
299: "[牛啊]",
300: "[胖三斤]",
301: "[好闪]",
302: "[左拜年]",
303: "[右拜年]",
304: "[红包包]",
305: "[右亲亲]",
306: "[牛气冲天]",
307: "[喵喵]",
308: "[求红包]",
309: "[谢红包]",
310: "[新年烟花]",
311: "[打call]",
312: "[变形]",
313: "[嗑到了]",
314: "[仔细分析]",
315: "[加油]",
316: "[我没事]",
317: "[菜狗]",
318: "[崇拜]",
319: "[比心]",
320: "[庆祝]",
321: "[老色痞]",
322: "[拒绝]",
323: "[嫌弃]",
2021-02-15 15:32:47 +00:00
}
# original text copied from Tim
qq_emoji_text_list = {
2022-02-05 12:58:20 +00:00
0: "[惊讶]",
1: "[撇嘴]",
2: "[色]",
3: "[发呆]",
4: "[得意]",
5: "[流泪]",
6: "[害羞]",
7: "[闭嘴]",
8: "[睡]",
9: "[大哭]",
10: "[尴尬]",
11: "[发怒]",
12: "[调皮]",
13: "[呲牙]",
14: "[微笑]",
15: "[难过]",
16: "[酷]",
17: "[Empty]",
18: "[抓狂]",
19: "[吐]",
20: "[偷笑]",
21: "[可爱]",
22: "[白眼]",
23: "[傲慢]",
24: "[饥饿]",
25: "[困]",
26: "[惊恐]",
27: "[流汗]",
28: "[憨笑]",
29: "[悠闲]",
30: "[奋斗]",
31: "[咒骂]",
32: "[疑问]",
33: "[嘘]",
34: "[晕]",
35: "[折磨]",
36: "[衰]",
37: "[骷髅]",
38: "[敲打]",
39: "[再见]",
40: "[Empty]",
41: "[发抖]",
42: "[爱情]",
43: "[跳跳]",
44: "[Empty]",
45: "[Empty]",
46: "[猪头]",
47: "[Empty]",
48: "[Empty]",
49: "[拥抱]",
50: "[Empty]",
51: "[Empty]",
52: "[Empty]",
53: "[蛋糕]",
54: "[闪电]",
55: "[炸弹]",
56: "[刀]",
57: "[足球]",
58: "[Empty]",
59: "[便便]",
60: "[咖啡]",
61: "[饭]",
62: "[Empty]",
63: "[玫瑰]",
64: "[凋谢]",
65: "[Empty]",
66: "[爱心]",
67: "[心碎]",
68: "[Empty]",
69: "[礼物]",
70: "[Empty]",
71: "[Empty]",
72: "[Empty]",
73: "[Empty]",
74: "[太阳]",
75: "[月亮]",
76: "[赞]",
77: "[踩]",
78: "[握手]",
79: "[胜利]",
80: "[Empty]",
81: "[Empty]",
82: "[Empty]",
83: "[Empty]",
84: "[Empty]",
85: "[飞吻]",
86: "[怄火]",
87: "[Empty]",
88: "[Empty]",
89: "[西瓜]",
90: "[Empty]",
91: "[Empty]",
92: "[Empty]",
93: "[Empty]",
94: "[Empty]",
95: "[Empty]",
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: "[NO]",
124: "[OK]",
125: "[转圈]",
126: "[磕头]",
127: "[回头]",
128: "[跳绳]",
129: "[挥手]",
130: "[激动]",
131: "[街舞]",
132: "[献吻]",
133: "[左太极]",
134: "[右太极]",
135: "[Empty]",
136: "[双喜]",
137: "[鞭炮]",
138: "[灯笼]",
139: "[发财]",
140: "[K歌]",
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: "[doge]",
180: "[惊喜]",
181: "[骚扰]",
182: "[笑哭]",
183: "[我最美]",
184: "[河蟹]",
185: "[羊驼]",
186: "[Empty]",
187: "[幽灵]",
188: "[蛋]",
189: "[Empty]",
190: "[菊花]",
191: "[Empty]",
192: "[红包]",
193: "[大笑]",
194: "[不开心]",
195: "[Empty]",
196: "[Empty]",
197: "[冷漠]",
198: "[呃]",
199: "[好棒]",
200: "[拜托]",
201: "[点赞]",
202: "[无聊]",
203: "[托脸]",
204: "[吃]",
205: "[送花]",
206: "[害怕]",
207: "[花痴]",
208: "[小样儿]",
209: "[Empty]",
210: "[飙泪]",
211: "[我不看]",
212: "[托腮]",
213: "[Empty]",
214: "[啵啵]",
215: "[糊脸]",
216: "[拍头]",
217: "[扯一扯]",
218: "[舔一舔]",
219: "[蹭一蹭]",
220: "[拽炸天]",
221: "[顶呱呱]",
222: "[抱抱]",
223: "[暴击]",
224: "[开枪]",
225: "[撩一撩]",
226: "[拍桌]",
227: "[拍手]",
228: "[恭喜]",
229: "[干杯]",
230: "[嘲讽]",
231: "[哼]",
232: "[佛系]",
233: "[掐一掐]",
234: "[惊呆]",
235: "[颤抖]",
236: "[啃头]",
237: "[偷看]",
238: "[扇脸]",
239: "[原谅]",
240: "[喷脸]",
241: "[生日快乐]",
242: "[Empty]",
243: "[Empty]",
244: "[Empty]",
245: "[Empty]",
246: "[Empty]",
247: "[Empty]",
248: "[Empty]",
249: "[Empty]",
250: "[Empty]",
251: "[Empty]",
252: "[Empty]",
253: "[Empty]",
254: "[Empty]",
255: "[Empty]",
2021-02-15 15:32:47 +00:00
}
qq_sface_list = {
2022-02-05 12:58:20 +00:00
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: "[眨眼]",
2021-02-15 15:32:47 +00:00
}
2022-02-05 12:58:20 +00:00
translator = translation(
"efb_qq_slave",
resource_filename("efb_qq_slave", "Clients/CoolQ/locale"),
fallback=True,
)
2021-02-15 15:32:47 +00:00
_ = translator.gettext
ngettext = translator.ngettext
def cq_get_image(image_link: str) -> tempfile: # Download image from QQ
file = tempfile.NamedTemporaryFile()
try:
urllib.request.urlretrieve(image_link, file.name)
except (URLError, HTTPError, ContentTooShortError) as e:
2022-02-05 12:58:20 +00:00
logging.getLogger(__name__).warning("Image download failed.")
2021-02-15 15:32:47 +00:00
logging.getLogger(__name__).warning(str(e))
return None
else:
if file.seek(0, 2) <= 0:
2022-02-05 12:58:20 +00:00
raise EOFError("File downloaded is Empty")
2021-02-15 15:32:47 +00:00
file.seek(0)
return file
def async_send_messages_to_master(msg: Message):
coordinator.send_message(msg)
if msg.file:
msg.file.close()
def process_quote_text(text, max_length): # Simple wrapper for processing quoted text
qt_txt = "%s" % text
if max_length > 0:
tgt_text = qt_txt[:max_length]
if len(qt_txt) >= max_length:
tgt_text += ""
tgt_text = "%s" % tgt_text
elif max_length < 0:
tgt_text = "%s" % qt_txt
else:
tgt_text = ""
return tgt_text
def coolq_text_encode(text: str): # Escape special characters for CQ Code text
2022-02-05 12:58:20 +00:00
expr = (("&", "&amp;"), ("[", "&#91;"), ("]", "&#93;"))
2021-02-15 15:32:47 +00:00
for r in expr:
text = text.replace(*r)
return text
def coolq_para_encode(text: str): # Escape special characters for CQ Code parameters
2022-02-05 12:58:20 +00:00
expr = (("&", "&amp;"), ("[", "&#91;"), ("]", "&#93;"), (",", "&#44;"))
2021-02-15 15:32:47 +00:00
for r in expr:
text = text.replace(*r)
return text
def param_spliter(str_param):
params = str_param.split(";")
param = {}
for _k in params:
key, value = _k.strip().split("=")
param[key] = value
return param
2021-05-30 17:16:50 +00:00
def download_file(download_url):
2021-02-15 15:32:47 +00:00
file = tempfile.NamedTemporaryFile()
try:
opener = urllib.request.build_opener()
urllib.request.install_opener(opener)
urllib.request.urlretrieve(download_url, file.name)
except (URLError, HTTPError, ContentTooShortError) as e:
logging.getLogger(__name__).warning("Error occurs when downloading files: " + str(e))
return _("Error occurs when downloading files: ") + str(e)
else:
if file.seek(0, 2) <= 0:
2022-02-05 12:58:20 +00:00
raise EOFError("File downloaded is Empty")
2021-02-15 15:32:47 +00:00
file.seek(0)
return file
def download_user_avatar(uid: str):
file = tempfile.NamedTemporaryFile()
url = "https://q1.qlogo.cn/g?b=qq&nk={}&s=0".format(uid)
try:
opener = urllib.request.build_opener()
urllib.request.install_opener(opener)
urllib.request.urlretrieve(url, file.name)
except (URLError, HTTPError, ContentTooShortError) as e:
logging.getLogger(__name__).warning("Error occurs when downloading files: " + str(e))
return _("Error occurs when downloading files: ") + str(e)
if file.seek(0, 2) <= 0:
2022-02-05 12:58:20 +00:00
raise EOFError("File downloaded is Empty")
2021-02-15 15:32:47 +00:00
file.seek(0)
return file
def download_group_avatar(uid: str):
file = tempfile.NamedTemporaryFile()
url = "https://p.qlogo.cn/gh/{}/{}/".format(uid, uid)
try:
opener = urllib.request.build_opener()
urllib.request.install_opener(opener)
urllib.request.urlretrieve(url, file.name)
except (URLError, HTTPError, ContentTooShortError) as e:
logging.getLogger(__name__).warning("Error occurs when downloading files: " + str(e))
return _("Error occurs when downloading files: ") + str(e)
if file.seek(0, 2) <= 0:
2022-02-05 12:58:20 +00:00
raise EOFError("File downloaded is Empty")
2021-02-15 15:32:47 +00:00
file.seek(0)
return file
2022-03-06 08:48:26 +00:00
def download_voice(voice_url: str):
with tempfile.NamedTemporaryFile() as origin_file:
try:
with urllib.request.build_opener() as opener:
urllib.request.install_opener(opener)
urllib.request.urlretrieve(voice_url, origin_file.name)
except (URLError, HTTPError, ContentTooShortError) as e:
logging.getLogger(__name__).warning("Error occurs when downloading files: " + str(e))
return _("Error occurs when downloading files: ") + str(e)
if origin_file.seek(0, 2) <= 0:
raise EOFError("File downloaded is Empty")
origin_file.seek(0)
silk_header = origin_file.read(10)
origin_file.seek(0)
if b"#!SILK_V3" in silk_header:
with tempfile.NamedTemporaryFile() as pcm_file:
pilk.decode(origin_file.name, pcm_file.name)
audio_file = tempfile.NamedTemporaryFile()
pydub.AudioSegment.from_raw(file=pcm_file, sample_width=2, frame_rate=24000, channels=1).export(
audio_file, format="ogg", codec="libopus", parameters=["-vbr", "on"]
)
else:
audio_file = origin_file
return audio_file