Files changed (1) hide show
  1. app.py +126 -114
app.py CHANGED
@@ -84,6 +84,15 @@ class DMButton(Button):
84
  await interaction.response.send_message(message, ephemeral=True)
85
 
86
 
 
 
 
 
 
 
 
 
 
87
  def generate_unique_string(length=6):
88
  return secrets.token_hex(length // 2)
89
 
@@ -122,7 +131,7 @@ async def on_ready():
122
 
123
  # updates both leaderboards
124
  remove_huggingfolks.start()
125
-
126
  print("------------------------------------------------------------------------")
127
  except Exception as e:
128
  print(f"on_ready Error: {e}")
@@ -208,7 +217,26 @@ def update_hub_stats():
208
  print(f"Hub stats successfully updated at {timestamp}! \n{global_df}")
209
  print("------------------------------------------------------------------------")
210
 
211
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
  thread_pool_executor = ThreadPoolExecutor(max_workers=2)
213
  asyncio_executor = AsyncIOExecutor()
214
  scheduler = BackgroundScheduler(executors={
@@ -216,6 +244,7 @@ scheduler = BackgroundScheduler(executors={
216
  })
217
  scheduler.add_job(update_google_sheet, trigger='interval', minutes=1, max_instances=2, executor='default')
218
  scheduler.add_job(update_hub_stats, trigger='interval', minutes=1.5, max_instances=2, executor='default')
 
219
  scheduler.start()
220
  #asyncio.get_event_loop().run_forever()
221
 
@@ -554,67 +583,65 @@ def format_hyperlink(username):
554
  return f'<a target="_blank" href="https://huggingface.co/{username}" style="color: var(--link-text-color);">{username}</a>'
555
 
556
 
557
-
558
- @tasks.loop(minutes=10)
559
  async def remove_huggingfolks():
560
  try:
 
 
 
 
 
 
 
561
  guild = bot.get_guild(879548962464493619)
562
  role = discord.utils.get(guild.roles, id=897376942817419265)
563
- await guild.chunk()
564
  members_with_role = [member.id for member in guild.members if role in member.roles]
565
 
566
- top_num_rows = await asyncio.to_thread(_remove_huggingfolks_sync, members_with_role)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
567
 
 
568
  channel = bot.get_channel(1197143964994773023)
569
  message = await channel.fetch_message(1197148293164187678)
570
 
 
571
  new_table = tabulate(top_num_rows, headers=["Name", "Level", "Experience", "Rank"], tablefmt="plain")
572
  await message.edit(content=f"Updated Leaderboard:\n```\n{new_table}\n```")
573
  print("Updated discord leaderboard!")
574
- print("------------------------------------------------------------------------")
575
  except Exception as e:
576
- print(f"remove_huggingfolks Error: {e}")
577
-
578
-
579
- def _remove_huggingfolks_sync(members_with_role):
580
- global community_global_df
581
- global community_global_df_with_id
582
- global community_global_df_gradio
583
-
584
-
585
- community_global_df = global_df.copy()
586
-
587
- community_global_df['discord_user_id'] = community_global_df['discord_user_id'].str.strip('L').astype(str)
588
-
589
- for member_id in members_with_role:
590
- community_global_df = community_global_df[community_global_df['discord_user_id'] != str(member_id)]
591
-
592
- community_global_df_with_id = community_global_df.copy()
593
-
594
- reorder = ['discord_user_id', 'hf_user_name', 'discord_exp', 'discord_level', 'discord_user_name', 'hub_exp', 'total_exp', 'verified_date']
595
- community_global_df = community_global_df[reorder]
596
-
597
- community_global_df.drop(community_global_df.columns[0], axis=1, inplace=True)
598
- community_global_df.drop(community_global_df.columns[1], axis=1, inplace=True)
599
- community_global_df.drop(community_global_df.columns[2], axis=1, inplace=True)
600
- community_global_df.drop(community_global_df.columns[2], axis=1, inplace=True)
601
- community_global_df.drop(community_global_df.columns[3], axis=1, inplace=True)
602
-
603
- # drop rows (records) where hf_user_name does not exist (we display only verified users)
604
- community_global_df = community_global_df.dropna(subset=['hf_user_name'])
605
- community_global_df['total_exp'] = community_global_df['total_exp'].str.strip('L').astype(int)
606
- community_global_df['total_exp'] = pd.to_numeric(community_global_df['total_exp'], errors='coerce').fillna(0).astype(int)
607
- community_global_df = community_global_df.nlargest(len(community_global_df), 'total_exp')
608
-
609
- community_global_df_gradio = community_global_df.copy()
610
- community_global_df_gradio['hf_user_name'] = community_global_df_gradio['hf_user_name'].apply(format_hyperlink)
611
-
612
- top_num = 30
613
- top_num_exp = community_global_df.head(top_num).copy()
614
- top_num_exp['Rank'] = ['πŸ₯‡', 'πŸ₯ˆ', 'πŸ₯‰'] + [''] * (top_num - 3)
615
- top_num_rows = top_num_exp.values.tolist()
616
- return top_num_rows
617
-
618
 
619
 
620
  @bot.command(name='xp_help')
@@ -624,7 +651,34 @@ async def xp_help(ctx):
624
  await ctx.author.send(help_message)
625
  except Exception as e:
626
  print(f"xp_help Error: {e}")
627
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
628
 
629
  DISCORD_TOKEN = os.environ.get("DISCORD_TOKEN", None)
630
  def run_bot():
@@ -648,48 +702,7 @@ def get_data2():
648
  display_df = pd.DataFrame(display_data)
649
  return display_df
650
  except Exception as e:
651
- print(f"get_data2 Error: {e}")
652
-
653
-
654
- @bot.event
655
- async def on_member_join(member):
656
- try:
657
- # Check if the member already has a record
658
- global global_df
659
- member_id = f"L{member.id}L" # Ensure consistent formatting with the database
660
- if member_id not in global_df['discord_user_id'].values:
661
- # Create a new row for the user
662
- print(f"Creating new record for {member}")
663
- xp = 0 # Start with zero XP
664
- current_level = calculate_level(xp)
665
- xp = f"L{xp}L"
666
- member_name = member.name
667
- hf_user_name = "n/a"
668
- hub_exp = "L0L"
669
- total_exp = xp
670
- verified_date = "n/a"
671
-
672
- # Initialize additional columns for the new row
673
- likes = 0
674
- models = 0
675
- datasets = 0
676
- spaces = 0
677
- discussions = 0
678
- papers = 0
679
- upvotes = 0
680
-
681
- row_data = [
682
- member_id, member_name, xp, current_level, hf_user_name, hub_exp,
683
- total_exp, verified_date, likes, models, datasets, spaces, discussions,
684
- papers, upvotes
685
- ]
686
- global_df.loc[len(global_df.index)] = row_data # Add the new row
687
-
688
- print(f"Added new user {member.name} with ID {member.id} to the database.")
689
- else:
690
- print(f"User {member.name} with ID {member.id} already exists in the database.")
691
- except Exception as e:
692
- print(f"Error adding new member {member}: {e}")
693
 
694
 
695
  #-------------------------------------------------------------------------------------------------------------------------------
@@ -889,27 +902,6 @@ with demo:
889
  TITLE = """<h1 align="center" id="space-title">πŸ€— Hugging Face Level Leaderboard</h1>"""
890
  gr.HTML(TITLE)
891
  with gr.Tabs(elem_classes="tab-buttons") as tabs:
892
- #------------------------------------------------------------------------------
893
- with gr.TabItem("βœ… Discord Verification", elem_id="verify-tab", id=2):
894
- login_button = gr.LoginButton()
895
- m1 = gr.Markdown()
896
- demo.load(verify_button, inputs=None, outputs=m1)
897
-
898
- def check_login_status():
899
- try:
900
- return login_button.get_session().get("oauth_info", None)
901
- except AttributeError:
902
- return None
903
-
904
- def check_login_wrapper():
905
- session = check_login_status()
906
- if session is None:
907
- return "Not logged in."
908
- else:
909
- return f"Logged in as {session.get('username', 'Unknown')}"
910
-
911
- login_button.click(check_login_wrapper, inputs=None, outputs=m1)
912
- #------------------------------------------------------------------------------
913
  with gr.TabItem("πŸ… Level leaderboard", elem_id="level-table", id=0):
914
  #gr.Markdown("# πŸ“ˆ Experience Leaderboard")
915
  with gr.Row():
@@ -929,7 +921,27 @@ with demo:
929
  with gr.Row():
930
  gr.Markdown("# πŸ“ˆ How to earn Experience!")
931
  with gr.Row():
932
- gr.DataFrame(get_data2, every=5, interactive=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
933
  #------------------------------------------------------------------------------
934
  with gr.TabItem("πŸ“ˆ Activity Heatmap", elem_id="activity-heatmap", id=1):
935
  with gr.Row():
 
84
  await interaction.response.send_message(message, ephemeral=True)
85
 
86
 
87
+ @bot.command(name='sendbutton')
88
+ async def send_button(ctx):
89
+ if ctx.author.id == 811235357663297546:
90
+ button = DMButton(label="Verify Discord Account", style=discord.ButtonStyle.primary)
91
+ view = View(timeout=None)
92
+ view.add_item(button)
93
+ await ctx.send("Click the button below to generate your verification link:",view=view) #
94
+
95
+
96
  def generate_unique_string(length=6):
97
  return secrets.token_hex(length // 2)
98
 
 
131
 
132
  # updates both leaderboards
133
  remove_huggingfolks.start()
134
+ give_verified_roles.start()
135
  print("------------------------------------------------------------------------")
136
  except Exception as e:
137
  print(f"on_ready Error: {e}")
 
217
  print(f"Hub stats successfully updated at {timestamp}! \n{global_df}")
218
  print("------------------------------------------------------------------------")
219
 
220
+
221
+ @tasks.loop(minutes=1)
222
+ async def give_verified_roles():
223
+ global global_df
224
+ guild = bot.get_guild(879548962464493619)
225
+ role = guild.get_role(900063512829755413)
226
+ await guild.chunk()
227
+ for index, row in global_df.iterrows():
228
+ hf_user_name = row['hf_user_name']
229
+ if pd.notna(hf_user_name) and hf_user_name.lower() != 'n/a':
230
+ discord_id = row['discord_user_id'].strip('L')
231
+ member = guild.get_member(int(discord_id))
232
+ if not member:
233
+ continue
234
+ if role not in member.roles:
235
+ await member.add_roles(role)
236
+ lunar = bot.get_user(811235357663297546)
237
+ await lunar.send(f"Verified role given to {member}!")
238
+
239
+
240
  thread_pool_executor = ThreadPoolExecutor(max_workers=2)
241
  asyncio_executor = AsyncIOExecutor()
242
  scheduler = BackgroundScheduler(executors={
 
244
  })
245
  scheduler.add_job(update_google_sheet, trigger='interval', minutes=1, max_instances=2, executor='default')
246
  scheduler.add_job(update_hub_stats, trigger='interval', minutes=1.5, max_instances=2, executor='default')
247
+ #scheduler.add_job(give_verified_roles, trigger='interval', minutes=1, max_instances=1, executor='asyncio')
248
  scheduler.start()
249
  #asyncio.get_event_loop().run_forever()
250
 
 
583
  return f'<a target="_blank" href="https://huggingface.co/{username}" style="color: var(--link-text-color);">{username}</a>'
584
 
585
 
586
+ @tasks.loop(minutes=1)
 
587
  async def remove_huggingfolks():
588
  try:
589
+ # remove huggingfolks
590
+ global community_global_df
591
+ global community_global_df_with_id
592
+ global community_global_df_gradio
593
+
594
+ community_global_df = global_df.copy()
595
+
596
  guild = bot.get_guild(879548962464493619)
597
  role = discord.utils.get(guild.roles, id=897376942817419265)
 
598
  members_with_role = [member.id for member in guild.members if role in member.roles]
599
 
600
+ # remove L formatting (doesn't affect main global_df)
601
+ community_global_df['discord_user_id'] = community_global_df['discord_user_id'].str.strip('L').astype(str)
602
+
603
+ for member_id in members_with_role:
604
+ community_global_df = community_global_df[community_global_df.iloc[:, 0] != str(member_id)]
605
+
606
+ # make a copy while discord id column still exists -> use for rank in discord embeds
607
+ community_global_df_with_id = community_global_df_with_id.copy()
608
+
609
+ # reorder (switching from discord_user_name to hf_user_name)
610
+ reorder = ['discord_user_id', 'hf_user_name', 'discord_exp','discord_level', 'discord_user_name', 'hub_exp', 'total_exp', 'verified_date']
611
+ community_global_df = community_global_df[reorder]
612
+
613
+ # drop first column (discord id -> this is so we can display the important stuff in the leaderboard)
614
+ community_global_df.drop(community_global_df.columns[0], axis=1, inplace=True)
615
+ community_global_df.drop(community_global_df.columns[1], axis=1, inplace=True)
616
+ community_global_df.drop(community_global_df.columns[2], axis=1, inplace=True)
617
+ community_global_df.drop(community_global_df.columns[2], axis=1, inplace=True)
618
+ community_global_df.drop(community_global_df.columns[3], axis=1, inplace=True)
619
+ # drop rows (records) where hf_user_name does not exist (we display only verified users)
620
+ community_global_df = community_global_df.dropna(subset=['hf_user_name'])
621
+ community_global_df['total_exp'] = community_global_df['total_exp'].str.strip('L').astype(int)
622
+ community_global_df['total_exp'] = pd.to_numeric(community_global_df['total_exp'], errors='coerce').fillna(0).astype(int)
623
+ community_global_df = community_global_df.nlargest(len(community_global_df), 'total_exp')
624
+ # add profile hyperlinks to gradio demo
625
+ community_global_df_gradio = community_global_df.copy() # must be a COPY, otherwise it adds a new name for the same dataframe.
626
+ community_global_df_gradio['hf_user_name'] = community_global_df_gradio['hf_user_name'].apply(format_hyperlink)
627
+
628
+ top_num = 30
629
+ top_num_exp = community_global_df.nlargest(top_num, 'total_exp')
630
+
631
+ top_num_exp['D'] = ['πŸ₯‡','πŸ₯ˆ','πŸ₯‰'] + [''] * (top_num - 3)
632
+ top_num_rows = top_num_exp.values.tolist()
633
 
634
+ #print(top_30_rows)
635
  channel = bot.get_channel(1197143964994773023)
636
  message = await channel.fetch_message(1197148293164187678)
637
 
638
+ # put into message / leaderboard
639
  new_table = tabulate(top_num_rows, headers=["Name", "Level", "Experience", "Rank"], tablefmt="plain")
640
  await message.edit(content=f"Updated Leaderboard:\n```\n{new_table}\n```")
641
  print("Updated discord leaderboard!")
642
+ print("------------------------------------------------------------------------")
643
  except Exception as e:
644
+ print(f"remove_huggingfolks Error: {e}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
645
 
646
 
647
  @bot.command(name='xp_help')
 
651
  await ctx.author.send(help_message)
652
  except Exception as e:
653
  print(f"xp_help Error: {e}")
654
+
655
+
656
+ @bot.command()
657
+ async def count_users_with_role(ctx, role_id):
658
+ role = discord.utils.get(ctx.guild.roles, id=int(role_id))
659
+ count = sum(1 for member in ctx.guild.members if role in member.roles)
660
+ await ctx.send(f"Number of users with the role '{role.name}': {count}")
661
+
662
+
663
+ @bot.command()
664
+ async def send_hub_org_dm_retroactive(ctx, role_id):
665
+ if ctx.author.id == 811235357663297546:
666
+ lunar = bot.get_user(811235357663297546)
667
+ role = discord.utils.get(ctx.guild.roles, id=int(role_id))
668
+ # for every person with this role
669
+ # dm them message with link
670
+ if role:
671
+ for member in role.members:
672
+ try:
673
+ dm_message = f"Hey {member}! You've just been invited to join the Hugging Face Discord Community org! πŸ€—\n If you're interested in collaborating on open source projects, hanging out with the community or just enjoying your new badge, we're happy to have you! ❀️ https://huggingface.co/organizations/discord-community/share/wPKRAHYbAlaEaCxUxcqVyaaaeZcYagDvqc"
674
+ await member.send(dm_message)
675
+ await lunar.send(dm_message)
676
+ await asyncio.sleep(5)
677
+ except discord.Forbidden:
678
+ print(f"Could not DM {member.name}")
679
+ await lunar.send(f"Could not DM {member.name} a Hugging Face Org invite link")
680
+
681
+
682
 
683
  DISCORD_TOKEN = os.environ.get("DISCORD_TOKEN", None)
684
  def run_bot():
 
702
  display_df = pd.DataFrame(display_data)
703
  return display_df
704
  except Exception as e:
705
+ print(f"get_data2 Error: {e}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
706
 
707
 
708
  #-------------------------------------------------------------------------------------------------------------------------------
 
902
  TITLE = """<h1 align="center" id="space-title">πŸ€— Hugging Face Level Leaderboard</h1>"""
903
  gr.HTML(TITLE)
904
  with gr.Tabs(elem_classes="tab-buttons") as tabs:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
905
  with gr.TabItem("πŸ… Level leaderboard", elem_id="level-table", id=0):
906
  #gr.Markdown("# πŸ“ˆ Experience Leaderboard")
907
  with gr.Row():
 
921
  with gr.Row():
922
  gr.Markdown("# πŸ“ˆ How to earn Experience!")
923
  with gr.Row():
924
+ gr.DataFrame(get_data2, every=5, interactive=False)
925
+ #------------------------------------------------------------------------------
926
+ with gr.TabItem("βœ… Discord Verification", elem_id="verify-tab", id=2):
927
+ login_button = gr.LoginButton()
928
+ m1 = gr.Markdown()
929
+ demo.load(verify_button, inputs=None, outputs=m1)
930
+
931
+ def check_login_status():
932
+ try:
933
+ return login_button.get_session().get("oauth_info", None)
934
+ except AttributeError:
935
+ return None
936
+
937
+ def check_login_wrapper():
938
+ session = check_login_status()
939
+ if session is None:
940
+ return "Not logged in."
941
+ else:
942
+ return f"Logged in as {session.get('username', 'Unknown')}"
943
+
944
+ login_button.click(check_login_wrapper, inputs=None, outputs=m1)
945
  #------------------------------------------------------------------------------
946
  with gr.TabItem("πŸ“ˆ Activity Heatmap", elem_id="activity-heatmap", id=1):
947
  with gr.Row():