Crissium/SilverDict

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

Closed this issue · 13 comments

通过 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 软件都正常。

这种状况如何排查?

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

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

已收到。

无法复现:

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),再次查询,检查终端输出?

➜ 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>

我在

locations = db_manager.get_entries(entry, self.name)

后加 print(locations)
结果是:

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

records = self._get_records_in_batch(locations)

后加
print(records)
结果是空的。

不知道在你的环境 locations 是不是和我的一致,这样我就可以怀疑是不是

records = self._get_records_in_batch(locations)

的函数有问题。

还有你的 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'

得到的。

我这次确认,我是复制粘贴的 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]
	"""

我基本可以确定是

def _get_records_in_batch(self, locations: 'list[tuple[str, int, int]]') -> 'list[str]':

函数有问题,

我在

records = self._get_records_in_batch(locations)

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

def _get_records_in_batch(self, locations: 'list[tuple[str, int, int]]') -> 'list[str]':

函数内没有返回。

MDX 类遍历,我试试看。

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

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 中。

找到原因了。

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 还是旧的?

难道有缓存?

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

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

谢谢耐心解答,搞定。