diff --git a/CHANGELOG.md b/CHANGELOG.md index 9888b15..9b1ba09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ - Fixes issue when getting streams that have multiple filters on single user property - Fixes issue where upper case file names would not be matched in `parse` - Reduce batch size when deleting comment batches +- Support attachment type filters # v0.24.0 - BREAKING: the `--context` option is now required. Users need to opt diff --git a/api/src/resources/dataset.rs b/api/src/resources/dataset.rs index e94c1c7..1d76499 100644 --- a/api/src/resources/dataset.rs +++ b/api/src/resources/dataset.rs @@ -11,7 +11,7 @@ use crate::{ source::Id as SourceId, user::Username, }, - AnnotatedComment, CommentFilter, Continuation, LabelName, + AnnotatedComment, CommentFilter, Continuation, }; use std::{ fmt::{Display, Formatter, Result as FmtResult}, @@ -87,12 +87,13 @@ pub enum TimeResolution { #[serde(rename_all = "snake_case")] pub enum Attribute { Labels, + AttachmentPropertyTypes, } #[derive(Debug, Clone, Serialize)] #[serde(tag = "kind", rename_all = "snake_case")] pub enum AttributeFilterEnum { - StringAnyOf { any_of: Vec }, + StringAnyOf { any_of: Vec }, } #[derive(Debug, Clone, Serialize)] @@ -326,7 +327,7 @@ mod tests { attribute_filters: vec![AttributeFilter { attribute: Attribute::Labels, filter: AttributeFilterEnum::StringAnyOf { - any_of: vec![LabelName("Access Management".to_string())], + any_of: vec!["Access Management".to_string()], }, }], continuation: Some(Continuation( @@ -361,7 +362,7 @@ mod tests { attribute_filters: vec![AttributeFilter { attribute: Attribute::Labels, filter: AttributeFilterEnum::StringAnyOf { - any_of: vec![LabelName("Access Management".to_string())], + any_of: vec!["Access Management".to_string()], }, }], continuation: Some(Continuation( @@ -394,7 +395,7 @@ mod tests { attribute_filters: vec![AttributeFilter { attribute: Attribute::Labels, filter: AttributeFilterEnum::StringAnyOf { - any_of: vec![LabelName("label Name".to_string())], + any_of: vec!["label Name".to_string()], }, }], label_property_timeseries: true, diff --git a/cli/src/commands/get/comments.rs b/cli/src/commands/get/comments.rs index 35170b8..fd5849c 100644 --- a/cli/src/commands/get/comments.rs +++ b/cli/src/commands/get/comments.rs @@ -112,6 +112,10 @@ pub struct GetManyCommentsArgs { #[structopt(long = "interactive-user-property-filter")] /// Open a dialog to interactively construct the user property filter to use interactive_property_filter: bool, + + #[structopt(long = "attachment-types")] + /// The list of attachment types to filter to + attachment_type_filters: Vec, } #[derive(Debug, Deserialize)] @@ -246,6 +250,7 @@ pub fn get_many(client: &Client, args: &GetManyCommentsArgs) -> Result<()> { to_timestamp, path, label_filter, + attachment_type_filters, property_filter: user_property_filter, interactive_property_filter: interative_property_filter, recipients, @@ -274,6 +279,10 @@ pub fn get_many(client: &Client, args: &GetManyCommentsArgs) -> Result<()> { bail!("Cannot use a label filter when `dataset` is not provided.") } + if !attachment_type_filters.is_empty() && dataset.is_none() { + bail!("Cannot use a attachment type filter when `dataset` is not provided.") + } + if label_filter.is_some() && reviewed_only { bail!("The `reviewed_only` and `label_filter` options are mutually exclusive.") } @@ -318,6 +327,17 @@ pub fn get_many(client: &Client, args: &GetManyCommentsArgs) -> Result<()> { } } + let mut attachment_property_types_filter: Option = None; + + if !attachment_type_filters.is_empty() { + attachment_property_types_filter = Some(AttributeFilter { + attribute: Attribute::AttachmentPropertyTypes, + filter: AttributeFilterEnum::StringAnyOf { + any_of: attachment_type_filters.to_vec(), + }, + }); + } + let user_properties_filter = if let Some(filter) = user_property_filter { Some(filter.0.clone()) } else if *interative_property_filter { @@ -364,6 +384,7 @@ pub fn get_many(client: &Client, args: &GetManyCommentsArgs) -> Result<()> { show_progress: !no_progress, label_attribute_filter, user_properties_filter, + attachment_property_types_filter, messages_filter: Some(messages_filter), }; @@ -386,25 +407,18 @@ fn get_label_attribute_filter( ) -> Result> { let dataset = client.get_dataset(dataset_id)?; - let label_names: Vec = dataset + let label_names: Vec = dataset .label_defs .into_iter() .filter(|label_def| filter.is_match(&label_def.name.0)) - .map(|label_def| label_def.name) + .map(|label_def| label_def.name.0) .collect(); if label_names.is_empty() { info!("No label names matching the filter '{}'", filter); Ok(None) } else { - info!( - "Filtering on label(s):\n- {}", - label_names - .iter() - .map(|label_name| label_name.0.as_str()) - .collect::>() - .join("\n- ") - ); + info!("Filtering on label(s):\n- {}", label_names.join("\n- ")); Ok(Some(AttributeFilter { attribute: Attribute::Labels, filter: AttributeFilterEnum::StringAnyOf { @@ -422,6 +436,7 @@ struct CommentDownloadOptions { timerange: CommentsIterTimerange, show_progress: bool, label_attribute_filter: Option, + attachment_property_types_filter: Option, user_properties_filter: Option, messages_filter: Option, } @@ -434,6 +449,10 @@ impl CommentDownloadOptions { filters.push(label_attribute_filter.clone()); } + if let Some(attachment_types_attribute_filter) = &self.attachment_property_types_filter { + filters.push(attachment_types_attribute_filter.clone()) + } + filters } }