Skip to content

Commit e89662b

Browse files
authored
Improves the output format of factoid search, and speeds it up a little (#1200)
1 parent 5a5241d commit e89662b

File tree

1 file changed

+78
-47
lines changed

1 file changed

+78
-47
lines changed

techsupport_bot/commands/factoids.py

Lines changed: 78 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -713,7 +713,6 @@ async def add_factoid(
713713

714714
# Removes the factoid from the cache
715715
await self.handle_cache(guild, name)
716-
717716
await auxiliary.send_confirm_embed(
718717
message=f"Successfully {fmt} the factoid `{factoid_name}`",
719718
channel=ctx.channel,
@@ -1900,34 +1899,64 @@ async def send_factoids_as_file(
19001899

19011900
def search_content_and_bold(
19021901
self: Self, original: str, search_string: str
1903-
) -> list[str]:
1904-
"""Searches a string for a substring and bolds it
1902+
) -> str | None:
1903+
"""Finds all starting indices of the search_string in the original string.
19051904
19061905
Args:
1907-
original (str): The original content to search through
1908-
search_string (str): The string we are searching for
1906+
original (str): The original content to search through.
1907+
search_string (str): The string we are searching for.
19091908
19101909
Returns:
1911-
list[str]: Snippets that have been modified with the search string
1910+
str | None: A single string with bolded matches and surrounding context,
1911+
or None if no matches exist.
19121912
"""
1913-
# Compile the regular expression for the substring
1914-
pattern = re.compile(re.escape(search_string))
1915-
matches = list(pattern.finditer(original))
1916-
1917-
matches_list = []
1918-
1919-
# Print all instances with 20 characters before and after each occurrence
1920-
for match in matches:
1921-
start = max(match.start() - 20, 0)
1922-
end = min(match.end() + 20, len(original))
1923-
context = original[start:end]
1924-
# Replace the substring in the context with the formatted version
1925-
context_with_formatting = context.replace(
1926-
search_string, f"**{search_string}**"
1913+
1914+
original = original.replace(search_string, f"**{search_string}**")
1915+
1916+
show_range = 20
1917+
1918+
indices = []
1919+
search_len = len(search_string)
1920+
for i in range(len(original) - search_len + 1):
1921+
if original[i : i + search_len] == search_string:
1922+
indices.append(i)
1923+
1924+
if len(indices) == 0:
1925+
return None
1926+
1927+
# Generate ranges to include
1928+
ranges_to_include = []
1929+
for start in indices:
1930+
ranges_to_include.append(
1931+
(
1932+
max(0, start - show_range - 2),
1933+
min(len(original), start + search_len + show_range + 2),
1934+
)
19271935
)
1928-
matches_list.append(context_with_formatting.replace("****", ""))
19291936

1930-
return matches_list
1937+
# Minimize ranges by merging overlapping or adjacent ranges
1938+
minimized_ranges = []
1939+
for start, end in sorted(ranges_to_include):
1940+
if minimized_ranges and start <= minimized_ranges[-1][1]:
1941+
minimized_ranges[-1] = (
1942+
min(minimized_ranges[-1][0], start),
1943+
max(minimized_ranges[-1][1], end),
1944+
)
1945+
else:
1946+
minimized_ranges.append((start, end))
1947+
1948+
ranges_to_strs = []
1949+
1950+
if minimized_ranges[0][0] != 0:
1951+
ranges_to_strs.append("")
1952+
1953+
for include_range in minimized_ranges:
1954+
ranges_to_strs.append(original[include_range[0] : include_range[1]])
1955+
1956+
if minimized_ranges[len(minimized_ranges) - 1][1] != len(original):
1957+
ranges_to_strs.append("")
1958+
1959+
return "...".join(ranges_to_strs)
19311960

19321961
@auxiliary.with_typing
19331962
@commands.guild_only()
@@ -1956,43 +1985,45 @@ async def search(self: Self, ctx: commands.Context, *, query: str) -> None:
19561985

19571986
factoids = await self.get_all_factoids(guild, list_hidden=False)
19581987
matches = {}
1959-
19601988
for factoid in factoids:
1989+
if factoid.alias:
1990+
continue
1991+
19611992
factoid_key = ", ".join(await self.get_list_of_aliases(factoid.name, guild))
1962-
if query in factoid.name.lower():
1993+
1994+
# Name string
1995+
name_highlight = self.search_content_and_bold(factoid_key.lower(), query)
1996+
if name_highlight:
19631997
if factoid_key in matches:
1964-
matches[factoid_key].append(
1965-
f"Name: {factoid.name.lower().replace(query, f'**{query}**')}"
1966-
)
1998+
matches[factoid_key].append(f"Name: {name_highlight}")
19671999
else:
1968-
matches[factoid_key] = [
1969-
f"Name: {factoid.name.lower().replace(query, f'**{query}**')}"
1970-
]
2000+
matches[factoid_key] = [f"Name: {name_highlight}"]
19712001

1972-
if query in factoid.message.lower():
1973-
matches_list = self.search_content_and_bold(
1974-
factoid.message.lower(), query
1975-
)
1976-
for match in matches_list:
1977-
if factoid_key in matches:
1978-
matches[factoid_key].append(f"Content: {match}")
1979-
else:
1980-
matches[factoid_key] = [f"Content: {match}"]
2002+
# Content
2003+
content_highlight = self.search_content_and_bold(
2004+
factoid.message.lower(), query
2005+
)
2006+
if content_highlight:
2007+
if factoid_key in matches:
2008+
matches[factoid_key].append(f"Content: {content_highlight}")
2009+
else:
2010+
matches[factoid_key] = [f"Content: {content_highlight}"]
19812011

1982-
if (
1983-
factoid.embed_config is not None
1984-
and query in factoid.embed_config.lower()
1985-
):
1986-
matches_list = self.search_content_and_bold(
2012+
# Embed
2013+
if factoid.embed_config is not None:
2014+
embed_highlight = self.search_content_and_bold(
19872015
factoid.embed_config.lower(), query
19882016
)
1989-
for match in matches_list:
2017+
if embed_highlight:
19902018
if factoid_key in matches:
19912019
matches[factoid_key].append(
1992-
f"Embed: {match.replace('_', '`_`')}"
2020+
f"Embed: {embed_highlight.replace('_', '`_`')}"
19932021
)
19942022
else:
1995-
matches[factoid_key] = [f"Embed: {match.replace('_', '`_`')}"]
2023+
matches[factoid_key] = [
2024+
f"Embed: {embed_highlight.replace('_', '`_`')}"
2025+
]
2026+
19962027
if len(matches) == 0:
19972028
embed = auxiliary.prepare_deny_embed(
19982029
f"No factoids could be found matching `{query}`"

0 commit comments

Comments
 (0)