-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathbot.py
More file actions
176 lines (138 loc) · 6.37 KB
/
bot.py
File metadata and controls
176 lines (138 loc) · 6.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
import os
import re
from dotenv import load_dotenv
import discord
from discord.ext import commands
from discord import app_commands
from src.main import run_model
from flask import Flask
from threading import Thread
import logging
app = Flask('')
@app.route('/')
def home():
return "alive!"
def run():
log = logging.getLogger('werkzeug')
log.setLevel(logging.ERROR)
app.run(host='0.0.0.0', port=8080)
Thread(target=run).start()
load_dotenv()
TOKEN = os.getenv("DISCORD_TOKEN")
WATCHLIST_FILE = "watchlist.txt"
intents = discord.Intents.default()
bot = commands.Bot(command_prefix="!", intents=intents)
@bot.event
async def on_ready():
try:
synced = await bot.tree.sync()
print(f"Synced {len(synced)} command(s)")
except Exception as e:
print(f"Failed to sync commands: {e}")
print(f"Logged in as {bot.user} (ID: {bot.user.id})")
@bot.tree.command(name="ping", description="Replies with Pong!")
async def ping(interaction: discord.Interaction):
await interaction.response.send_message("Pong!")
@bot.tree.command(name="recommend", description="Get 1 recommendation based on your watchlist")
async def recommend(interaction: discord.Interaction):
await interaction.response.defer()
if not os.path.exists(WATCHLIST_FILE):
await interaction.followup.send("Your watchlist is empty. Add some movies first!")
return
with open(WATCHLIST_FILE, "r", encoding="utf-8") as f:
titles = [line.strip() for line in f if line.strip()]
if not titles:
await interaction.followup.send("Your watchlist is empty. Add some movies first!")
return
results = await run_model(titles, top_n=1)
await interaction.followup.send(results[0])
@bot.tree.command(name="recommend_n", description="Get N recommendations based on your watchlist")
async def recommend_n(interaction: discord.Interaction, number: int):
await interaction.response.defer()
if not os.path.exists(WATCHLIST_FILE):
await interaction.followup.send("Your watchlist is empty. Add some movies first!")
return
with open(WATCHLIST_FILE, "r", encoding="utf-8") as f:
titles = [line.strip() for line in f if line.strip()]
if not titles:
await interaction.followup.send("Your watchlist is empty. Add some movies first!")
return
results = await run_model(titles, top_n=number)
combined = "\n\n".join(results)
if len(combined) <= 2000:
await interaction.followup.send(combined)
else:
for i in range(0, len(combined), 1900):
await interaction.followup.send(combined[i:i+1900])
class MovieListModal(discord.ui.Modal, title="Add Movies to Watchlist"):
movies_input = discord.ui.TextInput(
label="Movie Titles",
style=discord.TextStyle.paragraph,
placeholder="Enter movie titles (one per line or comma-separated)...",
required=True,
max_length=2000
)
async def on_submit(self, interaction: discord.Interaction):
await interaction.response.defer()
raw_titles = re.split(r"\d+\.\s*|,|\n|\r", self.movies_input.value)
titles = [re.sub(r"\[.*?\]", "", t).strip(" :.-") for t in raw_titles if t.strip()]
if not titles:
await interaction.followup.send("No valid movie titles found in your input.")
return
with open(WATCHLIST_FILE, "a", encoding="utf-8") as f:
for title in titles:
f.write(title + "\n")
await interaction.followup.send(f"Added {len(titles)} movies to your watchlist.")
@bot.tree.command(name="add_list", description="Paste multiple movie titles at once")
async def add_list(interaction: discord.Interaction):
modal = MovieListModal()
await interaction.response.send_modal(modal)
@bot.tree.command(name="add_movie", description="Add a single movie to your watchlist")
async def add_movie(interaction: discord.Interaction, movie: str):
movie = re.sub(r"\[.*?\]", "", movie).strip(" :.-")
if not movie:
await interaction.response.send_message("Invalid movie title.")
return
with open(WATCHLIST_FILE, "a", encoding="utf-8") as f:
f.write(movie + "\n")
await interaction.response.send_message(f"Added **{movie}** to your watchlist.")
@bot.tree.command(name="watchlist", description="Show your current watchlist")
async def watchlist(interaction: discord.Interaction):
if not os.path.exists(WATCHLIST_FILE):
await interaction.response.send_message("Your watchlist is empty.")
return
with open(WATCHLIST_FILE, "r", encoding="utf-8") as f:
movies = [line.strip() for line in f if line.strip()]
if not movies:
await interaction.response.send_message("Your watchlist is empty.")
return
formatted = "\n".join(f"- {m}" for m in movies)
full_message = f"**Your Watchlist ({len(movies)} movies):**\n{formatted}"
if len(full_message) <= 2000:
await interaction.response.send_message(full_message)
else:
await interaction.response.send_message(f"**Your Watchlist ({len(movies)} movies):**")
for i in range(0, len(formatted), 1900):
await interaction.followup.send(formatted[i:i+1900])
@bot.tree.command(name="clear_watchlist", description="Clear your entire watchlist and dataset")
async def clear_watchlist(interaction: discord.Interaction):
open(WATCHLIST_FILE, "w").close()
if os.path.exists("watchlist.csv"):
os.remove("watchlist.csv")
await interaction.response.send_message("Your watchlist has been cleared.")
@bot.tree.command(name="clear_messages", description="Clear all messages in this channel")
async def clear_messages(interaction: discord.Interaction):
await interaction.response.defer(ephemeral=True)
if not interaction.guild:
await interaction.followup.send("This command can only be used in a server.", ephemeral=True)
return
if not isinstance(interaction.user, discord.Member):
await interaction.followup.send("Unable to verify permissions.", ephemeral=True)
return
if not interaction.user.guild_permissions.manage_messages:
await interaction.followup.send("You don't have permission to manage messages.", ephemeral=True)
return
deleted = await interaction.channel.purge(limit=None)
await interaction.followup.send(f"Deleted {len(deleted)} messages.", ephemeral=True)
if __name__ == "__main__":
bot.run(TOKEN)