Skip to main content

lichess_api/api/
broadcasts.rs

1//! Broadcasts: Lichess's live relays of over-the-board tournaments, made up
2//! of one tournament containing one or more rounds, each fed by an external
3//! PGN source.
4//!
5//! Reading broadcasts (getting a tournament, round, player, team standings,
6//! listing/searching/browsing top and official broadcasts, and exporting PGN)
7//! is public and needs no token. Creating or managing your own broadcasts —
8//! [`create_broadcast_tournament`](LichessApi::create_broadcast_tournament),
9//! [`update_broadcast_tournament`](LichessApi::update_broadcast_tournament),
10//! [`create_broadcast_round`](LichessApi::create_broadcast_round),
11//! [`update_broadcast_round`](LichessApi::update_broadcast_round),
12//! [`push_broadcast_round_pgn`](LichessApi::push_broadcast_round_pgn), and
13//! [`reset_broadcast_round`](LichessApi::reset_broadcast_round) — requires a
14//! bearer token with the `study:write` scope.
15//!
16//! The `stream_*_pgn` methods keep the connection open and yield PGN as
17//! games progress, so they return a `Stream` rather than a single value;
18//! `export_*_pgn` methods stream the same way but close once the current
19//! games have been sent.
20
21use futures::stream::StreamExt;
22
23use crate::client::LichessApi;
24use crate::error::Result;
25use crate::model::broadcasts::*;
26
27impl LichessApi<reqwest::Client> {
28    pub async fn export_broadcast_pgn(
29        &self,
30        broadcast_tournament_id: &str,
31        query: export_pgn::GetQuery,
32    ) -> Result<impl StreamExt<Item = Result<String>>> {
33        self.get_pgn(export_pgn::GetRequest::new(broadcast_tournament_id, query))
34            .await
35    }
36
37    pub async fn export_broadcast_round_pgn(
38        &self,
39        broadcast_round_id: &str,
40        query: export_round_pgn::GetQuery,
41    ) -> Result<impl StreamExt<Item = Result<String>>> {
42        self.get_pgn(export_round_pgn::GetRequest::new(broadcast_round_id, query))
43            .await
44    }
45
46    pub async fn stream_broadcast_group_pgn(
47        &self,
48        broadcast_group_id: &str,
49        query: stream_group_pgn::GetQuery,
50    ) -> Result<impl StreamExt<Item = Result<String>>> {
51        self.get_pgn(stream_group_pgn::GetRequest::new(broadcast_group_id, query))
52            .await
53    }
54
55    pub async fn stream_broadcast_round_pgn(
56        &self,
57        broadcast_round_id: &str,
58        query: stream_round_pgn::GetQuery,
59    ) -> Result<impl StreamExt<Item = Result<String>>> {
60        self.get_pgn(stream_round_pgn::GetRequest::new(broadcast_round_id, query))
61            .await
62    }
63
64    pub async fn stream_broadcast_tournament_pgn(
65        &self,
66        broadcast_tour_id: &str,
67        query: stream_tournament_pgn::GetQuery,
68    ) -> Result<impl StreamExt<Item = Result<String>>> {
69        self.get_pgn(stream_tournament_pgn::GetRequest::new(
70            broadcast_tour_id,
71            query,
72        ))
73        .await
74    }
75
76    pub async fn get_broadcast_round(
77        &self,
78        broadcast_tournament_slug: &str,
79        broadcast_round_slug: &str,
80        broadcast_round_id: &str,
81    ) -> Result<BroadcastRound> {
82        self.get_single_model(get_round::GetRequest::new(
83            broadcast_tournament_slug,
84            broadcast_round_slug,
85            broadcast_round_id,
86        ))
87        .await
88    }
89
90    pub async fn get_my_broadcast_rounds(
91        &self,
92        query: list_my_rounds::GetQuery,
93    ) -> Result<impl StreamExt<Item = Result<BroadcastMyRound>>> {
94        self.get_streamed_models(list_my_rounds::GetRequest::new(query))
95            .await
96    }
97
98    pub async fn get_broadcasts_by_user(
99        &self,
100        username: &str,
101        query: list_by_user::GetQuery,
102    ) -> Result<BroadcastByUserPaginator> {
103        self.get_single_model(list_by_user::GetRequest::new(username, query))
104            .await
105    }
106
107    pub async fn get_official_broadcasts(
108        &self,
109        query: list_official::GetQuery,
110    ) -> Result<impl StreamExt<Item = Result<BroadcastWithRounds>>> {
111        self.get_streamed_models(list_official::GetRequest::from(query))
112            .await
113    }
114
115    pub async fn search_broadcasts(
116        &self,
117        query: search::GetQuery,
118    ) -> Result<BroadcastSearchPaginator> {
119        self.get_single_model(search::GetRequest::from(query)).await
120    }
121
122    pub async fn get_top_broadcasts(&self, query: top::GetQuery) -> Result<BroadcastTop> {
123        self.get_single_model(top::GetRequest::from(query)).await
124    }
125
126    pub async fn update_broadcast_tournament(
127        &self,
128        broadcast_tournament_id: &str,
129        form: create_tournament::CreateBroadcastTournamentForm,
130    ) -> Result<bool> {
131        self.get_ok(update_tournament::PostRequest::new(
132            broadcast_tournament_id,
133            form,
134        ))
135        .await
136    }
137
138    pub async fn create_broadcast_round(
139        &self,
140        broadcast_tournament_id: &str,
141        form: create_round::BroadcastRoundForm,
142    ) -> Result<BroadcastRoundNew> {
143        self.get_single_model(create_round::PostRequest::new(
144            broadcast_tournament_id,
145            form,
146        ))
147        .await
148    }
149
150    pub async fn get_broadcast_player(
151        &self,
152        broadcast_tournament_id: &str,
153        player_id: &str,
154    ) -> Result<BroadcastPlayerEntryWithFideAndGames> {
155        self.get_single_model(get_player::GetRequest::new(
156            broadcast_tournament_id,
157            player_id,
158        ))
159        .await
160    }
161
162    pub async fn get_broadcast_players(
163        &self,
164        request: impl Into<get_players::GetRequest>,
165    ) -> Result<Vec<BroadcastPlayerEntry>> {
166        self.get_single_model(request.into()).await
167    }
168
169    pub async fn get_broadcast_team_standings(
170        &self,
171        request: impl Into<get_team_standings::GetRequest>,
172    ) -> Result<Vec<BroadcastTeamLeaderboardEntry>> {
173        self.get_single_model(request.into()).await
174    }
175
176    pub async fn get_broadcast_tournament(
177        &self,
178        request: impl Into<get_tournament::GetRequest>,
179    ) -> Result<BroadcastWithRoundsAndFullGroup> {
180        self.get_single_model(request.into()).await
181    }
182
183    pub async fn create_broadcast_tournament(
184        &self,
185        form: create_tournament::CreateBroadcastTournamentForm,
186    ) -> Result<BroadcastWithRounds> {
187        self.get_single_model(create_tournament::PostRequest::new(form))
188            .await
189    }
190
191    pub async fn update_broadcast_round(
192        &self,
193        broadcast_round_id: &str,
194        query: update_round::PostQuery,
195        form: create_round::BroadcastRoundForm,
196    ) -> Result<BroadcastRound> {
197        self.get_single_model(update_round::PostRequest::new(
198            broadcast_round_id,
199            query,
200            form,
201        ))
202        .await
203    }
204
205    pub async fn push_broadcast_round_pgn(
206        &self,
207        broadcast_round_id: &str,
208        pgn: String,
209    ) -> Result<BroadcastPgnPush> {
210        self.get_single_model(push_pgn::PostRequest::new(broadcast_round_id, pgn))
211            .await
212    }
213
214    pub async fn reset_broadcast_round(
215        &self,
216        request: impl Into<reset_round::PostRequest>,
217    ) -> Result<bool> {
218        self.get_ok(request.into()).await
219    }
220}