浏览代码

Reporting to guild or home. Ignoring users.

root 3 年之前
父节点
当前提交
85f7b3d85b

+ 8 - 1
bot/commands/admin.py

@@ -5,6 +5,7 @@ from local_settings import WEB_SCHEME, WEB_HOST
 from query.guild_access_token import get_active_token, upsert_token
 from common.datetime import plus10min
 from common.logging import report
+from query.user import is_ignored
 
 def setup(bot: commands.Bot):
 	bot.add_cog(Admin(bot))
@@ -22,14 +23,20 @@ class Admin(commands.Cog):
 	)
 	@commands.has_guild_permissions(administrator=True)
 	async def chanset(self, ctx: commands.Context):
+
+		# Ignore user if on the ignore list.
+		if await is_ignored(self.bot.pg, ctx.author.id):
+			return
+
 		record = await get_active_token(self.bot.pg, ctx.guild.id)
 
 		if record:	# Check for active token
 			await ctx.send(f"Token {record['id']} is in use by {record['user']} until {plus10min(record['created'])}.")
+			await report(self.bot, ctx.guild, f"`{ctx.author}` has requested a token for `{ctx.guild.name}`, but got rejected until {plus10min(record['created'])} for use by `{record['user']}`.")
 		else:	# No active token
 			token = secrets.token_urlsafe(40)[:40]
 			await upsert_token(self.bot.pg, ctx.guild.id, ctx.author.id, token)
 
 			await ctx.author.send(f"{WEB_SCHEME}://{WEB_HOST}/config/channel-settings/{ctx.channel.id}/{token}")	# DM token
 			await ctx.send("Your access token has been sent to you in a private DM.")
-			await report(self.bot, f"`{ctx.author}` has requested a token for `{ctx.guild.name}`.")
+			await report(self.bot, ctx.guild, f"`{ctx.author}` has requested a token for `{ctx.guild.name}`.")

+ 9 - 0
bot/commands/games.py

@@ -3,6 +3,7 @@ import discord
 import random
 from typing import Optional
 from query.channel import get_games
+from query.user import is_ignored
 
 def setup(bot: commands.Bot):
 	bot.add_cog(Games(bot))
@@ -20,6 +21,10 @@ class Games(commands.Cog):
 		help="Roll two dice."
 	)
 	async def dice(self, ctx: commands.Context, amount: Optional[int], sides: Optional[int]):
+		# Ignore user if on the ignore list.
+		if await is_ignored(self.bot.pg, ctx.author.id):
+			return
+
 		if not await get_games(self.bot.pg, ctx.channel.id):
 			return
 		if not amount:
@@ -49,6 +54,10 @@ class Games(commands.Cog):
 		name="8ball"
 	)
 	async def eightball(self, ctx: commands.Context, *, question: str = None):
+		# Ignore user if on the ignore list.
+		if await is_ignored(self.bot.pg, ctx.author.id):
+			return
+
 		if not await get_games(self.bot.pg, ctx.channel.id):
 			return
 

+ 63 - 2
bot/commands/general.py

@@ -3,7 +3,9 @@ import discord
 import time
 from typing import Optional
 from query.channel import get_interact
+from query.user import ignore_user, unignore_user, is_ignored
 from common.logging import report
+from local_settings import COMMAND_PREFIX
 
 def setup(bot: commands.Bot):
 	bot.add_cog(General(bot))
@@ -21,6 +23,10 @@ class General(commands.Cog):
 		help="Test latency by polling the gateway and API."
 	)
 	async def ping(self, ctx: commands.Context):
+		# Ignore user if on the ignore list.
+		if await is_ignored(self.bot.pg, ctx.author.id):
+			return
+
 		start_time = time.time()
 		message = await ctx.send(f"Pong!\nGateway heartbeat in {round(self.bot.latency * 1000)}ms.")
 		end_time = time.time()
@@ -33,6 +39,10 @@ class General(commands.Cog):
 		help="Display some crap."
 	)
 	async def info(self, ctx: commands.Context):
+		# Ignore user if on the ignore list.
+		if await is_ignored(self.bot.pg, ctx.author.id):
+			return
+
 		"""Displays some rubbish info."""
 		embed = discord.Embed(title=f"Guild: {ctx.guild}.")
 		await ctx.send(embed=embed)
