From 8c58585af159bc3f8382128d8198377cb1235486 Mon Sep 17 00:00:00 2001 From: Dan Date: Sun, 30 Jun 2024 17:35:51 -0400 Subject: [PATCH] FEAT: added new policy requirements for Discord --- config.py | 4 +- main.py | 10 +++++ modules/admin/data_privacy.py | 51 ++++++++++++++++++++++++ modules/admin/terms_privacy.py | 73 ++++++++++++++++++++++++++++++++++ 4 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 modules/admin/data_privacy.py create mode 100644 modules/admin/terms_privacy.py diff --git a/config.py b/config.py index f0e9599..9c0e689 100644 --- a/config.py +++ b/config.py @@ -21,7 +21,9 @@ config = { 'music': {'enabled': True}, 'youtube': {'enabled': True}, 'twitch': {'enabled': True}, - 'update': {'enabled': True} + 'update': {'enabled': True}, + 'data_privacy': {'enabled': True}, + 'term_privacy': {'enabled': True} }, 'UPDATE_BRANCH': 'dev-rework' } diff --git a/main.py b/main.py index f8d18b7..2139129 100644 --- a/main.py +++ b/main.py @@ -64,6 +64,16 @@ class Selena(discord.Client): branch_name = config.get('UPDATE_BRANCH', 'dev-rework') update_setup(self, branch=branch_name) + if config['modules']['data_privacy']['enabled']: + from modules.admin.data_privacy import DataPrivacy + data_privacy = DataPrivacy(self) + data_privacy.setup(self.tree) + + if config['modules']['terms_privacy']['enabled']: + from modules.admin.terms_privacy import TermsPrivacy + terms_privacy = TermsPrivacy(self) + terms_privacy.setup(self.tree) + bot = Selena() diff --git a/modules/admin/data_privacy.py b/modules/admin/data_privacy.py new file mode 100644 index 0000000..e6b3013 --- /dev/null +++ b/modules/admin/data_privacy.py @@ -0,0 +1,51 @@ +import discord +from discord import app_commands +import sqlite3 + + +class DataPrivacy: + def __init__(self, bot): + self.bot = bot + self.db_path = 'data/selena.db' + + async def fetch_user_data(self, user_id): + conn = sqlite3.connect(self.db_path) + cursor = conn.cursor() + cursor.execute("SELECT * FROM user_data WHERE user_id = ?", (user_id,)) + data = cursor.fetchall() + conn.close() + return data + + async def delete_user_data(self, user_id): + conn = sqlite3.connect(self.db_path) + cursor = conn.cursor() + cursor.execute("DELETE FROM user_data WHERE user_id = ?", (user_id,)) + conn.commit() + conn.close() + + def setup(self, tree: app_commands.CommandTree): + @tree.command(name="request_data", description="Request your stored data") + async def request_data_command(interaction: discord.Interaction): + user_id = interaction.user.id + data = await self.fetch_user_data(user_id) + if data: + await interaction.response.send_message(f"Your data: {data}", ephemeral=True) + else: + await interaction.response.send_message("No data found for your user.", ephemeral=True) + + @tree.command(name="delete_data", description="Request deletion of your stored data") + async def delete_data_command(interaction: discord.Interaction): + user_id = interaction.user.id + await self.delete_user_data(user_id) + await interaction.response.send_message("Your data has been deleted.", ephemeral=True) + + if not tree.get_command("request_data"): + tree.add_command(request_data_command) + + if not tree.get_command("delete_data"): + tree.add_command(delete_data_command) + + +def setup(bot): + data_privacy = DataPrivacy(bot) + data_privacy.setup(bot.tree) diff --git a/modules/admin/terms_privacy.py b/modules/admin/terms_privacy.py new file mode 100644 index 0000000..9956464 --- /dev/null +++ b/modules/admin/terms_privacy.py @@ -0,0 +1,73 @@ +import discord +from discord import app_commands +import sqlite3 + + +class TermsPrivacy: + def __init__(self, bot): + self.bot = bot + self.db_path = 'data/selena.db' + self.privacy_policy_url = "https://advtech92.github.io/selena-website/privacy_policy.html" + self.terms_of_service_url = "https://advtech92.github.io/selena-website/terms_of_service.html" + + async def user_opt_out(self, user_id): + conn = sqlite3.connect(self.db_path) + cursor = conn.cursor() + cursor.execute("INSERT INTO opt_out_users (user_id) VALUES (?)", (user_id,)) + conn.commit() + conn.close() + + async def user_opt_in(self, user_id): + conn = sqlite3.connect(self.db_path) + cursor = conn.cursor() + cursor.execute("DELETE FROM opt_out_users WHERE user_id = ?", (user_id,)) + conn.commit() + conn.close() + + async def is_user_opted_out(self, user_id): + conn = sqlite3.connect(self.db_path) + cursor = conn.cursor() + cursor.execute("SELECT 1 FROM opt_out_users WHERE user_id = ?", (user_id,)) + result = cursor.fetchone() + conn.close() + return result is not None + + def setup(self, tree: app_commands.CommandTree): + @tree.command(name="privacy_policy", description="Show the privacy policy") + async def privacy_policy_command(interaction: discord.Interaction): + embed = discord.Embed(title="Privacy Policy", url=self.privacy_policy_url, description="Read our privacy policy.", color=discord.Color.blue()) + await interaction.response.send_message(embed=embed, ephemeral=True) + + @tree.command(name="terms_of_service", description="Show the terms of service") + async def terms_of_service_command(interaction: discord.Interaction): + embed = discord.Embed(title="Terms of Service", url=self.terms_of_service_url, description="Read our terms of service.", color=discord.Color.blue()) + await interaction.response.send_message(embed=embed, ephemeral=True) + + @tree.command(name="opt_out", description="Opt out of using the bot") + async def opt_out_command(interaction: discord.Interaction): + user_id = interaction.user.id + await self.user_opt_out(user_id) + await interaction.response.send_message("You have opted out of using the bot.", ephemeral=True) + + @tree.command(name="opt_in", description="Opt back in to using the bot") + async def opt_in_command(interaction: discord.Interaction): + user_id = interaction.user.id + await self.user_opt_in(user_id) + await interaction.response.send_message("You have opted back in to using the bot.", ephemeral=True) + + if not tree.get_command("privacy_policy"): + tree.add_command(privacy_policy_command) + + if not tree.get_command("terms_of_service"): + tree.add_command(terms_of_service_command) + + if not tree.get_command("opt_out"): + tree.add_command(opt_out_command) + + if not tree.get_command("opt_in"): + tree.add_command(opt_in_command) + + +def setup(bot): + terms_privacy = TermsPrivacy(bot) + terms_privacy.setup(bot.tree)