enhancements for view commands
All checks were successful
Build and Push Docker Image / build (push) Successful in 13s

This commit is contained in:
Corban-Lee Jones 2024-08-23 17:47:01 +01:00
parent 2a1aaa689e
commit e8a9c270e4
2 changed files with 100 additions and 15 deletions

View File

@ -1,4 +1,11 @@
**unreleased v0.2.1**
- Enhancement: view filters command
- Enhancement: more control over view commands
- Enhancement: show active state of viewed subscriptions
-
**v0.2.0** **v0.2.0**
- Fix: Fetch channels if not found in bot cache (error fix) - Fix: Fetch channels if not found in bot cache (error fix)

View File

@ -12,11 +12,11 @@ import validators
from feedparser import FeedParserDict, parse from feedparser import FeedParserDict, parse
from discord.ext import commands from discord.ext import commands
from discord import Interaction, TextChannel, Embed, Colour from discord import Interaction, TextChannel, Embed, Colour
from discord.app_commands import Choice, Group, autocomplete, rename, command from discord.app_commands import Choice, choices, Group, autocomplete, rename, command
from discord.errors import Forbidden from discord.errors import Forbidden
from api import API from api import API
from feed import Subscription, TrackedContent from feed import Subscription, TrackedContent, ContentFilter
from utils import ( from utils import (
Followup, Followup,
PaginationView, PaginationView,
@ -78,6 +78,12 @@ async def validate_rss_source(nickname: str, url: str) -> Tuple[str | None, Feed
return None, feed return None, feed
tri_choices = [
Choice(name="Yes", value=2),
Choice(name="No (default)", value=1),
Choice(name="All", value=0),
]
class CommandsCog(commands.Cog): class CommandsCog(commands.Cog):
""" """
@ -109,14 +115,13 @@ class CommandsCog(commands.Cog):
def formatdata(index, item): def formatdata(index, item):
item = Subscription.from_dict(item) item = Subscription.from_dict(item)
channels = f"{item.channels_count}{' channels' if item.channels_count != 1 else ' channel'}"
filters = f"{len(item.filters)}{' filters' if len(item.filters) != 1 else ' filter'}"
notes = item.extra_notes[:25] + "..." if len(item.extra_notes) > 28 else item.extra_notes
links = f"[RSS Link]({item.url}) · [API Link]({API.API_EXTERNAL_ENDPOINT}subscription/{item.id}/)"
description = f"{channels}, {filters}\n" notes = item.extra_notes[:25] + "..." if len(item.extra_notes) > 28 else item.extra_notes
description += f"{notes}\n" if notes else "" links = f"[RSS Link]({item.url}) • [API Link]({API.API_EXTERNAL_ENDPOINT}subscription/{item.id}/)"
activeness = "✅ `enabled`" if item.active else "🚫 `disabled`"
description = f"🆔 `{item.id}`\n{activeness}\n#️⃣ `{item.channels_count}` 🔽 `{len(item.filters)}`\n"
description = f"{notes}\n" + description if notes else description
description += links description += links
key = f"{index}. {item.name}" key = f"{index}. {item.name}"
@ -145,29 +150,48 @@ class CommandsCog(commands.Cog):
await pagination.send() await pagination.send()
@view_group.command(name="tracked-content") @view_group.command(name="tracked-content")
async def cmd_list_tracked(self, inter: Interaction, search: str = ""): @choices(blocked=tri_choices)
"""List Tracked Content from this server, or a given sub""" async def cmd_list_tracked(self, inter: Interaction, search: str = "", blocked: Choice[int] = 1):
"""List Tracked Content from this server""" # TODO: , or a given sub
await inter.response.defer() await inter.response.defer()
# If the user picks an option it's an instance of `Choice` otherwise `str`
# Can't figure a way to select a default choices, so blame discordpy for this mess.
if isinstance(blocked, Choice):
blocked = blocked.value
def formatdata(index, item): def formatdata(index, item):
item = TrackedContent.from_dict(item) item = TrackedContent.from_dict(item)
sub = Subscription.from_dict(item.subscription) sub = Subscription.from_dict(item.subscription)
links = f"[Content Link]({item.url}) · [Message Link](https://discord.com/channels/{sub.guild_id}/{item.channel_id}/{item.message_id}/)" links = f"[Content Link]({item.url}) · [Message Link](https://discord.com/channels/{sub.guild_id}/{item.channel_id}/{item.message_id}/) · [API Link]({API.API_EXTERNAL_ENDPOINT}tracked-content/{item.id}/)"
description = f"Subscription: {sub.name}\n{links}" delivery_state = "✅ Delivered" if not item.blocked else "🚫 Blocked"
key = f"{item.id}. {item.title}" description = f"🆔 `{item.id}`\n"
description += f"{delivery_state}\n" if blocked == 0 else ""
description += f"➡️ *{sub.name}*\n{links}"
key = f"{index}. {item.title}"
return key, description return key, description
def determine_blocked():
match blocked:
case 0: return ""
case 1: return "false"
case 2: return "true"
case _: return ""
async def getdata(page: int, pagesize: int): async def getdata(page: int, pagesize: int):
async with aiohttp.ClientSession() as session: async with aiohttp.ClientSession() as session:
api = API(self.bot.api_token, session) api = API(self.bot.api_token, session)
is_blocked = determine_blocked()
return await api.get_tracked_content( return await api.get_tracked_content(
subscription__guild_id=inter.guild_id, subscription__guild_id=inter.guild_id,
blocked=is_blocked,
page=page, page=page,
page_size=pagesize, page_size=pagesize,
search=search search=search,
) )
embed = Followup(f"Tracked Content in {inter.guild.name}").info()._embed embed = Followup(f"Tracked Content in {inter.guild.name}").info()._embed
@ -182,6 +206,60 @@ class CommandsCog(commands.Cog):
) )
await pagination.send() await pagination.send()
@view_group.command(name="filters")
async def cmd_list_filters(self, inter: Interaction, search: str = ""):
"""List Filters from this server."""
await inter.response.defer()
def formatdata(index, item):
item = ContentFilter.from_dict(item)
matching_algorithm = get_algorithm_name(item.matching_algorithm)
whitelist = "Whitelist" if item.is_whitelist else "Blacklist"
sensitivity = "Case insensitive" if item.is_insensitive else "Case sensitive"
description = f"🆔 `{item.id}`\n"
description += f"🔄 `{matching_algorithm}`\n🟰 `{item.match}`\n"
description += f"✅ `{whitelist}` 🔠 `{sensitivity}`\n"
description += f"[API Link]({API.API_EXTERNAL_ENDPOINT}filter/{item.id}/)"
key = f"{index}. {item.name}"
return key, description
def get_algorithm_name(matching_algorithm: int):
match matching_algorithm:
case 0: return "None"
case 1: return "Any word"
case 2: return "All words"
case 3: return "Exact match"
case 4: return "Regex match"
case 5: return "Fuzzy match"
case _: return "unknown"
async def getdata(page, pagesize):
async with aiohttp.ClientSession() as session:
api = API(self.bot.api_token, session)
return await api.get_filters(
guild_id=inter.guild_id,
page=page,
page_size=pagesize,
search=search
)
embed = Followup(f"Filters in {inter.guild.name}").info()._embed
pagination = PaginationView(
self.bot,
inter=inter,
embed=embed,
getdata=getdata,
formatdata=formatdata,
pagesize=10,
initpage=1
)
await pagination.send()
# Group for test related commands # Group for test related commands
test_group = Group( test_group = Group(
name="test", name="test",