Skip to content

Commit

Permalink
Merge pull request #7 from Vioshim/patch-1
Browse files Browse the repository at this point in the history
Implements transformers for params in queries
  • Loading branch information
JDJGInc authored Apr 28, 2024
2 parents c1e42c3 + c130a4e commit c7d436d
Showing 1 changed file with 103 additions and 86 deletions.
189 changes: 103 additions & 86 deletions cogs/rtfm_slash.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
from __future__ import annotations

import typing
from typing import TYPE_CHECKING
import os
from typing import TYPE_CHECKING, Optional

from discord.app_commands import AppCommandError, Choice
from discord.app_commands import command as app_command
import discord
from discord.ext import commands
from discord import app_commands
from utils import fuzzy
from discord.app_commands import Choice, Transform, Transformer
from discord.ext import commands

import utils
from utils import fuzzy
from utils.extra import RtfmObject

if TYPE_CHECKING:
from discord import Interaction
Expand All @@ -20,114 +19,134 @@
RTFMBot = commands.Bot


class RTFMSlash(commands.Cog):
def __init__(self, bot: RTFMBot) -> None:
self.bot = bot
class LibraryTransformer(Transformer):
async def transform(self, interaction: Interaction[RTFMBot], value: str) -> str:
return interaction.client.rtfm_libraries.get(value, value)

async def autocomplete(self, interaction: Interaction[RTFMBot], current: str) -> list[Choice]:
choices = [Choice(name=name, value=name) for name in interaction.client.rtfm_libraries]
start_with = list(filter(lambda x: x.name.startswith(current), choices)) or choices
return start_with[:25]


class QueryTransformer(Transformer):
async def transform(self, interaction: Interaction[RTFMBot], value: str) -> RtfmObject:
library = interaction.client.rtfm_libraries.get(interaction.namespace.library, interaction.namespace.library)
library = library or "https://discord.com/developers/docs/"
unfiltered_results = await utils.rtfm(interaction.client, library)
if item := fuzzy.find(value, unfiltered_results, key=lambda t: t.name):
return item

raise commands.BadArgument("No Results Found")

async def autocomplete(self, interaction: Interaction[RTFMBot], current: str) -> list[Choice]:
library = interaction.client.rtfm_libraries.get(interaction.namespace.library, interaction.namespace.library)
library = library or "https://discord.com/developers/docs/"
unfiltered_results = await utils.rtfm(interaction.client, library)
choices = [
Choice(name=result.name, value=result.name)
for result in fuzzy.finder(current, unfiltered_results, key=lambda t: t.name)
]
return choices[:25]


class DocsQueryTransformer(Transformer):
async def transform(self, interaction: Interaction[RTFMBot], value: str) -> RtfmObject:
unfiltered_results = await utils.algolia_lookup(
interaction.client,
os.environ["ALGOLIA_APP_ID"],
os.environ["ALGOLIA_API_KEY"],
"discord",
value,
)

@app_commands.user_install()
@app_commands.allow_contexts(guilds=True, dms=True, private_channels=True)
@app_commands.command(description="looks up docs", name="rtfm")
async def rtfm_slash(
self, interaction: discord.Interaction, library: typing.Optional[str] = None, query: typing.Optional[str] = None
) -> None:
"""Looks up docs for a library with optionally a query."""
if result := fuzzy.find(value, unfiltered_results, key=lambda t: t.name):
return result

raise commands.BadArgument("No Results Found")

library = library or self.bot.rtfm_libraries["master"]
async def autocomplete(self, interaction: Interaction[RTFMBot], current: str) -> list[Choice]:
unfiltered_results = await utils.algolia_lookup(
interaction.client,
os.environ["ALGOLIA_APP_ID"],
os.environ["ALGOLIA_API_KEY"],
"discord",
current,
)
# use new method to handle results from discord ologia, but fuzzy can be used now
# I will remove the starting discord api docs if necessary.

if query is None or query == "No Results Found":
return await interaction.response.send_message(f"Alright Let's see \n{library}")
all_choices = [Choice(name=result.name, value=result.name) for result in unfiltered_results]

await interaction.response.send_message(f"Alright Let's see \n{library+query}")
if not current:
return all_choices[:25]

@rtfm_slash.autocomplete("library")
async def rtfm_library_autocomplete(self, interaction: discord.Interaction, current: str) -> list[Choice]:
libraries = self.bot.rtfm_libraries
filtered_results = fuzzy.finder(current, unfiltered_results, key=lambda t: t.name)

all_choices: list[Choice] = [Choice(name=name, value=link) for name, link in libraries.items()]
startswith: list[Choice] = [choices for choices in all_choices if choices.name.startswith(current)]
if not (current and startswith):
return all_choices[0:25]
results = [Choice(name=result.name, value=result.name) for result in filtered_results]

return startswith[0:25]
if not results:
results = [Choice(name="Getting Started", value="Getting Started")]

