From 9dcb43da39bcfbfb37ca8307e0d46bbfeee9363b Mon Sep 17 00:00:00 2001 From: gotty Date: Wed, 15 Jan 2020 04:35:36 +0300 Subject: [PATCH] [LIB-13] Add chessbomb scanner --- .../hedgecode/chess/scanner/ChessHogScanner.java | 2 + .../chess/scanner/portal/ChessBombScanner.java | 113 +++++++++++++++++++++ src/main/resources/settings/chessbomb.settings | 9 ++ 3 files changed, 124 insertions(+) create mode 100644 src/main/java/org/hedgecode/chess/scanner/portal/ChessBombScanner.java create mode 100644 src/main/resources/settings/chessbomb.settings diff --git a/src/main/java/org/hedgecode/chess/scanner/ChessHogScanner.java b/src/main/java/org/hedgecode/chess/scanner/ChessHogScanner.java index 0191cff..9b90990 100644 --- a/src/main/java/org/hedgecode/chess/scanner/ChessHogScanner.java +++ b/src/main/java/org/hedgecode/chess/scanner/ChessHogScanner.java @@ -19,6 +19,7 @@ package org.hedgecode.chess.scanner; import java.util.HashMap; import java.util.Map; +import org.hedgecode.chess.scanner.portal.ChessBombScanner; import org.hedgecode.chess.scanner.portal.ChessGamesScanner; import org.hedgecode.chess.scanner.portal.LiChessScanner; @@ -35,6 +36,7 @@ public final class ChessHogScanner { { put( ScannerType.CHESSGAMES, new ChessGamesScanner() ); put( ScannerType.LICHESS, new LiChessScanner() ); + put( ScannerType.CHESSBOMB, new ChessBombScanner() ); } }; diff --git a/src/main/java/org/hedgecode/chess/scanner/portal/ChessBombScanner.java b/src/main/java/org/hedgecode/chess/scanner/portal/ChessBombScanner.java new file mode 100644 index 0000000..d8b6ed0 --- /dev/null +++ b/src/main/java/org/hedgecode/chess/scanner/portal/ChessBombScanner.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2019-2020. Developed by Hedgecode. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.hedgecode.chess.scanner.portal; + +import java.util.Base64; + +import org.hedgecode.chess.scanner.ChessHogScannerException; +import org.hedgecode.chess.scanner.entity.PGNGame; +import org.hedgecode.chess.scanner.entity.PGNTournament; +import org.hedgecode.chess.scanner.format.ArenaFormat; +import org.hedgecode.chess.scanner.format.Format; +import org.hedgecode.chess.scanner.format.GameFormat; +import org.hedgecode.chess.scanner.format.TournamentFormat; + +/** + * ChessBombScanner + * + * @author Dmitry Samoshin aka gotty + */ +public class ChessBombScanner extends AbstractSettingsScanner { + + private static final String SETTINGS_FILENAME = "chessbomb.settings"; + + @Override + protected String getResourceName() { + return SETTINGS_FILENAME; + } + + @Override + public PGNTournament getTournament(String tournamentId) throws ChessHogScannerException { + String decodeTournament = decodeUrlByRegex( + assignUrl(tournamentId, null), + getSettings().getTournamentGamesUrlRegex() + ); + + TournamentFormat tournamentFormat = Format.formatTournament(decodeTournament); + + PGNTournament tournament = new PGNTournament( + tournamentFormat.id(), tournamentFormat.name() + ); + + for (String gameId : tournamentFormat.gameUrls()) { + tournament.addGame( + getGame(gameId, tournamentId) + ); + } + + return tournament; + } + + @Override + public PGNTournament findTournament(String tournamentName) throws ChessHogScannerException { + String decodeArena = decodeUrlByRegex( + assignUrl(tournamentName, false), + getSettings().getTournamentQueryUrlRegex() + ); + + ArenaFormat arenaFormat = Format.formatArena(decodeArena); + + String tournamentId = arenaFormat.findTournament(tournamentName); + + return tournamentId != null + ? getTournament(tournamentId) + : null; + } + + @Override + public PGNGame getGame(String gameId) throws ChessHogScannerException { + throw new ChessHogScannerException( + "ChessBomb does not support searching game without a tournament name!" + ); + } + + @Override + public PGNGame getGame(String gameId, String tournamentId) throws ChessHogScannerException { + String decodeGame = decodeUrlByRegex( + assignUrl(gameId, tournamentId, true), + getSettings().getGameUrlRegex() + ); + + GameFormat gameFormat = Format.formatGame(decodeGame); + + return new PGNGame( + gameFormat.id(), + gameFormat.pgn() + ); + } + + private String decodeUrlByRegex(String url, String regex) throws ChessHogScannerException { + String encodeString = match( + url, + regex + ); + return new String( + Base64.getDecoder().decode(encodeString) + ); + } + +} diff --git a/src/main/resources/settings/chessbomb.settings b/src/main/resources/settings/chessbomb.settings new file mode 100644 index 0000000..d6e3b65 --- /dev/null +++ b/src/main/resources/settings/chessbomb.settings @@ -0,0 +1,9 @@ +{ + "tournamentUrl": "https://www.chessbomb.com/arena/[tournamentId]", + "tournamentIsMultiPage": false, + "tournamentGamesUrlRegex": "cbConfigData=\"([^\"]+)\"", + "tournamentQuery": "https://www.chessbomb.com/arena/", + "tournamentQueryUrlRegex": "cbConfigData=\"([^\"]+)\"", + "gameUrl": "https://www.chessbomb.com/arena/[tournamentId]/[gameId]", + "gameUrlRegex": "cbConfigData=\"([^\"]+)\"" +} \ No newline at end of file -- 2.10.0