Merge pull request #7 from ubq323/master

add tel searchrecent and tel delrecent commands
This commit is contained in:
osmarks 2022-01-19 18:31:50 +00:00 committed by GitHub
commit 66db1b344c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 94 additions and 5 deletions

View File

@ -78,4 +78,4 @@ def setup(bot):
if ext == "all":
for ext in util.extensions: bot.reload_extension(ext)
else: bot.reload_extension(ext)
await ctx.send("Done!")
await ctx.send("Done!")

View File

@ -4,10 +4,12 @@ import logging
import asyncio
import re
import hashlib
from datetime import datetime
from datetime import datetime, timedelta
import os
import pydot
import tempfile
import collections
import aiohttp
import util
import eventbus
@ -179,6 +181,88 @@ When you want to end a call, use hangup.
await ctx.send(f"Successfully deleted.")
pass
async def _find_recent(self, chs, query):
one_week = timedelta(seconds=60*60*24*7)
one_week_ago = datetime.now()-one_week
found = collections.defaultdict(list)
async def find_msgs(ch):
# the parameters to history() here might need to be tweaked
# somewhat, for more general usage
async for msg in ch.history(limit=None,after=one_week_ago):
if query in msg.content.lower():
found[ch].append(msg)
await asyncio.gather(*(find_msgs(ch) for ch in chs))
return found
@telephone.command(brief="find recent messages in channels linked to this")
@commands.check(util.extpriv_check)
async def searchrecent(self, ctx, ch: discord.TextChannel, *, query):
author = ctx.author
chs = []
for dest in eventbus.find_all_destinations(('discord',ch.id)):
if dest[0] == 'discord':
chs.append(self.bot.get_channel(dest[1]))
found = await self._find_recent(chs, query)
out = ""
for ch,ms in found.items():
out += f"{ch.mention} (`#{ch.name}` in `{ch.guild.name}`)\n"
for m in ms:
u = m.author.name if m.author else None
w = "[WH]" if m.webhook_id else ""
out += f"- {m.content[:20]} @{m.created_at} by {u} {w}\n"
for c in util.chunks(out,2000):
await author.send(c)
return found
@telephone.command(brief="delete recent messages in channels linked to this")
@commands.check(util.extpriv_check)
async def delrecent(self, ctx, ch: discord.TextChannel, *, query):
author = ctx.author
found = await self.searchrecent(ctx,ch,query=query)
await author.send("please say 'GO' to confirm or wait 10 seconds to not confirm")
try:
await self.bot.wait_for('message',check=lambda m:m.author == ctx.author and m.content == "GO" and m.channel == ctx.author.dm_channel,timeout=10)
except asyncio.TimeoutError:
await author.send("timed out")
return
async def try_delete(msg,session):
if msg.webhook_id is not None:
# note: assumes there is only one webhook we control per channel
# i think that's the case
wh_url = await self.bot.database.execute_fetchone("SELECT webhook FROM discord_webhooks WHERE channel_id = ?",(msg.channel.id,))
if wh_url is None:
await author.send(f"no access to webhook: {msg.id} {msg.channel.mention} {msg.jump_url}")
return
wh_url = wh_url['webhook']
wh = discord.Webhook.from_url(wh_url,session=session)
await wh.delete_message(msg.id)
else:
try:
await msg.delete()
except discord.errors.Forbidden:
await author.send(f"!!! couldn't delete msg {msg.id} in {msg.channel.mention}")
msgs = []
for q in found.values():
msgs.extend(q)
async with aiohttp.ClientSession() as session:
await asyncio.gather(*(try_delete(msg,session) for msg in msgs))
await author.send("done")
@telephone.command(brief="Generate a webhook")
@commands.check(util.server_mod_check)
async def init_webhook(self, ctx):
@ -223,7 +307,7 @@ When you want to end a call, use hangup.
if address == originating_address: return await ctx.send(embed=util.error_embed("A channel cannot dial itself. That means *you*, Gibson."))
recv_info = await self.get_addr_config(address)
if not recv_info: return await ctx.send(embed=util.error_embed("Destination address not found. Please check for typos and/or antimemes."))
current_call = await self.bot.database.execute_fetchone("SELECT * FROM calls WHERE from_id = ?", (originating_address,))
if current_call: return await ctx.send(embed=util.error_embed(f"A call is already open (to {current_call['to_id']}) from this channel. Currently, only one outgoing call is permitted at a time."))
@ -348,4 +432,4 @@ When you want to end a call, use hangup.
def setup(bot):
cog = Telephone(bot)
bot.add_cog(cog)
asyncio.create_task(cog.initial_load_webhooks())
asyncio.create_task(cog.initial_load_webhooks())

View File

@ -327,4 +327,9 @@ def random_id():
second_time -= SIMPLEFLAKE_EPOCH
millisecond_time = int(second_time * 1000)
randomness = random.getrandbits(SIMPLEFLAKE_RANDOM_LENGTH)
return (millisecond_time << SIMPLEFLAKE_TIMESTAMP_SHIFT) + randomness
return (millisecond_time << SIMPLEFLAKE_TIMESTAMP_SHIFT) + randomness
def chunks(source, length):
for i in range(0, len(source), length):
yield source[i : i+length]