def loadCache(obj, user=None): if isinstance(obj, dict): if 'applet' in obj: try: obj["applet"]["responseDates"] = responseDateList( obj['applet'].get('_id', '').split('applet/')[-1], user.get('_id'), user ) except: obj["applet"]["responseDates"] = [] return(obj) else: cache = json_util.loads(obj) if 'applet' in cache: try: cache["applet"]["responseDates"] = responseDateList( cache['applet'].get('_id', '').split('applet/')[-1], user.get('_id'), user ) except: cache["applet"]["responseDates"] = [] return( { k: v for k, v in cache.items() if k!="prov:generatedAtTime" } if isinstance(cache, dict) else cache )
def formatLdObject(obj, mesoPrefix='folder', user=None, keepUndefined=False, dropErrors=False, refreshCache=False, responseDates=False): """ Function to take a compacted JSON-LD Object within a Girder for Mindlogger database and return an exapanded JSON-LD Object including an _id. :param obj: Compacted JSON-LD Object :type obj: dict or list :param mesoPrefix: Girder for Mindlogger entity type, defaults to 'folder' if not provided :type mesoPrefix: str :param user: User making the call :type user: User :param keepUndefined: Keep undefined properties :type keepUndefined: bool :param dropErrors: Return `None` instead of raising an error for illegal JSON-LD definitions. :type dropErrors: bool :param refreshCache: Refresh from Dereferencing URLs? :type refreshCache: bool :param responseDates: Include list of ISO date strings of responses :type responseDates: bool :returns: Expanded JSON-LD Object (dict or list) """ from girderformindlogger.models import pluralize refreshCache = False if refreshCache is None else refreshCache try: if obj is None: return (None) if isinstance(obj, dict): oc = obj.get("cached") if all([not refreshCache, oc is not None]): return (loadCache(oc)) if 'meta' not in obj.keys(): return (_fixUpFormat(obj)) mesoPrefix = camelCase(mesoPrefix) if type(obj) == list: return (_fixUpFormat([ formatLdObject(o, mesoPrefix, refreshCache=refreshCache, user=user) for o in obj if o is not None ])) if not type(obj) == dict and not dropErrors: raise TypeError("JSON-LD must be an Object or Array.") newObj = obj.get('meta', obj) newObj = newObj.get(mesoPrefix, newObj) newObj = expand(newObj, keepUndefined=keepUndefined) if type(newObj) == list and len(newObj) == 1: try: newObj = newObj[0] except: raise ValidationException(str(newObj)) if type(newObj) != dict: newObj = {} objID = str(obj.get('_id', 'undefined')) if objID == 'undefined': raise ResourcePathNotFound() newObj['_id'] = "/".join([snake_case(mesoPrefix), objID]) if mesoPrefix == 'applet': protocolUrl = obj.get('meta', {}).get('protocol', obj).get( 'http://schema.org/url', obj.get('meta', {}).get('protocol', obj).get('url')) protocol = ProtocolModel().getFromUrl( protocolUrl, 'protocol', user, thread=False, refreshCache=refreshCache )[0] if protocolUrl is not None else {} protocol = formatLdObject(protocol, 'protocol', user, refreshCache=refreshCache) applet = {} applet['activities'] = protocol.pop('activities', {}) applet['items'] = protocol.pop('items', {}) applet['protocol'] = { key: protocol.get('protocol', protocol.get('activitySet', {})).pop(key) for key in ['@type', '_id', 'http://schema.org/url', 'schema:url', 'url'] if key in list(protocol.get('protocol', {}).keys()) } applet['applet'] = { **protocol.pop('protocol', {}), **obj.get('meta', {}).get(mesoPrefix, {}), '_id': "/".join([snake_case(mesoPrefix), objID]), 'url': "#".join( [obj.get('meta', {}).get('protocol', {}).get("url", "")]) } createCache(obj, applet, 'applet', user) if responseDates: try: applet["applet"]["responseDates"] = responseDateList( obj.get('_id'), user.get('_id'), user) except: applet["applet"]["responseDates"] = [] return (applet) elif mesoPrefix == 'protocol': protocol = {'protocol': newObj, 'activities': {}, "items": {}} activitiesNow = set() itemsNow = set() try: protocol = componentImport(newObj, deepcopy(protocol), user, refreshCache=refreshCache) except: print("636") protocol = componentImport(newObj, deepcopy(protocol), user, refreshCache=True) newActivities = [ a for a in protocol.get('activities', {}).keys() if a not in activitiesNow ] newItems = [ i for i in protocol.get('items', {}).keys() if i not in itemsNow ] while (any([len(newActivities), len(newItems)])): activitiesNow = set(protocol.get('activities', {}).keys()) itemsNow = set(protocol.get('items', {}).keys()) for activityURL in newActivities: activity = protocol['activities'][activityURL] activity = activity.get('meta', {}).get('activity', activity) try: protocol = componentImport(deepcopy(activity), deepcopy(protocol), user, refreshCache=refreshCache) except: print("670") protocol = componentImport(deepcopy(activity), deepcopy(protocol), user, refreshCache=True) for itemURL in newItems: activity = protocol['items'][itemURL] activity = activity.get('meta', {}).get('screen', activity) try: protocol = componentImport(deepcopy(activity), deepcopy(protocol), user, refreshCache=refreshCache) except: print("691") protocol = componentImport(deepcopy(activity), deepcopy(protocol), user, refreshCache=True) newActivities = list( set(protocol.get('activities', {}).keys()) - activitiesNow) newItems = list( set(protocol.get('items', {}).keys()) - itemsNow) return (_fixUpFormat(protocol)) else: return (_fixUpFormat(newObj)) except: if refreshCache == False: return (_fixUpFormat( formatLdObject(obj, mesoPrefix, user, keepUndefined, dropErrors, refreshCache=False, responseDates=responseDates))) import sys, traceback print(sys.exc_info()) print(traceback.print_tb(sys.exc_info()[2]))
def formatLdObject(obj, mesoPrefix='folder', user=None, keepUndefined=False, dropErrors=False, refreshCache=False, responseDates=False): """ Function to take a compacted JSON-LD Object within a Girder for Mindlogger database and return an exapanded JSON-LD Object including an _id. :param obj: Compacted JSON-LD Object :type obj: dict or list :param mesoPrefix: Girder for Mindlogger entity type, defaults to 'folder' if not provided :type mesoPrefix: str :param user: User making the call :type user: User :param keepUndefined: Keep undefined properties :type keepUndefined: bool :param dropErrors: Return `None` instead of raising an error for illegal JSON-LD definitions. :type dropErrors: bool :param refreshCache: Refresh from Dereferencing URLs? :type refreshCache: bool :param responseDates: Include list of ISO date strings of responses :type responseDates: bool :returns: Expanded JSON-LD Object (dict or list) """ from girderformindlogger.models import pluralize refreshCache = False if refreshCache is None else refreshCache try: if obj is None: return (None) if isinstance(obj, dict): oc = obj.get("cached") if all([not refreshCache, oc is not None]): return (loadCache(oc)) if 'meta' not in obj.keys(): return (_fixUpFormat(obj)) mesoPrefix = camelCase(mesoPrefix) if type(obj) == list: return (_fixUpFormat([ formatLdObject(o, mesoPrefix, refreshCache=refreshCache, user=user) for o in obj if o is not None ])) if not type(obj) == dict and not dropErrors: raise TypeError("JSON-LD must be an Object or Array.") newObj = obj.get('meta', obj) newObj = newObj.get(mesoPrefix, newObj) if not obj.get('loadedFromSingleFile', False): newObj = expand(newObj, keepUndefined=keepUndefined) if type(newObj) == list and len(newObj) == 1: try: newObj = newObj[0] except: raise ValidationException(str(newObj)) if type(newObj) != dict: newObj = {} objID = str(obj.get('_id', 'undefined')) if objID == 'undefined': raise ResourcePathNotFound('unable to load object') newObj['_id'] = "/".join([snake_case(mesoPrefix), objID]) if mesoPrefix == 'applet': protocolUrl = obj.get('meta', {}).get('protocol', obj).get( 'http://schema.org/url', obj.get('meta', {}).get('protocol', obj).get('url')) # get protocol data from id protocol = None protocolId = obj.get('meta', {}).get('protocol', {}).get('_id', '').split('/')[-1] if protocolId: cache = ProtocolModel().getCache(protocolId) if cache: protocol = loadCache(cache) if protocolUrl is not None and not protocol: # get protocol from url protocol = ProtocolModel().getFromUrl( protocolUrl, 'protocol', user, thread=False, refreshCache=refreshCache)[0] # format protocol data protocol = formatLdObject(protocol, 'protocol', user, refreshCache=refreshCache) applet = {} applet['activities'] = protocol.pop('activities', {}) applet['items'] = protocol.pop('items', {}) applet['protocol'] = { key: protocol.get('protocol', protocol.get('activitySet', {})).pop(key) for key in ['@type', '_id', 'http://schema.org/url', 'schema:url', 'url'] if key in list(protocol.get('protocol', {}).keys()) } applet['applet'] = { **protocol.pop('protocol', {}), **obj.get('meta', {}).get(mesoPrefix, {}), '_id': "/".join([snake_case(mesoPrefix), objID]), 'url': "#".join( [obj.get('meta', {}).get('protocol', {}).get("url", "")]) } if 'appletName' in obj and obj['appletName']: suffix = obj['appletName'].split('/')[-1] inserted = False candidates = ['prefLabel', 'altLabel'] for candidate in candidates: for key in applet['applet']: if not inserted and str(key).endswith( candidate) and len( applet['applet'][key]) and len( applet['applet'][key][0].get( '@value', '')): if len(suffix): applet['applet'][key][0]['@value'] += (' ' + suffix) if not len(applet['applet'] ['url']): # for development applet['applet'][key][0][ '@value'] += ' ( single-file )' AppletModel().update({'_id': obj['_id']}, { '$set': { 'displayName': applet['applet'][key][0]['@value'] } }) inserted = True createCache(obj, applet, 'applet', user) if responseDates: try: applet["applet"]["responseDates"] = responseDateList( obj.get('_id'), user.get('_id'), user) except: applet["applet"]["responseDates"] = [] return (applet) elif mesoPrefix == 'protocol': protocol = {'protocol': newObj, 'activities': {}, "items": {}} if obj.get('loadedFromSingleFile', False): activities = list(ActivityModel().find({ 'meta.protocolId': '{}/{}'.format(MODELS()['protocol']().name, obj['_id']) })) items = list(ScreenModel().find({ 'meta.protocolId': '{}/{}'.format(MODELS()['protocol']().name, obj['_id']) })) for activity in activities: formatted = formatLdObject(activity, 'activity', user) protocol['activities'][formatted['@id']] = formatted for item in items: formatted = formatLdObject(item, 'screen', user) protocol['items'][formatted['@id']] = formatted else: try: protocol = componentImport(newObj, deepcopy(protocol), user, refreshCache=refreshCache) except: print("636") protocol = componentImport(newObj, deepcopy(protocol), user, refreshCache=True) newActivities = protocol.get('activities', {}).keys() newItems = protocol.get('items', {}).keys() while (any([len(newActivities), len(newItems)])): activitiesNow = set(protocol.get('activities', {}).keys()) itemsNow = set(protocol.get('items', {}).keys()) for activityURL in newActivities: activity = protocol['activities'][activityURL] activity = activity.get('meta', {}).get('activity', activity) try: protocol = componentImport( deepcopy(activity), deepcopy(protocol), user, refreshCache=refreshCache) except: print("670") protocol = componentImport(deepcopy(activity), deepcopy(protocol), user, refreshCache=True) for itemURL in newItems: activity = protocol['items'][itemURL] activity = activity.get('meta', {}).get('screen', activity) try: protocol = componentImport( deepcopy(activity), deepcopy(protocol), user, refreshCache=refreshCache) except: print("691") protocol = componentImport(deepcopy(activity), deepcopy(protocol), user, refreshCache=True) newActivities = list( set(protocol.get('activities', {}).keys()) - activitiesNow) newItems = list( set(protocol.get('items', {}).keys()) - itemsNow) formatted = _fixUpFormat(protocol) createCache(obj, formatted, 'protocol') return formatted else: return (_fixUpFormat(newObj)) except: if refreshCache == False: return (_fixUpFormat( formatLdObject(obj, mesoPrefix, user, keepUndefined, dropErrors, refreshCache=True, responseDates=responseDates))) import sys, traceback print(sys.exc_info()) print(traceback.print_tb(sys.exc_info()[2]))
def getOwnApplets( self, role, ids_only=False, unexpanded=False, refreshCache=False ): from bson.objectid import ObjectId from girderformindlogger.utility.jsonld_expander import loadCache from girderformindlogger.utility.response import responseDateList reviewer = self.getCurrentUser() if reviewer is None: raise AccessException("You must be logged in to get user applets.") role = role.lower() if role not in USER_ROLES.keys(): raise RestException( 'Invalid user role.', 'role' ) applet_ids = reviewer.get('applets', {}).get(role, []) if ids_only: return applet_ids applets = [AppletModel().load(ObjectId(applet_id), AccessType.READ) for applet_id in applet_ids] if unexpanded: return([{ 'applet': AppletModel().unexpanded(applet) } for applet in applets]) try: result = [] for applet in applets: if applet.get('cached'): formatted = { **jsonld_expander.formatLdObject( applet, 'applet', reviewer, refreshCache=refreshCache, responseDates=False ), "users": AppletModel().getAppletUsers(applet, reviewer), "groups": AppletModel().getAppletGroups( applet, arrayOfObjects=True ) } if role in ["coordinator", "manager"] else { **jsonld_expander.formatLdObject( applet, 'applet', reviewer, refreshCache=refreshCache, responseDates=(role=="user") ), "groups": [ group for group in AppletModel().getAppletGroups(applet).get( role ) if ObjectId( group ) in [ *reviewer.get('groups', []), *reviewer.get('formerGroups', []), *[invite['groupId'] for invite in [ *reviewer.get('groupInvites', []), *reviewer.get('declinedInvites', []) ]] ] ] } try: formatted["applet"]["responseDates"] = responseDateList( applet.get('_id'), reviewer.get('_id'), reviewer ) except: formatted["applet"]["responseDates"] = [] result.append(formatted) return(result) except: import sys, traceback print(sys.exc_info()) return([])