Crissium / SilverDict

Web-Based Alternative to GoldenDict
https://silverdict.lecoteauverdoyant.co.uk
GNU General Public License v3.0
161 stars 18 forks source link

特定词典,可以获取到 suggestions 但是将具体 suggetion 传入 query API 时没有结果 #7

Closed czqhurricnae closed 12 months ago

czqhurricnae commented 12 months ago

通过 suggestions API 查询 满足时,获取到 30 个结果:

{'suggestions': ['满足', '满足不了的', '满足不了需求', '满足于', '满足于既得成就', '满足于既得荣誉', '满足于既有成就', '满足人们吃饱', '满足地', '满足大家的需要', '满足对的欲望', '满足感', '满足感官', '满足感官的', '满足或欢乐的', '满足法庭', '满足特定目的', '满足用户', '满足的', '满足的事由', '满足的心情', '满足的状态', '满足的需求', '满足的需要', '满足肉欲的', '满足肉欲的场所', '满足自我', '满足要求', '满足需求', '满足需要', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''], 'timestamp': 1699265280538.1938}

和 GoldenDict 软件的查询结果一致。

然后将 满足肉欲的场所 这个具体的 suggestion 传入 query API,结果显示 not found:

➜ curl http://127.0.0.1:2628/api/query/Default%20Group/%E6%BB%A1%E8%B6%B3%E8%82%89%E6%AC%B2%E7%9A%84%E5%9C%BA%E6%89%80

<p>Entry 满足肉欲的场所 not found. Suggestions:</p>
<ul>

</ul>%

但是在 GoldenDict 软件点击 满足肉欲的场所 是有结果的,如图:

image

后来我发现,SilverDict 对于 query TIOv5_单词反查 这个词典中的 suggestion 都是 not found,但是 GoldenDict 软件都正常。

这种状况如何排查?

Crissium commented 12 months ago

写一个通用的 dictionary shell 就是这样,各种边缘情况。可以把词典发给我,我来排查,我的邮箱可以在 git log 中找到。

czqhurricnae commented 12 months ago

我已经通过 Gmail 发送到你的邮箱,不知道能否收到,不能的话我用 QQ 邮箱再发一次。

Crissium commented 12 months ago

已收到。

Crissium commented 12 months ago

无法复现:

curl http://127.0.0.1:2628/api/query/Default%20Group/%E6%BB%A1%E8%B6%B%89%E6%AC%B2%E7%9A%84%E5%9C%BA%E6%89%80
<!DOCTYPE html>
<html>
<head>
    <title>Definition</title>
    <meta charset="utf-8">
    <style type="text/css">
        .article-block {
            border-top: 2px solid #ccc;
            border-bottom: 2px solid #ccc;
            margin-top: 10px;
            margin-bottom: 10px;
        }

        img {
            max-width: 100%;
        }

        hr {
            border: none;
            border-top: 0.5px solid #ccc;
            width: 98%;
        }

        .dictionary-headings {
            padding-top: 5px;
            padding-bottom: 5px;
            color: darkgreen;
            font-weight: bolder;
        }
    </style>
</head>

<body>

<div class="article-block">
    <h2 class="dictionary-headings" id="TIOv5_单词反查"> <!-- dictionary name -->
        TIO <!-- dictionary display name -->
    </h2>
    <link rel="stylesheet" href="tiov5word.css">
<div class="tioresult"> <div class="tioresult">智能推荐 : <span class="abc">fleshpots</span>|<span class="abc">fleshpot</span></div><hr /><span class="pg_exam_def"><span class="fc_key_word">〔fleshpot〕</span> a place that supplies sexual entertainment and food and drink<zh_cn_def><span class="hl">满足肉欲的场所</span>;红灯区;</zh_cn_def></span><br /><span class="pg_exam_def"><span class="fc_key_word">〔fleshpots〕</span> areas in a city or town where there are many places that people go to for pleasure, especially sexual pleasure – used humorously<zh_cn_def><span class="hl">满足肉欲的场所</span>;寻欢作乐的地方;</zh_cn_def></span><br /><hr /> </div>
 <!-- body of article, already HTML-formatted -->
