Skip to content

Commit 72337c6

Browse files
authored
Merge pull request #6 from ombulabs/IIRR-18-leaderboard
[IIRR-18] Add weekly leaderboard thingy
2 parents c9fa570 + eb4af9c commit 72337c6

File tree

7 files changed

+106
-13
lines changed

7 files changed

+106
-13
lines changed

app/jobs/daily_puzzle_job.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,13 @@ def puzzle_buttons(puzzle_id)
3838
view.row do |row|
3939
row.button(
4040
style: :primary,
41-
emoji: "👍",
41+
emoji: "🔴",
4242
label: "Ruby",
4343
custom_id: "ruby__#{puzzle_id}"
4444
)
4545
row.button(
4646
style: :primary,
47-
emoji: "👍",
47+
emoji: "🚂",
4848
label: "Rails",
4949
custom_id: "rails__#{puzzle_id}"
5050
)

app/jobs/weekly_leaderboard_job.rb

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
class WeeklyLeaderboardJob < ApplicationJob
2+
queue_as :default
3+
4+
def perform
5+
start_time = Time.now.utc.beginning_of_week.beginning_of_day # Monday at 00:00 UTC
6+
end_time = Time.now.utc.end_of_week.end_of_day # Sunday at 23:59 UTC
7+
8+
leaderboard_data = Answer
9+
.where(created_at: start_time..end_time, is_correct: true)
10+
.group(:user_id)
11+
.order(Arel.sql("COUNT(*) DESC"))
12+
.count
13+
14+
return if leaderboard_data.empty?
15+
16+
Server.all.each do |server|
17+
channel = server.channel
18+
bot.send_message(
19+
channel.channel_id,
20+
"",
21+
false,
22+
leaderboard_embed(leaderboard_data),
23+
nil,
24+
nil,
25+
nil,
26+
nil) if channel
27+
end
28+
end
29+
30+
private
31+
32+
def leaderboard_embed(leaderboard_data)
33+
embed = Discordrb::Webhooks::Embed.new(
34+
title: "🏆 Weekly Leaderboard 🏆",
35+
description: "Here are the top 10 players from this week's competition!",
36+
color: 0xFFD700 # Gold color
37+
)
38+
39+
# Group leaderboard data by score
40+
grouped_by_score = leaderboard_data.group_by { |_, score| score }
41+
42+
previous_score = nil
43+
rank = 0
44+
displayed_count = 0
45+
46+
# Iterate over the grouped leaderboard data
47+
grouped_by_score.sort_by { |score, _| -score }.each do |score, users|
48+
users.each do |user_id, _|
49+
user = User.find(user_id)
50+
51+
rank += 1 if score != previous_score
52+
previous_score = score
53+
54+
break if displayed_count >= 10
55+
56+
embed.add_field(name: "##{rank} | #{user.username} | #{score} points\n", value: "", inline: false)
57+
displayed_count += 1
58+
end
59+
end
60+
61+
embed
62+
end
63+
end

app/lib/discord/events/puzzle_answer.rb

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,14 @@ def handle(event)
1818
return unless puzzle
1919

2020
# Find or create the user
21-
user = User.find_or_create_by(user_id: event.user.id) do |user|
22-
user.username = event.user.username
21+
user = User.find_or_initialize_by(user_id: event.user.id)
22+
user.assign_attributes(
23+
username: event.user.username,
2324
# Users with permission to manage the server are admins, all other users fall under the member role
24-
user.role = event.user.permission?(:manage_server) ? 1 : 0
25-
end
25+
role: event.user.permission?(:manage_server) ? 1 : 0
26+
)
27+
user.save if user.changed?
2628

27-
if user.persisted?
28-
user.update(username: event.user.username, role: event.user.permission?(:manage_server) ? 1 : 0)
29-
end
3029

3130
# Check if the user has already answered this puzzle
3231
existing_answer = Answer.find_by(puzzle_id: puzzle.id, user_id: user.id)

app/lib/discord/events/server_create.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,11 @@ def create_or_update_server(server)
5454

5555
# Update or create a system channel is one is set
5656
if server.system_channel
57-
create_or_update_system_channel(discord_server)
57+
create_or_update_system_channel(server, discord_server)
5858
end
5959
end
6060

61-
def create_or_update_system_channel(discord_server)
61+
def create_or_update_system_channel(server, discord_server)
6262
if discord_server.channel
6363
discord_server.channel.update!(
6464
channel_id: server.system_channel.id,

app/lib/discord/events/set_channel.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ def handle(event)
2626
display_settings(event)
2727
end
2828

29-
3029
private
3130

3231
def display_settings(event)

config/sidekiq.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
:schedule:
22
daily_puzzle_job:
33
cron: "0 9 * * *" # This runs the job at 9:00 AM every day
4-
class: "SendDailyPuzzleJob"
4+
class: "SendDailyPuzzleJob"
5+
6+
weekly_puzzle_job:
7+
cron: "0 0 * * 0" # This runs the every Sunday at midnight
8+
class: "SendWeeklyPuzzleJob"

db/seeds.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,31 @@
1010
{ question: "Ruby or Rails provided this method? link_to 'Home', root_path", answer: :rails, explanation: "`link_to` is a Rails helper method that generates HTML links. `root_path` is a Rails path helper." },
1111
{ question: "Ruby or Rails provided this method? params[:id]", answer: :rails, explanation: "`params[:id]` is used in Rails to fetch query parameters or URL parameters in controller actions." }
1212
])
13+
14+
# Seed data for 10 users with answers
15+
users = [
16+
{ user_id: 101, username: "user1", role: "member" },
17+
{ user_id: 102, username: "user2", role: "member" },
18+
{ user_id: 103, username: "user3", role: "member" },
19+
{ user_id: 104, username: "user4", role: "member" },
20+
{ user_id: 105, username: "user5", role: "member" },
21+
{ user_id: 106, username: "user6", role: "member" },
22+
{ user_id: 107, username: "user7", role: "member" },
23+
{ user_id: 108, username: "user8", role: "member" },
24+
{ user_id: 109, username: "user9", role: "member" },
25+
{ user_id: 110, username: "user10", role: "member" }
26+
]
27+
28+
users.each do |user_data|
29+
user = User.create(user_id: user_data[:user_id], username: user_data[:username], role: user_data[:role])
30+
31+
# Randomly assign scores to answers (you can adjust as needed)
32+
3.times do
33+
Answer.create!(
34+
user_id: user.id,
35+
puzzle_id: Puzzle.all.sample.id,
36+
choice: [ "ruby", "rails" ].sample,
37+
is_correct: [ true, false ].sample
38+
)
39+
end
40+
end

0 commit comments

Comments
 (0)