aboutsummaryrefslogtreecommitdiff
path: root/src/client
diff options
context:
space:
mode:
authorAustin Hellyer <[email protected]>2016-11-30 05:52:47 -0800
committerAustin Hellyer <[email protected]>2016-11-30 05:52:47 -0800
commit5c4a79fd62e549573e97c400176313cbc8f66b58 (patch)
tree987787378d6d8214b53d5b23584ed20779633f24 /src/client
parentAdd documentation for examples (diff)
downloadserenity-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.rs15
-rw-r--r--src/client/rest/mod.rs65
-rw-r--r--src/client/rest/ratelimiting.rs13
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");