</div>

</body>

</html>

尝试在 https://github.com/Crissium/SilverDict/blob/18a09b4cd8524394c4011a751ba580c8e5c8b77a/server/app/dictionaries.py#L162C4-L162C14 后面加上一行 print(dictionary_name, keys_found),再次查询,检查终端输出?

czqhurricnae commented 12 months ago
➜ python3.10 server.py
INFO:app.dicts.mdict_reader:Entries of dictionary 要你命 3000 added to database
INFO:app.dictionaries:Dictionaries loaded.
INFO:waitress:Serving on http://127.0.0.1:2628
不择手段背单词 []
英文字用法指南 2021 圣诞版 []
要你命 3000 []
牛津短语动词词典(英汉双解第二版) []
idiom大合集3 []
SIO 双向双解词典 v3.3 []
TIOv5_单词反查 ['满足肉欲的场所']
英语常用词疑难用法手册_文字版 []

还是 not found

➜ curl http://127.0.0.1:2628/api/query/Default%20Group/%E6%BB%A1%E8%B6%B3%E8%82%89%E6%AC%B2%E7%9A%84%E5%9C%BA%E6%89%80
<p>Entry 满足肉欲的场所 not found. Suggestions:</p>
<ul>

</ul>
czqhurricnae commented 12 months ago

我在 https://github.com/Crissium/SilverDict/blob/18a09b4cd8524394c4011a751ba580c8e5c8b77a/server/app/dicts/mdict_reader.py#L196 后加 print(locations) 结果是:

[('满足肉欲的场所', 125477634, 746)]

https://github.com/Crissium/SilverDict/blob/18a09b4cd8524394c4011a751ba580c8e5c8b77a/server/app/dicts/mdict_reader.py#L197 后加 print(records) 结果是空的。

不知道在你的环境 locations 是不是和我的一致,这样我就可以怀疑是不是 https://github.com/Crissium/SilverDict/blob/18a09b4cd8524394c4011a751ba580c8e5c8b77a/server/app/dicts/mdict_reader.py#L197 的函数有问题。

还有你的 query 命令:

curl http://127.0.0.1:2628/api/query/Default%20Group/%E6%BB%A1%E8%B6%B%89%E6%AC%B2%E7%9A%84%E5%9C%BA%E6%89%80

和我的不一致:

curl http://127.0.0.1:2628/api/query/Default%20Group/%E6%BB%A1%E8%B6%B3%E8%82%89%E6%AC%B2%E7%9A%84%E5%9C%BA%E6%89%80

我的最后参数 肉欲的场所 是通过 Python

>>> urllib.request.quote("满足肉欲的场所")
'%E6%BB%A1%E8%B6%B3%E8%82%89%E6%AC%B2%E7%9A%84%E5%9C%BA%E6%89%80'

得到的。

Crissium commented 12 months ago

我这次确认,我是复制粘贴的 curl http://127.0.0.1:2628/api/query/Default%20Group/%E6%BB%A1%E8%B6%B3%E8%82%89%E6%AC%B2%E7%9A%84%E5%9C%BA%E6%89%80,结果正常。

我又直接查了数据库记录:

select * from entries where key = "满足肉欲的场所";
满足肉欲的场所|TIOv5_单词反查|满足肉欲的场所|125477634|746

正常。

你会使用 Python 吗?server/app/dicts/mdict/readmdict.py 是我从别处捞来的,_get_record 函数也是根据里面的类似函数魔改来的。可以直接用里面的 MDX 类遍历试下?

class MDX(MDict):
    """
    MDict dictionary file format (*.MDD) reader.
    >>> mdx = MDX('example.mdx')
    >>> len(mdx)
    42481
    >>> for key,value in mdx.items():
    ... print key, value[:10]
    """
czqhurricnae commented 12 months ago

我基本可以确定是 https://github.com/Crissium/SilverDict/blob/18a09b4cd8524394c4011a751ba580c8e5c8b77a/server/app/dicts/mdict_reader.py#L184 函数有问题,

