def merge_metadata(self, schema_uid, source_object_uid, target_object_uid, dry_run=False): url = '/v5/metadata/' source_params = { 'object_ids': source_object_uid, 'schema_id': schema_uid } source_obj_resp = get_object(self.api_key, url, source_params) if not source_obj_resp['meta']['total']: print('No source metadata for {} {}'.format( schema_uid, source_object_uid)) return source_metadata = source_obj_resp['data'][0] check_params = { 'object_ids': target_object_uid, 'schema_id': schema_uid } md_obj_resp = get_object(self.api_key, url, check_params) md_obj_exists = md_obj_resp['meta']['total'] for field in ('created_at', 'updated_at', 'id'): del source_metadata[field] source_metadata['object_id'] = target_object_uid if not md_obj_exists: if dry_run: print('POST {} to {}'.format(source_object_uid, target_object_uid)) pprint(source_metadata) else: post_object(self.api_key, url, source_metadata) else: existing_md = md_obj_resp['data'][0]['ext'] adding_md = source_metadata['ext'] schema = self._get_schema(schema_uid) new_md = {} for field in schema['fields']: if field['type'] == 'term' and field['ext']['limit'] is None: key = field['key'] # TODO - associate to empty value of schema field dynamically existing = existing_md.get(key, []) adding = adding_md.get(key, []) new_md[key] = list(set(existing) | set(adding)) new_md_obj = { 'object_id': target_object_uid, 'schema_id': schema_uid, 'ext': new_md } md_obj_id = md_obj_resp['data'][0]['id'] if dry_run: print('PUT {} to {} ({})'.format(source_object_uid, target_object_uid, md_obj_id)) pprint(new_md_obj) else: put_object(self.api_key, url + md_obj_id, new_md_obj)
def update_metadata(self, object_uid, metadata_dict): existing_metadata = get_object(self.api_key, '/v5/metadata/', {'object_ids': object_uid})['data'] asset_metadata_id = next((x['id'] for x in existing_metadata if x['schema_id'] == self.asset_schema_uid), None) usage_metadata_id = next((x['id'] for x in existing_metadata if x['schema_id'] == self.usage_schema_uid), None) asset_metadata = { 'schema_id': self.asset_schema_uid, 'object_id': object_uid, 'ext': { 'title': metadata_dict['Title'], 'description': metadata_dict['Description'], } } if metadata_dict['Tags']: tags = self._prepare_tags( [tag.strip() for tag in metadata_dict['Tags'].split(',')]) asset_metadata['ext']['tags'] = tags else: asset_metadata['ext']['tags'] = [] if asset_metadata_id: md_url = '/v5/metadata/{}'.format(asset_metadata_id) put_object(self.api_key, md_url, asset_metadata) else: md_url = '/v5/metadata/' post_object(self.api_key, md_url, asset_metadata) if metadata_dict['Add Usage Rights Information'] and \ metadata_dict['Add Usage Rights Information'] not in\ ('No', 'no', 'NO', '0'): usage_metadata = { 'schema_id': self.usage_schema_uid, 'object_id': object_uid, } uri = {} translation = { 'License Type': 'title', 'Usage Rights Information': 'description', 'Expiration Date': 'expiration' } for f in translation.keys(): uri[translation[f]] = metadata_dict[f] usage_metadata['ext'] = uri if usage_metadata_id: md_url = '/v5/metadata/{}'.format(usage_metadata_id) put_object(self.api_key, md_url, usage_metadata) else: md_url = '/v5/metadata/' post_object(self.api_key, md_url, usage_metadata)
def copy_metadata(self, schema_uid, source_object_uid, target_object_uid): source_params = { 'object_ids': source_object_uid, 'schema_id': schema_uid } check_params = { 'object_ids': target_object_uid, 'schema_id': schema_uid } url = '/v5/metadata/' source_metadata_resp = get_object(self.api_key, url, source_params) if source_metadata_resp['meta']['total'] == 0: print('No metadata for schema {} on object {}'.format( schema_uid, source_object_uid)) return None source_metadata = source_metadata_resp['data'][0] md_obj_resp = get_object(self.api_key, url, check_params) md_obj_exists = md_obj_resp['meta']['total'] for field in ('created_at', 'updated_at', 'id'): del source_metadata[field] source_metadata['object_id'] = target_object_uid if md_obj_exists: md_obj_id = md_obj_resp['data'][0]['id'] put_object(self.api_key, url + md_obj_id, source_metadata) result = md_obj_id else: response = post_object(self.api_key, url, source_metadata) result = response['id'] return result
def update_custom_metadata(self, object_uid, metadata_dict, tag_path_terms=False): new_metadata = self._create_metadata(metadata_dict, object_uid, tag_path_terms) # New method existing_metadata = get_object(self.api_key, '/v5/metadata/', {'object_ids': object_uid})['data'] custom_metadata = [ x for x in existing_metadata if x['schema_id'] not in (self.asset_schema_uid, self.usage_schema_uid) ] payloads = {} metadata_id_for_schema = {} for x in custom_metadata: payloads[x['schema_id']] = x['ext'] metadata_id_for_schema[x['schema_id']] = x['id'] for schema_id, fields_dict in new_metadata.items(): if schema_id not in payloads: payloads[schema_id] = {} # Schema not in existing custom metadata, but it can be created. # payload['schemas'].append({'schema_uid': schema_id, 'data': {}}) # s_index = len(payload['schemas']) - 1 for key, new_value in fields_dict.items(): payloads[schema_id][key] = new_value for schema_id, ext in payloads.items(): new_payload = { 'schema_id': schema_id, 'object_id': object_uid, 'ext': ext } if schema_id in metadata_id_for_schema: if schema_id not in new_metadata: continue m_id = metadata_id_for_schema[schema_id] put_object(self.api_key, '/v5/metadata/{}'.format(m_id), new_payload) else: post_object(self.api_key, '/v5/metadata/', new_payload)
def _prepare_tags(self, tags_list): term_ids = [] for tag in tags_list: if tag.startswith('term:'): term_ids.append(tag) continue # cache_stats['count'] += 1 if tag[:64] in self.tag_cache: term_ids.append(self.tag_cache[tag[:64]]) # cache_stats['cache'] += 1 else: data = { 'scope_id': self.license_uid, 'namespace': 'tag', 'name': tag[:64] } response = post_object(self.api_key, '/v5/term/', data) term_ids.append(response['id']) self.tag_cache[tag[:64]] = response['id'] return term_ids
def create_custom_metadata(self, schema_id, metadata_dict, tag_path_terms=False): schema_id_list = [schema_id] schema_list = self._get_custom_fields(schema_uids=schema_id_list) info_for_field = {} result = {} for s in schema_list: for f in s[1]: info_for_field[f['label']] = f info_for_field[f['label']]['schema_uid'] = s[0] for key, value in metadata_dict.items(): key_info = info_for_field.get(key) if not key_info: continue new_value = value # Map select to value if key_info['type'] == 'select': # all_values = map(str.strip, new_value.split('|')) value_for_label = {} for x in key_info['ext']['values']: value_for_label[x['label']] = x['value'] new_value = value_for_label.get(new_value) # Map multi-select to value if key_info['type'] == 'multi-select': # all_values = map(str.strip, new_value.split('|')) all_values = new_value.split('|') value_for_label = {} for x in key_info['ext']['values']: value_for_label[x['label']] = x['value'] new_value = [ value_for_label.get(x) for x in all_values if value_for_label.get(x) is not None ] # Map string-array to list if key_info['type'] == 'string-array': all_values = new_value.split('|') all_values = [x for x in all_values if x] new_value = all_values # Map asset to list if key_info['type'] == 'asset': all_values = new_value.split(',') all_values = [x for x in all_values if x.startswith('asset:')] new_value = all_values # Map date to date format if key_info['type'] == 'date': try: date_value = parse(new_value) if key_info['ext']['include_time']: time_format = '%Y-%m-%dT%H:%M:%S.000Z' new_value = date_value.strftime(time_format) else: new_value = date_value.date().isoformat() except ValueError: new_value = None # Validate link if key_info['type'] == 'link': if not isinstance(new_value, list): all_values = [new_value] else: all_values = new_value val = URLValidator() good_values = [] for x in all_values: try: val(x) good_values.append(x) except ValidationError: pass good_link_objs = [] for l in good_values: link_params = {'url': l} link_obj = post_object(self.api_key, '/v3/links/', data=link_params) good_link_objs.append('link:{}'.format(link_obj['id'])) new_value = good_link_objs # Map path to term for taxonomies if key_info['type'] == 'term': root_id = key_info['ext']['parent_term_ids'][0] all_values = new_value.split('||') if new_value else [] # if not isinstance(new_value, list): # new_value = [new_value] if tag_path_terms: new_value = [] for x in all_values: if self.taxonomies[root_id].get(x) is not None: new_value.extend( self.taxonomies[root_id].get(x)['path']) # new_value = [self.taxonomies[root_id].get(x)['path'] # for x in all_values # if self.taxonomies[root_id].get(x) is not None] else: new_value = [ self.taxonomies[root_id].get(x)['leaf'] for x in all_values if self.taxonomies[root_id].get(x) is not None ] result[key_info['key']] = new_value return result