aboutsummaryrefslogtreecommitdiff
path: root/src/client
diff options
context:
space:
mode:
authorAustin Hellyer <[email protected]>2016-11-10 20:25:32 -0700
committerAustin Hellyer <[email protected]>2016-12-29 11:55:10 -0800
commit0359f512a8aada5ae0371049eb7c66ecd8d68d84 (patch)
treef88dd9b362a2d349d0cdcd13b0859c4cc3329f46 /src/client
parentRework some event handles (diff)
downloadserenity-0359f512a8aada5ae0371049eb7c66ecd8d68d84.tar.xz
serenity-0359f512a8aada5ae0371049eb7c66ecd8d68d84.zip
Add guild and channel search
Diffstat (limited to 'src/client')
-rw-r--r--src/client/context.rs83
-rw-r--r--src/client/error.rs3
-rw-r--r--src/client/rest/mod.rs69
-rw-r--r--src/client/rest/ratelimiting.rs2
4 files changed, 155 insertions, 2 deletions
diff --git a/src/client/context.rs b/src/client/context.rs
index 8bbdfbe..d6d9ef9 100644
--- a/src/client/context.rs
+++ b/src/client/context.rs
@@ -16,7 +16,8 @@ use ::utils::builder::{
EditMember,
EditProfile,
EditRole,
- GetMessages
+ GetMessages,
+ Search,
};
use ::internal::prelude::*;
use ::model::*;
@@ -1444,6 +1445,86 @@ impl Context {
}
}
+ /// Searches a [`Channel`]'s messages by providing query parameters via the
+ /// search builder.
+ ///
+ /// Refer to the documentation for the [`Search`] builder for restrictions
+ /// and defaults parameters, as well as potentially advanced usage.
+ ///
+ /// **Note**: Bot users can not search.
+ ///
+ /// # Examples
+ ///
+ /// Refer to the [`Search`] builder's documentation for examples,
+ /// specifically the section on [searching a channel][search channel].
+ ///
+ /// # Errors
+ ///
+ /// If the `cache` is enabled, returns a
+ /// [`ClientError::InvalidOperationAsBot`] if the current user is a bot.
+ ///
+ /// [`ClientError::InvalidOperationAsBot`]: ../client/enum.ClientError.html#variant.InvalidOperationAsBot
+ /// [`Channel`]: ../model/enum.Channel.html
+ /// [`Search`]: ../utils/builder/struct.Search.html
+ /// [search channel]: ../../utils/builder/struct.Search.html#searching-a-channel
+ pub fn search_channel<C, F>(&self, channel_id: C, f: F)
+ -> Result<SearchResult> where C: Into<ChannelId>,
+ F: FnOnce(Search) -> Search {
+ #[cfg(feature="cache")]
+ {
+ if CACHE.read().unwrap().user.bot {
+ return Err(Error::Client(ClientError::InvalidOperationAsBot));
+ }
+ }
+
+ let map = f(Search::default()).0;
+
+ rest::search_channel_messages(channel_id.into().0, map)
+ }
+
+ /// Searches a [`Guild`]'s messages by providing query parameters via the
+ /// search builder, with the ability to narrow down channels to search.
+ ///
+ /// Refer to the documentation for the [`Search`] builder for restrictions
+ /// and default parameters, as well as potentially advanced usage.
+ ///
+ /// **Note**: Bot users can not search.
+ ///
+ /// # Examples
+ ///
+ /// Refer to the [`Search`] builder's documentation for more examples,
+ /// specifically the section on
+ /// [searching a guild's channels][search guild].
+ ///
+ /// # Errors
+ ///
+ /// If the `cache` is enabled, returns a
+ /// [`ClientError::InvalidOperationAsBot`] if the current user is a bot.
+ ///
+ /// [`ClientError::InvalidOperationAsBot`]: ../client/enum.ClientError.html#variant.InvalidOperationAsBot
+ /// [`Guild`]: ../model/struct.Guild.html
+ /// [`Search`]: ../utils/builder/struct.Search.html
+ /// [search guild]: ../../utils/builder/struct.Search.html#searching-a-guilds-channels
+ pub fn search_guild<F, G>(&self,
+ guild_id: G,
+ channel_ids: Vec<ChannelId>,
+ f: F)
+ -> Result<SearchResult>
+ where F: FnOnce(Search) -> Search,
+ G: Into<GuildId> {
+ #[cfg(feature="cache")]
+ {
+ if CACHE.read().unwrap().user.bot {
+ return Err(Error::Client(ClientError::InvalidOperationAsBot));
+ }
+ }
+
+ let map = f(Search::default()).0;
+ let ids = channel_ids.iter().map(|ch| ch.0).collect::<Vec<u64>>();
+
+ rest::search_guild_messages(guild_id.into().0, &ids, map)
+ }
+
/// Sends a file along with optional message contents. The filename _must_
/// be specified.
///
diff --git a/src/client/error.rs b/src/client/error.rs
index 0ed3bd8..14818d9 100644
--- a/src/client/error.rs
+++ b/src/client/error.rs
@@ -1,4 +1,5 @@
use hyper::status::StatusCode;
+use ::constants::ErrorCode;
use ::model::{ChannelType, Permissions};
/// An error returned from the [`Client`] or the [`Context`], or model instance.
@@ -46,6 +47,7 @@ use ::model::{ChannelType, Permissions};
/// [`Context`]: struct.Context.html
/// [`Context::ban`]: struct.Context.html#method.ban
/// [`Error::Client`]: ../enum.Error.html#variant.Client
+#[allow(enum_variant_names)]
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub enum Error {
/// When attempting to delete below or above the minimum and maximum allowed
@@ -54,6 +56,7 @@ pub enum Error {
/// When attempting to delete a number of days' worth of messages that is
/// not allowed.
DeleteMessageDaysAmount(u8),
+ ErrorCode(ErrorCode),
/// When there was an error retrieving the gateway URI from the REST API.
Gateway,
/// An indication that a [guild][`Guild`] could not be found by
diff --git a/src/client/rest/mod.rs b/src/client/rest/mod.rs
index 5a03f37..1af067d 100644
--- a/src/client/rest/mod.rs
+++ b/src/client/rest/mod.rs
@@ -44,7 +44,7 @@ use std::default::Default;
use std::fmt::Write as FmtWrite;
use std::io::{ErrorKind as IoErrorKind, Read};
use std::sync::{Arc, Mutex};
-use ::constants;
+use ::constants::{self, ErrorCode};
use ::internal::prelude::*;
use ::model::*;
use ::utils::decode_array;
@@ -1429,6 +1429,73 @@ pub fn remove_group_recipient(group_id: u64, user_id: u64)
user_id))
}
+/// Searches a [`Channel`] for [`Message`]s that meet provided requirements.
+///
+/// **Note**: Bot users can not search.
+///
+/// [`Channel`]: ../../model/enum.Channel.html
+/// [`Message`]: ../../model/struct.Message.html
+pub fn search_channel_messages(channel_id: u64, map: BTreeMap<&str, String>)
+ -> Result<SearchResult> {
+ let mut uri = format!("/channels/{}/messages/search?", channel_id);
+
+ for (k, v) in map {
+ uri.push('&');
+ uri.push_str(k);
+ uri.push('=');
+ uri.push_str(&v);
+ }
+
+ let response = request!(Route::ChannelsIdMessagesSearch(channel_id),
+ get,
+ "{}",
+ uri);
+
+ if response.status == StatusCode::Accepted {
+ return Err(Error::Client(ClientError::ErrorCode(ErrorCode::SearchIndexUnavailable)));
+ }
+
+ let content = try!(serde_json::from_reader(response));
+
+ SearchResult::decode(content)
+}
+
+/// Searches a [`Guild`] - and optionally specific [channel][`GuildChannel`]s
+/// within it - for messages that meet provided requirements.
+///
+/// **Note**: Bot users can not search.
+///
+/// [`Guild`]: ../../model/struct.Guild.html
+/// [`GuildChannel`]: ../../model/struct.GuildChannel.html
+pub fn search_guild_messages(guild_id: u64,
+ channel_ids: &[u64],
+ map: BTreeMap<&str, String>)
+ -> Result<SearchResult> {
+ let mut uri = format!("/guilds/{}/messages/search?", guild_id);
+
+ for (k, v) in map {
+ uri.push('&');
+ uri.push_str(k);
+ uri.push('=');
+ uri.push_str(&v);
+ }
+
+ for channel_id in channel_ids {
+ write!(uri, "&channel_id={}", channel_id)?;
+ }
+
+ let response = request!(Route::GuildsIdMessagesSearch(guild_id),
+ get,
+ "{}",
+ uri);
+
+ if response.status == StatusCode::Accepted {
+ return Err(Error::Client(ClientError::ErrorCode(ErrorCode::SearchIndexUnavailable)));
+ }
+
+ SearchResult::decode(try!(serde_json::from_reader(response)))
+}
+
/// Sends a file to a channel.
pub fn send_file<R: Read>(channel_id: u64,
mut file: R,
diff --git a/src/client/rest/ratelimiting.rs b/src/client/rest/ratelimiting.rs
index ac085eb..a404310 100644
--- a/src/client/rest/ratelimiting.rs
+++ b/src/client/rest/ratelimiting.rs
@@ -64,6 +64,7 @@ pub enum Route {
ChannelsIdMessagesIdAck(u64),
ChannelsIdMessagesIdReactions(u64),
ChannelsIdMessagesIdReactionsUserIdType(u64),
+ ChannelsIdMessagesSearch(u64),
ChannelsIdPermissionsOverwriteId(u64),
ChannelsIdPins(u64),
ChannelsIdPinsMessageId(u64),
@@ -87,6 +88,7 @@ pub enum Route {
GuildsIdMembersId(u64),
GuildsIdMembersIdRolesId(u64),
GuildsIdMembersMeNick(u64),
+ GuildsIdMessagesSearch(u64),
GuildsIdPrune(u64),
GuildsIdRegions(u64),
GuildsIdRoles(u64),