diff --git a/src/cli.rs b/src/cli.rs index 3c7ac8f..da42f93 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -27,6 +27,16 @@ pub fn build_cli(preferences: &Preferences) -> App { .short('n') .long("needs-review") .help("Show diffs that need your review"), + ) + .arg( + Arg::with_name("author") + .short('a') + .long("author") + .required(false) + .takes_value(true) + .help( + "Find diffs with given author name. This is the Phabricator username", + ), ), ) .subcommand( diff --git a/src/diffs.rs b/src/diffs.rs index 177b180..d9db7c2 100644 --- a/src/diffs.rs +++ b/src/diffs.rs @@ -1,9 +1,10 @@ -use crate::auth; use crate::structs::{FabConfig, Revision, RevisionData}; use crate::NO_BORDER_PRESET; +use crate::{auth, users}; use clap::ArgMatches; use comfy_table::{Attribute, Cell, CellAlignment, ContentArrangement, Table}; use failure::Error; +use serde_json::{Map, Value}; use tokio::runtime::Runtime; const DIFFERENTIAL_SEARCH_URL: &str = "api/differential.revision.search"; @@ -32,6 +33,45 @@ pub async fn get_authored_diffs(config: &FabConfig) -> Result, Err Ok(result) } +/// Get diffs authored by given author +pub async fn get_diffs(config: &FabConfig, author: &Option<&str>) -> Result, Error> { + if author.is_none() { + return Err(failure::err_msg("No author specified")); + } + + let author = author.unwrap(); + + let user = users::get_user(&author, config).await?; + + let url = format!( + "{}{}", + &config.hosted_instance, + DIFFERENTIAL_SEARCH_URL.to_string() + ); + + let mut map = Map::new(); + map.insert( + "api.token".to_string(), + Value::from(config.api_token.clone()), + ); + map.insert( + "constraints[authorPHIDs][0]".to_string(), + Value::from(user.phid.clone()), + ); + + let json_body = Value::Object(map); + + let result = + auth::send::(config, reqwest::Client::new().post(&url).form(&json_body)) + .await? + .data + .into_iter() + .filter(|rev| !rev.fields.status.closed) + .collect(); + + Ok(result) +} + /// Get the diffs that needs review from the user. pub async fn get_needs_review_diffs(config: &FabConfig) -> Result, Error> { let json_body = json!({ @@ -78,6 +118,10 @@ pub fn process_diff_command(_matches: &ArgMatches, config: &FabConfig) -> Result process_diffs_needs_review(config)?; return Ok(()); } + if _matches.is_present("author") { + process_authored_diffs(config, _matches.value_of("author"))?; + return Ok(()); + } let result = Runtime::new()?.block_on(get_authored_diffs(config))?; @@ -91,3 +135,10 @@ fn process_diffs_needs_review(config: &FabConfig) -> Result<(), Error> { render_diffs(config, &revisions); Ok(()) } + +fn process_authored_diffs(config: &FabConfig, author: Option<&str>) -> Result<(), Error> { + let revisions = Runtime::new()?.block_on(get_diffs(config, &author))?; + + render_diffs(config, &revisions); + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index 708beea..0772078 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,6 +13,7 @@ mod preferences; mod structs; mod summary; mod tasks; +mod users; const WHO_AM_I: &str = "api/user.whoami"; /// Preset for comfy-table so that it styles the table for no borders diff --git a/src/users.rs b/src/users.rs new file mode 100644 index 0000000..9744254 --- /dev/null +++ b/src/users.rs @@ -0,0 +1,42 @@ +use crate::auth; +use crate::structs::FabConfig; +use failure::Error; +use serde::{Deserialize, Serialize}; +use serde_json::{Map, Value}; + +pub async fn get_user(username: &str, config: &FabConfig) -> Result { + let mut map = Map::new(); + map.insert( + "api.token".to_string(), + Value::from(config.api_token.clone()), + ); + map.insert( + "constraints[usernames][0]".to_string(), + Value::from(username), + ); + + let url = format!("{}{}", &config.hosted_instance, "api/user.search"); + + let json_body = Value::Object(map); + + let result = + auth::send::(config, reqwest::Client::new().post(&url).form(&json_body)) + .await? + .data + .into_iter() + .next() + .unwrap(); + + Ok(result) +} + +#[derive(Deserialize, Serialize, Debug)] +struct UserSearchData { + data: Vec, +} + +#[derive(Deserialize, Serialize, Debug, Clone)] +pub struct User { + pub id: i32, + pub phid: String, +}