rating-chgk-info-0.3.6.4: src/RatingChgkInfo/Api.hs
{-|
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"