55a53e932d65343b921f1b85486d780298854100
[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.entity.PGNGame;
26 import org.hedgecode.chess.scanner.entity.PGNTournament;
27 import org.hedgecode.chess.scanner.format.lichess.Format;
28 import org.hedgecode.chess.scanner.format.lichess.GameFormat;
29
30 import static org.hedgecode.chess.scanner.ScannerConstants.*;
31
32 /**
33  * LiChessScanner
34  *
35  * @author Dmitry Samoshin aka gotty
36  */
37 public class LiChessScanner extends AbstractSettingsScanner implements Scanner {
38
39     private static final String SETTINGS_FILENAME = "lichess.settings";
40
41     @Override
42     protected String getResourceName() {
43         return SETTINGS_FILENAME;
44     }
45
46     @Override
47     public PGNTournament scanTournament(String tournamentId) throws ScannerException {
48         PGNTournament tournament = new PGNTournament(tournamentId);
49         assignTournamentGames(tournament);
50         return tournament;
51     }
52
53     @Override
54     public PGNTournament findTournament(String tournamentName) throws ScannerException {
55         throw new ScannerException(
56                 "Lichess does not support searching for a tournament by name!"
57         );
58     }
59
60     @Override
61     public PGNGame scanGame(String gameId) throws ScannerException {
62         String pgn = request(
63                 assignUrl(gameId)
64         );
65         if (!isPgnFormat(pgn)) {
66             throw new ScannerException(
67                     String.format("Failed to get PGN for requesting game ID: %s", gameId)
68             );
69         }
70         return new PGNGame(
71                 gameId, pgn
72         );
73     }
74
75     @Override
76     public PGNGame scanGame(String gameId, String tournamentId) throws ScannerException {
77         return scanGame(gameId);
78     }
79
80     @Override
81     public PGNGame scanUrl(String gameUrl) throws ScannerException {
82         String gamePage = request(gameUrl);
83         String pgn = regex(
84                 gamePage,
85                 getSettings().getGameUrlRegex()
86         );
87         if (pgn == null) {
88             pgn = regex(
89                     gamePage,
90                     getSettings().getGameJsonUrlRegex()
91             );
92             if (pgn == null) {
93                 throw new ScannerException(
94                         String.format("Failed to get source data for requesting URL: %s", gameUrl)
95                 );
96             }
97             GameFormat gameFormat = Format.formatGame(pgn);
98             return new PGNGame(
99                     gameFormat.id(),
100                     gameFormat.pgn()
101             );
102         } else {
103             pgn = StringEscapeUtils.unescapeHtml4(pgn);
104             if (!isPgnFormat(pgn)) {
105                 throw new ScannerException(
106                         String.format("Failed to get PGN for requesting URL: %s", gameUrl)
107                 );
108             }
109             return new PGNGame(
110                     regex(pgn, getSettings().getGameIdRegex()),
111                     pgn
112             );
113         }
114     }
115
116     private void assignTournamentGames(PGNTournament tournament) throws ScannerException {
117         tournament.clearGames();
118         List<String> pgnGames = split(
119                 assignUrl(
120                         tournament.id(),
121                         null
122                 ),
123                 PGN_DETECT_REGEX
124         );
125
126         if (!pgnGames.isEmpty()) {
127             tournament.setName(
128                     regex(
129                             pgnGames.get(0),
130                             getSettings().getTournamentNameRegex()
131                     )
132             );
133         }
134
135         for (String pgn : pgnGames) {
136             String gameId = regex(
137                     pgn,
138                     getSettings().getGameIdRegex()
139             );
140             tournament.addGame(
141                     new PGNGame(gameId, pgn)
142             );
143         }
144     }
145
146 }