55
66from cs_tools .data .enums import (
77 DownloadableContent , GUID , MetadataCategory , MetadataObject , MetadataObjectSubtype ,
8- PermissionType
98)
109from cs_tools .errors import ContentDoesNotExist
1110from cs_tools .util import chunks
@@ -302,35 +301,54 @@ def get_edoc_object_list(self, guids: List[GUID]) -> List[Dict[str,str]]:
302301 return mapped_guids
303302
304303 @validate_arguments
305- def get_object_ids_with_tags (self , tags : List [str ]) -> List [Dict [str ,str ]]:
304+ def get_object_ids_with_tags_or_author (
305+ self , tags : List [str ] = None ,
306+ author : GUID = None ,
307+ ignore_datasources : bool = False
308+ ) -> List [Dict [str ,str ]]:
306309 """
307- Gets a list of IDs for the associated tag and returns as a list of object ID to type mapping.
310+ Gets a list of IDs for the associated tag and/or author and returns as a list of object ID to type mapping.
311+ Either the author or the tag must be specified. If both are specified, it will be the content owned by that
312+ person with the given tag.
308313
309314 The return format looks like:
310315 [
311316 {"id": "0291f1cd-5f8e-4d96-80e2-e5ef1aa6c44f", "type":"QUESTION_ANSWER_BOOK"},
312317 {"id": "4bcaadb4-031a-4afd-b159-2c0c0f194c42", "type":"PINBOARD_ANSWER_BOOK"}
313318 ]
314319 :param tags: The list of tags to get ids for.
320+ :param author: The author of the content.
321+ :param ignore_datasources: If true, will ignore data sources.
315322 """
316323
324+ # testing - remove later
317325 object_ids = []
318326 for metadata_type in DownloadableContent :
327+ if ignore_datasources and metadata_type == DownloadableContent .data_source :
328+ continue
329+
319330 offset = 0
320331
321332 while True :
322- r = self .ts .api ._metadata .list (type = metadata_type .value , batchsize = 500 , offset = offset , tagname = tags )
333+ r = self .ts .api ._metadata .list (type = metadata_type .value , batchsize = 500 ,
334+ offset = offset , tagname = tags , authorguid = author )
323335 data = r .json ()
324336 offset += len (data )
325337
326338 for metadata in data ['headers' ]:
327- object_ids .append (metadata ["id" ])
339+
340+ if author and metadata ['author' ] == author : # workaround for 7.1/7.2
341+ object_ids .append (metadata ["id" ])
342+ elif not author : # no author specified, so just add it.
343+ object_ids .append (metadata ["id" ])
344+ # else just ignore it.
328345
329346 if data ['isLastBatch' ]:
330347 break
331348
332349 return list (set (object_ids )) # might have been duplicates
333350
351+
334352 @classmethod
335353 @validate_arguments
336354 def map_subtype_to_type (self , subtype : Union [str , None ]) -> str :
@@ -344,7 +362,7 @@ def map_subtype_to_type(self, subtype: Union[str, None]) -> str:
344362
345363 return subtype
346364
347- def _lookup_geo_config (self , column_details ) -> str :
365+ def _lookup_geo_config (self , column_details ) -> Union [ str , None ] :
348366 try :
349367 config = column_details ['geoConfig' ]
350368 except KeyError :
@@ -362,7 +380,7 @@ def _lookup_geo_config(self, column_details) -> str:
362380
363381 return 'Unknown'
364382
365- def _lookup_calendar_guid (self , column_details ) -> str :
383+ def _lookup_calendar_guid (self , column_details ) -> Union [ str , None ] :
366384 try :
367385 ccal_guid = column_details ['calendarTableGUID' ]
368386 except KeyError :
@@ -375,12 +393,13 @@ def _lookup_calendar_guid(self, column_details) -> str:
375393
376394 return self .cache ['calendar_type' ][ccal_guid ]
377395
378- def _lookup_currency_type (self , column_details ) -> str :
396+ def _lookup_currency_type (self , column_details ) -> Union [ str , None ] :
379397 try :
380398 currency_info = column_details ['currencyTypeInfo' ]
381399 except KeyError :
382400 return None
383401
402+ name = None
384403 if currency_info ['setting' ] == 'FROM_USER_LOCALE' :
385404 name = 'Infer From Browser'
386405 elif currency_info ['setting' ] == 'FROM_ISO_CODE' :
@@ -396,3 +415,41 @@ def _lookup_currency_type(self, column_details) -> str:
396415 name = self .cache ['currency_type' ][g ]
397416
398417 return name
418+
419+ @validate_arguments
420+ def objects_exist (self , metadata_type : MetadataObject , guids : List [GUID ]) -> Dict [GUID , bool ]:
421+ """
422+ Checks if the list of objects exist.
423+ :param metadata_type: The type to check for. Must do one at a time.
424+ :param guids: The list of GUIDs to check.
425+ :return: A map of GUID to boolean, where True == it exists.
426+ """
427+ r = self .ts .api .metadata .list_object_headers (type = metadata_type , fetchids = guids )
428+ content = r .json ()
429+
430+ # The response is a list of objects that only include the ones that exist. So check each GUID and add to the
431+ # map.
432+ returned_ids = [obj .get ("id" ) for obj in content ]
433+ existence = {}
434+ for guid in guids :
435+ existence [guid ] = guid in returned_ids
436+
437+ return existence
438+
439+ @classmethod
440+ @validate_arguments
441+ def tml_type_to_metadata_object (cls , tml_type : str ) -> Union [MetadataObject , None ]:
442+ """
443+ Converts a tml type (e.g. "worksheet") to a MetadataObject type, (e.g. MetadataObject.logical_table)
444+ :param tml_type: The TML type, such as None
445+ """
446+ mapping = {
447+ "table" : MetadataObject .logical_table ,
448+ "view" : MetadataObject .logical_table ,
449+ "worksheet" : MetadataObject .logical_table ,
450+ "pinboard" : MetadataObject .pinboard ,
451+ "liveboard" : MetadataObject .pinboard ,
452+ "answer" : MetadataObject .saved_answer ,
453+ }
454+
455+ return mapping .get (tml_type , None )
0 commit comments