Add leaderboard route

This commit is contained in:
Francois G 2023-02-25 21:19:58 +01:00
parent ec72b90020
commit b5db4328f2
5 changed files with 143 additions and 4 deletions

View file

@ -28,6 +28,7 @@ import org.jose4j.lang.JoseException;
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository; import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
import be.jeffcheasey88.peeratcode.routes.ChapterElement; import be.jeffcheasey88.peeratcode.routes.ChapterElement;
import be.jeffcheasey88.peeratcode.routes.ChapterList; import be.jeffcheasey88.peeratcode.routes.ChapterList;
import be.jeffcheasey88.peeratcode.routes.Leaderboard;
import be.jeffcheasey88.peeratcode.routes.Login; import be.jeffcheasey88.peeratcode.routes.Login;
import be.jeffcheasey88.peeratcode.routes.PuzzleElement; import be.jeffcheasey88.peeratcode.routes.PuzzleElement;
import be.jeffcheasey88.peeratcode.routes.PuzzleResponse; import be.jeffcheasey88.peeratcode.routes.PuzzleResponse;
@ -79,6 +80,7 @@ public class Main {
router.register(new Login(router.getDataBase(), router)); router.register(new Login(router.getDataBase(), router));
router.register(new Result(router.getDataBase())); router.register(new Result(router.getDataBase()));
router.register(new PuzzleResponse(router.getDataBase())); router.register(new PuzzleResponse(router.getDataBase()));
router.register(new Leaderboard(router.getDataBase()));
} }
private static void startWebServer(Configuration config, Router router) throws IOException { private static void startWebServer(Configuration config, Router router) throws IOException {

View file

@ -1,6 +1,8 @@
package be.jeffcheasey88.peeratcode.model; package be.jeffcheasey88.peeratcode.model;
public class Player { import java.util.Objects;
public class Player implements Comparable<Player> {
public static final String PATH_TO_CODE = "/home/%s/peer-at-source/"; public static final String PATH_TO_CODE = "/home/%s/peer-at-source/";
private String pseudo; private String pseudo;
@ -9,14 +11,29 @@ public class Player {
private String lastname; private String lastname;
private String description; private String description;
private String sgroup; private String sgroup;
private byte[] avatar;
private int totalScore;
private int totalCompletion;
private int totalTries;
public Player(String pseudo, String email, String firstname, String lastname, String description, String sgroup) { public Player(String pseudo, String email, String firstname, String lastname, String description, String sgroup) {
this(pseudo, email, firstname, lastname, description, sgroup, null);
}
public Player(String pseudo, String email, String firstname, String lastname, String description, String sgroup,
byte[] avatar) {
this.pseudo = pseudo; this.pseudo = pseudo;
this.email = email; this.email = email;
this.firstname = firstname; this.firstname = firstname;
this.lastname = lastname; this.lastname = lastname;
this.description = description; this.description = description;
this.sgroup = sgroup; this.sgroup = sgroup;
this.avatar = avatar;
totalScore = 0;
totalCompletion = 0;
totalTries = 0;
} }
public String getPseudo() { public String getPseudo() {
@ -43,7 +60,52 @@ public class Player {
return this.sgroup; return this.sgroup;
} }
public byte[] getAvatar() {
return this.avatar;
}
public String getPathToSourceCode() { public String getPathToSourceCode() {
return String.format(PATH_TO_CODE, pseudo); return String.format(PATH_TO_CODE, pseudo);
} }
public int getTotalScore() {
return totalScore;
}
public void setTotalScore(int totalScore) {
this.totalScore = totalScore;
}
public int getTotalCompletion() {
return totalCompletion;
}
public void setTotalCompletion(int totalCompletion) {
this.totalCompletion = totalCompletion;
}
public int getTotalTries() {
return totalTries;
}
public void setTotalTries(int totalTries) {
this.totalTries = totalTries;
}
@Override
public int compareTo(Player arg0) {
if (this == arg0)
return 0;
if (arg0 == null)
return -1;
int compare = Integer.compare(arg0.getTotalScore(), totalScore);
if (compare == 0) {
compare = Integer.compare(arg0.getTotalCompletion(), totalCompletion);
if (compare == 0) {
compare = Integer.compare(totalTries, arg0.getTotalTries());
}
}
return compare;
}
} }

View file

@ -8,6 +8,8 @@ import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
import com.password4j.Hash; import com.password4j.Hash;
import com.password4j.Password; import com.password4j.Password;
@ -30,6 +32,7 @@ public class DatabaseRepository {
private static final String SCORE = "SELECT score FROM completions WHERE fk_player = ? AND fk_puzzle = ?"; private static final String SCORE = "SELECT score FROM completions WHERE fk_player = ? AND fk_puzzle = ?";
private static final String GET_COMPLETION = "SELECT id_completion, tries, fileName, score FROM completions WHERE fk_puzzle = ? AND fk_player = ?"; private static final String GET_COMPLETION = "SELECT id_completion, tries, fileName, score FROM completions WHERE fk_puzzle = ? AND fk_player = ?";
private static final String GET_PLAYER = "SELECT * FROM players WHERE id_player = ?"; private static final String GET_PLAYER = "SELECT * FROM players WHERE id_player = ?";
private static final String ALL_PLAYERS_FOR_LEADERBOARD = "SELECT p.*, sum(c.score) AS playerScore, count(c.id_completion) AS playerCompletions, sum(c.tries) AS playerTries FROM players p LEFT JOIN completions c ON c.fk_player = p.id_player GROUP BY p.id_player ORDER BY playerScore DESC";
private static final String INSERT_COMPLETION = "INSERT INTO completions (fk_puzzle, fk_player, tries, code, fileName, score) values (?, ?, ?, ?, ?, ?)"; private static final String INSERT_COMPLETION = "INSERT INTO completions (fk_puzzle, fk_player, tries, code, fileName, score) values (?, ?, ?, ?, ?, ?)";
private static final String UPDATE_COMPLETION = "UPDATE completions SET tries = ?, filename = ?, score = ? WHERE fk_puzzle = ? AND fk_player = ?"; private static final String UPDATE_COMPLETION = "UPDATE completions SET tries = ?, filename = ?, score = ? WHERE fk_puzzle = ? AND fk_player = ?";
@ -66,7 +69,8 @@ public class DatabaseRepository {
private Player makePlayer(ResultSet playerResult) throws SQLException { private Player makePlayer(ResultSet playerResult) throws SQLException {
return new Player(playerResult.getString("pseudo"), playerResult.getString("email"), return new Player(playerResult.getString("pseudo"), playerResult.getString("email"),
playerResult.getString("firstName"), playerResult.getString("LastName"), playerResult.getString("firstName"), playerResult.getString("LastName"),
playerResult.getString("description"), playerResult.getString("sgroup")); playerResult.getString("description"), playerResult.getString("sgroup"),
playerResult.getBytes("avatar"));
} }
private List<Puzzle> getPuzzlesInChapter(int id) throws SQLException { private List<Puzzle> getPuzzlesInChapter(int id) throws SQLException {
@ -147,6 +151,27 @@ public class DatabaseRepository {
return null; return null;
} }
public SortedSet<Player> getAllPlayerForLeaderboard() {
try {
ensureConnection();
PreparedStatement playersStmt = con.prepareStatement(ALL_PLAYERS_FOR_LEADERBOARD);
ResultSet result = playersStmt.executeQuery();
SortedSet<Player> players = new TreeSet<Player>();
Player tmpPlayer;
while (result.next()) {
tmpPlayer = makePlayer(result);
tmpPlayer.setTotalScore(result.getInt("playerScore"));
tmpPlayer.setTotalCompletion(result.getInt("playerCompletions"));
tmpPlayer.setTotalTries(result.getInt("playerTries"));
players.add(tmpPlayer);
}
return players;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
/** /**
* Get a specific chapter * Get a specific chapter
* *

View file

@ -0,0 +1,52 @@
package be.jeffcheasey88.peeratcode.routes;
import be.jeffcheasey88.peeratcode.model.Player;
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
import be.jeffcheasey88.peeratcode.webserver.HttpReader;
import be.jeffcheasey88.peeratcode.webserver.HttpUtil;
import be.jeffcheasey88.peeratcode.webserver.HttpWriter;
import be.jeffcheasey88.peeratcode.webserver.Response;
import be.jeffcheasey88.peeratcode.webserver.User;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import java.util.SortedSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Leaderboard implements Response {
private final DatabaseRepository databaseRepo;
public Leaderboard(DatabaseRepository databaseRepo) {
this.databaseRepo = databaseRepo;
}
@Override
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
HttpUtil.responseHeaders(writer, 200, "Access-Control-Allow-Origin: *");
SortedSet<Player> allPlayers = databaseRepo.getAllPlayerForLeaderboard();
if (allPlayers != null) {
JSONArray playersJSON = new JSONArray();
for (Player player : allPlayers) {
JSONObject playerJSON = new JSONObject();
playerJSON.put("pseudo", player.getPseudo());
playerJSON.put("group", player.getGroup());
// chapterJSON.put("avatar", player.);
playerJSON.put("score", player.getTotalScore());
playerJSON.put("completions", player.getTotalCompletion());
playerJSON.put("tries", player.getTotalTries());
playersJSON.add(playerJSON);
}
writer.write(playersJSON.toJSONString());
}
writer.flush();
writer.close();
}
@Override
public Pattern getPattern() {
return Pattern.compile("^\\/leaderboard$");
}
}

View file

@ -1,11 +1,9 @@
package be.jeffcheasey88.peeratcode.routes; package be.jeffcheasey88.peeratcode.routes;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Arrays; import java.util.Arrays;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;