@@ -45,6 +55,10 @@ class General(commands.Cog):
 		aliases= ("say", "pm", "dm", "echo", "print")
 	)
 	async def msg(self, ctx: commands.Context, channel: Optional[discord.TextChannel], user: Optional[discord.User], *, message: str = None):
+		# Ignore user if on the ignore list.
+		if await is_ignored(self.bot.pg, ctx.author.id):
+			return
+
 		if not message:
 			if channel:
 				await ctx.send(f"What would you like me to say in {channel}?")
@@ -55,7 +69,7 @@ class General(commands.Cog):
 		elif channel:
 			if await get_interact(self.bot.pg, channel.id): # or await ctx.author.get_guild_permissions(channel.guild):
 				await channel.send(message)
-				await report(f"{ctx.author}  has sent {message} to {channel.name}")
+				await report(self.bot, ctx.guild, f"{ctx.author}  has sent {message} to {channel.name}")
 			else:
 				await ctx.send(f"Interactive mode for {channel} is deactivated.")
 		elif user:
@@ -63,7 +77,7 @@ class General(commands.Cog):
 			await report(f"{ctx.author}  has sent {message} to {user.name}")
 		else:
 			await ctx.send(message)
-			await report(self.bot, f"`{ctx.author}`  has sent `{message}` locally.")
+			await report(self.bot, ctx.guild, f"`{ctx.author}` has sent `{message}` locally.")
 
 
 	@commands.command(
@@ -72,6 +86,53 @@ class General(commands.Cog):
 		help="Update the bot's status."
 	)
 	async def status(self, ctx: commands.Context, *, text: str):
+		# Ignore user if on the ignore list.
+		if await is_ignored(self.bot.pg, ctx.author.id):
+			return
+
 		await self.bot.change_presence(activity=discord.Game(name=text))
+		await report(self.bot, f"`{ctx.author}` has set my status to `{text}`.")
+
+
+	@commands.command(
+		description="Get ignored.",
+		brief="Ignore sender",
+		help="Will have the bot ignore the user from now on."
+	)
+	async def ignoreme(self, ctx: commands.Context):
+		# Ignore user if on the ignore list.
+		if await is_ignored(self.bot.pg, ctx.author.id):
+			return
+
+		await ignore_user(self.bot.pg, ctx.author.id)
+		await ctx.send(f"To revert this use the `{COMMAND_PREFIX}unignoreme` command.")
+		await report(self.bot, f"`{ctx.author}` has requested to be ignored.")
 
 
+	@commands.command(
+		description="No longer get ingored.",
+		brief="Un-ignore sender",
+		help="No longer will the bot ignore the user."
+	)
+	async def unignoreme(self, ctx: commands.Context):
+		await unignore_user(self.bot.pg, ctx.author.id)
+		await ctx.send(f"I shall now interact with you again where my channel settings allow it.")
+		await report(self.bot, f"`{ctx.author}` has requested to be un-ignored.")
+
+	@commands.command(
+		description="Ignore status for user.",
+		brief="Check if user is ingored",
+		help="Verify if the user is being ignored."
+	)
+	async def isignored(self, ctx: commands.Context, user: Optional[discord.User]):
+		# Ignore user if on the ignore list.
+		if await is_ignored(self.bot.pg, ctx.author.id):
+			return
+
+		if not user:
+			user = ctx.author
+
+		if await is_ignored(self.bot.pg, user.id):
+			await ctx.send(f"I am ingoring `{user}`.")
+		else:
+			await ctx.send(f"I am not ignoring `{user}`.")

+ 11 - 2
bot/common/logging.py

@@ -1,5 +1,14 @@
+import discord
+from typing import Optional
 from local_settings import OUTPUT_CHANNEL
+from query.guild import get_output_channel
+
+async def report(bot, message, *, guild: Optional[discord.Guild]=None):
+    channel = bot.get_channel(OUTPUT_CHANNEL)
+    if guild:
+        message = f"`{guild}` message"
+        try: channel = bot.get_channel(get_output_channel(guild.id))
+        except:
+            pass
 
