{-| Module : RatingChgkInfo.Api Description : Функции для работы с API сайта рейтинга Copyright : (c) Mansur Ziiatdinov, 2018-2019 License : BSD-3 Maintainer : chgk@pm.me Stability : experimental Portability : POSIX Функции здесь повторяют те запросы, которые доступны в API сайта рейтинга. Те функции, которые недоступны через API, реализованы в 'RatingChgkInfo.NoApi'. Кроме того, есть вспомогательная функция 'getAllItems' для удобства. -} module RatingChgkInfo.Api ( -- * Работа с API RatingClient , runRatingApi -- * Информация об игроках , players , player -- ** О командах игроков , playerTeams , playerLastTeam , playerTeam -- ** О турнирах игроков , playerTournaments , playerLastTournament , playerTournament -- ** О рейтингах игроков , playerRatings , playerLastRating , playerRating -- * Информация о командах , teams , team -- ** Базовые составы , teamBaseRecaps , teamLastBaseRecap , teamBaseRecap -- ** Отыгранные турниры , teamTournaments , teamLastTournament , teamTournament -- ** Рейтинги , teamRatings , teamRatingA , teamRatingB , teamRating -- * Информация о турнирах , tournaments , tournament -- ** Результаты турнира , tournamentResults , tournamentResultsTown , tournamentResultsRegion , tournamentResultsCountry , tournamentTeamResult -- ** Составы на турнире , tournamentRecaps , tournamentRecap -- ** Спорные и апелляции , tournamentControversials , tournamentAppeals -- * Различные способы поиска -- -- $maybeParams , teamSearch , playerSearch , tournamentSearch -- * Вспомогательные функции , getAllItems ) where import RatingChgkInfo.Types import Network.HTTP.Client (newManager) import Network.HTTP.Client.TLS (tlsManagerSettings) import Servant.API import Servant.Client api :: Proxy RatingApi api = Proxy -- | Список всех игроков -- -- Запрос @\/players@ players :: Maybe Int -- ^ Номер страницы в результате -> RatingClient (Items Player) -- ^ Список игроков, по 1000 элементов -- | Информация об игроке -- -- __API NOTE__. Результат должен быть 'Player', а не список игроков из одного элемента -- -- Запрос @\/players\/:id@ player :: PlayerId -- ^ Идентификатор игрока -> RatingClient [Player] -- ^ Информация об игроке, список из единственного элемента -- | Команды, в базовых составах которых играл игрок -- -- Запрос @\/players\/:id\/teams@ playerTeams :: PlayerId -- ^ Идентификатор игрока -> RatingClient [PlayerTeam] -- ^ Список команд игрока -- | Команды, в базовый состав которых игрок входит в текущем сезоне -- -- Запрос @\/players\/:id\/teams\/last@ playerLastTeam :: PlayerId -- ^ Идентификатор игрока -> RatingClient [PlayerTeam] -- ^ Список команд игрока -- | Команды, в базовый состав которых игрок входил в указанном сезоне -- -- Запрос @\/players\/:id\/teams\/:season@ playerTeam :: PlayerId -- ^ Идентификатор игрока -> Int -- ^ Идентификатор сезона -> RatingClient [PlayerTeam] -- ^ Список команд игрока -- | Турниры, которые отыграл игрок, по сезонам -- -- Запрос @\/players\/:id\/tournaments@ playerTournaments :: PlayerId -- ^ Идентификатор игрока -> RatingClient (SeasonMap PlayerSeason) -- ^ Турниры игрока по сезонам -- | Турниры, которые игрок отыграл в текущем сезоне -- -- Запрос @\/players\/:id\/tournaments\/last@ playerLastTournament :: PlayerId -- ^ Идентификатор игрока -> RatingClient PlayerSeason -- | Турниры, которые игрок отыграл в указанном сезоне -- -- Запрос @\/players\/:id\/tournaments\/:season@ playerTournament :: PlayerId -- ^ Идентификатор игрока -> Int -- ^ Идентификатор сезона -> RatingClient PlayerSeason -- | Рейтинги игрока -- -- Запрос @\/players\/:id\/rating@ playerRatings :: PlayerId -- ^ Идентификатор игрока -> RatingClient [PlayerRating] -- ^ Список рейтингов игрока, порядок не определён -- | Рейтинг игрока в последнем релизе -- -- __API NOTE__. Работает не всегда: например, для 54345 в декабре 2018 ничего не возвращало (off-by-one error?) -- -- Запрос @\/players\/:id\/rating\/last@ playerLastRating :: PlayerId -- ^ Идентификатор игрока -> RatingClient PlayerRating -- | Рейтинг игрока в указанном релизе -- -- Запрос @\/players\/:id\/rating\/:release@ playerRating :: PlayerId -- ^ Идентификатор игрока -> Int -- ^ Идентификатор релиза -> RatingClient PlayerRating -- | Список всех команд -- -- Запрос @\/teams@ teams :: Maybe Int -- ^ Номер страницы в результате -> RatingClient (Items Team) -- ^ Команды по 1000 элементов -- | Информация о команде -- -- __API NOTE__: должна быть команда, а не список из команд -- -- Запрос @\/teams\/:id@ team :: TeamId -- ^ Идентификатор команды -> RatingClient [Team] -- ^ Команда, список из единственного элемента -- | Базовые составы команды -- -- Запрос @\/teams\/:id\/recaps@ teamBaseRecaps :: TeamId -- ^ Идентификатор команды -> RatingClient (SeasonMap TeamBaseRecap) -- ^ Базовые составы по сезонам -- | Базовый состав команды в последнем сезоне -- -- Запрос @\/teams\/:id\/recaps\/last@ teamLastBaseRecap :: TeamId -- ^ Идентификатор команды -> RatingClient TeamBaseRecap -- | Базовый состав команды в указанном сезоне -- -- Запрос @\/teams\/:id\/recaps\/:season@ teamBaseRecap :: TeamId -- ^ Идентификатор команды -> Int -- ^ Идентификатор сезона -> RatingClient TeamBaseRecap -- | Турниры, отыгранные командой -- -- Запрос @\/teams\/:id\/tournaments@ teamTournaments :: TeamId -- ^ Идентификатор команды -> RatingClient (SeasonMap TeamTournament) -- ^ Турниры команды по сезонам -- | Турниры, отыгранные командой в последнем сезоне -- -- Запрос @\/teams\/:id\/tournaments\/last@ teamLastTournament :: TeamId -- ^ Идентификатор команды -> RatingClient TeamTournament -- | Турниры, отыгранные командой в указанном сезоне -- -- Запрос @\/teams\/:id\/tournaments\/:season@ teamTournament :: TeamId -- ^ Идентификатор команды -> Int -- ^ Идентификатор сезона -> RatingClient TeamTournament -- | Рейтинги команды -- -- Запрос @\/teams\/:id\/rating@ teamRatings :: TeamId -- ^ Идентификатор команды -> RatingClient [TeamRating] -- ^ Список рейтингов команды, порядок не определён -- | Последний рейтинг команды по формуле A -- -- __API NOTE__. Работает не всегда: для 1 ничего не возвращает (off-by-one error?) -- -- Запрос @\/teams\/:id\/rating\/a@ teamRatingA :: TeamId -- ^ Идентификатор команды -> RatingClient TeamRating -- | Последний рейтинг команды по формуле B -- -- __API NOTE__. Работает не всегда: для 1 ничего не возвращает (off-by-one error?) -- -- Запрос @\/teams\/:id\/rating\/b@ teamRatingB :: TeamId -- ^ Идентификатор команды -> RatingClient TeamRating -- | Рейтинг команды в указанном релизе -- -- Запрос @\/teams\/:id\/rating\/:release@ teamRating :: TeamId -- ^ Идентификатор команды -> Int -- ^ Идентификатор релиза -> RatingClient TeamRating -- | Список всех турниров -- -- Запрос @\/tournaments@ tournaments :: Maybe Int -- ^ Номер страницы (@page@) в результате -> RatingClient (Items TournamentShort) -- ^ Информация о турнирах по 1000 элементов -- | Информация о турнире -- -- __API NOTE__: должен быть турнир, а не список турниров -- -- Запрос @\/tournaments\/:id@ tournament :: TournamentId -- ^ Идентификатор турнира -> RatingClient [Tournament] -- ^ Единственный элемент списка - турнир -- | Результаты турнира -- -- Запрос @\/tournaments\/:id\/list@ tournamentResults :: TournamentId -- ^ Идентификатор турнира -> RatingClient [TournamentResult] -- ^ Результаты по командам, порядок не определён -- | Результаты турнира для команд города -- -- Запрос @\/tournaments\/:id\/list\/town\/:town@ tournamentResultsTown :: TournamentId -- ^ Идентификатор турнира -> Int -- ^ Идентификатор города -> RatingClient [TournamentResult] -- ^ Результаты по командам, порядок не определён -- | Результаты турнира для команд региона -- -- Запрос @\/tournaments\/:id\/list\/region\/:region@ tournamentResultsRegion :: TournamentId -- ^ Идентификатор турнира -> Int -- ^ Идентификатор региона -> RatingClient [TournamentResult] -- ^ Результаты по командам, порядок не определён -- | Результаты турнира для команд страны -- -- Запрос @\/tournaments\/:id\/list\/country\/:country@ tournamentResultsCountry :: TournamentId -- ^ Идентификатор турнира -> Int -- ^ Идентификатор страны -> RatingClient [TournamentResult] -- ^ Результаты по командам, порядок не определён -- | Составы команд на турнире -- -- Запрос @\/tournaments\/:id\/recaps@ -- -- @since 0.3.6.4 tournamentRecaps :: TournamentId -- ^ Идентификаторр турнира -> RatingClient [RecapTeam] -- | Составы указанной команды на турнире -- -- Запрос @\/tournaments\/:id\/recaps\/:team@ tournamentRecap :: TournamentId -- ^ Идентификатор турнира -> TeamId -- ^ Идентификатор команды -> RatingClient [RecapPlayer] -- ^ Список игроков с флагами К\/Б\/Л -- | Результат указанной команды на турнире -- -- Запрос @\/tournaments\/:id\/results\/:team@ tournamentTeamResult :: TournamentId -- ^ Идентификатор турнира -> TeamId -- ^ Идентификатор команды -> RatingClient [TourResult] -- ^ Список результатов по турам -- | Спорные на турнире -- -- Запрос @\/tournaments\/:id\/controversials@ -- -- @since 0.3.6.3 tournamentControversials :: TournamentId -- ^ Идентификатор турнира -> RatingClient [Controversial] -- ^ Спорные -- | Апелляции на турнире -- -- Запрос @\/tournaments\/:id\/appeals@ -- -- @since 0.3.6.3 tournamentAppeals :: TournamentId -- ^ Идентификатор турнира -> RatingClient [Appeal] -- ^ Апелляции -- $maybeParams -- -- В функции поиска передаётся несколько значений типа 'Maybe a'. Если -- соответствующее значение установлено, по этому параметру производится поиск. -- Если установлено несколько значений, они объединяются при помощи логической -- связки И. -- | Поиск по командам -- -- Запрос @\/teams\/search@ teamSearch :: Maybe Text -- ^ Название (name) -> Maybe Text -- ^ Город (town) -> Maybe Text -- ^ Регион (region_name) -> Maybe Text -- ^ Страна (country_name) -> Bool -- ^ Играла в текущем сезоне (active_this_season) -> Maybe Int -- ^ Номер страницы в результате -> RatingClient (Items Team) -- ^ Список команд по 1000 элементов -- | Поиск по игрокам -- -- Запрос @\/players\/search@ playerSearch :: Maybe Text -- ^ Фамилия -> Maybe Text -- ^ Имя -> Maybe Text -- ^ Отчество -> Maybe Int -- ^ Номер страницы в результате -> RatingClient (Items Player) -- ^ Список игроков по 1000 элементов -- | Поиск по турнирам -- -- Запрос @\/tournaments\/search@ tournamentSearch :: Maybe TournamentType -- ^ Тип турнира -> Maybe Int -- ^ Находится ли турнир в архиве (0 - не находится, 1 - находится) -> Maybe Int -- ^ Номер страницы в результате -> RatingClient (Items TournamentShort) players :<|> player :<|> playerTeams :<|> playerLastTeam :<|> playerTeam :<|> playerTournaments :<|> playerLastTournament :<|> playerTournament :<|> playerRatings :<|> playerLastRating :<|> playerRating :<|> teams :<|> team :<|> teamBaseRecaps :<|> teamLastBaseRecap :<|> teamBaseRecap :<|> teamTournaments :<|> teamLastTournament :<|> teamTournament :<|> teamRatings :<|> teamRatingA :<|> teamRatingB :<|> teamRating :<|> tournaments :<|> tournament :<|> tournamentResults :<|> tournamentResultsTown :<|> tournamentResultsRegion :<|> tournamentResultsCountry :<|> tournamentRecaps :<|> tournamentRecap :<|> tournamentTeamResult :<|> tournamentControversials :<|> tournamentAppeals :<|> teamSearch :<|> playerSearch :<|> tournamentSearch = client api -- | Получение всех элементов из запроса с разбиением по страницам -- -- В функции предполагается, что сайт рейтинга, как и указано в документации, -- разбивает ответ на куски по 1000 элементов getAllItems :: (Maybe Int -> RatingClient (Items a)) -- ^ Запрос с разбиением на страницы -> RatingClient [a] -- ^ Список всех элементов getAllItems getter = do Items cnt is0 <- getter Nothing let lastPage = ceiling (fromIntegral cnt / 1000 :: Double) iss <- forM [2..lastPage] $ fmap items . getter . Just pure $ concat $ is0:iss -- | Запуск клиента API сайта рейтинга -- -- Все запросы внутри 'RatingClient' используют один и тот же менеджер соединений runRatingApi :: RatingClient a -- ^ Набор команд, работающих с API сайта рейтинга -> IO (Either ClientError a) -- ^ Результат работы, либо ошибка runRatingApi act = do mgr <- newManager tlsManagerSettings runClientM act $ mkClientEnv mgr $ BaseUrl Https "rating.chgk.info" 443 "api"