Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
import os | |
import io | |
import sys | |
import asyncio | |
import discord | |
import aiohttp | |
import pandas as pd | |
import gradio as gr | |
import logging | |
from discord.ext import commands | |
# Set up logging | |
logging.basicConfig( | |
level=logging.INFO, | |
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s", | |
datefmt="%Y-%m-%d %H:%M:%S" | |
) | |
logger = logging.getLogger(__name__) | |
DISCORD_TOKEN = os.environ.get("DISCORD_TOKEN", None) | |
if not DISCORD_TOKEN: | |
logger.error("DISCORD_TOKEN not set. Exiting.") | |
sys.exit(1) | |
intents = discord.Intents.all() | |
bot = commands.Bot(command_prefix="!", intents=intents) | |
# Cache guild/role globally | |
GUILD_ID = 879548962464493619 | |
ROLE_ID = 900063512829755413 | |
LUNAR_ID = 811235357663297546 | |
async def process_row(row, guild, role): | |
hf_user_name = row["hf_user_name"] | |
if pd.notna(hf_user_name) and hf_user_name.lower() != "n/a": | |
discord_id = row["discord_user_id"].strip("L") | |
try: | |
member = guild.get_member(int(discord_id)) | |
except Exception as e: | |
logger.error(f"Error converting Discord ID {discord_id}: {e}") | |
return | |
if not member: | |
return | |
if role not in member.roles: | |
try: | |
await member.add_roles(role) | |
logger.info(f"Role added to member: {member}") | |
# Send confirmation to Lunar (optional) | |
lunar = bot.get_user(LUNAR_ID) | |
if lunar: | |
try: | |
await lunar.send(f"Verified role given to {member}!") | |
except discord.Forbidden: | |
logger.warning("Could not DM Lunar.") | |
# DM the user (optional) | |
try: | |
await member.send( | |
f"Verification successful! [{member} <---> {row['discord_user_name']}]" | |
) | |
except discord.Forbidden: | |
logger.warning(f"Cannot DM {member} — DMs likely off.") | |
except Exception as e: | |
logger.error(f"Error processing member {member}: {e}") | |
async def give_verified_roles(): | |
guild = bot.get_guild(GUILD_ID) | |
role = guild.get_role(ROLE_ID) | |
if not guild or not role: | |
logger.error("Guild or role not found. Exiting loop.") | |
return | |
while True: | |
try: | |
async with aiohttp.ClientSession() as session: | |
try: | |
async with session.get( | |
"https://docs.google.com/spreadsheets/d/1C8aLqgCqLYcMiIFf-P_Aosaa03C_WLIB_UyqvjSdWg8/export?format=csv&gid=0", | |
timeout=10, | |
) as response: | |
if response.status != 200: | |
logger.error(f"Failed to fetch CSV: HTTP {response.status}") | |
await asyncio.sleep(30) | |
continue | |
csv_data = await response.text() | |
global_df = await asyncio.to_thread(pd.read_csv, io.StringIO(csv_data)) | |
except asyncio.TimeoutError: | |
logger.error("CSV fetch timed out.") | |
await asyncio.sleep(30) | |
continue | |
except Exception as e: | |
logger.error(f"Error fetching CSV: {e}") | |
await asyncio.sleep(30) | |
continue | |
# Throttled loop to avoid hitting rate limits | |
for _, row in global_df.iterrows(): | |
await process_row(row, guild, role) | |
await asyncio.sleep(1.5) # Delay between role assignments | |
except Exception as e: | |
logger.error(f"Error in give_verified_roles loop: {e}") | |
await asyncio.sleep(30) | |
async def on_ready(): | |
logger.info(f"We have logged in as {bot.user}") | |
guild = bot.get_guild(GUILD_ID) | |
if guild: | |
await guild.chunk() # Cache members once on ready | |
logger.info("Guild member cache initialized.") | |
else: | |
logger.warning("Guild not found on startup.") | |
bot.loop.create_task(give_verified_roles()) | |
bot.loop.create_task(heartbeat()) | |
async def heartbeat(): | |
while True: | |
logger.info("Heartbeat: Bot is active.") | |
await asyncio.sleep(60) | |
# Gradio setup | |
def greet(name): | |
return "Hello " + name + "!" | |
demo = gr.Interface(fn=greet, inputs="text", outputs="text") | |
async def main(): | |
gradio_thread = asyncio.to_thread(demo.launch, share=False) | |
await asyncio.gather( | |
bot.start(DISCORD_TOKEN), | |
gradio_thread | |
) | |
if __name__ == "__main__": | |
try: | |
asyncio.run(main()) | |
except KeyboardInterrupt: | |
logger.info("Shutting down...") | |