generated from CaiJimmy/hugo-theme-stack-starter
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
185 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
--- | ||
title: "快捷翻译脚本" | ||
author: "Li, Caleb Chaoqun" | ||
date: "2024-8-17" | ||
description: "通过快捷键将剪切板中的内容进行翻译,并将结果放到剪切板中。" | ||
typora-copy-images-to: "" | ||
tags: | ||
- "Python" | ||
- "翻译" | ||
- "实用工具" | ||
--- | ||
|
||
```python | ||
""" | ||
通过监听快捷键快速实现指定功能。 | ||
监听快捷键 [Alt + O], 从剪切板拿到图片数据,通过调用腾讯AI的OCR接口,获得返回后的文本,将OCR的文本放入剪切板中。 | ||
Python Version: 3.12.2 | ||
依赖: | ||
win10toast==0.9 -- 向操作系统发送通知 | ||
pywin32==223 -- Windons API 库 | ||
Pillow==10.4.0 -- PIL 图像处理库 | ||
keyboard==0.13.5 -- 使用这个小型Python库完全控制你的键盘。挂钩全局事件、注册热键、模拟按键等等。 | ||
requests==2.32.3 -- HTTP请求库 | ||
快速安装: | ||
pip install win10toast==0.9 pywin32==223 Pillow==10.4.0 keyboard==0.13.5 requests==2.32.3 | ||
""" | ||
|
||
import base64 | ||
import datetime | ||
import io | ||
import json | ||
import logging | ||
import random | ||
import hashlib | ||
import hmac | ||
import time | ||
import functools | ||
from pathlib import Path | ||
from urllib.parse import urlparse | ||
|
||
import requests | ||
import keyboard | ||
import pyperclip | ||
import win32clipboard as wc | ||
from PIL import Image | ||
from win10toast import ToastNotifier | ||
|
||
logger = logging.getLogger("root") | ||
FILE_DIR = Path(__file__).parent.absolute() | ||
keys = json.loads(FILE_DIR.joinpath("self_config.json").read_text()) | ||
s_keys = keys["tencent_key"] | ||
|
||
|
||
def send_notication(title, text, duration=3): | ||
ToastNotifier().show_toast(title=title, msg=text, duration=duration, threaded=True) | ||
|
||
|
||
def get_image_from_clipboard(): | ||
try: | ||
wc.OpenClipboard() | ||
if wc.IsClipboardFormatAvailable(wc.CF_DIB): | ||
# Get the device-independent bitmap (DIB) format data | ||
dib = wc.GetClipboardData(wc.CF_DIB) | ||
return Image.open(io.BytesIO(dib)) | ||
except Exception as e: | ||
logger.error(f"Error reading image from clipboard: {e}") | ||
return 0 | ||
finally: | ||
wc.CloseClipboard() | ||
|
||
|
||
def most_english(text) -> bool: | ||
"""字符串中大多数是英语""" | ||
if len(text) == 0: | ||
raise ValueError("空字符串.") | ||
ec_num = 0 | ||
for c in text: | ||
if c.isalpha and "a" <= c.lower() <= "z": | ||
ec_num += 1 | ||
if ec_num / len(text) > 0.5: | ||
return True | ||
return False | ||
|
||
|
||
@functools.lru_cache(25) | ||
def translate_api(text, from_lang="auto", to_lang="zh") -> list[dict[str, str]]: | ||
"""翻译API, | ||
return src, dst | ||
""" | ||
url = "http://api.fanyi.baidu.com/api/trans/vip/translate" | ||
salt = random.randint(32768, 65536) | ||
appid, appkey = keys["baidu_translate"] | ||
sign = hashlib.md5((appid + text + str(salt) + appkey).encode("utf-8")).hexdigest() | ||
resp = requests.post( | ||
url=url, | ||
headers={"Content-Type": "application/x-www-form-urlencoded"}, | ||
params={ | ||
"appid": appid, | ||
"q": text, | ||
"from": from_lang, | ||
"to": to_lang, | ||
"salt": salt, | ||
"sign": sign, | ||
}, | ||
) | ||
if resp.status_code != 200: | ||
raise Exception(resp.text()) | ||
return resp.json().get("trans_result") | ||
|
||
|
||
def translate_iamge(image_data: bytes, from_lang="auto", to_lang="zh") -> list: | ||
"""""" | ||
url = "http://fanyi-api.baidu.com/api/trans/sdk/picture" | ||
salt = random.randint(32768, 65536) | ||
appid = "20240531002066479" | ||
appkey = "05IgcgzWKnf5J7hDKlyK" | ||
file_md5 = hashlib.md5(image_data).hexdigest() | ||
cuid, mac = "APICUID", "mac" | ||
sign = hashlib.md5( | ||
(appid + file_md5 + str(salt) + cuid + mac + appkey).encode() | ||
).hexdigest() | ||
payload = { | ||
"from": from_lang, | ||
"to": to_lang, | ||
"appid": appid, | ||
"salt": salt, | ||
"sign": sign, | ||
"cuid": cuid, | ||
"mac": mac, | ||
} | ||
image = {"image": ("translate-iamge", image_data, "multipart/form-data")} | ||
resp = requests.post(url, params=payload, files=image) | ||
if resp.status_code != 200: | ||
raise Exception(resp.text()) | ||
return resp.json().get("data", {}).get("content", []) | ||
|
||
|
||
|
||
def translate(): | ||
# 从剪贴板读取数据 | ||
keyboard.send("ctrl+c") | ||
clipb_data = pyperclip.paste() | ||
if not clipb_data: | ||
logger.error("翻译失败: 未从剪切板获取到数据") | ||
send_notication("翻译失败", "未从剪切板获取到数据") | ||
return | ||
|
||
logger.debug("剪贴板内容: %s", clipb_data) | ||
|
||
# 处理剪贴板数据 | ||
processed_data = translate_api( | ||
clipb_data, | ||
to_lang="zh" if most_english(clipb_data) else "en", | ||
) | ||
# processed_data = json.dumps(processed_data, ensure_ascii=False, indent=2) | ||
processed_data = "\n".join([l.get("dst") for l in processed_data]) | ||
|
||
# 将处理后的数据放回剪贴板 | ||
pyperclip.copy(processed_data) | ||
# keyboard.send("F3") | ||
send_notication("翻译结果已经放入剪切板", processed_data) | ||
logger.debug("处理后的数据已放回剪贴板: %s", processed_data) | ||
|
||
|
||
|
||
if __name__ == "__main__": | ||
# 注册快捷键组合 | ||
keyboard.add_hotkey("ctrl+alt+d", translate, suppress=False) | ||
|
||
print("""1. 监听快捷 [Ctrl+Alt+S], 从剪切板中得到拿到文本数据, 通过调用百度翻译的API接口翻译文本,将翻译后的数据放入剪切板中。 | ||
2. 监听快捷键 [Alt + O], 从剪切板拿到图片数据,通过调用腾讯AI的OCR接口,获得返回后的文本,将OCR的文本放入剪切板中。""") | ||
|
||
logging.basicConfig(level="DEBUG") | ||
|
||
# 保持程序运行,直到手动终止 | ||
keyboard.wait() | ||
|
||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters