Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: feat: use deeplx to translate #58

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
"play-sound": "^1.1.6",
"qs": "^6.11.0",
"run-applescript": "^6.1.0",
"swr": "^2.2.5",
"tencentcloud-sdk-nodejs-tmt": "^4.0.559"
},
"devDependencies": {
Expand Down
20 changes: 19 additions & 1 deletion src/easydict.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*/

import { Icon, LaunchProps, List, getSelectedText } from "@raycast/api";
import { useEffect, useState } from "react";
import { useEffect, useMemo, useState } from "react";
import { configAxiosProxy, delayGetSystemProxy } from "./axiosConfig";
import { ListActionPanel, checkIfPreferredLanguagesConflict, getListItemIcon, getWordAccessories } from "./components";
import { DataManager } from "./dataManager/dataManager";
Expand All @@ -18,6 +18,8 @@ import { LanguageItem } from "./language/type";
import { myPreferences, preferredLanguage1 } from "./preferences";
import { DisplaySection } from "./types";
import { checkIfInstalledEudic, checkIfNeedShowReleasePrompt, trimTextLength } from "./utils";
import useSWR from "swr";
import { requestDeepLXTranslate } from "./translation/deepLX";

const disableConsoleLog = false;

Expand Down Expand Up @@ -235,6 +237,19 @@ export default function (props: LaunchProps<{ arguments: EasydictArguments }>) {
updateInputTextAndQueryText(text, true);
}

const queryInfo = useMemo(
() => ({
word: searchText,
fromLanguage: currentFromLanguageItem.youdaoLangCode,
toLanguage: userSelectedTargetLanguageItem.youdaoLangCode,
}),
[searchText, currentFromLanguageItem, userSelectedTargetLanguageItem]
);

const { data: deepLXResult } = useSWR(["deepLX", queryInfo], ([, wordInfo]: [string, QueryWordInfo]) =>
requestDeepLXTranslate(wordInfo)
);

return (
<List
isLoading={isLoadingState}
Expand Down Expand Up @@ -274,6 +289,9 @@ export default function (props: LaunchProps<{ arguments: EasydictArguments }>) {
</List.Section>
);
})}
<List.Section title="DeepLX">
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不不,不要这样写死固定一个 DeepLX 服务放这里,我们应该要让用户选择开启或关闭这些服务,具体你可以看一下设置页,里面甚至还支持服务顺序排序。

本来我希望直接复用已有的 DeepL 服务,只是对它进行一些优化,如果用户没有填写 DeepL API URL,就直接调用网页 API,这样实现起来最简单,你都不用改其他地方的代码。

如果你想添加一个单独的 DeepLX 也行,那就参考项目中已有的新增服务流程。

image

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

好的,我再重新改一下

{deepLXResult && <List.Item title={deepLXResult?.translations[0] ?? ""} subtitle={queryInfo.word} />}
</List.Section>
<List.EmptyView icon={Icon.BlankDocument} title="Type a word to look up or translate" />
</List>
);
Expand Down
2 changes: 1 addition & 1 deletion src/preferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export class AppKeyStore {
static volcanoSecretKey = myPreferences.volcanoAccessKeySecret.trim();

static openAIAPIKey = myPreferences.openAIAPIKey.trim();
static openAIEndpoint = myPreferences.openAIAPIURL.trim() || "https://api.openai.com/v1/chat/completions";
static openAIEndpoint = myPreferences.openAIAPIURL?.trim() || "https://api.openai.com/v1/chat/completions";
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里 myPreferences.openAIAPIURL 需要加 ? 吗

MyPreferences 定义

openAIAPIKey: string;

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typescript的定义只是提示,不影响真实运行中的值是不是undefined。我开发过程中刚启动的时候会报这个read property from undefined错误,我才加这个的。反正加了没什么缺点

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok,ts 我是野生实战派,水平有限,只要求代码能跑起来就行,没怎么注意代码细节 😥

期待你能优化改进这些问题。

static openAIModel = myPreferences.openAIModel.trim() || "gpt-3.5-turbo";
}

Expand Down
13 changes: 13 additions & 0 deletions src/translation/deepLX.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { QueryWordInfo } from "../dictionary/youdao/types";
import axios from "axios";

export const requestDeepLXTranslate = async (queryWordInfo: QueryWordInfo): Promise<{ translations: string[] }> => {
const body = await axios.post<{ data: string }>("https://deeplx.mingming.dev/translate", {
text: queryWordInfo.word,
Copy link
Owner

@tisfeng tisfeng Apr 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

虽然这是一个取巧的方式,但这样并不好。

  1. 这样依赖了一个别人提供的网络服务,这个服务不能保证一直能用。
  2. 这个服务也是使用 DeepL 网页接口,Raycast-Easydict 有几千用户,高频使用很可能会导致接口被 DeepL 官方封 IP。
  3. 即使是这个接口保证能使用,但毕竟是第三方的野生接口,部分用户会有隐私担忧。

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

其实我也搭了一个这样的 DeepL 接口,但一直没有直接开放给用户,就是有这些方面的担忧。

所以,这里优先直接使用网页接口,使用用户自己的 IP 去请求,这样即能分担 IP 压力,也不会有隐私担忧。

具体实现可以用 https://github.com/ifyour/deeplx 这个库,如果直接使用不方便,那可以参考它的 ts 代码也行 https://github.com/ifyour/deeplx/blob/main/src/query.ts

source_lang: queryWordInfo.fromLanguage,
target_lang: queryWordInfo.toLanguage.split("-")[0],
});
return {
translations: [body.data.data],
};
};
Loading