[LIB-13] Functional for working with strings moved to StringUtils
[chesshog-scanner.git] / src / main / java / org / hedgecode / chess / scanner / portal / LiChessScanner.java
1 /*
2  * Copyright (c) 2019-2020. Developed by Hedgecode.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.hedgecode.chess.scanner.portal;
18
19 import java.util.List;
20
21 import org.apache.commons.text.StringEscapeUtils;
22
23 import org.hedgecode.chess.scanner.Scanner;
24 import org.hedgecode.chess.scanner.ScannerException;
25 import org.hedgecode.chess.scanner.StringUtils;
26 import org.hedgecode.chess.scanner.entity.PGNGame;
27 import org.hedgecode.chess.scanner.entity.PGNTournament;
28 import org.hedgecode.chess.scanner.format.lichess.Format;
29 import org.hedgecode.chess.scanner.format.lichess.GameFormat;
30
31 import static org.hedgecode.chess.scanner.format.PGNConstants.*;
32
33 /**
34  * LiChessScanner
35  *
36  * @author Dmitry Samoshin aka gotty
37  */
38 public class LiChessScanner extends AbstractSettingsScanner implements Scanner {
39
40     private static final String SETTINGS_FILENAME = "lichess.settings";
41
42     @Override
43     protected String getResourceName() {
44         return SETTINGS_FILENAME;
45     }
46
47     @Override
48     public PGNTournament scanTournament(String tournamentId) throws ScannerException {
49         PGNTournament tournament = new PGNTournament(tournamentId);
50         assignTournamentGames(tournament);
51         return tournament;
52     }
53
54     @Override
55     public PGNTournament findTournament(String tournamentName) throws ScannerException {
56         throw new ScannerException(
57                 "Lichess does not support searching for a tournament by name!"
58         );
59     }
60
61     @Override
62     public PGNGame scanGame(String gameId) throws ScannerException {
63         String pgn = request(
64                 assignUrl(gameId)
65         );
66         if (!StringUtils.isPgn(pgn)) {
67             throw new ScannerException(
68                     String.format("Failed to get PGN for requesting game ID: %s", gameId)
69             );
70         }
71         return new PGNGame(
72                 gameId, pgn
73         );
74     }
75
76     @Override
77     public PGNGame scanGame(String gameId, String tournamentId) throws ScannerException {
78         return scanGame(gameId);
79     }
80
81     @Override
82     public PGNGame scanUrl(String gameUrl) throws ScannerException {
83         String gamePage = request(gameUrl);
84         String pgn = StringUtils.match(
85                 gamePage,
86                 getSettings().getGameUrlRegex()
87         );
88         if (pgn == null) {
89             pgn = StringUtils.match(
90                     gamePage,
91                     getSettings().getGameJsonUrlRegex()
92             );
93             if (pgn == null) {
94                 throw new ScannerException(
95                         String.format("Failed to get source data for requesting URL: %s", gameUrl)
96                 );
97             }
98             GameFormat gameFormat = Format.formatGame(pgn);
99             return new PGNGame(
100                     gameFormat.id(),
101                     gameFormat.pgn()
102             );
103         } else {
104             pgn = StringEscapeUtils.unescapeHtml4(pgn);
105             if (!StringUtils.isPgn(pgn)) {
106                 throw new ScannerException(
107                         String.format("Failed to get PGN for requesting URL: %s", gameUrl)
108                 );
109             }
110             return new PGNGame(
111                     StringUtils.match(
112                             pgn,
113                             getSettings().getGameIdRegex()
114                     ),
115                     pgn
116             );
117         }
118     }
119
120     private void assignTournamentGames(PGNTournament tournament) throws ScannerException {
121         tournament.clearGames();
122         List<String> pgnGames = split(
123                 assignUrl(
124                         tournament.id(),
125                         null
126                 ),
127                 PGN_DETECT_REGEX
128         );
129
130         if (!pgnGames.isEmpty()) {
131             tournament.setName(
132                     StringUtils.match(
133                             pgnGames.get(0),
134                             getSettings().getTournamentNameRegex()
135                     )
136             );
137         }
138
139         for (String pgn : pgnGames) {
140             String gameId = StringUtils.match(
141                     pgn,
142                     getSettings().getGameIdRegex()
143             );
144             tournament.addGame(
145                     new PGNGame(gameId, pgn)
146             );
147         }
148     }
149
150 }