编写 Albert 翻译插件

本文详细介绍了如何使用有道智云API创建Albert翻译插件,包括注册获取ID和Key、查询翻译API、解析JSON响应及整合插件代码,提供丰富的翻译结果展示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载自编写 Albert 翻译插件,Mark住有时间自己也参照写一个

翻译接口 - 有道词典(有道智云)

翻译插件主要参考上文链接 2,作者使用了有道词典。为了了解发送查询到有道,再到数据返回形式,最终将该形式的数据如何通过 albert 接口读取后显示。所以我也注册了有道智云,然后使用 API 获取了一下查询单词的数据。

由于原先我已经注册过了百度的翻译 API,但是发现有道的返回结果更加丰富。所以我就不打算将源转为百度了。如果有一定编程经验的朋友,看过之后会发现编写这么一个 albert 插件还是很简单的,其中接口和显示等形式和用法都很直接易懂。但是,这篇博客还是比参考链接 2 中更精细地记录了实现一个 albert 翻译插件的过程(同时在代码上使用 Python3,和 Albert 提供的其它新接口),因为这样也方便我自己以后回顾查看。

1 使用查询翻译 API

在真正去实现 Albert 翻译插件之前,必须要了解清楚如何实现翻译,如何使用翻译接口。

如果之前没有使用过类似此种接口的经验的话,不妨花几十分钟到小几个小时实践一下。

这里 ? 有一篇我较早写的使用百度翻译 API 的博客。

1.1 注册以获得 ID 和 Key

参阅 有道智云帮助文档 ?

1.2 使用翻译API示例

n/a

查询结果

{
    "tSpeakUrl":"http://openapi.youdao.com/ttsapi?q=%E8%8B%B9%E6%9E%9C&langType=zh-CHS&sign=n/a&salt=n/a&voice=4&format=mp3&appKey=n/a",
    "returnPhrase":["apple"],
    "web":[{"value":["苹果","苹果公司","苹果电脑","苹果汁"],"key":"Apple"},
           {"value":["苹果公司","美国苹果公司","苹果"],"key":"apple inc"},
           {"value":["韩版恶作之吻造型曝光"],"key":"Apple Daily"}],
    "query":"apple",
    "translation":["苹果"],
    "errorCode":"0",
    "dict":{"url":"yddict://m.youdao.com/dict?le=eng&q=apple"},
    "webdict":{"url":"http://m.youdao.com/dict?le=eng&q=apple"},
    "basic":{
        "exam_type":["初中"], "us-phonetic":"\'æpl",
        "phonetic":"\'æp(ə)l", "uk-phonetic":"\'æp(ə)l",
        "uk-speech":"http://openapi.youdao.com/ttsapi?q=apple&langType=en&sign=n/a&salt=n/a&voice=5&format=mp3&appKey=n/a",
        "explains":["n. 苹果,苹果树,苹果似的东西;[美俚]炸弹,手榴弹,(棒球的)球;[美俚]人,家伙。"],
        "us-speech":"http://openapi.youdao.com/ttsapi?q=apple&langType=en&sign=n/a&salt=n/a&voice=6&format=mp3&appKey=n/a"
    },
    "l":"en2zh-CHS",
    "speakUrl":"http://openapi.youdao.com/ttsapi?q=apple&langType=en&sign=n/a&salt=n/a&voice=4&format=mp3&appKey=n/a"
}

1.3 按条目提取结果用于显示

对结果一行一行显示,去除一些获取发音的链接等。

第一个显示读音(“phonetic”:"'æp(ə)l"):

>>> response_json2dict['basic']['phonetic']
'æp(ə)l

我们可以看到一个单词对应中文可以有多个“不同的”(非同义)释义和不同的词性,并且含有“网络释义”(上例只有一个,但是中返回的 json 中释义键对应的值使用的是列表(加上常识)可以推断出上述),

将每一个(不同的)“标准”释义起一行显示:

>>> for explain in response_json2dict['basic']['explains']:
        print(explain)