@rtfm_slash.autocomplete("query")
async def rtfm_query_autocomplete(self, interaction: discord.Interaction, current: str) -> list[Choice]:
url = interaction.namespace.library or self.bot.rtfm_libraries["master"]
unfiltered_results = await utils.rtfm(self.bot, url)
return results[:25]

all_choices = [Choice(name=result.name, value=result.url.removeprefix(url)) for result in unfiltered_results]

if not current:
return all_choices[:25]
Library = Transform[str, LibraryTransformer]
Query = Transform[RtfmObject, QueryTransformer]
DocsQuery = Transform[RtfmObject, DocsQueryTransformer]

filtered_results = fuzzy.finder(current, unfiltered_results, key=lambda t: t[0])

results = [Choice(name=result.name, value=result.url.removeprefix(url)) for result in filtered_results]

return results[:25]
class RTFMSlash(commands.Cog):
def __init__(self, bot: RTFMBot) -> None:
self.bot = bot

@app_commands.command(name="rtfm")
@app_commands.user_install()
@app_commands.allow_contexts(guilds=True, dms=True, private_channels=True)
async def rtfm_slash(self, interaction: Interaction[RTFMBot], library: Library, query: Optional[Query]) -> None:
"""Looks up docs for a library with optionally a query.
Parameters
----------
library : str
The library to search for.
query : RtfmObject
The query to search for.
"""
url = query.url if query else library
await interaction.response.send_message(f"Alright Let's see \n{url}")

@rtfm_slash.error
async def rtfm_error(self, interaction: discord.Interaction, error) -> None:
await interaction.response.send_message(f"{error}! Please Send to this to my developer", ephemeral=True)
print(error)
print(interaction.command)

@app_commands.command()
@app_commands.user_install()
@app_commands.allow_contexts(guilds=True, dms=True, private_channels=True)
@app_commands.command(description="looks up docs from discord developer docs", name="docs")
async def docs(
self, interaction: discord.Interaction, query: typing.Optional[str] = None
) -> None:
"""Looks up docs from discord developer docs with optionally a query."""

url = "https://discord.com/developers/docs/"
if query is None or query == "No Results Found":
# place holder for now.
return await interaction.response.send_message(f"Alright Let's see \n{url}")

await interaction.response.send_message(f"Alright Let's see \n{url+query}")

@docs.autocomplete("query")
async def docs_autocomplete(self, interaction: discord.Interaction, current: str) -> list[Choice]:

url = "https://discord.com/developers/docs/"

unfiltered_results = await utils.algolia_lookup(self.bot, os.environ["ALGOLIA_APP_ID"], os.environ["ALGOLIA_API_KEY"], "discord", current)
# use new method to handle results from discord ologia, but fuzzy can be used now
# I will remove the starting discord api docs if necessary.

all_choices = [Choice(name=result.name, value=result.url.removeprefix(url)) for result in unfiltered_results]
async def docs(self, interaction: Interaction[RTFMBot], query: DocsQuery):
"""Looks up docs from discord developer docs with optionally a query.
if not current:
return all_choices[:25]

filtered_results = fuzzy.finder(current, unfiltered_results, key=lambda t: t[0])

results = [Choice(name=result.name, value=result.url.removeprefix(url)) for result in filtered_results]

for result in results:
if len(result.value) > 100:
print(result.value)

# seems to have issues with some sizes.

if not results:
result = utils.RtfmObject("Getting Started", "https://discord.com/developers/docs/")
results = [Choice(name=result.name, value=result.url.removeprefix(url))]

return results[:25]
Parameters
----------
query : RtfmObject
The query to search for.
"""
await interaction.response.send_message(f"Alright Let's see \n{query.url}")

@docs.error
async def docs_error(self, interaction: discord.Interaction, error) -> None:
await interaction.response.send_message(f"{error}! Please Send to this to my developer", ephemeral=True)
print(error)
print(interaction.command)

@app_commands.command()
@app_commands.user_install()
@app_commands.allow_contexts(guilds=True, dms=True, private_channels=True)
@app_commands.command(description="sends link to bot's source code", name="source")
async def source(self, interaction: discord.Interaction):

async def source(self, interaction: Interaction[RTFMBot]):
"""Sends link to the bot's source code"""
view = discord.ui.View()
view.add_item(
discord.ui.Button(
Expand All @@ -136,9 +155,7 @@ async def source(self, interaction: discord.Interaction):
style=discord.ButtonStyle.link,
)
)
await interaction.response.send_message(
"Source: https://github.com/JDsProjects/Rtfm-Bot", view=view
)
await interaction.response.send_message("Source: https://github.com/JDsProjects/Rtfm-Bot", view=view)

async def setup(bot: RTFMBot) -> None:
await bot.add_cog(RTFMSlash(bot))

0 comments on commit c7d436d

Please sign in to comment.