def addApplet(new_user, protocolUrl):
    """
    adds an applet for the user, where the user becomes a manager for it.

    inputs
    ------

    new_user: a user oject (from testCreateUser)
    protocolURL: String, a valid URL to an activity set.

    returns
    -------
    applet response object

    """

    currentUser = authenticate(new_user)

    # TODO: create an activity-set that JUST for testing.
    # make sure it has all the weird qualities that can break

    userAppletsToStart = AppletModel().getAppletsForUser('manager',
                                                         currentUser,
                                                         active=True)

    userApplets = userAppletsToStart.copy()

    # for now, lets do the mindlogger demo
    protocol = ProtocolModel().getFromUrl(protocolUrl, 'protocol',
                                          currentUser)[0]
    randomAS = np.random.randint(1000000)
    ar = AppletModel().createAppletFromUrl(
        name="testProtocol{}".format(randomAS),
        protocolUrl=protocolUrl,
        user=currentUser,
        sendEmail=False)

    while len(userApplets) == len(userAppletsToStart):
        nightyNight(sleepInterval)
        userApplets = AppletModel().getAppletsForUser('manager',
                                                      currentUser,
                                                      active=True)

    ar = jsonld_expander.loadCache(userApplets[-1]['cached'])

    assert jsonld_expander.reprolibCanonize(
        ar['protocol']['url']
    ) == jsonld_expander.reprolibCanonize(protocolUrl), \
        'the URLS do not match! {} {}'.format(
            ar['protocol']['url'],
            protocolUrl
        )

    assert ar['applet']['_id'], 'there is no ID!'

    assert getAppletById(new_user,
                         ar) is not None, 'something wrong with getAppletById'
    return ar
示例#2
0
 def getProtocolFromURL(self, url):
     try:
         thisUser = self.getCurrentUser()
         return (jsonld_expander.formatLdObject(
             ProtocolModel().importUrl(url, thisUser), 'protocol',
             thisUser))
     except:
         import sys, traceback
         print(sys.exc_info())
         return ({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)
        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]))
示例#4
0
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]))
示例#5
0
def loadFromSingleFile(document, user):
    if 'protocol' not in document or 'data' not in document['protocol']:
        raise ValidationException(
            'should contain protocol field in the json file.', )
    if 'activities' not in document['protocol']:
        raise ValidationException(
            'should contain activities field in the json file.', )

    contexts = document.get('contexts', {})

    protocol = {'protocol': {}, 'activity': {}, 'screen': {}}

    expandedProtocol = expandObj(contexts, document['protocol']['data'])
    protocol['protocol'][expandedProtocol['@id']] = {
        'expanded': expandedProtocol
    }

    protocolId = None
    for activity in document['protocol']['activities'].values():
        expandedActivity = expandObj(contexts, activity['data'])
        protocol['activity'][expandedActivity['@id']] = {
            'parentKey': 'protocol',
            'parentId': expandedProtocol['@id'],
            'expanded': expandedActivity
        }

        if 'items' not in activity:
            raise ValidationException(
                'should contain at least one item in each activity.', )

        for item in activity['items'].values():
            expandedItem = expandObj(contexts, item)
            protocol['screen'][expandedItem['@id']] = {
                'parentKey': 'activity',
                'parentId': expandedActivity['@id'],
                'expanded': expandedItem
            }

    for modelType in ['protocol', 'activity', 'screen']:
        modelClass = MODELS()[modelType]()
        docCollection = getModelCollection(modelType)

        for model in protocol[modelType].values():
            prefName = modelClass.preferredName(model['expanded'])

            if modelClass.name in ['folder', 'item']:
                docFolder = FolderModel().createFolder(
                    name=prefName,
                    parent=docCollection,
                    parentType='collection',
                    public=True,
                    creator=user,
                    allowRename=True,
                    reuseExisting=(modelType != 'applet'))

                metadata = {modelType: model['expanded']}

                tmp = model
                while tmp.get('parentId', None):
                    key = tmp['parentKey']
                    tmp = protocol[key][tmp['parentId']]
                    metadata['{}Id'.format(key)] = '{}/{}'.format(
                        MODELS()[key]().name, tmp['_id'])

                if modelClass.name == 'folder':
                    newModel = modelClass.setMetadata(docFolder, metadata)
                elif modelClass.name == 'item':
                    newModel = modelClass.setMetadata(
                        modelClass.createItem(
                            name=prefName if prefName else str(
                                len(
                                    list(FolderModel().childItems(
                                        FolderModel().load(docFolder,
                                                           level=None,
                                                           user=user,
                                                           force=True)))) + 1),
                            creator=user,
                            folder=docFolder,
                            reuseExisting=True), metadata)

                # we don't need this in the future because we will only using single-file-format
                modelClass.update({'_id': newModel['_id']},
                                  {'$set': {
                                      'loadedFromSingleFile': True
                                  }})
                if modelType != 'protocol':
                    formatted = _fixUpFormat(
                        formatLdObject(newModel,
                                       mesoPrefix=modelType,
                                       user=user,
                                       refreshCache=False))

                    createCache(newModel, formatted, modelType, user)
                model['_id'] = newModel['_id']

                if modelType == 'protocol':
                    protocolId = newModel['_id']

    return formatLdObject(ProtocolModel().load(protocolId, force=True),
                          mesoPrefix='protocol',
                          user=user,
                          refreshCache=False)
示例#6
0
 def __init__(self):
     super(Protocol, self).__init__()
     self.resourceName = 'protocol'
     self._model = ProtocolModel()
     self.route('GET', (), self.getProtocolFromURL)
     self.route('GET', (':id', ), self.getProtocol)