n. 苹果,苹果树,苹果似的东西;[美俚]炸弹,手榴弹,(棒球的)球;[美俚]人,家伙。

将每一个(不同的)网络释义一行行显示:

>>> for web_expl in response_json2dict['web']:
        print(web_expl)
{'key': 'Apple', 'value': ['苹果', '苹果公司', '苹果电脑', '苹果汁']}
{'key': 'apple inc', 'value': ['苹果公司', '美国苹果公司', '苹果']}
{'key': 'Apple Daily', 'value': ['韩版恶作之吻造型曝光']}

至此我们就按题目(行)提取出了发音、释义、网络释义的内容,对于一个单词的翻译有这些就足够了。

2 关于 Albert 插件

做一个“直接的”,最简单的 demo:

"""This is a simple python template extension.
Synopsis: spell word"""

from albertv0 import *
import os

__iid__ = "PythonInterface/v0.1"
__prettyname__ = "Speel Word"
__version__ = "1.0"
__trigger__ = "spell "
__author__ = "Joseph Lin"
__dependencies__ = []

ICON_PATH = iconLookup("albert")

def handleQuery(query):
    if not query.isTriggered:
        return

    results = []
    for letter in query.string:
        item = Item(id="", icon=ICON_PATH,
                    text=letter, subtext="",
                    completion="", urgency=ItemBase.Notification, actions=[])
        results.append(item)
    return results
aGVpdGk,shadow_10,text_aHR0cHM6Ly9zaXhnb2xkZW4uYmxvZy5jc2RuLm5ldA==,size_16,color_FFFFFF,t_70)

在这里插入图片描述
安装方式:

将上面代码保存为 spell.py 文件。

然后复制到 python 模块目录下即完成安装:

$ cp spell.py ~/.local/share/albert/org.albert.extension.python/modules

注:如果没有特意配置过,albert 对结果显示 5 个条目,多出的条目需要使用上下键来查看

2.1 激活“代码”

2.2 键入的查询

在 Ablert 搜索(查询)输入框中,输入了 "tr " + “word” 之后,回车,Albert 根据激活代码 "tr " 调用对应插件的 handleQuery 函数1,该函数执行期望的查询功能,并且最后通过构造一个含有 (Albert 接口提供的)Item 类2元素的列表返回以用于显示查询结果。

2.3 结果输出

3 使用翻译 API 编写 Albert 翻译插件

3.1 注册激活代码

__trigger__ = "tr "  # 触发命令

3.2 发起查询

获取查询单词:word = query.string
生成 url:url = getUrl(‘auto’, ‘zh’, word)
发起查询:req = requests.get(url, headers={‘User-Agent’: ua})
将查询结果(json)转化为字典对象:response_json2dict = json.loads(req.text)

def get_result_from_API_as_dict(word):
    url = getUrl('auto', 'zh', word)
    req = requests.get(url, headers={'User-Agent': ua})
    return json.loads(req.text)

data = get_result_from_API_as_dict(query.string)

3.3 从查询结果构建显示条目

初始化一个显示的条目对象: item = Item()
显示的内容:item.text = data[‘basic’][‘phonetic’]
小号的说明字段:item.subtext = “phonetic”
将条目对象加入用于显示的列表:results.append(item)

def generate_display_items(data):
    results = []

    item = Item()  # 发音
    item.text = data['basic']['phonetic']
    item.subtext = "phonetic"
    results.append(item)

    for explain in data['basic']['explains']:
        item = Item()  # 释义
        item.text = explain
        item.subtext = 'explain'
        results.append(item)
    
    for web_expl in data['web']:
        item = Item()  # 网络释义
        item.text = web_expl
        item.subtext = 'web explain'
        results.append(item)

    return results

return generate_display_items(data)

3.4 拓展插件的信息

__iid__ = "PythonInterface/v0.1"
__prettyname__ = "Translation Word"
__version__ = "1.0"
__author__ = "Joseph Lin"
__dependencies__ = ["requests", "youdao account"]

