mirror of
https://github.com/Lilac-Rose/Lacie.git
synced 2026-08-22 00:35:05 -05:00
emote credits: add /emote_credits_resolve admin command
ping protect: use pronoun roles in disabled-ping replies chore: remove stray =5.0 file, clean up constants emote credits: - Add /emote_credits_resolve — scans credits where artist starts with "@", fuzzes against guild members (username, global_name, display_name), rewrites matches as <@id> mentions; reports resolved vs not-found in chunked ephemeral output ping protect: - Add _get_subject_pronoun() — reads pronoun roles (he/him, she/her, it/its) to return the correct subject pronoun - Add _get_verb() — returns "has" or "have" to match - Reply now reads e.g. "She has pings disabled" instead of always "they have pings disabled" chore: - Delete =5.0 (stray file from unquoted pip install shell redirect) - Remove unused ARG channel ID constants from utils/constants.py
This commit is contained in:
@@ -406,6 +406,69 @@ class EmoteCredits(ModerationBase, commands.Cog):
|
||||
summary += f"Total missing: {len(missing_emojis) + len(missing_stickers)}"
|
||||
await interaction.followup.send(summary)
|
||||
|
||||
@app_commands.command(name="emote_credits_resolve", description="[Admin] Auto-convert @username credits to user mentions where possible")
|
||||
@ModerationBase.is_admin()
|
||||
async def emote_credits_resolve(self, interaction: discord.Interaction):
|
||||
await interaction.response.defer(ephemeral=True)
|
||||
guild = interaction.guild
|
||||
if not guild:
|
||||
await interaction.followup.send("Server only.", ephemeral=True)
|
||||
return
|
||||
|
||||
# Fetch all members so we can search by username/display name
|
||||
await guild.chunk()
|
||||
|
||||
async with aiosqlite.connect(self.db_path) as conn:
|
||||
async with conn.execute(
|
||||
"SELECT emote_name, artist FROM emote_credits WHERE artist LIKE '@%'"
|
||||
) as cursor:
|
||||
rows = await cursor.fetchall()
|
||||
|
||||
if not rows:
|
||||
await interaction.followup.send("No raw @username credits found.", ephemeral=True)
|
||||
return
|
||||
|
||||
resolved = []
|
||||
skipped = []
|
||||
|
||||
async with aiosqlite.connect(self.db_path) as conn:
|
||||
for emote_name, artist in rows:
|
||||
# Strip leading @ and any trailing whitespace
|
||||
raw_name = artist.lstrip("@").strip()
|
||||
|
||||
# Try to match against username, global_name, or display_name (case-insensitive)
|
||||
match = discord.utils.find(
|
||||
lambda m, n=raw_name: (
|
||||
m.name.lower() == n.lower()
|
||||
or (m.global_name and m.global_name.lower() == n.lower())
|
||||
or m.display_name.lower() == n.lower()
|
||||
),
|
||||
guild.members
|
||||
)
|
||||
|
||||
if match:
|
||||
new_artist = f"<@{match.id}>"
|
||||
await conn.execute(
|
||||
"UPDATE emote_credits SET artist = ? WHERE LOWER(emote_name) = LOWER(?)",
|
||||
(new_artist, emote_name)
|
||||
)
|
||||
resolved.append(f"`{emote_name}`: {artist} → {new_artist}")
|
||||
else:
|
||||
skipped.append(f"`{emote_name}`: {artist}")
|
||||
|
||||
await conn.commit()
|
||||
|
||||
lines = []
|
||||
if resolved:
|
||||
lines.append(f"**Resolved ({len(resolved)}):**\n" + "\n".join(resolved))
|
||||
if skipped:
|
||||
lines.append(f"**Not found ({len(skipped)}):**\n" + "\n".join(skipped))
|
||||
|
||||
# Split into chunks if needed to stay under Discord's message limit
|
||||
output = "\n\n".join(lines)
|
||||
for chunk in [output[i:i+1900] for i in range(0, len(output), 1900)]:
|
||||
await interaction.followup.send(chunk, ephemeral=True)
|
||||
|
||||
@commands.command(name="missing_credits")
|
||||
@ModerationBase.is_admin()
|
||||
async def missing_credits_text(self, ctx):
|
||||
|
||||
@@ -66,6 +66,21 @@ class PingProtect(commands.GroupCog, name="noping"):
|
||||
)
|
||||
return await cursor.fetchone() is not None
|
||||
|
||||
def _get_subject_pronoun(self, member: discord.Member | None) -> str:
|
||||
if not member:
|
||||
return "They"
|
||||
role_names = {r.name.lower() for r in member.roles}
|
||||
if "he/him" in role_names:
|
||||
return "He"
|
||||
if "she/her" in role_names:
|
||||
return "She"
|
||||
if "it/its" in role_names:
|
||||
return "It"
|
||||
return "They"
|
||||
|
||||
def _get_verb(self, pronoun: str) -> str:
|
||||
return "have" if pronoun == "They" else "has"
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_message(self, message: discord.Message):
|
||||
if message.author.bot or not message.guild:
|
||||
@@ -96,8 +111,12 @@ class PingProtect(commands.GroupCog, name="noping"):
|
||||
await db.commit()
|
||||
await message.reply("Please don't ping faer", mention_author=False)
|
||||
else:
|
||||
name = member.display_name if member else user.name
|
||||
await message.reply(f"Please don't ping {name}, they have pings disabled.", mention_author=False)
|
||||
pronoun = self._get_subject_pronoun(member)
|
||||
verb = self._get_verb(pronoun)
|
||||
await message.reply(
|
||||
f"Please don't ping {user.name}. {pronoun} {verb} pings disabled.",
|
||||
mention_author=False
|
||||
)
|
||||
|
||||
@app_commands.command(name="allow", description="Allow someone to ping you")
|
||||
@app_commands.describe(user="The user to allow")
|
||||
|
||||
@@ -20,12 +20,6 @@ BOT_TRAP_ROLE_ID = 1439354601672282335
|
||||
SERVER_ADMIN_ROLE_ID = 952560403970416722
|
||||
BOT_DEV_ROLE_ID = 1470439484549234866
|
||||
|
||||
# --- ARG ---
|
||||
ARG_ANNOUNCEMENT_CHANNEL_ID = 876772600704020533 # #chat — initial anomaly post
|
||||
ARG_LORE_CHANNEL_ID = 1229700500010569750 # #lore-and-theories — hints + 0187: reveal
|
||||
ARG_ARCHIVE_CHANNEL_ID = 1478997241565020280 # #the-archive — visitor arrival announcements
|
||||
ARG_ARCHIVIST_ROLE_NAME = "Archivist"
|
||||
|
||||
# --- Emojis ---
|
||||
SALT_EMOJI_ID = 1074583707459010560
|
||||
|
||||
|
||||
Reference in New Issue
Block a user