package org.hedgecode.chess.scanner.portal;
import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import org.hedgecode.chess.scanner.ChessHogScannerException;
+import org.apache.commons.text.StringEscapeUtils;
+
+import org.hedgecode.chess.scanner.Scanner;
+import org.hedgecode.chess.scanner.ScannerException;
+import org.hedgecode.chess.scanner.StringUtils;
import org.hedgecode.chess.scanner.entity.PGNGame;
import org.hedgecode.chess.scanner.entity.PGNTournament;
+import org.hedgecode.chess.scanner.format.lichess.Format;
+import org.hedgecode.chess.scanner.format.lichess.GameFormat;
+
+import static org.hedgecode.chess.scanner.format.PGNConstants.*;
/**
* LiChessScanner
*
* @author Dmitry Samoshin aka gotty
*/
-public class LiChessScanner extends AbstractSettingsScanner {
+public class LiChessScanner extends AbstractSettingsScanner implements Scanner {
private static final String SETTINGS_FILENAME = "lichess.settings";
- private static final String TOURNAMENT_GAMES_SPLIT_REGEX = "\\[Event \"[^\"]+\"\\]";
- private static final String TOURNAMENT_NAME_REGEX = "\\[Event \"([^\"]+)\"\\]";
- private static final String GAME_ID_REGEX = "\\[Site \"https://lichess.org/([^\"]+)\"\\]";
-
@Override
protected String getResourceName() {
return SETTINGS_FILENAME;
}
@Override
- public PGNTournament getTournament(String tournamentId) throws ChessHogScannerException {
+ public PGNTournament scanTournament(String tournamentId) throws ScannerException {
PGNTournament tournament = new PGNTournament(tournamentId);
assignTournamentGames(tournament);
return tournament;
}
@Override
- public PGNTournament findTournament(String tournamentName) throws ChessHogScannerException {
- throw new ChessHogScannerException(
+ public PGNTournament findTournament(String tournamentName) throws ScannerException {
+ throw new ScannerException(
"Lichess does not support searching for a tournament by name!"
);
}
@Override
- public PGNGame getGame(String gameId) throws ChessHogScannerException {
+ public PGNGame scanGame(String gameId) throws ScannerException {
String pgn = request(
assignUrl(gameId)
);
+ if (!StringUtils.isPgn(pgn)) {
+ throw new ScannerException(
+ String.format("Failed to get PGN for requesting game ID: %s", gameId)
+ );
+ }
return new PGNGame(
gameId, pgn
);
}
- private void assignTournamentGames(PGNTournament tournament) throws ChessHogScannerException {
+ @Override
+ public PGNGame scanGame(String gameId, String tournamentId) throws ScannerException {
+ return scanGame(gameId);
+ }
+
+ @Override
+ public PGNGame scanUrl(String gameUrl) throws ScannerException {
+ String gamePage = request(gameUrl);
+ String pgn = StringUtils.match(
+ gamePage,
+ getSettings().getGameUrlRegex()
+ );
+ if (pgn == null) {
+ pgn = StringUtils.match(
+ gamePage,
+ getSettings().getGameJsonUrlRegex()
+ );
+ if (pgn == null) {
+ throw new ScannerException(
+ String.format("Failed to get source data for requesting URL: %s", gameUrl)
+ );
+ }
+ GameFormat gameFormat = Format.formatGame(pgn);
+ return new PGNGame(
+ gameFormat.id(),
+ gameFormat.pgn()
+ );
+ } else {
+ pgn = StringEscapeUtils.unescapeHtml4(pgn);
+ if (!StringUtils.isPgn(pgn)) {
+ throw new ScannerException(
+ String.format("Failed to get PGN for requesting URL: %s", gameUrl)
+ );
+ }
+ return new PGNGame(
+ StringUtils.match(
+ pgn,
+ getSettings().getGameIdRegex()
+ ),
+ pgn
+ );
+ }
+ }
+
+ private void assignTournamentGames(PGNTournament tournament) throws ScannerException {
tournament.clearGames();
List<String> pgnGames = split(
assignUrl(
tournament.id(),
null
),
- TOURNAMENT_GAMES_SPLIT_REGEX
+ PGN_DETECT_REGEX
);
if (!pgnGames.isEmpty()) {
tournament.setName(
- find(TOURNAMENT_NAME_REGEX, pgnGames.get(0))
+ StringUtils.match(
+ pgnGames.get(0),
+ getSettings().getTournamentNameRegex()
+ )
);
}
for (String pgn : pgnGames) {
- String gameId = find(GAME_ID_REGEX, pgn);
+ String gameId = StringUtils.match(
+ pgn,
+ getSettings().getGameIdRegex()
+ );
tournament.addGame(
new PGNGame(gameId, pgn)
);
}
}
- private String find(String regex, String pgn) {
- Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
- Matcher matcher = pattern.matcher(pgn);
- if (matcher.find()) {
- return matcher.group(1);
- }
- return null;
- }
-
}