FEAT: Added Privacy Policy/TOS

REF: Changed Birthday and Currency Modules to use a single Database (cut down on some space)
FEAT: Added a list of always enabled modules and modules that can be disabled.
This commit is contained in:
Dan 2024-06-21 15:01:11 -04:00
parent 3742029410
commit c78912783a
7 changed files with 195 additions and 18 deletions

2
.gitignore vendored
View File

@ -160,4 +160,4 @@ cython_debug/
# option (not recommended) you can uncomment the following to ignore the entire idea folder. # option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/ #.idea/
/birthdays.db /selena.db

View File

@ -13,3 +13,10 @@ PLEX_TOKEN = os.getenv("PLEX_TOKEN")
TWITCH_CLIENT_ID = os.getenv("TWITCH_CLIENT_ID") TWITCH_CLIENT_ID = os.getenv("TWITCH_CLIENT_ID")
TWITCH_CLIENT_SECRET = os.getenv("TWITCH_CLIENT_SECRET") TWITCH_CLIENT_SECRET = os.getenv("TWITCH_CLIENT_SECRET")
TWITCH_CHANNEL = os.getenv("TWITCH_CHANNEL") TWITCH_CHANNEL = os.getenv("TWITCH_CHANNEL")
# List of enabled modules
ENABLED_MODULES = [
"modules.media.spotify_module",
"modules.user.birthday_module",
"modules.money.currency_module",
]

22
main.py
View File

@ -1,5 +1,9 @@
import discord import discord
import config import config
import logging
# Set up logging
logging.basicConfig(level=logging.DEBUG)
class Selena(discord.Client): class Selena(discord.Client):
@ -11,21 +15,25 @@ class Selena(discord.Client):
guild = discord.Object(id=config.DISCORD_GUILD_ID) guild = discord.Object(id=config.DISCORD_GUILD_ID)
await self.load_extensions() await self.load_extensions()
self.tree.copy_global_to(guild=guild) self.tree.copy_global_to(guild=guild)
await self.tree.sync(guild=guild) await self.tree.sync()
async def load_extension(self, name): async def load_extension(self, name):
module = __import__(name, fromlist=["setup"]) module = __import__(name, fromlist=["setup"])
await module.setup(self) await module.setup(self)
async def load_extensions(self): async def load_extensions(self):
extensions = [ # Mandatory modules that cannot be disabled
mandatory_modules = [
"modules.admin.logger_module", "modules.admin.logger_module",
"modules.media.spotify_module", "modules.admin.policy_module",
"modules.user.birthday_module",
"modules.money.currency_module",
# Add other modules here
] ]
for extension in extensions:
# Load mandatory modules
for extension in mandatory_modules:
await self.load_extension(extension)
# Load enabled modules from configuration
for extension in config.ENABLED_MODULES:
await self.load_extension(extension) await self.load_extension(extension)
async def on_ready(self): async def on_ready(self):

View File

@ -0,0 +1,109 @@
import discord
from discord import app_commands
import logging
logger = logging.getLogger(__name__)
class PolicyModule:
def __init__(self, bot):
self.bot = bot
self.add_commands()
def add_commands(self):
@app_commands.command(
name="privacy_policy", description="View the Privacy Policy"
)
async def privacy_policy(interaction: discord.Interaction):
await interaction.response.defer()
try:
privacy_policy_text = """
**Privacy Policy**
1. **Data Collection**
- We collect your Discord user ID and messages sent to the bot.
- No sensitive personal data is collected.
2. **Data Usage**
- Your data is used to provide and improve the bot's functionality.
- We do not share your data with third parties.
3. **Data Storage**
- Data is stored securely on our servers.
- Data is retained for as long as necessary to provide our services.
4. **Your Rights**
- You have the right to access, modify, and delete your data.
- To exercise these rights, contact the bot admin.
5. **Changes to Privacy Policy**
- We may update this policy from time to time.
- You will be notified of any significant changes.
6. **Contact**
- For any questions about this policy, contact the bot admin.
"""
await interaction.followup.send(
embed=discord.Embed(
title="Privacy Policy",
description=privacy_policy_text,
color=discord.Color.blue()
)
)
logger.info(f"User {interaction.user.id} viewed the privacy policy")
except Exception as e:
await interaction.followup.send(f"An error occurred: {e}")
logger.error(f"Error in privacy_policy command: {e}")
@app_commands.command(
name="terms_of_service", description="View the Terms of Service"
)
async def terms_of_service(interaction: discord.Interaction):
await interaction.response.defer()
try:
tos_text = """
**Terms of Service**
1. **Acceptance of Terms**
- By using this bot, you agree to these terms.
- If you do not agree, do not use the bot.
2. **Use of the Bot**
- You must follow all applicable laws and regulations.
- Do not use the bot for any illegal or unauthorized purpose.
3. **Changes to Terms**
- We may update these terms from time to time.
- You will be notified of any significant changes.
4. **Termination**
- We reserve the right to terminate or restrict your access to the bot at any time, without notice or liability.
5. **Disclaimer of Warranties**
- The bot is provided "as is" without warranties of any kind.
- We do not guarantee that the bot will be error-free or uninterrupted.
6. **Limitation of Liability**
- We shall not be liable for any damages arising from your use of the bot.
7. **Contact**
- For any questions about these terms, contact the bot admin.
"""
await interaction.followup.send(
embed=discord.Embed(
title="Terms of Service",
description=tos_text,
color=discord.Color.blue()
)
)
logger.info(f"User {interaction.user.id} viewed the terms of service")
except Exception as e:
await interaction.followup.send(f"An error occurred: {e}")
logger.error(f"Error in terms_of_service command: {e}")
self.bot.tree.add_command(privacy_policy)
self.bot.tree.add_command(terms_of_service)
async def setup(bot):
PolicyModule(bot)

