annotate libervia/backend/plugins/plugin_misc_jid_search.py @ 4358:c8d089b0e478

plugin JID Search: Use Pydantic models + better handling of partial search.
author Goffi <goffi@goffi.org>
date Fri, 11 Apr 2025 18:19:28 +0200
parents 0d7bb4df2343
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4108
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/env python3
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
2
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
3 # Libervia plugin to handle XMPP entities search
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
4 # Copyright (C) 2009-2023 Jérôme Poisson (goffi@goffi.org)
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
5
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
6 # This program is free software: you can redistribute it and/or modify
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # it under the terms of the GNU Affero General Public License as published by
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # the Free Software Foundation, either version 3 of the License, or
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # (at your option) any later version.
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
10
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
11 # This program is distributed in the hope that it will be useful,
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # GNU Affero General Public License for more details.
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
15
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
16 # You should have received a copy of the GNU Affero General Public License
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
18
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
19 from collections import OrderedDict
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
20 import difflib
4358
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
21 from typing import Annotated, Iterator, Literal, NamedTuple
4108
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
22
4358
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
23 from pydantic import BaseModel, Field, RootModel
4108
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
24 from twisted.internet import defer
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
25 from twisted.words.protocols.jabber import jid
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
26
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
27 from libervia.backend.core.constants import Const as C
4358
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
28 from libervia.backend.core.core_types import SatXMPPClient, SatXMPPEntity
4108
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
29 from libervia.backend.core.i18n import _
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
30 from libervia.backend.core.log import getLogger
4358
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
31 from libervia.backend.models.types import JIDType
4108
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
32
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
33 log = getLogger(__name__)
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
34
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
35
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
36 PLUGIN_INFO = {
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
37 C.PI_NAME: "JID Search",
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
38 C.PI_IMPORT_NAME: "JID_SEARCH",
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
39 C.PI_TYPE: C.PLUG_TYPE_MISC,
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
40 C.PI_MODES: C.PLUG_MODE_BOTH,
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
41 C.PI_PROTOCOLS: [],
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
42 C.PI_DEPENDENCIES: [],
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
43 C.PI_RECOMMENDATIONS: [],
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
44 C.PI_MAIN: "JidSearch",
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
45 C.PI_HANDLER: "no",
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
46 C.PI_DESCRIPTION: _("""Search for XMPP entities"""),
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
47 }
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
48 RATIO_CUTOFF = 0.6
4358
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
49 # Used when a search term matches a substring of a relevant data.
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
50 PARTIAL_MATCH_RATIO = 0.8
4108
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
51 MAX_CACHE_SIZE = 10
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
52
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
53
4358
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
54 class JidSearchItem(BaseModel):
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
55 entity: JIDType
4108
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
56 name: str = ""
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
57 exact_match: bool = False
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
58 relevance: float | None = None
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
59
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
60
4358
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
61 class EntitySearchItem(JidSearchItem):
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
62 type: Literal["entity"] = "entity"
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
63 in_roster: bool = False
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
64 groups: list[str] | None = None
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
65
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
66
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
67 class RoomSearchItem(JidSearchItem):
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
68 type: Literal["room"] = "room"
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
69 local: bool = Field(
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
70 description="True if the room comes from a server local component."
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
71 )
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
72 service_type: str | None = None
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
73 description: str | None = None
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
74 language: str | None = None
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
75 nusers: int | None = Field(default=None, ge=0)
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
76 anonymity_mode: str | None = None
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
77 is_open: bool | None = None
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
78
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
79
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
80 SearchItem = Annotated[EntitySearchItem | RoomSearchItem, Field(discriminator="type")]
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
81
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
82
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
83 class SearchItems(RootModel):
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
84 root: list[SearchItem]
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
85
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
86 def __iter__(self) -> Iterator[SearchItem]: # type: ignore
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
87 return iter(self.root)
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
88
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
89 def __getitem__(self, item) -> str:
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
90 return self.root[item]
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
91
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
92 def __len__(self) -> int:
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
93 return len(self.root)
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
94
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
95 def append(self, item: SearchItem) -> None:
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
96 self.root.append(item)
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
97
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
98 def sort(self, key=None, reverse=False) -> None:
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
99 self.root.sort(key=key, reverse=reverse) # type: ignore
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
100
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
101
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
102 class Options(BaseModel):
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
103 entities: bool = Field(
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
104 default=False, description="Search for entities for direct chat"
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
105 )
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
106 groupchat: bool = Field(
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
107 default=False, description="Search for group chats."
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
108 )
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
109 allow_external: bool = Field(
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
110 default=False, description="Authorise doing request to external services."
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
111 )
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
112
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
113
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
114 class CachedSearch(NamedTuple):
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
115 search_items: SearchItems
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
116 options: Options
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
117
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
118
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
119 JidSearchCache = OrderedDict[str, CachedSearch]
4108
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
120
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
121
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
122 class JidSearch:
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
123 def __init__(self, host) -> None:
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
124 log.info(f"plugin {PLUGIN_INFO[C.PI_NAME]!r} initialization")
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
125 self.host = host
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
126 host.bridge.add_method(
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
127 "jid_search",
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
128 ".plugin",
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
129 in_sign="sss",
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
130 out_sign="s",
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
131 method=self._search,
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
132 async_=True,
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
133 )
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
134
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
135 def profile_connecting(self, client: SatXMPPEntity) -> None:
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
136 client._jid_search_cache = JidSearchCache()
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
137
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
138 def _search(self, search_term: str, options_s: str, profile: str) -> defer.Deferred:
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
139 client = self.host.get_client(profile)
4358
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
140 options = Options.model_validate_json(options_s)
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
141 d = defer.ensureDeferred(self.search(client, search_term, options))
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
142 d.addCallback(lambda search_items: search_items.model_dump_json())
4108
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
143 return d
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
144
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
145 async def search(
4358
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
146 self,
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
147 client: SatXMPPEntity,
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
148 search_term: str,
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
149 options: Options | dict | None = None,
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
150 ) -> SearchItems:
4108
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
151 """Searches for entities in various locations.
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
152
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
153 @param client: The SatXMPPEntity client where the search is to be performed.
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
154 @param search_term: The query to be searched.
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
155 @param options: Additional search options.
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
156 @return: A list of matches found.
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
157 """
4358
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
158 if options is None:
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
159 options = Options()
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
160 elif isinstance(options, dict):
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
161 options = Options(**options)
4108
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
162 search_term = search_term.strip().lower()
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
163 sequence_matcher = difflib.SequenceMatcher()
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
164 sequence_matcher.set_seq1(search_term)
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
165 # FIXME: cache can give different results due to the filtering mechanism (if a
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
166 # cached search term match the beginning of current search term, its results a
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
167 # re-used and filtered, and sometimes items can be missing in compraison to the
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
168 # results without caching). This may need to be fixed.
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
169 cache: JidSearchCache = client._jid_search_cache
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
170
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
171 # Look for a match in the cache
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
172 for cache_key in cache:
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
173 if search_term.startswith(cache_key):
4358
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
174 cached_data = cache[cache_key]
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
175 if cached_data.options != options:
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
176 log.debug("Ignoring cached data due to incompatible options.")
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
177 continue
4108
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
178 log.debug(
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
179 f"Match found in cache for {search_term!r} in [{client.profile}]."
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
180 )
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
181 # If an exact match is found, return the results as is
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
182 if search_term == cache_key:
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
183 log.debug("Exact match found in cache, reusing results.")
4358
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
184 matches = cached_data.search_items
4108
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
185 else:
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
186 # If only the beginning matches, filter the cache results
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
187 log.debug("Prefix match found in cache, filtering results.")
4358
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
188 matches = SearchItems([])
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
189 for jid_search_item in cached_data.search_items:
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
190 self.process_matching(
4108
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
191 search_term, sequence_matcher, matches, jid_search_item
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
192 )
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
193 cache.move_to_end(cache_key)
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
194 break
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
195 else:
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
196 # If no match is found in the cache, perform a new search
4358
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
197 matches = await self.perform_search(
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
198 client, search_term, options, sequence_matcher
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
199 )
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
200 cache[search_term] = CachedSearch(matches, options)
4108
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
201 if len(cache) > MAX_CACHE_SIZE:
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
202 cache.popitem(last=False)
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
203
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
204 # If no exact match is found, but the search term is a valid JID, we add the JID
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
205 # as a result
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
206 exact_match = any(m.exact_match for m in matches)
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
207 if not exact_match and "@" in search_term:
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
208 try:
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
209 search_jid = jid.JID(search_term)
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
210 except jid.InvalidFormat:
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
211 pass
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
212 else:
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
213 matches.append(
4358
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
214 EntitySearchItem(
4108
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
215 entity=search_jid,
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
216 in_roster=False,
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
217 exact_match=True,
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
218 relevance=1,
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
219 )
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
220 )
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
221
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
222 matches.sort(
4358
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
223 key=lambda item: (
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
224 item.exact_match, item.relevance or 0, getattr(item, "in_roster", False)
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
225 ),
4108
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
226 reverse=True,
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
227 )
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
228
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
229 return matches
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
230
4358
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
231 def process_matching(
4108
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
232 self,
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
233 search_term: str,
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
234 sequence_matcher: difflib.SequenceMatcher,
4358
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
235 matches: SearchItems,
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
236 item: SearchItem,
4108
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
237 ) -> None:
4358
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
238 """Process the matching of an item against a search term.
4108
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
239
4358
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
240 This method checks if the given item is an exact match or if it has any
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
241 significant similarity to the search term. If a match is found, the item's
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
242 relevance score is set and the item is added to the matches list.
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
243
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
244 @param sequence_matcher: The sequence matcher used for comparing strings.
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
245 @param matches: A list where matched items will be appended.
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
246 @param item: The item to be compared against the search term.
4108
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
247 """
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
248
4358
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
249 item_name_lower = item.name.strip().lower()
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
250 item_entity_lower = item.entity.userhost().lower()
4108
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
251
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
252 if search_term in (item_name_lower, item_entity_lower):
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
253 item.exact_match = True
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
254 item.relevance = 1
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
255 matches.append(item)
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
256 return
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
257
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
258 item.exact_match = False
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
259
4358
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
260 # Check if search_term is a substring of item_name_lower or item_entity_lower
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
261 if len(search_term) >= 3:
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
262 if item_name_lower and search_term in item_name_lower:
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
263 item.relevance = PARTIAL_MATCH_RATIO
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
264 matches.append(item)
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
265 return
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
266
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
267 if search_term in item_entity_lower:
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
268 item.relevance = PARTIAL_MATCH_RATIO
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
269 matches.append(item)
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
270 return
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
271
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
272 if item_name_lower:
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
273 sequence_matcher.set_seq2(item_name_lower)
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
274 name_ratio = sequence_matcher.ratio()
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
275 if name_ratio >= RATIO_CUTOFF:
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
276 item.relevance = name_ratio
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
277 matches.append(item)
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
278 return
4108
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
279
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
280 sequence_matcher.set_seq2(item_entity_lower)
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
281 jid_ratio = sequence_matcher.ratio()
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
282 if jid_ratio >= RATIO_CUTOFF:
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
283 item.relevance = jid_ratio
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
284 matches.append(item)
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
285 return
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
286
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
287 localpart = item.entity.user.lower() if item.entity.user else ""
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
288 if localpart:
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
289 sequence_matcher.set_seq2(localpart)
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
290 domain_ratio = sequence_matcher.ratio()
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
291 if domain_ratio >= RATIO_CUTOFF:
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
292 item.relevance = domain_ratio
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
293 matches.append(item)
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
294 return
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
295
4358
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
296 if isinstance(item, EntitySearchItem) and item.groups:
4108
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
297 group_ratios = []
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
298 for group in item.groups:
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
299 sequence_matcher.set_seq2(group.lower())
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
300 group_ratios.append(sequence_matcher.ratio())
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
301 group_ratio = max(group_ratios)
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
302 if group_ratio >= RATIO_CUTOFF:
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
303 item.relevance = group_ratio
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
304 matches.append(item)
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
305 return
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
306
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
307 domain = item.entity.host.lower()
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
308 sequence_matcher.set_seq2(domain)
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
309 domain_ratio = sequence_matcher.ratio()
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
310 if domain_ratio >= RATIO_CUTOFF:
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
311 item.relevance = domain_ratio
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
312 matches.append(item)
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
313 return
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
314
4358
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
315 async def perform_search(
4108
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
316 self,
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
317 client: SatXMPPEntity,
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
318 search_term: str,
4358
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
319 options: Options,
4108
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
320 sequence_matcher: difflib.SequenceMatcher,
4358
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
321 ) -> SearchItems:
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
322 """Performs a new search.
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
323
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
324 Cache is not used here.
4108
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
325
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
326 @param search_term: The query to be searched.
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
327 @param sequence_matcher: The SequenceMatcher object to be used for matching.
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
328 @return: A list of matches found.
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
329 """
4358
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
330 matches = SearchItems([])
4108
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
331
4358
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
332 if options.entities:
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
333 assert isinstance(client, SatXMPPClient)
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
334 try:
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
335 client.roster
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
336 except AttributeError:
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
337 # components have no roster
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
338 roster = []
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
339 else:
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
340 roster = client.roster.get_items()
4108
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
341
4358
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
342 for roster_item in roster:
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
343 jid_search_item = EntitySearchItem(
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
344 entity=roster_item.entity,
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
345 name=roster_item.name,
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
346 in_roster=True,
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
347 groups=list(roster_item.groups),
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
348 )
4108
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
349
4358
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
350 self.process_matching(
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
351 search_term, sequence_matcher, matches, jid_search_item
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
352 )
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
353
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
354 await self.host.trigger.async_point(
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
355 "JID_SEARCH_perform_search",
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
356 client,
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
357 search_term,
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
358 options,
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
359 sequence_matcher,
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
360 matches,
c8d089b0e478 plugin JID Search: Use Pydantic models + better handling of partial search.
Goffi <goffi@goffi.org>
parents: 4270
diff changeset
361 )
4108
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
362
238e305f2306 plugin JID Search: JID search plugin, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
363 return matches