use egg_mode::{Token, request_token, authorize_url, access_token};
use self::super::super::util::{prompt_exact_len, span_r};
use self::super::{User, verify_file};
use self::super::super::Outcome;
use std::path::{Path, PathBuf};
use std::io::{BufRead, Write};
use std::str::FromStr;
pub fn verify(config_dir: &(String, PathBuf)) -> Result<(PathBuf, PathBuf), Outcome> {
let app = try!(verify_file("app.toml", true, config_dir, false, "init"));
Ok((app, config_dir.1.join("users.toml")))
}
pub fn authorise<'t, R, W, T>(input: &mut R, output: &mut W, conn_token: T, verbose: bool) -> Result<User, Outcome>
where R: BufRead,
W: Write,
T: Into<Token<'t>>
{
let conn_token = conn_token.into();
let req_token = try!(wrap_network_op_in_ellipsis_done(output,
|| {
let req_token = request_token(&conn_token, "oob")
.map_err(|e| Outcome::TwitterAPIError(format!("{}", e)));
(req_token.is_ok(), req_token)
},
"request token",
verbose,
false,
true));
writeln!(output, "Visit this URL: {}", authorize_url(&req_token)).unwrap();
let pin = prompt_exact_len(input, output, "Enter the PIN from that page", |s| u32::from_str(s).is_ok(), 7).unwrap();
let access_token_data = try!(wrap_network_op_in_ellipsis_done(output,
|| {
let access_token_data = access_token(&conn_token, &req_token, pin)
.map_err(|e| Outcome::TwitterAPIError(format!("{}", e)));
(access_token_data.is_ok(), access_token_data)
},
"access token",
verbose,
true,
false));
Ok(User::from_raw_access_token(access_token_data))
}
pub fn append_user(users_path: &Path, user: User) -> Outcome {
let mut users = if users_path.exists() {
match User::read(users_path).map_err(Option::unwrap) {
Ok(users) => users,
Err(out) => return out,
}
} else {
vec![]
};
match users.binary_search_by(|u| u.cmp(&user)) {
Ok(curidx) => users[curidx] = user,
Err(possidx) => users.insert(possidx, user),
}
User::write(users, &users_path);
Outcome::NoError
}
pub fn print_success_message<W: Write>(output: &mut W, user: &User, verbose: bool) {
writeln!(output, "Successfully authenticated user {}#{}", user.name, user.id).unwrap();
if verbose {
writeln!(output, "Access tokens:").unwrap();
writeln!(output, " Key : {}", user.access_token_key).unwrap();
writeln!(output, " Secret: {}", user.access_token_secret).unwrap();
}
}
fn wrap_network_op_in_ellipsis_done<W, T, F>(output: &mut W, f: F, desc: &str, verbose: bool, nl_before: bool, nl_after: bool) -> T
where W: Write,
F: FnOnce() -> (bool, T)
{
if verbose {
if nl_before {
writeln!(output, "").unwrap();
}
write!(output, "Getting {}...", desc).unwrap();
output.flush().unwrap();
let (dur, (succeeded, res)) = span_r(f);
if succeeded {
writeln!(output, " {}ms", dur.num_milliseconds()).unwrap();
} else {
writeln!(output, " FAILED").unwrap();
}
if nl_after {
writeln!(output, "").unwrap();
}
res
} else {
f().1
}
}