我在

https://github.com/Crissium/SilverDict/blob/18a09b4cd8524394c4011a751ba580c8e5c8b77a/server/app/dicts/mdict_reader.py#L197

后加 print(“records”, records) 就算是 records 为空,也应该打印 records,但是终端始终没有打印出来。说明在

https://github.com/Crissium/SilverDict/blob/18a09b4cd8524394c4011a751ba580c8e5c8b77a/server/app/dicts/mdict_reader.py#L184

函数内没有返回。

MDX 类遍历,我试试看。

czqhurricnae commented 12 months ago

我按照你的要求,用 MDX 类遍历文件。log 在 附件中。 log1.txt

Crissium commented 12 months ago
Python 3.11.5 (main, Sep 06 2023, 11:21:05) [GCC] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from app.dicts.mdict import MDX
>>> mdx = MDX('/home/ellis/workspace/Frontend/TIOCheck/TIOv5_单词反查.mdx')
>>> for key, value in mdx.items():
...  if key == b'\xe6\xbb\xa1\xe8\xb6\xb3\xe8\x82\x89\xe6\xac\xb2\xe7\x9a\x84\xe5\x9c\xba\xe6\x89\x80':
...   print(key, value[:10]
... 
... 
... 
... )
... 
b'\xe6\xbb\xa1\xe8\xb6\xb3\xe8\x82\x89\xe6\xac\xb2\xe7\x9a\x84\xe5\x9c\xba\xe6\x89\x80' b'<link rel='
>>> len(mdx)
177262
>>> '满足肉欲的场所'.encode('utf-8')
b'\xe6\xbb\xa1\xe8\xb6\xb3\xe8\x82\x89\xe6\xac\xb2\xe7\x9a\x84\xe5\x9c\xba\xe6\x89\x80'
grep \xe6\xbb\xa1\xe8\xb6\xb3\xe8\x82\x89\xe6\xac\xb2\xe7\x9a\x84\xe5\x9c\xba\xe6\x89\x80 log1.txt

(没找到)

grep 用法错了…… 找到了……

另外有几点信息:

这个 mdict 是 v2, 正常 zlib 压缩,所以可以在 mdict_reader.py:170-182 行之间多加几个 print 试试看?

我自己是不管怎么 print 都是正常的,现在也可以根据上面的结果确认 MDX 类没有问题,所以毛病应该就在 _get_records_in_batch_get_record_v1v2 中。

czqhurricnae commented 12 months ago

找到原因了。

https://github.com/Crissium/SilverDict/blob/18a09b4cd8524394c4011a751ba580c8e5c8b77a/server/app/dicts/mdict_reader.py#L189C2-L189C2

中的 self._mdict._fname,打印出来是:

mdict_reader.py -> 192 -> MDictReader._get_records_in_batch -> self._mdict._fname /Users/c/Downloads/TIOv5_单词反查/tio_word.mdx

而实际上 /Users/c/Downloads/TIOv5_单词反查/tio_word.mdx 已经被我重命名,并且移动到:/Users/c/Documents/mdx/TIOv5_单词反查/TIOv5_单词反查.mdx。 所以程序没有读取到字典文件。

但是我在 dictionaries.ymal 中配置的文件路径是新的,正确的。

{
        "dictionary_display_name": "TIOv5_单词反查",
        "dictionary_name": "TIOv5_单词反查",
        "dictionary_format": "MDict (.mdx)",
        "dictionary_filename": "/Users/c/Documents/mdx/TIOv5_单词反查/TIOv5_单词反查.mdx"
    }

为啥程序中的 self._mdict._fname 还是旧的?

难道有缓存?

Crissium commented 12 months ago

是的,看 42-49 行,我把 MDX 给 pickle 了。可以去 ~/.cache/SilverDict/词典名字/mdx.pickle 给删了。

最安全的做法是用 API 删掉词典然后重新添加。

czqhurricnae commented 12 months ago

谢谢耐心解答,搞定。