Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
test (self restart adjust)
Browse files
app.py
CHANGED
@@ -6,40 +6,34 @@ import discord
|
|
6 |
import aiohttp
|
7 |
import pandas as pd
|
8 |
import gradio as gr
|
9 |
-
|
10 |
from discord.ext import commands
|
11 |
-
|
|
|
|
|
|
|
12 |
|
13 |
# Environment variable for Discord token
|
14 |
DISCORD_TOKEN = os.environ.get("DISCORD_TOKEN", None)
|
|
|
|
|
|
|
15 |
|
16 |
# Create Discord bot with all intents
|
17 |
intents = discord.Intents.all()
|
18 |
-
bot = commands.Bot(command_prefix=
|
19 |
-
|
20 |
-
# Set up an async scheduler for periodic tasks (like a bot restart)
|
21 |
-
scheduler = AsyncIOScheduler()
|
22 |
-
|
23 |
-
def restart_bot():
|
24 |
-
print("Restarting bot...")
|
25 |
-
os.execv(sys.executable, ['python'] + sys.argv)
|
26 |
-
|
27 |
-
@scheduler.scheduled_job('interval', minutes=60)
|
28 |
-
def periodic_restart():
|
29 |
-
print("Scheduled restart triggered...")
|
30 |
-
restart_bot()
|
31 |
|
32 |
async def process_row(row, guild, role):
|
33 |
"""
|
34 |
Process a single CSV row: if the Discord member associated with the row hasn't received the role, add it.
|
35 |
"""
|
36 |
-
hf_user_name = row[
|
37 |
-
if pd.notna(hf_user_name) and hf_user_name.lower() !=
|
38 |
-
discord_id = row[
|
39 |
try:
|
40 |
member = guild.get_member(int(discord_id))
|
41 |
except Exception as e:
|
42 |
-
|
43 |
return
|
44 |
|
45 |
if not member:
|
@@ -48,7 +42,7 @@ async def process_row(row, guild, role):
|
|
48 |
if role not in member.roles:
|
49 |
try:
|
50 |
await member.add_roles(role)
|
51 |
-
|
52 |
lunar = bot.get_user(811235357663297546)
|
53 |
if lunar:
|
54 |
await lunar.send(f"Verified role given to {member}!")
|
@@ -56,7 +50,7 @@ async def process_row(row, guild, role):
|
|
56 |
f"Verification successful! [{member} <---> {row['discord_user_name']}]"
|
57 |
)
|
58 |
except Exception as e:
|
59 |
-
|
60 |
|
61 |
async def give_verified_roles():
|
62 |
"""
|
@@ -68,48 +62,57 @@ async def give_verified_roles():
|
|
68 |
try:
|
69 |
async with session.get(
|
70 |
"https://docs.google.com/spreadsheets/d/1C8aLqgCqLYcMiIFf-P_Aosaa03C_WLIB_UyqvjSdWg8/export?format=csv&gid=0",
|
71 |
-
timeout=10
|
72 |
) as response:
|
73 |
if response.status != 200:
|
74 |
-
|
75 |
await asyncio.sleep(30)
|
76 |
continue
|
77 |
csv_data = await response.text()
|
78 |
-
|
|
|
79 |
except asyncio.TimeoutError:
|
80 |
-
|
81 |
await asyncio.sleep(30)
|
82 |
continue
|
83 |
except Exception as e:
|
84 |
-
|
85 |
await asyncio.sleep(30)
|
86 |
continue
|
87 |
|
88 |
guild = bot.get_guild(879548962464493619)
|
89 |
if not guild:
|
90 |
-
|
91 |
await asyncio.sleep(30)
|
92 |
continue
|
93 |
role = guild.get_role(900063512829755413)
|
94 |
if not role:
|
95 |
-
|
96 |
await asyncio.sleep(30)
|
97 |
continue
|
98 |
|
99 |
-
|
|
|
100 |
|
101 |
tasks = [process_row(row, guild, role) for _, row in global_df.iterrows()]
|
102 |
await asyncio.gather(*tasks)
|
103 |
except Exception as e:
|
104 |
-
|
105 |
await asyncio.sleep(30) # Adjust the sleep interval as needed
|
106 |
|
107 |
@bot.event
|
108 |
async def on_ready():
|
109 |
-
|
110 |
-
scheduler.start()
|
111 |
# Start the background role verification loop
|
112 |
bot.loop.create_task(give_verified_roles())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
|
114 |
def greet(name):
|
115 |
return "Hello " + name + "!"
|
@@ -118,9 +121,8 @@ def greet(name):
|
|
118 |
demo = gr.Interface(fn=greet, inputs="text", outputs="text")
|
119 |
|
120 |
async def main():
|
121 |
-
# Launch Gradio in a separate thread
|
122 |
gradio_thread = asyncio.to_thread(demo.launch, share=False)
|
123 |
-
# Run both the Discord bot and Gradio concurrently
|
124 |
await asyncio.gather(
|
125 |
bot.start(DISCORD_TOKEN),
|
126 |
gradio_thread
|
@@ -130,4 +132,4 @@ if __name__ == "__main__":
|
|
130 |
try:
|
131 |
asyncio.run(main())
|
132 |
except KeyboardInterrupt:
|
133 |
-
|
|
|
6 |
import aiohttp
|
7 |
import pandas as pd
|
8 |
import gradio as gr
|
9 |
+
import logging
|
10 |
from discord.ext import commands
|
11 |
+
|
12 |
+
# Set up logging
|
13 |
+
logging.basicConfig(level=logging.INFO)
|
14 |
+
logger = logging.getLogger(__name__)
|
15 |
|
16 |
# Environment variable for Discord token
|
17 |
DISCORD_TOKEN = os.environ.get("DISCORD_TOKEN", None)
|
18 |
+
if not DISCORD_TOKEN:
|
19 |
+
logger.error("DISCORD_TOKEN not set. Exiting.")
|
20 |
+
sys.exit(1)
|
21 |
|
22 |
# Create Discord bot with all intents
|
23 |
intents = discord.Intents.all()
|
24 |
+
bot = commands.Bot(command_prefix="!", intents=intents)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
|
26 |
async def process_row(row, guild, role):
|
27 |
"""
|
28 |
Process a single CSV row: if the Discord member associated with the row hasn't received the role, add it.
|
29 |
"""
|
30 |
+
hf_user_name = row["hf_user_name"]
|
31 |
+
if pd.notna(hf_user_name) and hf_user_name.lower() != "n/a":
|
32 |
+
discord_id = row["discord_user_id"].strip("L")
|
33 |
try:
|
34 |
member = guild.get_member(int(discord_id))
|
35 |
except Exception as e:
|
36 |
+
logger.error(f"Error converting Discord ID {discord_id}: {e}")
|
37 |
return
|
38 |
|
39 |
if not member:
|
|
|
42 |
if role not in member.roles:
|
43 |
try:
|
44 |
await member.add_roles(role)
|
45 |
+
logger.info(f"Role added to member: {member}")
|
46 |
lunar = bot.get_user(811235357663297546)
|
47 |
if lunar:
|
48 |
await lunar.send(f"Verified role given to {member}!")
|
|
|
50 |
f"Verification successful! [{member} <---> {row['discord_user_name']}]"
|
51 |
)
|
52 |
except Exception as e:
|
53 |
+
logger.error(f"Error processing member {member}: {e}")
|
54 |
|
55 |
async def give_verified_roles():
|
56 |
"""
|
|
|
62 |
try:
|
63 |
async with session.get(
|
64 |
"https://docs.google.com/spreadsheets/d/1C8aLqgCqLYcMiIFf-P_Aosaa03C_WLIB_UyqvjSdWg8/export?format=csv&gid=0",
|
65 |
+
timeout=10,
|
66 |
) as response:
|
67 |
if response.status != 200:
|
68 |
+
logger.error(f"Failed to fetch CSV: HTTP {response.status}")
|
69 |
await asyncio.sleep(30)
|
70 |
continue
|
71 |
csv_data = await response.text()
|
72 |
+
# Offload CSV parsing to avoid blocking the event loop.
|
73 |
+
global_df = await asyncio.to_thread(pd.read_csv, io.StringIO(csv_data))
|
74 |
except asyncio.TimeoutError:
|
75 |
+
logger.error("CSV fetch timed out.")
|
76 |
await asyncio.sleep(30)
|
77 |
continue
|
78 |
except Exception as e:
|
79 |
+
logger.error(f"Error fetching CSV: {e}")
|
80 |
await asyncio.sleep(30)
|
81 |
continue
|
82 |
|
83 |
guild = bot.get_guild(879548962464493619)
|
84 |
if not guild:
|
85 |
+
logger.error("Guild not found.")
|
86 |
await asyncio.sleep(30)
|
87 |
continue
|
88 |
role = guild.get_role(900063512829755413)
|
89 |
if not role:
|
90 |
+
logger.error("Role not found.")
|
91 |
await asyncio.sleep(30)
|
92 |
continue
|
93 |
|
94 |
+
# Ensure all guild members are cached.
|
95 |
+
await guild.chunk()
|
96 |
|
97 |
tasks = [process_row(row, guild, role) for _, row in global_df.iterrows()]
|
98 |
await asyncio.gather(*tasks)
|
99 |
except Exception as e:
|
100 |
+
logger.error(f"Error in give_verified_roles loop: {e}")
|
101 |
await asyncio.sleep(30) # Adjust the sleep interval as needed
|
102 |
|
103 |
@bot.event
|
104 |
async def on_ready():
|
105 |
+
logger.info(f"We have logged in as {bot.user}")
|
|
|
106 |
# Start the background role verification loop
|
107 |
bot.loop.create_task(give_verified_roles())
|
108 |
+
# Optionally, you can add a heartbeat task to log regular status messages.
|
109 |
+
bot.loop.create_task(heartbeat())
|
110 |
+
|
111 |
+
async def heartbeat():
|
112 |
+
"""Simple heartbeat task to indicate the bot is still responsive."""
|
113 |
+
while True:
|
114 |
+
logger.info("Heartbeat: Bot is active.")
|
115 |
+
await asyncio.sleep(60)
|
116 |
|
117 |
def greet(name):
|
118 |
return "Hello " + name + "!"
|
|
|
121 |
demo = gr.Interface(fn=greet, inputs="text", outputs="text")
|
122 |
|
123 |
async def main():
|
124 |
+
# Launch Gradio in a separate thread to avoid blocking
|
125 |
gradio_thread = asyncio.to_thread(demo.launch, share=False)
|
|
|
126 |
await asyncio.gather(
|
127 |
bot.start(DISCORD_TOKEN),
|
128 |
gradio_thread
|
|
|
132 |
try:
|
133 |
asyncio.run(main())
|
134 |
except KeyboardInterrupt:
|
135 |
+
logger.info("Shutting down...")
|