diff options
author | David Blajda <blajda@hotmail.com> | 2018-12-13 20:56:55 +0000 |
---|---|---|
committer | David Blajda <blajda@hotmail.com> | 2018-12-13 20:56:55 +0000 |
commit | 8615cc2f030240ba2982dba893fe63f11a0c8a88 (patch) | |
tree | 30c7103625323404696331c2384130ce06f8bc96 | |
parent | 54bcdf63d941dbbd0b3e565259515f013f1ecd13 (diff) |
Restructure project and included kraken endpoint
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | src/bin/main.rs | 20 | ||||
-rw-r--r-- | src/helix/endpoints.rs | 121 | ||||
-rw-r--r-- | src/helix/mod.rs | 2 | ||||
-rw-r--r-- | src/helix/models.rs (renamed from src/models.rs) | 0 | ||||
-rw-r--r-- | src/kraken/endpoints.rs | 20 | ||||
-rw-r--r-- | src/kraken/mod.rs | 33 | ||||
-rw-r--r-- | src/kraken/models.rs | 44 | ||||
-rw-r--r-- | src/lib.rs | 122 |
9 files changed, 247 insertions, 117 deletions
@@ -1,6 +1,6 @@ [package] name = "twitch_api" -version = "0.0.22" +version = "0.0.25" authors = ["David Blajda <blajda@hotmail.com>"] edition = "2018" diff --git a/src/bin/main.rs b/src/bin/main.rs index 61e16ef..1aa55ed 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -6,11 +6,13 @@ extern crate twitch_api; use futures::future::Future; use std::env; +use twitch_api::HelixClient; use twitch_api::Client; fn main() { dotenv::dotenv().unwrap(); - let twitch_api = Client::new(&env::var("TWITCH_API").unwrap()); + let client_id = &env::var("TWITCH_API").unwrap(); + let client = Client::new(client_id); /* let users = twitch_api @@ -40,7 +42,7 @@ fn main() { */ - let clip = twitch_api + let clip = client.helix .clip(&"EnergeticApatheticTarsierThisIsSparta") .and_then(|json| { println!("{:?}", json); @@ -52,5 +54,17 @@ fn main() { () }); - tokio::run(clip); + let clip2 = client.kraken + .clip(&"EnergeticApatheticTarsierThisIsSparta") + .and_then(|json| { + print!("{:?}", json); + Ok(json) + }) + .map(|_| ()) + .map_err(|err| { + println!("{:?}", err); + () + }); + + tokio::run(clip.join(clip2).map(|_| ()).map_err(|_| ())); } 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/models.rs b/src/helix/models.rs index 2b01e7c..2b01e7c 100644 --- a/src/models.rs +++ b/src/helix/models.rs diff --git a/src/kraken/endpoints.rs b/src/kraken/endpoints.rs new file mode 100644 index 0000000..2dbc8d1 --- /dev/null +++ b/src/kraken/endpoints.rs @@ -0,0 +1,20 @@ +use futures::Future; +use super::models::Clip; +use super::Client; + +use super::API_DOMAIN; + +impl Client { + pub fn clip(&self, id: &str) + -> impl Future<Item=Clip, Error=reqwest::Error> + { + let url = String::from("https://") + API_DOMAIN + "/kraken/clips/" + id; + let client = self.create_reqwest_client(); + + client + .get(&url) + .send() + .map(|mut res| res.json::<Clip>()) + .and_then(|json| json) + } +} diff --git a/src/kraken/mod.rs b/src/kraken/mod.rs new file mode 100644 index 0000000..2015781 --- /dev/null +++ b/src/kraken/mod.rs @@ -0,0 +1,33 @@ +use reqwest::header; +use reqwest::r#async::{Chunk, Decoder, Request, Response}; +use reqwest::r#async::Client as ReqwestClient; + +mod endpoints; +mod models; + +const ACCEPT: &str = "application/vnd.twitchtv.v5+json"; +pub const API_DOMAIN: &str = "api.twitch.tv"; + +pub struct Client { + id: String, +} + +impl Client { + pub fn new(id: &str) -> Client { + Client { + id: id.to_owned(), + } + } + + fn create_reqwest_client(&self) -> ReqwestClient { + let mut headers = header::HeaderMap::new(); + let auth_key = &self.id; + let client_header = header::HeaderValue::from_str(auth_key).unwrap(); + let accept_header = header::HeaderValue::from_str(ACCEPT).unwrap(); + headers.insert("Client-ID", client_header); + headers.insert("Accept", accept_header); + + let client = ReqwestClient::builder().default_headers(headers).build().unwrap(); + client + } +} diff --git a/src/kraken/models.rs b/src/kraken/models.rs new file mode 100644 index 0000000..13c524c --- /dev/null +++ b/src/kraken/models.rs @@ -0,0 +1,44 @@ +extern crate serde_json; +extern crate chrono; + +#[derive(Debug, Deserialize)] +pub struct Clip { + pub slug: String, + pub tracking_id: String, + pub url: String, + pub embed_url: String, + pub embed_html: String, + pub broadcaster: UserData, + pub curator: UserData, + pub vod: Vod, + pub game: String, + pub language: String, + pub title: String, + pub views: i32, + pub duration: f32, + pub created_at: String, + pub thumbnails: Thumbnails, +} + + +#[derive(Debug, Deserialize)] +pub struct Thumbnails { + pub medium: String, + pub small: String, + pub tiny: String, +} + +#[derive(Debug, Deserialize)] +pub struct UserData { + pub id: String, + pub name: String, + pub display_name: String, + pub channel_url: String, + pub logo: String, +} + +#[derive(Debug, Deserialize)] +pub struct Vod { + pub id: String, + pub url: String, +} @@ -6,126 +6,22 @@ extern crate chrono; #[macro_use] extern crate serde_derive; -pub mod models; +mod helix; +mod kraken; -use futures::future::Future; -use reqwest::header; -use reqwest::r#async::{Chunk, Decoder, Request, Response}; -use reqwest::r#async::Client as ReqwestClient; - -use self::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 use self::helix::endpoints::Client as HelixClient; +pub use self::kraken::Client as KrakenClient; pub struct Client { - id: String, + pub helix: HelixClient, + pub kraken: KrakenClient, } 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('&'); - } + Client { + helix: HelixClient::new(client_id), + kraken: KrakenClient::new(client_id), } - - - 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; } } |