diff options
| author | Austin Hellyer <[email protected]> | 2016-11-30 05:52:47 -0800 |
|---|---|---|
| committer | Austin Hellyer <[email protected]> | 2016-11-30 05:52:47 -0800 |
| commit | 5c4a79fd62e549573e97c400176313cbc8f66b58 (patch) | |
| tree | 987787378d6d8214b53d5b23584ed20779633f24 /src/client | |
| parent | Add documentation for examples (diff) | |
| download | serenity-5c4a79fd62e549573e97c400176313cbc8f66b58.tar.xz serenity-5c4a79fd62e549573e97c400176313cbc8f66b58.zip | |
Add remaining REST routes
The status routes were missing from the HTTP module (now the REST
module) rewrite, as well as the `GET /guilds/:id/members` route. In
addition, remove an unnecessary counter to the global ratelimit mutex.
Diffstat (limited to 'src/client')
| -rw-r--r-- | src/client/context.rs | 15 | ||||
| -rw-r--r-- | src/client/rest/mod.rs | 65 | ||||
| -rw-r--r-- | src/client/rest/ratelimiting.rs | 13 |
3 files changed, 85 insertions, 8 deletions
diff --git a/src/client/context.rs b/src/client/context.rs index d648888..529a0b4 100644 --- a/src/client/context.rs +++ b/src/client/context.rs @@ -1028,6 +1028,21 @@ impl Context { rest::get_member(guild_id.0, user_id.0) } + /// Gets a list of a [`Guild`]'s members. + /// + /// Optionally pass in the `limit` to limit the number of results. Maximum + /// value is 1000. Optionally pass in `after` to offset the results by a + /// [`User`]'s Id. + /// + /// [`Guild`]: ../model/struct.Guild.html + /// [`User`]: ../model/struct.User.html + pub fn get_members<G, U>(&self, guild_id: G, limit: Option<u64>, after: Option<U>) + -> Result<Vec<Member>> where G: Into<GuildId>, U: Into<UserId> { + rest::get_guild_members(guild_id.into().0, + limit, + after.map(|x| x.into().0)) + } + /// Retrieves a single [`Message`] from a [`Channel`]. /// /// Requires the [Read Message History] permission. diff --git a/src/client/rest/mod.rs b/src/client/rest/mod.rs index fcd29e3..8cdb5ac 100644 --- a/src/client/rest/mod.rs +++ b/src/client/rest/mod.rs @@ -860,6 +860,22 @@ pub fn execute_webhook(webhook_id: u64, token: &str, map: Value) Message::decode(try!(serde_json::from_reader(response))) } +/// Gets the active maintenances from Discord's Status API. +/// +/// Does not require authentication. +pub fn get_active_maintenances() -> Result<Vec<Maintenance>> { + let client = HyperClient::new(); + let response = try!(retry(|| client.get( + status!("/scheduled-maintenances/active.json")))); + + let mut map: BTreeMap<String, Value> = try!(serde_json::from_reader(response)); + + match map.remove("scheduled_maintenances") { + Some(v) => decode_array(v, Maintenance::decode), + None => Ok(vec![]), + } +} + /// Gets information about an oauth2 application we own. /// /// **Note**: Only user accounts may use this endpoint. @@ -1028,8 +1044,21 @@ pub fn get_guild_invites(guild_id: u64) -> Result<Vec<RichInvite>> { "/guilds/{}/invites", guild_id); - decode_array(try!(serde_json::from_reader(response)), - RichInvite::decode) + decode_array(try!(serde_json::from_reader(response)), RichInvite::decode) +} + +/// Gets the members of a guild. Optionally pass a `limit` and the Id of the +/// user to offset the result by. +pub fn get_guild_members(guild_id: u64, limit: Option<u64>, after: Option<u64>) + -> Result<Vec<Member>> { + let response = request!(Route::GuildsIdMembers(guild_id), + get, + "/guilds/{}/members?limit={}&after={}", + guild_id, + limit.unwrap_or(500), + after.unwrap_or(0)); + + decode_array(try!(serde_json::from_reader(response)), Member::decode) } /// Gets the amount of users that can be pruned. @@ -1184,6 +1213,38 @@ pub fn get_reaction_users(channel_id: u64, decode_array(try!(serde_json::from_reader(response)), User::decode) } +/// Gets the current unresolved incidents from Discord's Status API. +/// +/// Does not require authentication. +pub fn get_unresolved_incidents() -> Result<Vec<Incident>> { + let client = HyperClient::new(); + let response = try!(retry(|| client.get( + status!("/incidents/unresolved.json")))); + + let mut map: BTreeMap<String, Value> = try!(serde_json::from_reader(response)); + + match map.remove("incidents") { + Some(incidents) => decode_array(incidents, Incident::decode), + None => Ok(vec![]), + } +} + +/// Gets the upcoming (planned) maintenances from Discord's Status API. +/// +/// Does not require authentication. +pub fn get_upcoming_maintenances() -> Result<Vec<Maintenance>> { + let client = HyperClient::new(); + let response = try!(retry(|| client.get( + status!("/scheduled-maintenances/upcoming.json")))); + + let mut map: BTreeMap<String, Value> = try!(serde_json::from_reader(response)); + + match map.remove("scheduled_maintenances") { + Some(v) => decode_array(v, Maintenance::decode), + None => Ok(vec![]), + } +} + /// Gets a user by Id. pub fn get_user(user_id: u64) -> Result<CurrentUser> { let response = request!(Route::UsersId, get, "/users/{}", user_id); diff --git a/src/client/rest/ratelimiting.rs b/src/client/rest/ratelimiting.rs index ca29053..ff5e352 100644 --- a/src/client/rest/ratelimiting.rs +++ b/src/client/rest/ratelimiting.rs @@ -83,6 +83,7 @@ pub enum Route { GuildsIdIntegrationsId(u64), GuildsIdIntegrationsIdSync(u64), GuildsIdInvites(u64), + GuildsIdMembers(u64), GuildsIdMembersId(u64), GuildsIdMembersIdRolesId(u64), GuildsIdMembersMeNick(u64), @@ -107,6 +108,12 @@ pub fn perform<'a, F>(route: Route, f: F) -> Result<Response> where F: Fn() -> RequestBuilder<'a> { loop { + { + /// This will block if another thread already has the global + /// unlocked already (due to receiving an x-ratelimit-global). + let mut _global = GLOBAL.lock().expect("global route lock poisoned"); + } + // Perform pre-checking here: // // - get the route's relevant rate @@ -115,11 +122,6 @@ pub fn perform<'a, F>(route: Route, f: F) -> Result<Response> // - get the global rate; // - sleep if there is 0 remaining // - then, perform the request - { - let mut global = GLOBAL.lock().expect("global route lock poisoned"); - global.pre_hook(); - } - if route != Route::None { if let Some(route) = ROUTES.lock().expect("routes poisoned").get_mut(&route) { route.pre_hook(); @@ -141,7 +143,6 @@ pub fn perform<'a, F>(route: Route, f: F) -> Result<Response> // It _may_ be possible for the limit to be raised at any time, // so check if it did from the value of the 'x-ratelimit-limit' // header. If the limit was 5 and is now 7, add 2 to the 'remaining' - if route != Route::None { let redo = if response.headers.get_raw("x-ratelimit-global").is_some() { let mut global = GLOBAL.lock().expect("global route lock poisoned"); |