summaryrefslogtreecommitdiff
path: root/src/helix
diff options
context:
space:
mode:
Diffstat (limited to 'src/helix')
-rw-r--r--src/helix/endpoints.rs121
-rw-r--r--src/helix/mod.rs2
-rw-r--r--src/helix/models.rs76
3 files changed, 199 insertions, 0 deletions
diff --git a/src/helix/endpoints.rs b/src/helix/endpoints.rs
new file mode 100644
index 0000000..5c3aa05
--- /dev/null
+++ b/src/helix/endpoints.rs
@@ -0,0 +1,121 @@
+use futures::future::Future;
+use reqwest::header;
+use reqwest::r#async::{Chunk, Decoder, Request, Response};
+use reqwest::r#async::Client as ReqwestClient;
+
+use super::models::{DataContainer, PaginationContainer, User, Video, Clip};
+
+const API_DOMAIN: &'static str = "api.twitch.tv";
+
+/* When Client owns a ReqwestClient, any futures spawned do not immediately
+ * terminate but 'hang'. When creating a new client for each request this problem
+ * does not occur. This would need to be resolved so we can benefit from keep alive
+ * connections.
+ *
+ */
+
+pub struct Client {
+ id: String,
+}
+
+impl Client {
+ pub fn new(client_id: &str) -> Client {
+ Client {
+ id: client_id.to_owned(),
+ }
+ }
+
+ fn create_client(&self) -> ReqwestClient {
+ let mut headers = header::HeaderMap::new();
+ let auth_key = &self.id;
+ let header_value = header::HeaderValue::from_str(auth_key).unwrap();
+ headers.insert("Client-ID", header_value);
+
+ let client = ReqwestClient::builder().default_headers(headers).build().unwrap();
+ client
+ }
+
+ pub fn users(
+ &self,
+ id: Vec<&str>,
+ login: Vec<&str>,
+ ) -> impl Future<Item = DataContainer<User>, Error = reqwest::Error> {
+ let mut url =
+ String::from("https://") + &String::from(API_DOMAIN) + &String::from("/helix/users");
+
+ if id.len() > 0 || login.len() > 0 {
+ url.push_str("?");
+ }
+
+ if id.len() > 0 {
+ for index in 0..id.len() {
+ url.push_str("id=");
+ url.push_str(id[index]);
+ url.push('&');
+ }
+ }
+
+ if login.len() > 0 {
+ for index in 0..login.len() {
+ url.push_str("login=");
+ url.push_str(login[index]);
+ url.push('&');
+ }
+ }
+
+
+ let f = self.create_client()
+ .get(&url)
+ .send()
+ .map(|mut res| res.json::<DataContainer<User>>())
+ .and_then(|json| json);
+
+ return f;
+ }
+
+ pub fn videos(
+ &self,
+ video_id: Option<Vec<&str>>,
+ user_id: Option<&str>,
+ game_id: Option<&str>,
+ ) -> impl Future<Item = PaginationContainer<Video>, Error = reqwest::Error> {
+ let mut url =
+ String::from("https://") + &String::from(API_DOMAIN) + &String::from("/helix/videos");
+
+ url.push_str("?");
+ if let Some(user_id) = user_id {
+ url.push_str("user_id=");
+ url.push_str(user_id);
+ url.push('&');
+ }
+
+ let f = self.create_client()
+ .get(&url)
+ .send()
+ .map(|mut res| {
+ res.json::<PaginationContainer<Video>>()
+ })
+ .and_then(|json| json);
+
+ return f;
+ }
+
+ pub fn clip(&self, id: &str)
+ -> impl Future<Item=DataContainer<Clip>, Error=reqwest::Error>
+ {
+ let url =
+ String::from("https://") +
+ API_DOMAIN + "/helix/clips" + "?id=" + id;
+
+ let f = self.create_client()
+ .get(&url)
+ .send()
+ .map(|mut res| {
+ println!("{:?}", res);
+ res.json::<DataContainer<Clip>>()
+ })
+ .and_then(|json| json);
+
+ return f;
+ }
+}
diff --git a/src/helix/mod.rs b/src/helix/mod.rs
new file mode 100644
index 0000000..ce4a7a2
--- /dev/null
+++ b/src/helix/mod.rs
@@ -0,0 +1,2 @@
+pub mod endpoints;
+pub mod models;
diff --git a/src/helix/models.rs b/src/helix/models.rs
new file mode 100644
index 0000000..2b01e7c
--- /dev/null
+++ b/src/helix/models.rs
@@ -0,0 +1,76 @@
+extern crate serde_json;
+extern crate chrono;
+
+use chrono::{Duration, DateTime, Utc};
+
+
+#[derive(Debug, Deserialize)]
+pub struct DataContainer<T> {
+ pub data: Vec<T>
+}
+
+#[derive(Debug, Deserialize)]
+pub struct Cursor {
+ cursor: String
+}
+
+#[derive(Debug, Deserialize)]
+pub struct PaginationContainer<T> {
+ pub data: Vec<T>,
+ pub pagination: Option<Cursor>
+}
+
+#[derive(Debug, Deserialize)]
+pub struct Video {
+ pub id: String,
+ pub user_id: String,
+ pub user_name: String,
+ pub title: String,
+ pub description: String,
+ //Should be converted to a DateTime
+ pub created_at: String,
+ pub published_at: String,
+ //Should be converted to a URL
+ pub url: String,
+ pub thumbnail_url: String,
+ pub viewable: String,
+ pub view_count: i32,
+ pub language: String,
+ #[serde(rename = "type")]
+ pub video_type: String,
+ //Should be converted to a Duration
+ pub duration: String,
+}
+
+#[derive(Debug, Deserialize)]
+pub struct User {
+ pub id: String,
+ pub login: String,
+ pub display_name: String,
+ #[serde(rename = "type")]
+ pub user_type: String,
+ pub broadcaster_type: String,
+ pub description: String,
+ pub profile_image_url: String,
+ pub offline_image_url: String,
+ pub view_count: u32,
+ pub email: Option<String>,
+}
+
+#[derive(Debug, Deserialize)]
+pub struct Clip {
+ pub id: String,
+ pub url: String,
+ pub embed_url: String,
+ pub broadcaster_id: String,
+ pub broadcaster_name: String,
+ pub creator_id: String,
+ pub creator_name: String,
+ pub video_id: String,
+ pub game_id: String,
+ pub language: String,
+ pub title: String,
+ pub created_at: String,
+ pub thumbnail_url: String,
+ pub view_count: i32,
+}