From 2c79f6e3cfbf7044a061eef1ddfb6fadac19401d Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 16 Mar 2015 15:23:38 +0100 Subject: [PATCH] feat(doit): authentication with and without scopes It's quite rough around the edges, but has a slight chance to work. Will still to handle return values accordingly. --- gen/youtube3/src/cmn.rs | 20 +- gen/youtube3/src/lib.rs | 2331 +++++++++++++++++++++++++++++++------- src/mako/lib.rs.mako | 9 +- src/mako/lib/lib.mako | 4 +- src/mako/lib/mbuild.mako | 59 +- src/mako/lib/rbuild.mako | 6 +- src/mako/lib/util.py | 14 +- src/rust/cmn.rs | 14 + 8 files changed, 2024 insertions(+), 433 deletions(-) diff --git a/gen/youtube3/src/cmn.rs b/gen/youtube3/src/cmn.rs index de431e8c5bc..e01b37058d6 100644 --- a/gen/youtube3/src/cmn.rs +++ b/gen/youtube3/src/cmn.rs @@ -55,12 +55,19 @@ struct JsonServerError { /// uploading media pub trait Delegate { - /// Called whenever there is an HttpError, usually if there are network problems. + /// Called whenever there is an [HttpError](http://hyperium.github.io/hyper/hyper/error/enum.HttpError.html), usually if there are network problems. /// /// Return retry information. - fn connection_error(&mut self, hyper::HttpError) -> oauth2::Retry { + fn http_error(&mut self, &hyper::HttpError) -> oauth2::Retry { oauth2::Retry::Abort } + + /// Called whenever there is the need for your applications API key after + /// the official authenticator implementation didn't provide one, for some reason. + /// If this method returns None as well, the underlying operation will fail + fn api_key(&mut self) -> Option { + None + } } #[derive(Default)] @@ -74,9 +81,16 @@ pub enum Result { /// The http connection failed HttpError(hyper::HttpError), + /// We needed an API key for authentication, but didn't obtain one. + /// Neither through the authenticator, nor through the Delegate. + MissingAPIKey, + + /// We required a Token, but didn't get one from the Authenticator + MissingToken, + /// An additional, free form field clashed with one of the built-in optional ones FieldClash(&'static str), /// It worked ! Success(T), -} \ No newline at end of file +} diff --git a/gen/youtube3/src/lib.rs b/gen/youtube3/src/lib.rs index f811293e80f..beed0b093f4 100644 --- a/gen/youtube3/src/lib.rs +++ b/gen/youtube3/src/lib.rs @@ -164,9 +164,9 @@ //! [google-go-api]: https://github.com/google/google-api-go-client //! //! -#![feature(core,io)] +#![feature(core,io, old_io)] // DEBUG !! TODO: Remove this -#![allow(dead_code)] +#![allow(dead_code, deprecated)] // We don't warn about this, as depending on the API, some data structures or facilities are never used. // Instead of pre-determining this, we just disable the lint. It's manually tuned to not have any // unused imports in fully featured APIs. Same with unused_mut ... . @@ -182,13 +182,14 @@ extern crate url; pub mod cmn; use std::collections::HashMap; -use std::marker::PhantomData; -use std::borrow::BorrowMut; use std::cell::RefCell; +use std::borrow::BorrowMut; use std::default::Default; use std::collections::BTreeMap; +use std::marker::PhantomData; use std::io; use std::fs; +use std::old_io::timer::sleep; use cmn::{Hub, ReadSeek, Part, ResponseResult, RequestValue, NestedType, Delegate, DefaultDelegate}; @@ -312,19 +313,20 @@ impl Default for Scope { pub struct YouTube { client: RefCell, auth: RefCell, + _m: PhantomData } impl<'a, C, NC, A> Hub for YouTube {} impl<'a, C, NC, A> YouTube - where NC: hyper::net::NetworkConnector, C: BorrowMut> + 'a, A: oauth2::GetToken { + where NC: hyper::net::NetworkConnector, C: BorrowMut>, A: oauth2::GetToken { pub fn new(client: C, authenticator: A) -> YouTube { YouTube { client: RefCell::new(client), auth: RefCell::new(authenticator), - _m: PhantomData, + _m: PhantomData } } @@ -5144,9 +5146,7 @@ impl ChannelContentDetailsRelatedPlaylists { /// # } /// ``` pub struct I18nLanguageMethodsBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, } @@ -5202,9 +5202,7 @@ impl<'a, C, NC, A> I18nLanguageMethodsBuilder<'a, C, NC, A> { /// # } /// ``` pub struct ChannelBannerMethodsBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, } @@ -5264,9 +5262,7 @@ impl<'a, C, NC, A> ChannelBannerMethodsBuilder<'a, C, NC, A> { /// # } /// ``` pub struct ChannelSectionMethodsBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, } @@ -5370,9 +5366,7 @@ impl<'a, C, NC, A> ChannelSectionMethodsBuilder<'a, C, NC, A> { /// # } /// ``` pub struct GuideCategoryMethodsBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, } @@ -5430,9 +5424,7 @@ impl<'a, C, NC, A> GuideCategoryMethodsBuilder<'a, C, NC, A> { /// # } /// ``` pub struct PlaylistMethodsBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, } @@ -5539,9 +5531,7 @@ impl<'a, C, NC, A> PlaylistMethodsBuilder<'a, C, NC, A> { /// # } /// ``` pub struct ThumbnailMethodsBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, } @@ -5597,9 +5587,7 @@ impl<'a, C, NC, A> ThumbnailMethodsBuilder<'a, C, NC, A> { /// # } /// ``` pub struct VideoMethodsBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, } @@ -5741,9 +5729,7 @@ impl<'a, C, NC, A> VideoMethodsBuilder<'a, C, NC, A> { /// # } /// ``` pub struct SubscriptionMethodsBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, } @@ -5835,9 +5821,7 @@ impl<'a, C, NC, A> SubscriptionMethodsBuilder<'a, C, NC, A> { /// # } /// ``` pub struct SearchMethodsBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, } @@ -5921,9 +5905,7 @@ impl<'a, C, NC, A> SearchMethodsBuilder<'a, C, NC, A> { /// # } /// ``` pub struct I18nRegionMethodsBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, } @@ -5979,9 +5961,7 @@ impl<'a, C, NC, A> I18nRegionMethodsBuilder<'a, C, NC, A> { /// # } /// ``` pub struct LiveStreamMethodsBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, } @@ -6089,9 +6069,7 @@ impl<'a, C, NC, A> LiveStreamMethodsBuilder<'a, C, NC, A> { /// # } /// ``` pub struct ChannelMethodsBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, } @@ -6170,9 +6148,7 @@ impl<'a, C, NC, A> ChannelMethodsBuilder<'a, C, NC, A> { /// # } /// ``` pub struct PlaylistItemMethodsBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, } @@ -6275,9 +6251,7 @@ impl<'a, C, NC, A> PlaylistItemMethodsBuilder<'a, C, NC, A> { /// # } /// ``` pub struct WatermarkMethodsBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, } @@ -6348,9 +6322,7 @@ impl<'a, C, NC, A> WatermarkMethodsBuilder<'a, C, NC, A> { /// # } /// ``` pub struct LiveBroadcastMethodsBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, } @@ -6512,9 +6484,7 @@ impl<'a, C, NC, A> LiveBroadcastMethodsBuilder<'a, C, NC, A> { /// # } /// ``` pub struct VideoCategoryMethodsBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, } @@ -6572,9 +6542,7 @@ impl<'a, C, NC, A> VideoCategoryMethodsBuilder<'a, C, NC, A> { /// # } /// ``` pub struct ActivityMethodsBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, } @@ -6676,9 +6644,7 @@ impl<'a, C, NC, A> ActivityMethodsBuilder<'a, C, NC, A> { /// # } /// ``` pub struct I18nLanguageListMethodBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, _part: String, @@ -6690,11 +6656,16 @@ pub struct I18nLanguageListMethodBuilder<'a, C, NC, A> impl<'a, C, NC, A> cmn::MethodBuilder for I18nLanguageListMethodBuilder<'a, C, NC, A> {} -impl<'a, C, NC, A> I18nLanguageListMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut> + 'a, A: oauth2::GetToken { +impl<'a, C, NC, A> I18nLanguageListMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut>, A: oauth2::GetToken { /// Perform the operation you have build so far. pub fn doit(mut self) -> cmn::Result { + use hyper::method::Method; + use hyper::header::UserAgent; + use hyper::header::ContentType; + use mime::{Mime, TopLevel, SubLevel}; + use rustc_serialize::json; let mut params: Vec<(&str, String)> = Vec::with_capacity(3 + self._additional_params.len()); params.push(("part", self._part.to_string())); if self._hl.is_some() { @@ -6709,15 +6680,46 @@ impl<'a, C, NC, A> I18nLanguageListMethodBuilder<'a, C, NC, A> where NC: hyper:: params.push((&name, value.clone())); } - let mut url = "https://www.googleapis.com/youtube/v3/".to_string(); + let mut url = "https://www.googleapis.com/youtube/v3/i18nLanguages".to_string(); + + if self._scopes.len() == 0 { + self._scopes.insert(Scope::Readonly.as_slice().to_string(), ()); + } url.push('?'); url.push_str(&url::form_urlencoded::serialize(params.iter().map(|t| (t.0, t.1.as_slice())))); - let response: I18nLanguageListResponse = Default::default(); - - + loop { + let token = self.hub.auth.borrow_mut().token(self._scopes.keys()); + if token.is_none() { + return cmn::Result::MissingToken + } + let auth_header = hyper::header::Authorization(token.unwrap().access_token); + match (*self.hub.client.borrow_mut()).borrow_mut().request(Method::Extension("GET".to_string()), url.as_slice()) + .header(UserAgent("google-api-rust-client/0.0.1".to_string())) + .header(auth_header) + .send() { + Err(err) => { + if self._delegate.is_some() { + match self._delegate.as_mut().unwrap().http_error(&err) { + oauth2::Retry::Abort => return cmn::Result::HttpError(err), + oauth2::Retry::After(d) => { + sleep(d); + continue; + } + } + } else { + return cmn::Result::HttpError(err); + } + } + Ok(mut res) => { + + break; + } + } + } + let response: I18nLanguageListResponse = Default::default(); cmn::Result::Success(response) } @@ -6843,9 +6845,7 @@ impl<'a, C, NC, A> I18nLanguageListMethodBuilder<'a, C, NC, A> where NC: hyper:: /// # } /// ``` pub struct ChannelBannerInsertMethodBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, _request: ChannelBannerResource, @@ -6857,11 +6857,16 @@ pub struct ChannelBannerInsertMethodBuilder<'a, C, NC, A> impl<'a, C, NC, A> cmn::MethodBuilder for ChannelBannerInsertMethodBuilder<'a, C, NC, A> {} -impl<'a, C, NC, A> ChannelBannerInsertMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut> + 'a, A: oauth2::GetToken { +impl<'a, C, NC, A> ChannelBannerInsertMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut>, A: oauth2::GetToken { /// Perform the operation you have build so far. fn doit(mut self, stream: Option<(R, u64, mime::Mime)>, resumeable_stream: Option<(RS, u64, mime::Mime)>) -> cmn::Result where R: io::Read, RS: ReadSeek { + use hyper::method::Method; + use hyper::header::UserAgent; + use hyper::header::ContentType; + use mime::{Mime, TopLevel, SubLevel}; + use rustc_serialize::json; let mut params: Vec<(&str, String)> = Vec::with_capacity(3 + self._additional_params.len()); if self._on_behalf_of_content_owner.is_some() { params.push(("onBehalfOfContentOwner", self._on_behalf_of_content_owner.unwrap().to_string())); @@ -6883,13 +6888,46 @@ impl<'a, C, NC, A> ChannelBannerInsertMethodBuilder<'a, C, NC, A> where NC: hype unreachable!() }; + if self._scopes.len() == 0 { + self._scopes.insert(Scope::PartnerChannelAudit.as_slice().to_string(), ()); + } + url.push('?'); url.push_str(&url::form_urlencoded::serialize(params.iter().map(|t| (t.0, t.1.as_slice())))); - let response: ChannelBannerResource = Default::default(); - - + loop { + let token = self.hub.auth.borrow_mut().token(self._scopes.keys()); + if token.is_none() { + return cmn::Result::MissingToken + } + let auth_header = hyper::header::Authorization(token.unwrap().access_token); + match (*self.hub.client.borrow_mut()).borrow_mut().request(Method::Extension("POST".to_string()), url.as_slice()) + .header(UserAgent("google-api-rust-client/0.0.1".to_string())) + .header(auth_header) + .header(ContentType(Mime(TopLevel::Application, SubLevel::Json, Default::default()))) + .body(json::encode(&self._request).unwrap().as_slice()) + .send() { + Err(err) => { + if self._delegate.is_some() { + match self._delegate.as_mut().unwrap().http_error(&err) { + oauth2::Retry::Abort => return cmn::Result::HttpError(err), + oauth2::Retry::After(d) => { + sleep(d); + continue; + } + } + } else { + return cmn::Result::HttpError(err); + } + } + Ok(mut res) => { + + break; + } + } + } + let response: ChannelBannerResource = Default::default(); cmn::Result::Success(response) } @@ -7041,9 +7079,7 @@ impl<'a, C, NC, A> ChannelBannerInsertMethodBuilder<'a, C, NC, A> where NC: hype /// # } /// ``` pub struct ChannelSectionListMethodBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, _part: String, @@ -7058,11 +7094,16 @@ pub struct ChannelSectionListMethodBuilder<'a, C, NC, A> impl<'a, C, NC, A> cmn::MethodBuilder for ChannelSectionListMethodBuilder<'a, C, NC, A> {} -impl<'a, C, NC, A> ChannelSectionListMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut> + 'a, A: oauth2::GetToken { +impl<'a, C, NC, A> ChannelSectionListMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut>, A: oauth2::GetToken { /// Perform the operation you have build so far. pub fn doit(mut self) -> cmn::Result { + use hyper::method::Method; + use hyper::header::UserAgent; + use hyper::header::ContentType; + use mime::{Mime, TopLevel, SubLevel}; + use rustc_serialize::json; let mut params: Vec<(&str, String)> = Vec::with_capacity(6 + self._additional_params.len()); params.push(("part", self._part.to_string())); if self._on_behalf_of_content_owner.is_some() { @@ -7086,15 +7127,46 @@ impl<'a, C, NC, A> ChannelSectionListMethodBuilder<'a, C, NC, A> where NC: hyper params.push((&name, value.clone())); } - let mut url = "https://www.googleapis.com/youtube/v3/".to_string(); + let mut url = "https://www.googleapis.com/youtube/v3/channelSections".to_string(); + + if self._scopes.len() == 0 { + self._scopes.insert(Scope::Readonly.as_slice().to_string(), ()); + } url.push('?'); url.push_str(&url::form_urlencoded::serialize(params.iter().map(|t| (t.0, t.1.as_slice())))); - let response: ChannelSectionListResponse = Default::default(); - - + loop { + let token = self.hub.auth.borrow_mut().token(self._scopes.keys()); + if token.is_none() { + return cmn::Result::MissingToken + } + let auth_header = hyper::header::Authorization(token.unwrap().access_token); + match (*self.hub.client.borrow_mut()).borrow_mut().request(Method::Extension("GET".to_string()), url.as_slice()) + .header(UserAgent("google-api-rust-client/0.0.1".to_string())) + .header(auth_header) + .send() { + Err(err) => { + if self._delegate.is_some() { + match self._delegate.as_mut().unwrap().http_error(&err) { + oauth2::Retry::Abort => return cmn::Result::HttpError(err), + oauth2::Retry::After(d) => { + sleep(d); + continue; + } + } + } else { + return cmn::Result::HttpError(err); + } + } + Ok(mut res) => { + + break; + } + } + } + let response: ChannelSectionListResponse = Default::default(); cmn::Result::Success(response) } @@ -7260,9 +7332,7 @@ impl<'a, C, NC, A> ChannelSectionListMethodBuilder<'a, C, NC, A> where NC: hyper /// # } /// ``` pub struct ChannelSectionInsertMethodBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, _request: ChannelSection, @@ -7276,11 +7346,16 @@ pub struct ChannelSectionInsertMethodBuilder<'a, C, NC, A> impl<'a, C, NC, A> cmn::MethodBuilder for ChannelSectionInsertMethodBuilder<'a, C, NC, A> {} -impl<'a, C, NC, A> ChannelSectionInsertMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut> + 'a, A: oauth2::GetToken { +impl<'a, C, NC, A> ChannelSectionInsertMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut>, A: oauth2::GetToken { /// Perform the operation you have build so far. pub fn doit(mut self) -> cmn::Result { + use hyper::method::Method; + use hyper::header::UserAgent; + use hyper::header::ContentType; + use mime::{Mime, TopLevel, SubLevel}; + use rustc_serialize::json; let mut params: Vec<(&str, String)> = Vec::with_capacity(5 + self._additional_params.len()); if self._part.len() == 0 { self._part = self._request.to_parts(); @@ -7301,15 +7376,48 @@ impl<'a, C, NC, A> ChannelSectionInsertMethodBuilder<'a, C, NC, A> where NC: hyp params.push((&name, value.clone())); } - let mut url = "https://www.googleapis.com/youtube/v3/".to_string(); + let mut url = "https://www.googleapis.com/youtube/v3/channelSections".to_string(); + + if self._scopes.len() == 0 { + self._scopes.insert(Scope::PartnerChannelAudit.as_slice().to_string(), ()); + } url.push('?'); url.push_str(&url::form_urlencoded::serialize(params.iter().map(|t| (t.0, t.1.as_slice())))); - let response: ChannelSection = Default::default(); - - + loop { + let token = self.hub.auth.borrow_mut().token(self._scopes.keys()); + if token.is_none() { + return cmn::Result::MissingToken + } + let auth_header = hyper::header::Authorization(token.unwrap().access_token); + match (*self.hub.client.borrow_mut()).borrow_mut().request(Method::Extension("POST".to_string()), url.as_slice()) + .header(UserAgent("google-api-rust-client/0.0.1".to_string())) + .header(auth_header) + .header(ContentType(Mime(TopLevel::Application, SubLevel::Json, Default::default()))) + .body(json::encode(&self._request).unwrap().as_slice()) + .send() { + Err(err) => { + if self._delegate.is_some() { + match self._delegate.as_mut().unwrap().http_error(&err) { + oauth2::Retry::Abort => return cmn::Result::HttpError(err), + oauth2::Retry::After(d) => { + sleep(d); + continue; + } + } + } else { + return cmn::Result::HttpError(err); + } + } + Ok(mut res) => { + + break; + } + } + } + let response: ChannelSection = Default::default(); cmn::Result::Success(response) } @@ -7457,9 +7565,7 @@ impl<'a, C, NC, A> ChannelSectionInsertMethodBuilder<'a, C, NC, A> where NC: hyp /// # } /// ``` pub struct ChannelSectionDeleteMethodBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, _id: String, @@ -7471,11 +7577,13 @@ pub struct ChannelSectionDeleteMethodBuilder<'a, C, NC, A> impl<'a, C, NC, A> cmn::MethodBuilder for ChannelSectionDeleteMethodBuilder<'a, C, NC, A> {} -impl<'a, C, NC, A> ChannelSectionDeleteMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut> + 'a, A: oauth2::GetToken { +impl<'a, C, NC, A> ChannelSectionDeleteMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut>, A: oauth2::GetToken { /// Perform the operation you have build so far. pub fn doit(mut self) -> cmn::Result<()> { + use hyper::method::Method; + use hyper::header::UserAgent; let mut params: Vec<(&str, String)> = Vec::with_capacity(3 + self._additional_params.len()); params.push(("id", self._id.to_string())); if self._on_behalf_of_content_owner.is_some() { @@ -7490,15 +7598,46 @@ impl<'a, C, NC, A> ChannelSectionDeleteMethodBuilder<'a, C, NC, A> where NC: hyp params.push((&name, value.clone())); } - let mut url = "https://www.googleapis.com/youtube/v3/".to_string(); + let mut url = "https://www.googleapis.com/youtube/v3/channelSections".to_string(); + + if self._scopes.len() == 0 { + self._scopes.insert(Scope::PartnerChannelAudit.as_slice().to_string(), ()); + } url.push('?'); url.push_str(&url::form_urlencoded::serialize(params.iter().map(|t| (t.0, t.1.as_slice())))); - let response = (); - - + loop { + let token = self.hub.auth.borrow_mut().token(self._scopes.keys()); + if token.is_none() { + return cmn::Result::MissingToken + } + let auth_header = hyper::header::Authorization(token.unwrap().access_token); + match (*self.hub.client.borrow_mut()).borrow_mut().request(Method::Extension("DELETE".to_string()), url.as_slice()) + .header(UserAgent("google-api-rust-client/0.0.1".to_string())) + .header(auth_header) + .send() { + Err(err) => { + if self._delegate.is_some() { + match self._delegate.as_mut().unwrap().http_error(&err) { + oauth2::Retry::Abort => return cmn::Result::HttpError(err), + oauth2::Retry::After(d) => { + sleep(d); + continue; + } + } + } else { + return cmn::Result::HttpError(err); + } + } + Ok(mut res) => { + + break; + } + } + } + let response = (); cmn::Result::Success(response) } @@ -7631,9 +7770,7 @@ impl<'a, C, NC, A> ChannelSectionDeleteMethodBuilder<'a, C, NC, A> where NC: hyp /// # } /// ``` pub struct ChannelSectionUpdateMethodBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, _request: ChannelSection, @@ -7646,11 +7783,16 @@ pub struct ChannelSectionUpdateMethodBuilder<'a, C, NC, A> impl<'a, C, NC, A> cmn::MethodBuilder for ChannelSectionUpdateMethodBuilder<'a, C, NC, A> {} -impl<'a, C, NC, A> ChannelSectionUpdateMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut> + 'a, A: oauth2::GetToken { +impl<'a, C, NC, A> ChannelSectionUpdateMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut>, A: oauth2::GetToken { /// Perform the operation you have build so far. pub fn doit(mut self) -> cmn::Result { + use hyper::method::Method; + use hyper::header::UserAgent; + use hyper::header::ContentType; + use mime::{Mime, TopLevel, SubLevel}; + use rustc_serialize::json; let mut params: Vec<(&str, String)> = Vec::with_capacity(4 + self._additional_params.len()); if self._part.len() == 0 { self._part = self._request.to_parts(); @@ -7668,15 +7810,48 @@ impl<'a, C, NC, A> ChannelSectionUpdateMethodBuilder<'a, C, NC, A> where NC: hyp params.push((&name, value.clone())); } - let mut url = "https://www.googleapis.com/youtube/v3/".to_string(); + let mut url = "https://www.googleapis.com/youtube/v3/channelSections".to_string(); + + if self._scopes.len() == 0 { + self._scopes.insert(Scope::PartnerChannelAudit.as_slice().to_string(), ()); + } url.push('?'); url.push_str(&url::form_urlencoded::serialize(params.iter().map(|t| (t.0, t.1.as_slice())))); - let response: ChannelSection = Default::default(); - - + loop { + let token = self.hub.auth.borrow_mut().token(self._scopes.keys()); + if token.is_none() { + return cmn::Result::MissingToken + } + let auth_header = hyper::header::Authorization(token.unwrap().access_token); + match (*self.hub.client.borrow_mut()).borrow_mut().request(Method::Extension("PUT".to_string()), url.as_slice()) + .header(UserAgent("google-api-rust-client/0.0.1".to_string())) + .header(auth_header) + .header(ContentType(Mime(TopLevel::Application, SubLevel::Json, Default::default()))) + .body(json::encode(&self._request).unwrap().as_slice()) + .send() { + Err(err) => { + if self._delegate.is_some() { + match self._delegate.as_mut().unwrap().http_error(&err) { + oauth2::Retry::Abort => return cmn::Result::HttpError(err), + oauth2::Retry::After(d) => { + sleep(d); + continue; + } + } + } else { + return cmn::Result::HttpError(err); + } + } + Ok(mut res) => { + + break; + } + } + } + let response: ChannelSection = Default::default(); cmn::Result::Success(response) } @@ -7828,9 +8003,7 @@ impl<'a, C, NC, A> ChannelSectionUpdateMethodBuilder<'a, C, NC, A> where NC: hyp /// # } /// ``` pub struct GuideCategoryListMethodBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, _part: String, @@ -7844,11 +8017,16 @@ pub struct GuideCategoryListMethodBuilder<'a, C, NC, A> impl<'a, C, NC, A> cmn::MethodBuilder for GuideCategoryListMethodBuilder<'a, C, NC, A> {} -impl<'a, C, NC, A> GuideCategoryListMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut> + 'a, A: oauth2::GetToken { +impl<'a, C, NC, A> GuideCategoryListMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut>, A: oauth2::GetToken { /// Perform the operation you have build so far. pub fn doit(mut self) -> cmn::Result { + use hyper::method::Method; + use hyper::header::UserAgent; + use hyper::header::ContentType; + use mime::{Mime, TopLevel, SubLevel}; + use rustc_serialize::json; let mut params: Vec<(&str, String)> = Vec::with_capacity(5 + self._additional_params.len()); params.push(("part", self._part.to_string())); if self._region_code.is_some() { @@ -7869,15 +8047,46 @@ impl<'a, C, NC, A> GuideCategoryListMethodBuilder<'a, C, NC, A> where NC: hyper: params.push((&name, value.clone())); } - let mut url = "https://www.googleapis.com/youtube/v3/".to_string(); + let mut url = "https://www.googleapis.com/youtube/v3/guideCategories".to_string(); + + if self._scopes.len() == 0 { + self._scopes.insert(Scope::Readonly.as_slice().to_string(), ()); + } url.push('?'); url.push_str(&url::form_urlencoded::serialize(params.iter().map(|t| (t.0, t.1.as_slice())))); - let response: GuideCategoryListResponse = Default::default(); - - + loop { + let token = self.hub.auth.borrow_mut().token(self._scopes.keys()); + if token.is_none() { + return cmn::Result::MissingToken + } + let auth_header = hyper::header::Authorization(token.unwrap().access_token); + match (*self.hub.client.borrow_mut()).borrow_mut().request(Method::Extension("GET".to_string()), url.as_slice()) + .header(UserAgent("google-api-rust-client/0.0.1".to_string())) + .header(auth_header) + .send() { + Err(err) => { + if self._delegate.is_some() { + match self._delegate.as_mut().unwrap().http_error(&err) { + oauth2::Retry::Abort => return cmn::Result::HttpError(err), + oauth2::Retry::After(d) => { + sleep(d); + continue; + } + } + } else { + return cmn::Result::HttpError(err); + } + } + Ok(mut res) => { + + break; + } + } + } + let response: GuideCategoryListResponse = Default::default(); cmn::Result::Success(response) } @@ -8032,9 +8241,7 @@ impl<'a, C, NC, A> GuideCategoryListMethodBuilder<'a, C, NC, A> where NC: hyper: /// # } /// ``` pub struct PlaylistInsertMethodBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, _request: Playlist, @@ -8048,11 +8255,16 @@ pub struct PlaylistInsertMethodBuilder<'a, C, NC, A> impl<'a, C, NC, A> cmn::MethodBuilder for PlaylistInsertMethodBuilder<'a, C, NC, A> {} -impl<'a, C, NC, A> PlaylistInsertMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut> + 'a, A: oauth2::GetToken { +impl<'a, C, NC, A> PlaylistInsertMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut>, A: oauth2::GetToken { /// Perform the operation you have build so far. pub fn doit(mut self) -> cmn::Result { + use hyper::method::Method; + use hyper::header::UserAgent; + use hyper::header::ContentType; + use mime::{Mime, TopLevel, SubLevel}; + use rustc_serialize::json; let mut params: Vec<(&str, String)> = Vec::with_capacity(5 + self._additional_params.len()); if self._part.len() == 0 { self._part = self._request.to_parts(); @@ -8073,15 +8285,48 @@ impl<'a, C, NC, A> PlaylistInsertMethodBuilder<'a, C, NC, A> where NC: hyper::ne params.push((&name, value.clone())); } - let mut url = "https://www.googleapis.com/youtube/v3/".to_string(); + let mut url = "https://www.googleapis.com/youtube/v3/playlists".to_string(); + + if self._scopes.len() == 0 { + self._scopes.insert(Scope::PartnerChannelAudit.as_slice().to_string(), ()); + } url.push('?'); url.push_str(&url::form_urlencoded::serialize(params.iter().map(|t| (t.0, t.1.as_slice())))); - let response: Playlist = Default::default(); - - + loop { + let token = self.hub.auth.borrow_mut().token(self._scopes.keys()); + if token.is_none() { + return cmn::Result::MissingToken + } + let auth_header = hyper::header::Authorization(token.unwrap().access_token); + match (*self.hub.client.borrow_mut()).borrow_mut().request(Method::Extension("POST".to_string()), url.as_slice()) + .header(UserAgent("google-api-rust-client/0.0.1".to_string())) + .header(auth_header) + .header(ContentType(Mime(TopLevel::Application, SubLevel::Json, Default::default()))) + .body(json::encode(&self._request).unwrap().as_slice()) + .send() { + Err(err) => { + if self._delegate.is_some() { + match self._delegate.as_mut().unwrap().http_error(&err) { + oauth2::Retry::Abort => return cmn::Result::HttpError(err), + oauth2::Retry::After(d) => { + sleep(d); + continue; + } + } + } else { + return cmn::Result::HttpError(err); + } + } + Ok(mut res) => { + + break; + } + } + } + let response: Playlist = Default::default(); cmn::Result::Success(response) } @@ -8251,9 +8496,7 @@ impl<'a, C, NC, A> PlaylistInsertMethodBuilder<'a, C, NC, A> where NC: hyper::ne /// # } /// ``` pub struct PlaylistListMethodBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, _part: String, @@ -8271,11 +8514,16 @@ pub struct PlaylistListMethodBuilder<'a, C, NC, A> impl<'a, C, NC, A> cmn::MethodBuilder for PlaylistListMethodBuilder<'a, C, NC, A> {} -impl<'a, C, NC, A> PlaylistListMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut> + 'a, A: oauth2::GetToken { +impl<'a, C, NC, A> PlaylistListMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut>, A: oauth2::GetToken { /// Perform the operation you have build so far. pub fn doit(mut self) -> cmn::Result { + use hyper::method::Method; + use hyper::header::UserAgent; + use hyper::header::ContentType; + use mime::{Mime, TopLevel, SubLevel}; + use rustc_serialize::json; let mut params: Vec<(&str, String)> = Vec::with_capacity(9 + self._additional_params.len()); params.push(("part", self._part.to_string())); if self._page_token.is_some() { @@ -8308,15 +8556,46 @@ impl<'a, C, NC, A> PlaylistListMethodBuilder<'a, C, NC, A> where NC: hyper::net: params.push((&name, value.clone())); } - let mut url = "https://www.googleapis.com/youtube/v3/".to_string(); + let mut url = "https://www.googleapis.com/youtube/v3/playlists".to_string(); + + if self._scopes.len() == 0 { + self._scopes.insert(Scope::Readonly.as_slice().to_string(), ()); + } url.push('?'); url.push_str(&url::form_urlencoded::serialize(params.iter().map(|t| (t.0, t.1.as_slice())))); - let response: PlaylistListResponse = Default::default(); - - + loop { + let token = self.hub.auth.borrow_mut().token(self._scopes.keys()); + if token.is_none() { + return cmn::Result::MissingToken + } + let auth_header = hyper::header::Authorization(token.unwrap().access_token); + match (*self.hub.client.borrow_mut()).borrow_mut().request(Method::Extension("GET".to_string()), url.as_slice()) + .header(UserAgent("google-api-rust-client/0.0.1".to_string())) + .header(auth_header) + .send() { + Err(err) => { + if self._delegate.is_some() { + match self._delegate.as_mut().unwrap().http_error(&err) { + oauth2::Retry::Abort => return cmn::Result::HttpError(err), + oauth2::Retry::After(d) => { + sleep(d); + continue; + } + } + } else { + return cmn::Result::HttpError(err); + } + } + Ok(mut res) => { + + break; + } + } + } + let response: PlaylistListResponse = Default::default(); cmn::Result::Success(response) } @@ -8489,9 +8768,7 @@ impl<'a, C, NC, A> PlaylistListMethodBuilder<'a, C, NC, A> where NC: hyper::net: /// # } /// ``` pub struct PlaylistDeleteMethodBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, _id: String, @@ -8503,11 +8780,13 @@ pub struct PlaylistDeleteMethodBuilder<'a, C, NC, A> impl<'a, C, NC, A> cmn::MethodBuilder for PlaylistDeleteMethodBuilder<'a, C, NC, A> {} -impl<'a, C, NC, A> PlaylistDeleteMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut> + 'a, A: oauth2::GetToken { +impl<'a, C, NC, A> PlaylistDeleteMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut>, A: oauth2::GetToken { /// Perform the operation you have build so far. pub fn doit(mut self) -> cmn::Result<()> { + use hyper::method::Method; + use hyper::header::UserAgent; let mut params: Vec<(&str, String)> = Vec::with_capacity(3 + self._additional_params.len()); params.push(("id", self._id.to_string())); if self._on_behalf_of_content_owner.is_some() { @@ -8522,15 +8801,46 @@ impl<'a, C, NC, A> PlaylistDeleteMethodBuilder<'a, C, NC, A> where NC: hyper::ne params.push((&name, value.clone())); } - let mut url = "https://www.googleapis.com/youtube/v3/".to_string(); + let mut url = "https://www.googleapis.com/youtube/v3/playlists".to_string(); + + if self._scopes.len() == 0 { + self._scopes.insert(Scope::PartnerChannelAudit.as_slice().to_string(), ()); + } url.push('?'); url.push_str(&url::form_urlencoded::serialize(params.iter().map(|t| (t.0, t.1.as_slice())))); - let response = (); - - + loop { + let token = self.hub.auth.borrow_mut().token(self._scopes.keys()); + if token.is_none() { + return cmn::Result::MissingToken + } + let auth_header = hyper::header::Authorization(token.unwrap().access_token); + match (*self.hub.client.borrow_mut()).borrow_mut().request(Method::Extension("DELETE".to_string()), url.as_slice()) + .header(UserAgent("google-api-rust-client/0.0.1".to_string())) + .header(auth_header) + .send() { + Err(err) => { + if self._delegate.is_some() { + match self._delegate.as_mut().unwrap().http_error(&err) { + oauth2::Retry::Abort => return cmn::Result::HttpError(err), + oauth2::Retry::After(d) => { + sleep(d); + continue; + } + } + } else { + return cmn::Result::HttpError(err); + } + } + Ok(mut res) => { + + break; + } + } + } + let response = (); cmn::Result::Success(response) } @@ -8663,9 +8973,7 @@ impl<'a, C, NC, A> PlaylistDeleteMethodBuilder<'a, C, NC, A> where NC: hyper::ne /// # } /// ``` pub struct PlaylistUpdateMethodBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, _request: Playlist, @@ -8678,11 +8986,16 @@ pub struct PlaylistUpdateMethodBuilder<'a, C, NC, A> impl<'a, C, NC, A> cmn::MethodBuilder for PlaylistUpdateMethodBuilder<'a, C, NC, A> {} -impl<'a, C, NC, A> PlaylistUpdateMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut> + 'a, A: oauth2::GetToken { +impl<'a, C, NC, A> PlaylistUpdateMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut>, A: oauth2::GetToken { /// Perform the operation you have build so far. pub fn doit(mut self) -> cmn::Result { + use hyper::method::Method; + use hyper::header::UserAgent; + use hyper::header::ContentType; + use mime::{Mime, TopLevel, SubLevel}; + use rustc_serialize::json; let mut params: Vec<(&str, String)> = Vec::with_capacity(4 + self._additional_params.len()); if self._part.len() == 0 { self._part = self._request.to_parts(); @@ -8700,15 +9013,48 @@ impl<'a, C, NC, A> PlaylistUpdateMethodBuilder<'a, C, NC, A> where NC: hyper::ne params.push((&name, value.clone())); } - let mut url = "https://www.googleapis.com/youtube/v3/".to_string(); + let mut url = "https://www.googleapis.com/youtube/v3/playlists".to_string(); + + if self._scopes.len() == 0 { + self._scopes.insert(Scope::PartnerChannelAudit.as_slice().to_string(), ()); + } url.push('?'); url.push_str(&url::form_urlencoded::serialize(params.iter().map(|t| (t.0, t.1.as_slice())))); - let response: Playlist = Default::default(); - - + loop { + let token = self.hub.auth.borrow_mut().token(self._scopes.keys()); + if token.is_none() { + return cmn::Result::MissingToken + } + let auth_header = hyper::header::Authorization(token.unwrap().access_token); + match (*self.hub.client.borrow_mut()).borrow_mut().request(Method::Extension("PUT".to_string()), url.as_slice()) + .header(UserAgent("google-api-rust-client/0.0.1".to_string())) + .header(auth_header) + .header(ContentType(Mime(TopLevel::Application, SubLevel::Json, Default::default()))) + .body(json::encode(&self._request).unwrap().as_slice()) + .send() { + Err(err) => { + if self._delegate.is_some() { + match self._delegate.as_mut().unwrap().http_error(&err) { + oauth2::Retry::Abort => return cmn::Result::HttpError(err), + oauth2::Retry::After(d) => { + sleep(d); + continue; + } + } + } else { + return cmn::Result::HttpError(err); + } + } + Ok(mut res) => { + + break; + } + } + } + let response: Playlist = Default::default(); cmn::Result::Success(response) } @@ -8847,9 +9193,7 @@ impl<'a, C, NC, A> PlaylistUpdateMethodBuilder<'a, C, NC, A> where NC: hyper::ne /// # } /// ``` pub struct ThumbnailSetMethodBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, _video_id: String, @@ -8861,11 +9205,16 @@ pub struct ThumbnailSetMethodBuilder<'a, C, NC, A> impl<'a, C, NC, A> cmn::MethodBuilder for ThumbnailSetMethodBuilder<'a, C, NC, A> {} -impl<'a, C, NC, A> ThumbnailSetMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut> + 'a, A: oauth2::GetToken { +impl<'a, C, NC, A> ThumbnailSetMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut>, A: oauth2::GetToken { /// Perform the operation you have build so far. fn doit(mut self, stream: Option<(R, u64, mime::Mime)>, resumeable_stream: Option<(RS, u64, mime::Mime)>) -> cmn::Result where R: io::Read, RS: ReadSeek { + use hyper::method::Method; + use hyper::header::UserAgent; + use hyper::header::ContentType; + use mime::{Mime, TopLevel, SubLevel}; + use rustc_serialize::json; let mut params: Vec<(&str, String)> = Vec::with_capacity(3 + self._additional_params.len()); params.push(("videoId", self._video_id.to_string())); if self._on_behalf_of_content_owner.is_some() { @@ -8888,13 +9237,44 @@ impl<'a, C, NC, A> ThumbnailSetMethodBuilder<'a, C, NC, A> where NC: hyper::net: unreachable!() }; + if self._scopes.len() == 0 { + self._scopes.insert(Scope::PartnerChannelAudit.as_slice().to_string(), ()); + } + url.push('?'); url.push_str(&url::form_urlencoded::serialize(params.iter().map(|t| (t.0, t.1.as_slice())))); - let response: ThumbnailSetResponse = Default::default(); - - + loop { + let token = self.hub.auth.borrow_mut().token(self._scopes.keys()); + if token.is_none() { + return cmn::Result::MissingToken + } + let auth_header = hyper::header::Authorization(token.unwrap().access_token); + match (*self.hub.client.borrow_mut()).borrow_mut().request(Method::Extension("POST".to_string()), url.as_slice()) + .header(UserAgent("google-api-rust-client/0.0.1".to_string())) + .header(auth_header) + .send() { + Err(err) => { + if self._delegate.is_some() { + match self._delegate.as_mut().unwrap().http_error(&err) { + oauth2::Retry::Abort => return cmn::Result::HttpError(err), + oauth2::Retry::After(d) => { + sleep(d); + continue; + } + } + } else { + return cmn::Result::HttpError(err); + } + } + Ok(mut res) => { + + break; + } + } + } + let response: ThumbnailSetResponse = Default::default(); cmn::Result::Success(response) } @@ -9061,9 +9441,7 @@ impl<'a, C, NC, A> ThumbnailSetMethodBuilder<'a, C, NC, A> where NC: hyper::net: /// # } /// ``` pub struct VideoListMethodBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, _part: String, @@ -9084,11 +9462,16 @@ pub struct VideoListMethodBuilder<'a, C, NC, A> impl<'a, C, NC, A> cmn::MethodBuilder for VideoListMethodBuilder<'a, C, NC, A> {} -impl<'a, C, NC, A> VideoListMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut> + 'a, A: oauth2::GetToken { +impl<'a, C, NC, A> VideoListMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut>, A: oauth2::GetToken { /// Perform the operation you have build so far. pub fn doit(mut self) -> cmn::Result { + use hyper::method::Method; + use hyper::header::UserAgent; + use hyper::header::ContentType; + use mime::{Mime, TopLevel, SubLevel}; + use rustc_serialize::json; let mut params: Vec<(&str, String)> = Vec::with_capacity(12 + self._additional_params.len()); params.push(("part", self._part.to_string())); if self._video_category_id.is_some() { @@ -9130,15 +9513,46 @@ impl<'a, C, NC, A> VideoListMethodBuilder<'a, C, NC, A> where NC: hyper::net::Ne params.push((&name, value.clone())); } - let mut url = "https://www.googleapis.com/youtube/v3/".to_string(); + let mut url = "https://www.googleapis.com/youtube/v3/videos".to_string(); + + if self._scopes.len() == 0 { + self._scopes.insert(Scope::Readonly.as_slice().to_string(), ()); + } url.push('?'); url.push_str(&url::form_urlencoded::serialize(params.iter().map(|t| (t.0, t.1.as_slice())))); - let response: VideoListResponse = Default::default(); - - + loop { + let token = self.hub.auth.borrow_mut().token(self._scopes.keys()); + if token.is_none() { + return cmn::Result::MissingToken + } + let auth_header = hyper::header::Authorization(token.unwrap().access_token); + match (*self.hub.client.borrow_mut()).borrow_mut().request(Method::Extension("GET".to_string()), url.as_slice()) + .header(UserAgent("google-api-rust-client/0.0.1".to_string())) + .header(auth_header) + .send() { + Err(err) => { + if self._delegate.is_some() { + match self._delegate.as_mut().unwrap().http_error(&err) { + oauth2::Retry::Abort => return cmn::Result::HttpError(err), + oauth2::Retry::After(d) => { + sleep(d); + continue; + } + } + } else { + return cmn::Result::HttpError(err); + } + } + Ok(mut res) => { + + break; + } + } + } + let response: VideoListResponse = Default::default(); cmn::Result::Success(response) } @@ -9344,9 +9758,7 @@ impl<'a, C, NC, A> VideoListMethodBuilder<'a, C, NC, A> where NC: hyper::net::Ne /// # } /// ``` pub struct VideoRateMethodBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, _id: String, @@ -9359,11 +9771,13 @@ pub struct VideoRateMethodBuilder<'a, C, NC, A> impl<'a, C, NC, A> cmn::MethodBuilder for VideoRateMethodBuilder<'a, C, NC, A> {} -impl<'a, C, NC, A> VideoRateMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut> + 'a, A: oauth2::GetToken { +impl<'a, C, NC, A> VideoRateMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut>, A: oauth2::GetToken { /// Perform the operation you have build so far. pub fn doit(mut self) -> cmn::Result<()> { + use hyper::method::Method; + use hyper::header::UserAgent; let mut params: Vec<(&str, String)> = Vec::with_capacity(4 + self._additional_params.len()); params.push(("id", self._id.to_string())); params.push(("rating", self._rating.to_string())); @@ -9379,15 +9793,46 @@ impl<'a, C, NC, A> VideoRateMethodBuilder<'a, C, NC, A> where NC: hyper::net::Ne params.push((&name, value.clone())); } - let mut url = "https://www.googleapis.com/youtube/v3/".to_string(); + let mut url = "https://www.googleapis.com/youtube/v3/videos/rate".to_string(); + + if self._scopes.len() == 0 { + self._scopes.insert(Scope::PartnerChannelAudit.as_slice().to_string(), ()); + } url.push('?'); url.push_str(&url::form_urlencoded::serialize(params.iter().map(|t| (t.0, t.1.as_slice())))); - let response = (); - - + loop { + let token = self.hub.auth.borrow_mut().token(self._scopes.keys()); + if token.is_none() { + return cmn::Result::MissingToken + } + let auth_header = hyper::header::Authorization(token.unwrap().access_token); + match (*self.hub.client.borrow_mut()).borrow_mut().request(Method::Extension("POST".to_string()), url.as_slice()) + .header(UserAgent("google-api-rust-client/0.0.1".to_string())) + .header(auth_header) + .send() { + Err(err) => { + if self._delegate.is_some() { + match self._delegate.as_mut().unwrap().http_error(&err) { + oauth2::Retry::Abort => return cmn::Result::HttpError(err), + oauth2::Retry::After(d) => { + sleep(d); + continue; + } + } + } else { + return cmn::Result::HttpError(err); + } + } + Ok(mut res) => { + + break; + } + } + } + let response = (); cmn::Result::Success(response) } @@ -9509,9 +9954,7 @@ impl<'a, C, NC, A> VideoRateMethodBuilder<'a, C, NC, A> where NC: hyper::net::Ne /// # } /// ``` pub struct VideoGetRatingMethodBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, _id: String, @@ -9523,11 +9966,16 @@ pub struct VideoGetRatingMethodBuilder<'a, C, NC, A> impl<'a, C, NC, A> cmn::MethodBuilder for VideoGetRatingMethodBuilder<'a, C, NC, A> {} -impl<'a, C, NC, A> VideoGetRatingMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut> + 'a, A: oauth2::GetToken { +impl<'a, C, NC, A> VideoGetRatingMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut>, A: oauth2::GetToken { /// Perform the operation you have build so far. pub fn doit(mut self) -> cmn::Result { + use hyper::method::Method; + use hyper::header::UserAgent; + use hyper::header::ContentType; + use mime::{Mime, TopLevel, SubLevel}; + use rustc_serialize::json; let mut params: Vec<(&str, String)> = Vec::with_capacity(3 + self._additional_params.len()); params.push(("id", self._id.to_string())); if self._on_behalf_of_content_owner.is_some() { @@ -9542,15 +9990,46 @@ impl<'a, C, NC, A> VideoGetRatingMethodBuilder<'a, C, NC, A> where NC: hyper::ne params.push((&name, value.clone())); } - let mut url = "https://www.googleapis.com/youtube/v3/".to_string(); + let mut url = "https://www.googleapis.com/youtube/v3/videos/getRating".to_string(); + + if self._scopes.len() == 0 { + self._scopes.insert(Scope::Readonly.as_slice().to_string(), ()); + } url.push('?'); url.push_str(&url::form_urlencoded::serialize(params.iter().map(|t| (t.0, t.1.as_slice())))); - let response: VideoGetRatingResponse = Default::default(); - - + loop { + let token = self.hub.auth.borrow_mut().token(self._scopes.keys()); + if token.is_none() { + return cmn::Result::MissingToken + } + let auth_header = hyper::header::Authorization(token.unwrap().access_token); + match (*self.hub.client.borrow_mut()).borrow_mut().request(Method::Extension("GET".to_string()), url.as_slice()) + .header(UserAgent("google-api-rust-client/0.0.1".to_string())) + .header(auth_header) + .send() { + Err(err) => { + if self._delegate.is_some() { + match self._delegate.as_mut().unwrap().http_error(&err) { + oauth2::Retry::Abort => return cmn::Result::HttpError(err), + oauth2::Retry::After(d) => { + sleep(d); + continue; + } + } + } else { + return cmn::Result::HttpError(err); + } + } + Ok(mut res) => { + + break; + } + } + } + let response: VideoGetRatingResponse = Default::default(); cmn::Result::Success(response) } @@ -9662,9 +10141,7 @@ impl<'a, C, NC, A> VideoGetRatingMethodBuilder<'a, C, NC, A> where NC: hyper::ne /// # } /// ``` pub struct VideoDeleteMethodBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, _id: String, @@ -9676,11 +10153,13 @@ pub struct VideoDeleteMethodBuilder<'a, C, NC, A> impl<'a, C, NC, A> cmn::MethodBuilder for VideoDeleteMethodBuilder<'a, C, NC, A> {} -impl<'a, C, NC, A> VideoDeleteMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut> + 'a, A: oauth2::GetToken { +impl<'a, C, NC, A> VideoDeleteMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut>, A: oauth2::GetToken { /// Perform the operation you have build so far. pub fn doit(mut self) -> cmn::Result<()> { + use hyper::method::Method; + use hyper::header::UserAgent; let mut params: Vec<(&str, String)> = Vec::with_capacity(3 + self._additional_params.len()); params.push(("id", self._id.to_string())); if self._on_behalf_of_content_owner.is_some() { @@ -9695,15 +10174,46 @@ impl<'a, C, NC, A> VideoDeleteMethodBuilder<'a, C, NC, A> where NC: hyper::net:: params.push((&name, value.clone())); } - let mut url = "https://www.googleapis.com/youtube/v3/".to_string(); + let mut url = "https://www.googleapis.com/youtube/v3/videos".to_string(); + + if self._scopes.len() == 0 { + self._scopes.insert(Scope::PartnerChannelAudit.as_slice().to_string(), ()); + } url.push('?'); url.push_str(&url::form_urlencoded::serialize(params.iter().map(|t| (t.0, t.1.as_slice())))); - let response = (); - - + loop { + let token = self.hub.auth.borrow_mut().token(self._scopes.keys()); + if token.is_none() { + return cmn::Result::MissingToken + } + let auth_header = hyper::header::Authorization(token.unwrap().access_token); + match (*self.hub.client.borrow_mut()).borrow_mut().request(Method::Extension("DELETE".to_string()), url.as_slice()) + .header(UserAgent("google-api-rust-client/0.0.1".to_string())) + .header(auth_header) + .send() { + Err(err) => { + if self._delegate.is_some() { + match self._delegate.as_mut().unwrap().http_error(&err) { + oauth2::Retry::Abort => return cmn::Result::HttpError(err), + oauth2::Retry::After(d) => { + sleep(d); + continue; + } + } + } else { + return cmn::Result::HttpError(err); + } + } + Ok(mut res) => { + + break; + } + } + } + let response = (); cmn::Result::Success(response) } @@ -9856,9 +10366,7 @@ impl<'a, C, NC, A> VideoDeleteMethodBuilder<'a, C, NC, A> where NC: hyper::net:: /// # } /// ``` pub struct VideoUpdateMethodBuilder<'a, C, NC, A> - where NC: 'a, - C: 'a, - A: 'a, { + where C: 'a, NC: 'a, A: 'a { hub: &'a YouTube, _request: Video, @@ -9871,11 +10379,16 @@ pub struct VideoUpdateMethodBuilder<'a, C, NC, A> impl<'a, C, NC, A> cmn::MethodBuilder for VideoUpdateMethodBuilder<'a, C, NC, A> {} -impl<'a, C, NC, A> VideoUpdateMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut> + 'a, A: oauth2::GetToken { +impl<'a, C, NC, A> VideoUpdateMethodBuilder<'a, C, NC, A> where NC: hyper::net::NetworkConnector, C: BorrowMut>, A: oauth2::GetToken { /// Perform the operation you have build so far. pub fn doit(mut self) -> cmn::Result, + + _m: PhantomData } impl<'a, ${', '.join(HUB_TYPE_PARAMETERS)}> Hub for ${hub_type}${ht_params} {} @@ -91,10 +95,11 @@ impl<'a, ${', '.join(HUB_TYPE_PARAMETERS)}> Hub for ${hub_type}${ht_params} {} impl<'a, ${', '.join(HUB_TYPE_PARAMETERS)}> ${hub_type}${ht_params} where ${', '.join(hub_type_bounds())} { - pub fn new(client: hyper::Client, authenticator: A) -> ${hub_type}${ht_params} { + pub fn new(client: C, authenticator: A) -> ${hub_type}${ht_params} { ${hub_type} { client: RefCell::new(client), auth: RefCell::new(authenticator), + _m: PhantomData } } diff --git a/src/mako/lib/lib.mako b/src/mako/lib/lib.mako index 07bbf62de99..da4dcf34b6d 100644 --- a/src/mako/lib/lib.mako +++ b/src/mako/lib/lib.mako @@ -3,7 +3,7 @@ unindent_first_by, mangle_ident, mb_type, singular, scope_url_to_variant, PART_MARKER_TRAIT, RESOURCE_MARKER_TRAIT, METHOD_BUILDER_MARKERT_TRAIT, find_fattest_resource, build_all_params, pass_through, parts_from_params, - REQUEST_MARKER_TRAIT, RESPONSE_MARKER_TRAIT) %>\ + REQUEST_MARKER_TRAIT, RESPONSE_MARKER_TRAIT, supports_scopes) %>\ <%namespace name="util" file="util.mako"/>\ <%namespace name="mbuild" file="mbuild.mako"/>\ @@ -242,7 +242,7 @@ You can read the full text at the repository's [license file][repo-license]. ############################################################################################### ############################################################################################### <%def name="scope_enum()">\ -% if not auth or not auth.oauth2: +% if not supports_scopes(auth): <% return '' %>\ % endif /// Identifies the an OAuth2 authorization scope. diff --git a/src/mako/lib/mbuild.mako b/src/mako/lib/mbuild.mako index 7467b38e313..5694425c060 100644 --- a/src/mako/lib/mbuild.mako +++ b/src/mako/lib/mbuild.mako @@ -8,7 +8,7 @@ indent_by, to_rust_type, rnd_arg_val_for_type, extract_parts, mb_type_params_s, hub_type_params_s, method_media_params, enclose_in, mb_type_bounds, method_response, METHOD_BUILDER_MARKERT_TRAIT, pass_through, markdown_rust_block, parts_from_params, - DELEGATE_PROPERTY_NAME) + DELEGATE_PROPERTY_NAME, struct_type_bounds_s, supports_scopes, scope_url_to_variant) def get_parts(part_prop): if not part_prop: @@ -79,8 +79,7 @@ the *${m.scopes[0]}* scope to make a valid call. ${self.usage(resource, method, m, params, request_value, parts)}\ pub struct ${ThisType} - where NC: 'a, - A: 'a, { + where ${struct_type_bounds_s()} { hub: &'a ${hub_type_name}${hub_type_params_s()}, ## PROPERTIES ############### @@ -94,7 +93,7 @@ pub struct ${ThisType} % endfor ## A generic map for additinal parameters. Sometimes you can set some that are documented online only ${api.properties.params}: HashMap, - % if auth and auth.oauth2: + % if supports_scopes(auth): ## We need the scopes sorted, to not unnecessarily query new tokens ${api.properties.scopes}: BTreeMap % endif @@ -131,7 +130,7 @@ ${self._setter_fn(resource, method, m, p, part_prop, ThisType, c)}\ self } - % if auth and auth.oauth2: + % if supports_scopes(auth): /// Identifies the authorization scope for the method you are building. /// /// Use this method to actively specify which scope should be used, instead of relying on the @@ -361,6 +360,21 @@ match result { paddfields = 'self.' + api.properties.params delegate = 'self.' + property(DELEGATE_PROPERTY_NAME) + delegate_call = delegate + '.as_mut().unwrap()' + auth_call = 'self.hub.auth.borrow_mut()' + client = '(*self.hub.client.borrow_mut()).borrow_mut()' + + if supports_scopes(auth): + all_scopes = auth.oauth2.scopes.keys() + default_scope = all_scopes[0] + assert 'readonly' not in default_scope + if m.httpMethod in ('HEAD', 'GET', 'OPTIONS', 'TRACE'): + for scope in all_scopes: + if 'readonly' in scope: + default_scope = scope + break + # end try to find read-only default scope + # end handle default scope %> /// Perform the operation you have build so far. ${action_fn} { @@ -425,20 +439,49 @@ else { let mut url = "${baseUrl}${m.path}".to_string(); % endif + % if not supports_scopes(auth): + <% + assert 'key' in parameters, "Expected 'key' parameter if there are no scopes" + %>\ + let mut key = ${auth_call}.api_key(); + if key.is_none() && ${delegate}.is_some() { + key = ${delegate_call}.api_key(); + } + if key.is_some() { + params.push(("key", key.unwrap())); + } else { + return cmn::Result::MissingAPIKey + } + % else: + if self.${api.properties.scopes}.len() == 0 { + self.${api.properties.scopes}.insert(${scope_url_to_variant(name, default_scope, fully_qualified=True)}.as_slice().to_string(), ()); + } + % endif + url.push('?'); url.push_str(&url::form_urlencoded::serialize(params.iter().map(|t| (t.0, t.1.as_slice())))); loop { - match self.hub.client.borrow_mut().request(Method::Extension("${m.httpMethod}".to_string()), url.as_slice()) + % if supports_scopes(auth): + let token = ${auth_call}.token(self.${api.properties.scopes}.keys()); + if token.is_none() { + return cmn::Result::MissingToken + } + let auth_header = hyper::header::Authorization(token.unwrap().access_token); + % endif + match ${client}.request(Method::Extension("${m.httpMethod}".to_string()), url.as_slice()) .header(UserAgent("google-api-rust-client/${cargo.build_version}".to_string())) + % if supports_scopes(auth): + .header(auth_header) + % endif % if request_value: .header(ContentType(Mime(TopLevel::Application, SubLevel::Json, Default::default()))) - .body(json::encode(&self.${property(REQUEST_VALUE_PROPERTY_NAME)}).unwrap()) + .body(json::encode(&self.${property(REQUEST_VALUE_PROPERTY_NAME)}).unwrap().as_slice()) % endif .send() { Err(err) => { if ${delegate}.is_some() { - match ${delegate}.as_mut().unwrap().http_error(&err) { + match ${delegate_call}.http_error(&err) { oauth2::Retry::Abort => return cmn::Result::HttpError(err), oauth2::Retry::After(d) => { sleep(d); diff --git a/src/mako/lib/rbuild.mako b/src/mako/lib/rbuild.mako index 62bed795dcc..443fd714dcc 100644 --- a/src/mako/lib/rbuild.mako +++ b/src/mako/lib/rbuild.mako @@ -4,7 +4,8 @@ to_fqan, indent_all_but_first_by, activity_input_type, TREF, IO_REQUEST, schema_to_required_property, rust_copy_value_s, is_required_property, organize_params, REQUEST_VALUE_PROPERTY_NAME, - build_all_params, rb_type_params_s, hub_type_params_s, mb_type_params_s, mb_additional_type_params) + build_all_params, rb_type_params_s, hub_type_params_s, mb_type_params_s, mb_additional_type_params, + struct_type_bounds_s) %>\ <%namespace name="util" file="util.mako"/>\ <%namespace name="lib" file="lib.mako"/>\ @@ -38,8 +39,7 @@ let rb = hub.${mangle_ident(resource)}(); pub struct ${ThisType} - where NC: 'a, - A: 'a, { + where ${struct_type_bounds_s()} { hub: &'a ${hub_type_name}${hub_type_params_s()}, } diff --git a/src/mako/lib/util.py b/src/mako/lib/util.py index 4acdf7de7d3..0d774b5f6a8 100644 --- a/src/mako/lib/util.py +++ b/src/mako/lib/util.py @@ -98,7 +98,7 @@ '%': 1, } -HUB_TYPE_PARAMETERS = ('NC', 'A') +HUB_TYPE_PARAMETERS = ('C', 'NC', 'A') # ============================================================================== ## @name Filters @@ -732,8 +732,13 @@ def hub_type_params_s(): # return a list of where statements to server as bounds for the hub. def hub_type_bounds(): return ['NC: hyper::net::NetworkConnector', + 'C: BorrowMut>', 'A: oauth2::GetToken'] +# Returns True if this API has particular authentication scopes to choose from +def supports_scopes(auth): + return bool(auth) and bool(auth.oauth2) + # return list of type bounds required by method builder def mb_type_bounds(): return hub_type_bounds() @@ -745,6 +750,10 @@ def mb_type_bounds(): def rb_type_params_s(resource, c): return _to_type_params_s(_rb_type_params) +# type bounds for resource and method builder +def struct_type_bounds_s(): + return ', '.join(tp + ": 'a" for tp in HUB_TYPE_PARAMETERS) + # type params for the given method builder, as string suitable for Rust code def mb_type_params_s(m): return _to_type_params_s(_rb_type_params) @@ -808,8 +817,9 @@ def parts_from_params(params): return part_prop, list() # Convert a scope url to a nice enum variant identifier, ready for use in code -# name = name of the api, without version +# name = name of the api, without version, non-normalized (!) def scope_url_to_variant(name, url, fully_qualified=True): + name = normalize_library_name(name) FULL = 'Full' fqvn = lambda n: fully_qualified and 'Scope::%s' % n or n repl = lambda n: n.replace('-', '.').replace('_', '.') diff --git a/src/rust/cmn.rs b/src/rust/cmn.rs index 43d9621fcfc..6baec8bff43 100644 --- a/src/rust/cmn.rs +++ b/src/rust/cmn.rs @@ -59,6 +59,13 @@ pub trait Delegate { fn http_error(&mut self, &hyper::HttpError) -> oauth2::Retry { oauth2::Retry::Abort } + + /// Called whenever there is the need for your applications API key after + /// the official authenticator implementation didn't provide one, for some reason. + /// If this method returns None as well, the underlying operation will fail + fn api_key(&mut self) -> Option { + None + } } #[derive(Default)] @@ -72,6 +79,13 @@ pub enum Result { /// The http connection failed HttpError(hyper::HttpError), + /// We needed an API key for authentication, but didn't obtain one. + /// Neither through the authenticator, nor through the Delegate. + MissingAPIKey, + + /// We required a Token, but didn't get one from the Authenticator + MissingToken, + /// An additional, free form field clashed with one of the built-in optional ones FieldClash(&'static str),