-async def report(bot, message):
-    channel = bot.get_channel(int(OUTPUT_CHANNEL))
     await channel.send(message)

+ 9 - 6
bot/events/general.py

@@ -1,10 +1,10 @@
 import logging, discord, asyncpg, random
 from discord.ext import commands
-from query.guild import update_guild
+from query.guild import update_guild, get_report_deleted, get_output_channel
 from query.channel import insert_channel, get_interact
 from query.channel_user import upsert_total_messages
 from query.user import create_user
-from query.settings import get_crew_channel
+from common.logging import report
 
 def setup(bot: commands.Bot):
 	bot.add_cog(General(bot))
@@ -20,20 +20,23 @@ class General(commands.Cog):
 	@commands.Cog.listener()
 	async def on_ready(self):
 		logging.info("Logged in as %s - %i", self.bot.user.name, self.bot.user.id)
+		await report(self.bot, f"Logged in as {self.bot.user.name} - {self.bot.user.id}.")
 
 	@commands.Cog.listener()
 	async def on_guild_join(self, guild: discord.Guild):
-		await update_guild(self.bot.pg, guild.id)
+		await update_guild(self.bot.pg, guild)
+		logging.info(f"Joined guild {guild}")
+		await report(self.bot, f"Joined guild {guild.name}.")
 
 	@commands.Cog.listener()
 	async def on_message_delete(self, message: discord.Message):
+		if await get_report_deleted(self.bot.pg, message.guild.id):
+			report(self.bot, message.guild_id, f"Message from {message.author}, in {message.channel} deleted: {message}")
 		self.last_msg = message
 
 	@commands.Cog.listener()
 	async def on_raw_member_remove(self, payload):
-		channel = bot.get_channel(get_crew_channel(self.pg))
-		if channel:
-			await channel.send(f"{payload.user} has left {payload.guild_id}")
+		report(self.bot, f"{payload.user} has left {payload.guild_id}")
 
 	@commands.Cog.listener()
 	async def on_message(self, message: discord.Message):

+ 7 - 1
bot/query/guild.py

@@ -1,4 +1,10 @@
 async def update_guild(pg, guild):
 	await pg.execute("INSERT INTO guild(guild_id) VALUES($1) ON CONFLICT DO NOTHING", guild.id)
 	for chan in guild.text_channels:
-		await pg.execute("INSERT INTO channel(channel_id, guild) VALUES($1, $2) ON CONFLICT DO NOTHING", chan.id, guild.id)
+		await pg.execute("INSERT INTO channel(channel_id, guild) VALUES($1, $2) ON CONFLICT DO NOTHING", chan.id, guild.id)
+
+async def get_output_channel(pg, guild_id):
+	return await pg.fetchval("SELECT output_channel FROM guild WHERE guild_id = $1", guild_id)
+
+async def get_report_deleted(pg, guild_id):
+	return await pg.fetchval("SELECT report_deleted FROM guild WHERE guild_id = $1", guild_id)

+ 3 - 1
bot/query/initialise_database.py

@@ -3,7 +3,9 @@ async def init_db(pg):
         "CREATE TABLE IF NOT EXISTS \
             guild (\
                 id SERIAL PRIMARY KEY, \
-                guild_id BIGINT UNIQUE NOT NULL \
+                guild_id BIGINT UNIQUE NOT NULL, \
+                output_channel BIGINT REFERENCES channel (channel_id), \
+                report_deleted BOOL DEFAULT FALSE\
             )\
         ",
         "CREATE TABLE IF NOT EXISTS \

+ 0 - 2
bot/query/settings.py

@@ -1,2 +0,0 @@
-async def get_crew_channel(pg):
-	await pg.fetchrow("SELECT crew_channel FROM settings WHERE id=1")

+ 10 - 1
bot/query/user.py

@@ -1,2 +1,11 @@
 async def create_user(pg, user_id):
