lunarflu HF staff commited on
Commit
39d3eff
·
verified ·
1 Parent(s): 807606e

test fix ratelimits, timestampts for logs

Browse files
Files changed (1) hide show
  1. app.py +50 -37
app.py CHANGED
@@ -10,23 +10,27 @@ 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")
@@ -43,19 +47,34 @@ async def process_row(row, guild, role):
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}!")
49
- await member.send(
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
- """
57
- Periodically fetch CSV data from Google Sheets and verify roles for members.
58
- """
 
 
 
 
59
  while True:
60
  try:
61
  async with aiohttp.ClientSession() as session:
@@ -68,9 +87,10 @@ async def give_verified_roles():
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)
@@ -80,48 +100,41 @@ async def give_verified_roles():
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 + "!"
119
 
120
- # Create the Gradio interface
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),
 
10
  from discord.ext import commands
11
 
12
  # Set up logging
13
+ logging.basicConfig(
14
+ level=logging.INFO,
15
+ format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
16
+ datefmt="%Y-%m-%d %H:%M:%S"
17
+ )
18
  logger = logging.getLogger(__name__)
19
 
 
20
  DISCORD_TOKEN = os.environ.get("DISCORD_TOKEN", None)
21
  if not DISCORD_TOKEN:
22
  logger.error("DISCORD_TOKEN not set. Exiting.")
23
  sys.exit(1)
24
 
 
25
  intents = discord.Intents.all()
26
  bot = commands.Bot(command_prefix="!", intents=intents)
27
 
28
+ # Cache guild/role globally
29
+ GUILD_ID = 879548962464493619
30
+ ROLE_ID = 900063512829755413
31
+ LUNAR_ID = 811235357663297546
32
+
33
  async def process_row(row, guild, role):
 
 
 
34
  hf_user_name = row["hf_user_name"]
35
  if pd.notna(hf_user_name) and hf_user_name.lower() != "n/a":
36
  discord_id = row["discord_user_id"].strip("L")
 
47
  try:
48
  await member.add_roles(role)
49
  logger.info(f"Role added to member: {member}")
50
+
51
+ # Send confirmation to Lunar (optional)
52
+ lunar = bot.get_user(LUNAR_ID)
53
  if lunar:
54
+ try:
55
+ await lunar.send(f"Verified role given to {member}!")
56
+ except discord.Forbidden:
57
+ logger.warning("Could not DM Lunar.")
58
+
59
+ # DM the user (optional)
60
+ try:
61
+ await member.send(
62
+ f"Verification successful! [{member} <---> {row['discord_user_name']}]"
63
+ )
64
+ except discord.Forbidden:
65
+ logger.warning(f"Cannot DM {member} — DMs likely off.")
66
+
67
  except Exception as e:
68
  logger.error(f"Error processing member {member}: {e}")
69
 
70
  async def give_verified_roles():
71
+ guild = bot.get_guild(GUILD_ID)
72
+ role = guild.get_role(ROLE_ID)
73
+
74
+ if not guild or not role:
75
+ logger.error("Guild or role not found. Exiting loop.")
76
+ return
77
+
78
  while True:
79
  try:
80
  async with aiohttp.ClientSession() as session:
 
87
  logger.error(f"Failed to fetch CSV: HTTP {response.status}")
88
  await asyncio.sleep(30)
89
  continue
90
+
91
  csv_data = await response.text()
 
92
  global_df = await asyncio.to_thread(pd.read_csv, io.StringIO(csv_data))
93
+
94
  except asyncio.TimeoutError:
95
  logger.error("CSV fetch timed out.")
96
  await asyncio.sleep(30)
 
100
  await asyncio.sleep(30)
101
  continue
102
 
103
+ # Throttled loop to avoid hitting rate limits
104
+ for _, row in global_df.iterrows():
105
+ await process_row(row, guild, role)
106
+ await asyncio.sleep(1.5) # Delay between role assignments
107
+
 
 
 
 
 
 
 
 
 
 
 
108
  except Exception as e:
109
  logger.error(f"Error in give_verified_roles loop: {e}")
110
+
111
+ await asyncio.sleep(30)
112
 
113
  @bot.event
114
  async def on_ready():
115
  logger.info(f"We have logged in as {bot.user}")
116
+ guild = bot.get_guild(GUILD_ID)
117
+ if guild:
118
+ await guild.chunk() # Cache members once on ready
119
+ logger.info("Guild member cache initialized.")
120
+ else:
121
+ logger.warning("Guild not found on startup.")
122
+
123
  bot.loop.create_task(give_verified_roles())
 
124
  bot.loop.create_task(heartbeat())
125
 
126
  async def heartbeat():
 
127
  while True:
128
  logger.info("Heartbeat: Bot is active.")
129
  await asyncio.sleep(60)
130
 
131
+ # Gradio setup
132
  def greet(name):
133
  return "Hello " + name + "!"
134
 
 
135
  demo = gr.Interface(fn=greet, inputs="text", outputs="text")
136
 
137
  async def main():
 
138
  gradio_thread = asyncio.to_thread(demo.launch, share=False)
139
  await asyncio.gather(
140
  bot.start(DISCORD_TOKEN),