3.5 完整模块代码

"""translation module.
Synopsis: <triger> <word>
"""

import locale
import json
import urllib.parse
import hashlib

from albertv0 import *
import requests

__iid__ = "PythonInterface/v0.1"
__prettyname__ = "Translation Word"
__trigger__ = "tr "
__version__ = "1.0"
__author__ = "Joseph Lin"
__dependencies__ = ["requests", "youdao account"]

ICON_PATH = iconLookup("albert")
TO_LANG = 'zh'

def initialize():
    global TO_LANG
    try:
        TO_LANG = locale.getdefaultlocale()[0].split('_')[0]  # cat /etc/locale.gen
    except Exception as err:
        warning(err)

class YouDaoAPI():
    ua = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36"
    urltmpl = "http://openapi.youdao.com/api?appKey={}&q={}&from=auto&to={}&salt={}&sign={}"
    langSupported = dict.fromkeys(('zh', 'en', 'es', 'fr', 'ko', 'ja', 'ru', 'pt'))

    def __init__(self, word):
        self.word = word

    def get_url(self, src, dst, txt):
        ''' 按有道的格式生成请求地址。src为源语言,dst为目标语言 '''
        appKey = '<你的产品ID>'  # 注册智云后获得
        secretKey = '<你的密钥>'
        salt = '123456'  # TODO: 使用随机数
        sign = appKey + txt + salt + secretKey
        m1 = hashlib.md5()
        m1.update(sign.encode(encoding='utf-8'))
        sign = m1.hexdigest()
        q = urllib.parse.quote_plus(txt)
        url = self.urltmpl.format(appKey, q, dst, salt, sign)
        return url

    def get_result_from_api_as_dict(self):
        url = self.get_url('auto', TO_LANG, self.word)
        req = requests.get(url, headers={'User-Agent': self.ua})
        return json.loads(req.text)

def generate_display_items(data):
    results = []
    if set({'web', 'phonetic', 'basic'}) & set(data.keys()):
        try:
            results.append(  # 发音
                Item(id="", icon=ICON_PATH,
                     completion="", urgency=ItemBase.Notification,
                     text=str(data['basic']['phonetic']),
                     subtext="phonetic",
                     actions=[]))
        except:
            pass

        try:
            for explain in data['basic']['explains']:  # 释义
                results.append(
                    Item(id="", icon=ICON_PATH,
                         completion="", urgency=ItemBase.Notification,
                         text=str(explain), subtext='explain', actions=[]))
        except:
            pass

        try:
            for web_expl in data['web']:  # 网络释义
                results.append(
                    Item(id="", icon=ICON_PATH,
                         completion="", urgency=ItemBase.Notification,
                         text="{}: {}".format(web_expl['key'], web_expl['value']),
                         subtext='web explain', actions=[]))
        except:
            pass

        return results

    raise RuntimeError("no result")

def handleQuery(query):
    if not query.isValid or not query.isTriggered or len(query.string) <= 1:
        return

    # info(query.string)
    try:
        data = YouDaoAPI(query.string).get_result_from_api_as_dict()
    except Exception as err:
        warning("{!r}".format(err))
        return [Item(id="", icon=ICON_PATH,
                     completion="", urgency=ItemBase.Notification,
                     text=str(err), subtext="YouDaoAPI Error", actions=[])]
    try:
        return generate_display_items(data)
    except Exception as err:
        warning("{!r}".format(err))
        return [Item(id="", icon=ICON_PATH,
                     completion="", urgency=ItemBase.Notification,
                     text=str(err), subtext="Generate items Error", actions=[])]

4 Know Issue

虽然比较靠后,但是这一节非常非常重要!!!

关于可能崩溃退出,重新加载模块问题。

参阅 【译】拓展 Albert(编写 Alber 插件和拓展) 中的 Know Issue 小节。

5 功能升级与更新

请参阅下一篇博客 ? 编写 Albert 翻译插件之功能升级 ?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值