-	await pg.execute("INSERT INTO \"user\"(user_id) VALUES($1) ON CONFLICT DO NOTHING", user_id)
+	await pg.execute("INSERT INTO \"user\"(user_id) VALUES($1) ON CONFLICT DO NOTHING", user_id)
+
+async def ignore_user(pg, user_id):
+	await pg.execute("UPDATE \"user\" SET ignore = TRUE WHERE user_id = $1", user_id)
+
+async def unignore_user(pg, user_id):
+	await pg.execute("UPDATE \"user\" SET ignore = FALSE WHERE user_id = $1", user_id)
+
+async def is_ignored(pg, user_id):
+	return await pg.fetchval("SELECT ignore FROM \"user\" WHERE user_id = $1", user_id)

+ 35 - 24
webgui/config/templates/config/channel_settings.html

@@ -2,35 +2,46 @@
 {% load static %}
 {% load semanticui %}
 {% block content %}
-    {% if updated %}
-        <div class="ui icon success message">
-            <i class="save icon"></i>
-            <div class="content">
-                <div class="header">
-                    Changes saved
-                </div>
-                <p>You may close the page or continue making changes.</p>
+    {% if token_invalid %}
+        <div class="ui negative message">
+            <div class="header">
+                Invalid token
             </div>
+            <p>
+                You are on Santa's naughty list now!
+            </p>
         </div>
-    {% endif %}
-    <form class= "ui form" method="post">
-        {% csrf_token %}
-        {% render_form form %}
-
-        {{ channel_settings.interact }}
-        {% if token_expired %}
-            <div class="ui negative message">
-                <div class="header">
-                    Can not save change
+    {% else %}
+        {% if updated %}
+            <div class="ui icon success message">
+                <i class="save icon"></i>
+                <div class="content">
+                    <div class="header">
+                        Changes saved
+                    </div>
+                    <p>You may close the page or continue making changes.</p>
                 </div>
-                <p>
-                  The token has expired. Ask {{ settings.APPLICATION_NAME }} for a new token on Discord.
-                </p>
             </div>
-        {% else %}
-            <button class="ui right floated inverted positive button" type="submit" value="Submit"><i class="save icon"></i>Save</button>
         {% endif %}
-    </form>
+        <form class= "ui form" method="post">
+            {% csrf_token %}
+            {% render_form form %}
+
+            {{ channel_settings.interact }}
+            {% if token_expired %}
+                <div class="ui negative message">
+                    <div class="header">
+                        Can not save change
+                    </div>
+                    <p>
+                      The token has expired. Ask {{ settings.APPLICATION_NAME }} for a new token on Discord.
+                    </p>
+                </div>
+            {% else %}
+                <button class="ui right floated inverted positive button" type="submit" value="Submit"><i class="save icon"></i>Save</button>
+            {% endif %}
+        </form>
+    {% endif %}
     
 {% endblock %}
 {% block breadcrumbs %}

+ 10 - 8
webgui/config/views.py

@@ -13,23 +13,24 @@ def channel_settings(request, channel_id, token):
 
 	# Check if token is valid.
 	#print(token.created.replace(tzinfo=None))
-	print(token.created.replace(tzinfo=None) + datetime.timedelta(hours=-1))
-	#print(token.created)
-	print(datetime.datetime.now() - datetime.timedelta(minutes=10))
+	#print(token.created.replace(tzinfo=None) + datetime.timedelta(hours=-1))
+	#print(datetime.datetime.now() - datetime.timedelta(minutes=10))
+	token_expired = True
 	if token.created.replace(tzinfo=None) + datetime.timedelta(hours=-1) > datetime.datetime.now() - datetime.timedelta(minutes=10):
 		token_expired = False
-	else:
-		token_expired = True
+
+	token_invalid = True
+	if token.guild == channel.guild:
+		token_invalid = False
+
 
 	updated = False
-	if request.method == 'POST' and not token_expired:
-		print("Token valid")
+	if request.method == 'POST' and not token_expired and not token_invalid:
 		form = ChannelSettingsForm(request.POST, instance=channel)
 		if form.is_valid():
 			form.save()
 			updated = True
 	else:
-		print("Token expired")
 		form = ChannelSettingsForm(instance=channel)
 
 	context = {
@@ -40,5 +41,6 @@ def channel_settings(request, channel_id, token):
 		'form': form,
 		'updated': updated,
 		'token_expired': token_expired,
+		'token_invalid': token_invalid,
 	}
 	return render(request, 'config/channel_settings.html', context)