Skip to main content

edc_web_components/models/
asset_item.rs

1use crate::models::dataset_extra_fields::DatasetExtraFields;
2use crate::models::{Creator, DataspaceDataset, Thumbnail};
3use edc_connector_client::types::asset::Asset;
4use edc_connector_client::types::catalog::Dataset;
5use edc_connector_client::types::data_address::DataAddress;
6use edc_connector_client::types::properties::{Properties, PropertyValue};
7
8#[derive(Clone, Debug, PartialEq)]
9pub struct AssetItem {
10  pub id: String,
11  pub name: String,
12  pub version: Option<semver::Version>,
13  pub description: Option<String>,
14  pub creator: Option<Creator>,
15  pub thumbnail: Option<Thumbnail>,
16  pub keywords: Vec<String>,
17  pub landing_page: Option<String>,
18  pub dcterm_types: Vec<String>,
19  pub base_url: String,
20  pub datasource_type: String,
21  pub proxy_path: bool,
22  pub proxy_query_params: bool,
23  pub proxy_method: bool,
24  pub proxy_body: bool,
25  pub oauth2_client_id: String,
26  pub oauth2_client_secret_key: String,
27  pub oauth2_token_url: String,
28  pub oauth2_scope: String,
29}
30
31impl AssetItem {
32  pub fn is_filtered(&self, search: &Option<String>, dcterm_types: &[String]) -> bool {
33    let text_content = format!(
34      "{} {} {} {}",
35      self.name.to_lowercase(),
36      self.description.clone().unwrap_or_default().to_lowercase(),
37      self.keywords.join(" ").to_lowercase(),
38      self
39        .creator
40        .clone()
41        .map(|creator| creator.name.unwrap_or_default().to_lowercase())
42        .unwrap_or_default()
43    );
44
45    if !dcterm_types.is_empty() {
46      if self
47        .dcterm_types
48        .iter()
49        .any(|dcterm_type| dcterm_types.contains(dcterm_type))
50      {
51        if let Some(search) = &search {
52          text_content.contains(&search.to_lowercase())
53        } else {
54          true
55        }
56      } else {
57        false
58      }
59    } else {
60      if let Some(search) = &search {
61        text_content.contains(&search.to_lowercase())
62      } else {
63        true
64      }
65    }
66  }
67}
68
69impl From<Asset> for AssetItem {
70  fn from(asset: Asset) -> Self {
71    let id = asset.id().to_string();
72    let name = get_property(asset.properties(), "name");
73    let description = asset
74      .properties()
75      .get::<String>("http://www.w3.org/2000/01/rdf-schema#comment")
76      .unwrap_or_default();
77
78    let version = asset
79      .properties()
80      .get::<String>("http://www.w3.org/ns/dcat#version")
81      .unwrap_or_default()
82      .and_then(|version| semver::Version::parse(version.as_str()).ok());
83
84    let creator = asset
85      .properties()
86      .get_raw("http://purl.org/dc/terms/creator")
87      .and_then(|property_value| serde_json::from_value::<Creator>(property_value.0.clone()).ok());
88
89    let thumbnail = asset
90      .properties()
91      .get_raw("http://xmlns.com/foaf/0.1/thumbnail")
92      .and_then(|property_value| {
93        serde_json::from_value::<Thumbnail>(property_value.0.clone()).ok()
94      });
95
96    let keywords = asset
97      .properties()
98      .get_raw("http://www.w3.org/ns/dcat#keyword")
99      .and_then(|property_value| {
100        serde_json::from_value::<Vec<String>>(property_value.0.clone()).ok()
101      })
102      .unwrap_or_default();
103
104    let landing_page = asset
105      .properties()
106      .get::<String>("http://www.w3.org/ns/dcat#landingPage")
107      .unwrap_or_default();
108
109    let dcterm_types = asset
110      .properties()
111      .get_raw("http://purl.org/dc/terms/type")
112      .and_then(|property_value| {
113        if let Ok(value) = PropertyValue::try_from(property_value) {
114          Some(vec![value])
115        } else {
116          serde_json::from_value::<Vec<String>>(property_value.0.clone()).ok()
117        }
118      })
119      .unwrap_or_default();
120
121    let base_url = asset
122      .data_address()
123      .property("baseUrl")
124      .unwrap_or_default()
125      .unwrap_or_default();
126
127    let datasource_type = asset
128      .data_address()
129      .property("type")
130      .unwrap_or_default()
131      .unwrap_or_default();
132
133    let proxy_path = get_boolean_property(asset.data_address(), "proxyPath");
134    let proxy_query_params = get_boolean_property(asset.data_address(), "proxyQueryParams");
135    let proxy_method = get_boolean_property(asset.data_address(), "proxyMethod");
136    let proxy_body = get_boolean_property(asset.data_address(), "proxyBody");
137
138    let oauth2_client_id = asset
139      .data_address()
140      .property("oauth2:clientId")
141      .unwrap_or_default()
142      .unwrap_or_default();
143
144    let oauth2_client_secret_key = asset
145      .data_address()
146      .property("oauth2:clientSecretKey")
147      .unwrap_or_default()
148      .unwrap_or_default();
149
150    let oauth2_scope = asset
151      .data_address()
152      .property("oauth2:scope")
153      .unwrap_or_default()
154      .unwrap_or_default();
155
156    let oauth2_token_url = asset
157      .data_address()
158      .property("oauth2:tokenUrl")
159      .unwrap_or_default()
160      .unwrap_or_default();
161
162    AssetItem {
163      id,
164      name,
165      version,
166      description,
167      creator,
168      thumbnail,
169      keywords,
170      landing_page,
171      dcterm_types,
172      base_url,
173      datasource_type,
174      proxy_path,
175      proxy_query_params,
176      proxy_method,
177      proxy_body,
178      oauth2_client_id,
179      oauth2_client_secret_key,
180      oauth2_token_url,
181      oauth2_scope,
182    }
183  }
184}
185
186impl From<edc_federated_catalog_client::models::Dataset> for AssetItem {
187  fn from(dataset: edc_federated_catalog_client::models::Dataset) -> Self {
188    Self {
189      id: dataset.id.clone(),
190      name: dataset.name,
191      version: dataset
192        .version
193        .and_then(|version| semver::Version::parse(&version).ok()),
194      description: dataset.description,
195      creator: dataset.creator.map(|creator| Creator {
196        name: Some(creator.name),
197        thumbnail: Some(Thumbnail {
198          resource: Some(creator.thumbnail.resource),
199        }),
200      }),
201      thumbnail: dataset.thumbnail.map(|thumbnail| Thumbnail {
202        resource: Some(thumbnail.resource),
203      }),
204      keywords: dataset.keywords,
205      landing_page: dataset.landing_page,
206      dcterm_types: dataset.dcterm_types,
207      base_url: "".to_string(),
208      datasource_type: "".to_string(),
209      proxy_path: false,
210      proxy_query_params: false,
211      proxy_method: false,
212      proxy_body: false,
213      oauth2_client_id: "".to_string(),
214      oauth2_client_secret_key: "".to_string(),
215      oauth2_token_url: "".to_string(),
216      oauth2_scope: "".to_string(),
217    }
218  }
219}
220
221impl From<&Dataset<DatasetExtraFields>> for AssetItem {
222  fn from(dataset: &Dataset<DatasetExtraFields>) -> Self {
223    let id = dataset.id().to_string();
224    let extra = &dataset.extra;
225
226    Self {
227      id,
228      name: extra.name.clone(),
229      version: extra
230        .version
231        .as_ref()
232        .and_then(|version| semver::Version::parse(version).ok()),
233      description: extra.description.to_owned(),
234      creator: extra.creator.as_ref().map(|creator| Creator {
235        name: Some(creator.name.to_owned()),
236        thumbnail: Some(Thumbnail {
237          resource: Some(creator.thumbnail.resource.to_owned()),
238        }),
239      }),
240      thumbnail: extra.thumbnail.as_ref().map(|thumbnail| Thumbnail {
241        resource: Some(thumbnail.resource.to_owned()),
242      }),
243      keywords: extra.keywords.clone(),
244      landing_page: extra.landing_page.clone(),
245      dcterm_types: extra.dcterm_types.clone(),
246      base_url: "".to_string(),
247      datasource_type: "".to_string(),
248      proxy_path: false,
249      proxy_query_params: false,
250      proxy_method: false,
251      proxy_body: false,
252      oauth2_client_id: "".to_string(),
253      oauth2_client_secret_key: "".to_string(),
254      oauth2_token_url: "".to_string(),
255      oauth2_scope: "".to_string(),
256    }
257  }
258}
259
260impl From<AssetItem> for DataspaceDataset {
261  fn from(asset_item: AssetItem) -> Self {
262    Self {
263      id: asset_item.id,
264      title: asset_item.name,
265      version: asset_item.version,
266      comment: asset_item.description,
267      thumbnail: asset_item.thumbnail,
268      creator: asset_item.creator,
269      keywords: asset_item.keywords,
270      dcterm_types: asset_item.dcterm_types,
271      landing_page: asset_item.landing_page,
272      policies: vec![],
273    }
274  }
275}
276
277fn get_property(properties: &Properties, name: &str) -> String {
278  properties
279    .get::<String>(name)
280    .unwrap_or_default()
281    .unwrap_or_default()
282}
283
284fn get_boolean_property(data_address: &DataAddress, name: &str) -> bool {
285  data_address
286    .property::<String>(name)
287    .unwrap_or_default()
288    .unwrap_or_default()
289    == "true"
290}