rating-chgk-info-0.3.6.3: 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
-- ** Составы на турнире
, tournamentRecap
-- ** Спорные и апелляции
, tournamentControversials
, tournamentAppeals
-- * Различные способы поиска
--
-- $maybeParams
, teamSearch
, playerSearch
-- * Вспомогательные функции
, getAllItems
) where
import RatingChgkInfo.Types
import Network.HTTP.Client (newManager,defaultManagerSettings)
import Servant.API
import Servant.Client
api :: Proxy RatingApi
api = Proxy
-- | Список всех игроков
players :: Maybe Int -- ^ Номер страницы в результате
-> RatingClient (Items Player) -- ^ Список игроков, по 1000 элементов
-- | Информация об игроке
--
-- __API NOTE__. Результат должен быть 'Player', а не список игроков из одного элемента
player :: PlayerId -- ^ Идентификатор игрока
-> RatingClient [Player] -- ^ Информация об игроке, список из единственного элемента
-- | Команды, в базовых составах которых играл игрок
playerTeams :: PlayerId -- ^ Идентификатор игрока
-> RatingClient [PlayerTeam] -- ^ Список команд игрока
-- | Команды, в базовый состав которых игрок входит в текущем сезоне
playerLastTeam :: PlayerId -- ^ Идентификатор игрока
-> RatingClient [PlayerTeam] -- ^ Список команд игрока
-- | Команды, в базовый состав которых игрок входил в указанном сезоне
playerTeam :: PlayerId -- ^ Идентификатор игрока
-> Int -- ^ Идентификатор сезона
-> RatingClient [PlayerTeam] -- ^ Список команд игрока
-- | Турниры, которые отыграл игрок, по сезонам
playerTournaments :: PlayerId -- ^ Идентификатор игрока
-> RatingClient (SeasonMap PlayerSeason) -- ^ Турниры игрока по сезонам
-- | Турниры, которые игрок отыграл в текущем сезоне
playerLastTournament :: PlayerId -- ^ Идентификатор игрока
-> RatingClient PlayerSeason
-- | Турниры, которые игрок отыграл в указанном сезоне
playerTournament :: PlayerId -- ^ Идентификатор игрока
-> Int -- ^ Идентификатор сезона
-> RatingClient PlayerSeason
-- | Рейтинги игрока
playerRatings :: PlayerId -- ^ Идентификатор игрока
-> RatingClient [PlayerRating] -- ^ Список рейтингов игрока, порядок не определён
-- | Рейтинг игрока в последнем релизе
--
-- __API NOTE__. Работает не всегда: например, для 54345 в декабре 2018 ничего не возвращало (off-by-one error?)
playerLastRating :: PlayerId -- ^ Идентификатор игрока
-> RatingClient PlayerRating
-- | Рейтинг игрока в указанном релизе
playerRating :: PlayerId -- ^ Идентификатор игрока
-> Int -- ^ Идентификатор релиза
-> RatingClient PlayerRating
-- | Список всех команд
teams :: Maybe Int -- ^ Номер страницы в результате
-> RatingClient (Items Team) -- ^ Команды по 1000 элементов
-- | Информация о команде
--
-- __API NOTE__: должна быть команда, а не список из команд
team :: TeamId -- ^ Идентификатор команды
-> RatingClient [Team] -- ^ Команда, список из единственного элемента
-- | Базовые составы команды
teamBaseRecaps :: TeamId -- ^ Идентификатор команды
-> RatingClient (SeasonMap TeamBaseRecap) -- ^ Базовые составы по сезонам
-- | Базовый состав команды в последнем сезоне
teamLastBaseRecap :: TeamId -- ^ Идентификатор команды
-> RatingClient TeamBaseRecap
-- | Базовый состав команды в указанном сезоне
teamBaseRecap :: TeamId -- ^ Идентификатор команды
-> Int -- ^ Идентификатор сезона
-> RatingClient TeamBaseRecap
-- | Турниры, отыгранные командой
teamTournaments :: TeamId -- ^ Идентификатор команды
-> RatingClient (SeasonMap TeamTournament) -- ^ Турниры команды по сезонам
-- | Турниры, отыгранные командой в последнем сезоне
teamLastTournament :: TeamId -- ^ Идентификатор команды
-> RatingClient TeamTournament
-- | Турниры, отыгранные командой в указанном сезоне
teamTournament :: TeamId -- ^ Идентификатор команды
-> Int -- ^ Идентификатор сезона
-> RatingClient TeamTournament
-- | Рейтинги команды
teamRatings :: TeamId -- ^ Идентификатор команды
-> RatingClient [TeamRating] -- ^ Список рейтингов команды, порядок не определён
-- | Последний рейтинг команды по формуле A
--
-- __API NOTE__. Работает не всегда: для 1 ничего не возвращает (off-by-one error?)
teamRatingA :: TeamId -- ^ Идентификатор команды
-> RatingClient TeamRating
-- | Последний рейтинг команды по формуле B
--
-- __API NOTE__. Работает не всегда: для 1 ничего не возвращает (off-by-one error?)
teamRatingB :: TeamId -- ^ Идентификатор команды
-> RatingClient TeamRating
-- | Рейтинг команды в указанном релизе
teamRating :: TeamId -- ^ Идентификатор команды
-> Int -- ^ Идентификатор релиза
-> RatingClient TeamRating
-- | Список всех турниров
tournaments :: Maybe Int -- ^ Номер страницы в результате
-> RatingClient (Items TournamentShort) -- ^ Информация о турнирах по 1000 элементов
-- | Информация о турнире
--
-- __API NOTE__: должен быть турнир, а не список турниров
tournament :: TournamentId -- ^ Идентификатор турнира
-> RatingClient [Tournament] -- ^ Единственный элемент списка - турнир
-- | Результаты турнира
tournamentResults :: TournamentId -- ^ Идентификатор турнира
-> RatingClient [TournamentResult] -- ^ Результаты по командам, порядок не определён
-- | Результаты турнира для команд города
tournamentResultsTown :: TournamentId -- ^ Идентификатор турнира
-> Int -- ^ Идентификатор города
-> RatingClient [TournamentResult] -- ^ Результаты по командам, порядок не определён
-- | Результаты турнира для команд региона
tournamentResultsRegion :: TournamentId -- ^ Идентификатор турнира
-> Int -- ^ Идентификатор региона
-> RatingClient [TournamentResult] -- ^ Результаты по командам, порядок не определён
-- | Результаты турнира для команд страны
tournamentResultsCountry :: TournamentId -- ^ Идентификатор турнира
-> Int -- ^ Идентификатор страны
-> RatingClient [TournamentResult] -- ^ Результаты по командам, порядок не определён
-- | Составы указанной команды на турнире
tournamentRecap :: TournamentId -- ^ Идентификатор турнира
-> TeamId -- ^ Идентификатор команды
-> RatingClient [RecapPlayer] -- ^ Список игроков с флагами К\/Б\/Л
-- | Результат указанной команды на турнире
tournamentTeamResult :: TournamentId -- ^ Идентификатор турнира
-> TeamId -- ^ Идентификатор команды
-> RatingClient [TourResult] -- ^ Список результатов по турам
-- | Спорные на турнире
tournamentControversials :: TournamentId -- ^ Идентификатор турнира
-> RatingClient [Controversial] -- ^ Спорные
-- | Апелляции на турнире
tournamentAppeals :: TournamentId -- ^ Идентификатор турнира
-> RatingClient [Appeal] -- ^ Апелляции
-- $maybeParams
--
-- В функции поиска передаётся несколько значений типа 'Maybe a'. Если
-- соответствующее значение установлено, по этому параметру производится поиск.
-- Если установлено несколько значений, они объединяются при помощи логической
-- связки И.
-- | Поиск по командам
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 элементов
-- | Поиск по игрокам
playerSearch :: Maybe Text -- ^ Фамилия
-> Maybe Text -- ^ Имя
-> Maybe Text -- ^ Отчество
-> Maybe Int -- ^ Номер страницы в результате
-> RatingClient (Items Player) -- ^ Список игроков по 1000 элементов
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 :<|> tournamentRecap :<|> tournamentTeamResult :<|> tournamentControversials :<|> tournamentAppeals :<|> teamSearch :<|> playerSearch = 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 ServantError a) -- ^ Результат работы, либо ошибка
runRatingApi act = do
mgr <- newManager defaultManagerSettings
runClientM act $ mkClientEnv mgr $ BaseUrl Http "rating.chgk.info" 80 "api"