30
modules/data/db.py Normal file
View File

@ -0,0 +1,30 @@
import sqlite3
def initialize_db():
conn = sqlite3.connect('selena.db')
cursor = conn.cursor()
# Birthdays table
cursor.execute('''
CREATE TABLE IF NOT EXISTS birthdays (
user_id TEXT PRIMARY KEY,
birthday TEXT
)
''')
# Currency table
cursor.execute('''
CREATE TABLE IF NOT EXISTS currency (
user_id TEXT PRIMARY KEY,
balance INTEGER,
last_earned TIMESTAMP
)
''')
conn.commit()
conn.close()
def get_connection():
return sqlite3.connect('selena.db')

View File

@ -1,15 +1,19 @@
# Flake8:noqa: E501
import discord import discord
from discord import app_commands from discord import app_commands
import sqlite3 import sqlite3
import logging import logging
import random import random
from .currency_db import initialize_db, get_connection from datetime import datetime, timedelta
from modules.data.db import initialize_db, get_connection
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
initialize_db() initialize_db()
class CurrencyModule: class CurrencyModule:
COOLDOWN_PERIOD = timedelta(minutes=5) # Set the cooldown period here
def __init__(self, bot): def __init__(self, bot):
self.bot = bot self.bot = bot
self.add_commands() self.add_commands()
@ -21,15 +25,34 @@ class CurrencyModule:
async def earn_currency(interaction: discord.Interaction): async def earn_currency(interaction: discord.Interaction):
await interaction.response.defer() await interaction.response.defer()
try: try:
amount = random.choices([random.randint(1, 10), 100], [0.99, 0.01])[0]
conn = get_connection() conn = get_connection()
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute('INSERT OR IGNORE INTO currency (user_id, balance) VALUES (?, ?)', user_id = str(interaction.user.id)
(str(interaction.user.id), 0))
cursor.execute('UPDATE currency SET balance = balance + ? WHERE user_id = ?', # Check cooldown
(amount, str(interaction.user.id))) cursor.execute('SELECT last_earned FROM currency WHERE user_id = ?', (user_id,))
result = cursor.fetchone()
if result and result[0]:
last_earned = datetime.fromisoformat(result[0])
if datetime.now() - last_earned < CurrencyModule.COOLDOWN_PERIOD:
await interaction.followup.send(
embed=discord.Embed(
title="Earn Currency",
description="You are on cooldown. Please try again later.",
color=discord.Color.red()
)
)
conn.close()
logger.info(f"User {user_id} attempted to earn currency but is on cooldown.")
return
amount = random.choices([random.randint(1, 10), 100], [0.99, 0.01])[0]
cursor.execute('INSERT OR IGNORE INTO currency (user_id, balance, last_earned) VALUES (?, ?, ?)',
(user_id, 0, datetime.now().isoformat()))
cursor.execute('UPDATE currency SET balance = balance + ?, last_earned = ? WHERE user_id = ?',
(amount, datetime.now().isoformat(), user_id))
conn.commit() conn.commit()
cursor.execute('SELECT balance FROM currency WHERE user_id = ?', (str(interaction.user.id),)) cursor.execute('SELECT balance FROM currency WHERE user_id = ?', (user_id,))
new_balance = cursor.fetchone()[0] new_balance = cursor.fetchone()[0]
conn.close() conn.close()
await interaction.followup.send( await interaction.followup.send(
@ -39,7 +62,7 @@ class CurrencyModule:
color=discord.Color.green() color=discord.Color.green()
) )
) )
logger.info(f"User {interaction.user.id} earned {amount} currency. New balance: {new_balance}") logger.info(f"User {user_id} earned {amount} currency. New balance: {new_balance}")
except Exception as e: except Exception as e:
await interaction.followup.send(f"An error occurred: {e}") await interaction.followup.send(f"An error occurred: {e}")
logger.error(f"Error in earn_currency command: {e}") logger.error(f"Error in earn_currency command: {e}")

View File

@ -1,9 +1,9 @@
# Flake8: noqa # Flake8:noqa: E501
import discord import discord
from discord import app_commands from discord import app_commands
import sqlite3 import sqlite3
import logging import logging
from .birthday_db import initialize_db, get_connection from modules.data.db import initialize_db, get_connection
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
initialize_db() initialize_db()