示例#1
0
def get_collections(request):
    """
    Retrieve collections for which the current user has VIEW access.
    """
    return authorization.apply_filter(CollectionAuthorization.VIEW,
                                      request.user,
                                      Collection.objects.all())
示例#2
0
def get_collection_containers(user, collection):
    """
    Yield containers recursively for the supplied collection object.
    """
    containers = auth.apply_filter(
        ResourceAuthorization.VIEW, user,
        ResourceContainer.active.filter(part_of=collection.id))
    for container in containers:
        yield container

    subcollections = auth.apply_filter(
        CollectionAuthorization.VIEW, user,
        Collection.objects.filter(part_of=collection.id, hidden=False))
    for subcollection in subcollections:
        for container in get_collection_containers(user, subcollection):
            yield container
示例#3
0
def entity_merge(request):
    """
    User can merge selected entities.
    """

    entity_ids = request.GET.getlist('entity', [])
    if len(entity_ids) <= 1:
        raise ValueError('')

    qs = ConceptEntity.objects.filter(pk__in=entity_ids)
    qs = auth.apply_filter(ResourceAuthorization.EDIT, request.user, qs)
    # q = auth.get_auth_filter('merge_conceptentities', request.user)
    if qs.count() < 2:
        # TODO: make this pretty and informative.
        return HttpResponseForbidden('Only the owner can do that')

    if request.GET.get('confirm', False) == 'true':
        master_id = request.GET.get('master', None)
        if master_id is not None:
            master = operations.merge_conceptentities(qs,
                                                      master_id,
                                                      user=request.user)
            return HttpResponseRedirect(
                reverse('entity-details', args=(master.id, )))

    context = {
        'entities': qs,
    }
    template = 'entity_merge.html'
    return render(request, template, context)
示例#4
0
 def to_internal_value(self, data):
     request = self.context['request']
     collection = authorization.apply_filter(
         *(CollectionAuthorization.ADD, request.user,
           cookies.models.Collection.objects.filter(
               name=data).order_by('name')))
     if len(collection) < 1:
         raise ValidationError('Collection doesn\'t exist')
     return collection[0]
示例#5
0
def bulk_add_tag_to_resource(request):
    """
    Adding tag to selected resources.
    """
    next_page = request.GET.get('next')
    if request.method == 'GET':
        resource_ids = request.GET.getlist('resource', [])
        resources = auth.apply_filter(
            ResourceAuthorization.EDIT, request.user,
            Resource.objects.filter(pk__in=resource_ids))

        form = AddTagForm()
        form.fields['resources'].queryset = resources
        form.fields['resources'].initial = resources

    elif request.method == 'POST':
        form = AddTagForm(request.POST)
        resource_ids = eval(request.POST.get('resources', '[]'))
        resources = auth.apply_filter(
            ResourceAuthorization.EDIT, request.user,
            Resource.objects.filter(pk__in=resource_ids))

        if form.is_valid():
            tag = form.cleaned_data.get('tag', None)
            tag_name = form.cleaned_data.get('tag_name', None)

            resources = form.cleaned_data.get('resources')
            if tag:  # Don't add the same tag to a resource twice.
                resources = resources.filter(~Q(tags__tag__id=tag.id))
            elif tag_name:
                tag = Tag.objects.create(name=tag_name,
                                         created_by=request.user)

            ResourceTag.objects.bulk_create([
                ResourceTag(resource=resource,
                            tag=tag,
                            created_by=request.user) for resource in resources
            ])
            if next_page:
                return HttpResponseRedirect(next_page)
            return HttpResponseRedirect(reverse('resources'))
    context = {'form': form, 'resources': resources, 'next_page': next_page}
    template = 'add_tag_to_resource.html'
    return render(request, template, context)
示例#6
0
 def listSets(self):
     """
     Generate a list of resource set identifiers.
     """
     # The closest thing that we have to a concept of a "set" is our
     #  ``Collection`` model.
     # TODO: verify that OAIPMH wants int identifiers here, and not URIs.
     qs = Collection.active.all()
     qs = auth.apply_filter(CollectionAuthorization.VIEW, self.user, qs)
     return map(unicode, qs.values_list('id', flat=True))
示例#7
0
def collection_list(request):
    queryset = Collection.objects.filter(content_resource=False, hidden=False)
    queryset = authorization.apply_filter(request.user, 'view_resource',
                                          queryset)
    filtered_objects = CollectionFilter(request.GET, queryset=queryset)
    context = RequestContext(request, {
        'filtered_objects': filtered_objects,
    })
    template = loader.get_template('collections.html')

    return HttpResponse(template.render(context))
示例#8
0
def filter_relations(source=None,
                     predicate=None,
                     target=None,
                     qs=Relation.objects.all(),
                     user=None):
    """
    Filter a :class:`.Relation` queryset by source, predicate, and/or object.

    Parameters
    ----------
    source
    predicate
    target

    Returns
    -------
    :class:`django.db.models.query.QuerySet`
    """
    if user and not user.is_superuser:
        qs = authorization.apply_filter(user, 'view_relation', qs)

    for field, qfield, value in [('source', 'source_instance_id', source),
                                 ('target', 'target_instance_id', target)]:
        if value is not None:
            if type(value) is ConceptEntity:
                qs.filter(**{
                    '%s_instance_id': value.id,
                    '%s_type': entity_type
                })
            elif type(value) in [str, unicode]:
                if value.startswith('http'):  # Treat as a URI.
                    qs = filter_by_generic_with_uri(field, value, qs=qs)
                else:
                    qs = filter_by_generic_with_name(field, value, qs=qs)
            else:
                qs = qs.filter(qfield=getattr(value, 'id', value))

    if predicate is not None:
        if type(predicate) in [str, unicode]:
            if predicate.startswith('http'):  # Treat as a URI.
                qs = qs.filter(predicate__uri=predicate)
            else:
                qs = qs.filter(predicate__name__icontains=predicate)
        else:
            qs = qs.filter(predicate=getattr(predicate, 'id', predicate))

    try:
        _states = qs.distinct('id')
        bool(_states)  # Force evaluation... oh I don't know.
        return _states
    except NotImplementedError:
        return qs
示例#9
0
def entity_list(request):
    template = loader.get_template('entity_list.html')
    qs = authorization.apply_filter(request.user, 'view_entity',
                                    ConceptEntity.objects.all())
    filtered_objects = ConceptEntityFilter(request.GET, queryset=qs)

    context = RequestContext(
        request,
        {
            'user_can_edit': request.user.is_staff,  # TODO: change this!
            'filtered_objects': filtered_objects,
        })
    return HttpResponse(template.render(context))
示例#10
0
def _change_state(request, form_data, filtered_objects):
    if form_data.get('apply_type') == GilesLogForm.APPLY_ALL:
        resources = filtered_objects.qs
    else:
        resources = form_data.get('resources')

    auth_resources = auth.apply_filter(ResourceAuthorization.EDIT,
                                       request.user, resources)

    count_resources = resources.count()
    count_success = 0
    if auth_resources.count() > 0:
        count_success = auth_resources.update(state=form_data['desired_state'])
    return (count_success, count_resources - count_success)
示例#11
0
def create_resource_details(request, content_id):
    content_resource = get_object_or_404(Resource, pk=content_id)
    context = RequestContext(request, {})
    if request.method == 'GET':
        form = UserResourceForm(
            initial={
                'name': content_resource.name,
                'uri': content_resource.location,
                'public':
                True,  # If the resource is already online, it's public.
            })
        form.fields['collection'].queryset = authorization.apply_filter(
            *(request.user, 'change_collection',
              form.fields['collection'].queryset))
        # It wouldn't mean much for the user to indicate that the resource was
        #  non-public, given that we are accessing it over a public connection.
        # form.fields['public'].widget.attrs.update({'disabled': True})
    elif request.method == 'POST':
        form = UserResourceForm(request.POST)
        if form.is_valid():
            resource_data = copy.copy(form.cleaned_data)
            resource_data['entity_type'] = resource_data.pop(
                'resource_type', None)
            collection = resource_data.pop('collection', None)
            resource_data['created_by'] = request.user
            resource = Resource.objects.create(**resource_data)
            operations.add_creation_metadata(resource, request.user)
            content_relation = ContentRelation.objects.create(
                **{
                    'for_resource': resource,
                    'content_resource': content_resource,
                    'content_type': content_resource.content_type,
                })

            if collection:
                collection.resources.add(resource)
                collection.save()

            return HttpResponseRedirect(
                reverse('resource', args=(resource.id, )))

    context.update({
        'form': form,
        'content_resource': content_resource,
    })

    template = loader.get_template('create_resource_details.html')

    return HttpResponse(template.render(context))
示例#12
0
def resource_list(request):
    # Either the resource is public, or owned by the requesting user.
    qset_resources = Resource.objects.filter(content_resource=False,
                                             is_part=False,
                                             hidden=False)

    qset_resources = authorization.apply_filter(request.user, 'view_resource',
                                                qset_resources)
    predicate_ids = request.GET.getlist('predicate')
    target_ids = request.GET.getlist('target')
    target_type_ids = request.GET.getlist('target_type')
    if predicate_ids and target_ids and target_type_ids:
        for p, t, y in zip(predicate_ids, target_ids, target_type_ids):
            qset_resources = qset_resources.filter(
                relations_from__predicate_id=p,
                relations_from__target_instance_id=t,
                relations_from__target_type_id=y)
    # For now we use filters to achieve search functionality. At some point we
    #  should use a real search backend.
    #
    # TODO: implement a real search backend.
    filtered_objects = ResourceFilter(request.GET, queryset=qset_resources)
    qset_collections = Collection.objects.filter(
        Q(content_resource=False) & Q(hidden=False))
    qset_collections = authorization.apply_filter(request.user,
                                                  'view_collection',
                                                  qset_collections)
    collections = CollectionFilter(request.GET, queryset=qset_collections)

    context = RequestContext(request, {
        'filtered_objects': filtered_objects,
        'collections': collections
    })

    template = loader.get_template('resources.html')
    return HttpResponse(template.render(context))
示例#13
0
def collection(request, obj_id):
    collection = _get_collection_by_id(request, obj_id)
    resources = collection.resources.filter(content_resource=False,
                                            hidden=False)
    resources = authorization.apply_filter(request.user, 'view_resource',
                                           resources)
    filtered_objects = ResourceFilter(request.GET, queryset=resources)

    context = RequestContext(
        request, {
            'filtered_objects': filtered_objects,
            'collection': collection,
            'request': request,
        })
    template = loader.get_template('collection.html')
    return HttpResponse(template.render(context))
示例#14
0
def resource(request, obj_id):
    resource = _get_resource_by_id(request, obj_id)
    context = {
        'resource':
        resource,
        'request':
        request,
        'part_of':
        authorization.apply_filter(request.user, 'view_resource',
                                   resource.part_of.all())
    }
    if request.GET.get('format', None) == 'json':
        return JsonResponse(
            ResourceDetailSerializer(
                context=context).to_representation(resource))
    return render(request, 'resource.html', context)
示例#15
0
    def get_queryset(self):
        """
        Extended to provide authorization filtering.
        """
        qs = super(ResourceViewSet, self).get_queryset()
        qs = authorization.apply_filter(self.request.user, 'view_resource', qs)

        if not self.kwargs.get('pk', None):
            qs = qs.filter(content_resource=False)
        uri = self.request.query_params.get('uri', None)
        if uri:
            qs = qs.filter(uri=uri)

        query = self.request.query_params.get('search', None)
        if query:
            qs = qs.filter(name__icontains=query)
        return qs
示例#16
0
def collection_list(request):
    """
    Display the set of collections
    """

    queryset = Collection.objects.filter(content_resource=False,
                                         hidden=False,
                                         part_of__isnull=True)

    queryset = auth.apply_filter(ResourceAuthorization.VIEW, request.user,
                                 queryset)
    filtered_objects = CollectionFilter(request.GET, queryset=queryset)
    context = {
        'filtered_objects': filtered_objects,
    }

    return render(request, 'collections.html', context)
示例#17
0
def resource_list(request):
    """
    Display all :class:`.Resource` instances to which the user has access.
    """

    resources = auth.apply_filter(ResourceAuthorization.VIEW, request.user,
                                  ResourceContainer.active.all())

    predicate_ids = request.GET.getlist('predicate')
    target_ids = request.GET.getlist('target')
    target_type_ids = request.GET.getlist('target_type')

    if predicate_ids and target_ids and target_type_ids:
        for p, t, y in zip(predicate_ids, target_ids, target_type_ids):
            resources = resources.filter(
                primary__relations_from__predicate_id=p,
                primary__relations_from__target_instance_id=t,
                primary__relations_from__target_type_id=y)
    # For now we use filters to achieve search functionality. At some point we
    #  should use a real search backend.
    #
    # TODO: implement a real search backend.

    params = QueryDict(request.GET.urlencode(), mutable=True)
    if 'page' in params:
        del params['page']
    filter_parameters = urlquote_plus(params.urlencode())
    filtered_resources = ResourceContainerFilter(request.GET,
                                                 queryset=resources)

    # The following statement results in an expensive Postgres Query.
    # Disable tags in this view for now.
    # tags = filtered_resources.qs.order_by('primary__tags__tag__id')\
    #         .values_list('primary__tags__tag__id', 'primary__tags__tag__name')\
    #         .distinct('primary__tags__tag__id')

    context = {
        'filtered_objects': filtered_resources,
        # 'tags': filter(lambda tag: tag[0] is not None, tags),
        'q': request.GET.get('name'),
        'filter_parameters': filter_parameters,
        'resource_count': filtered_resources.qs.count()
    }
    return render(request, 'resources.html', context)
示例#18
0
def entity_list(request):
    """
    List view for :class:`.ConceptEntity`\.
    """
    qs = ConceptEntity.active.all()
    qs = qs.filter(
        Q(identities__id__isnull=True)
        | Q(represents__isnull=False)).distinct('id')
    qs = auth.apply_filter(ResourceAuthorization.VIEW, request.user, qs)

    filtered_objects = ConceptEntityFilter(request.GET,
                                           queryset=qs,
                                           request=request)

    context = {
        'user_can_edit': request.user.is_staff,  # TODO: change this!
        'filtered_objects': filtered_objects,
    }
    return render(request, 'entity_list.html', context)
示例#19
0
    def _get_resources(self, setSpec=None, from_=None, until=None, cursor=0,
                       batch_size=10, **kwargs):
        qs = ResourceContainer.objects.filter(primary__is_deleted=False)
        qs = auth.apply_filter(ResourceAuthorization.VIEW, self.user, qs)

        if setSpec is None:
            setSpec = kwargs.get('set', None)
        if setSpec is not None:
            qs = qs.filter(part_of__id=setSpec)

        if from_ is not None and until is not None:
            if from_ > until:
                raise BadArgumentError('``from`` cannot be later than ``until``')

        if from_ is not None:
            qs = qs.filter(created__gte=from_)
        if until is not None:
            qs = qs.filter(created__lte=until)

        return qs.order_by('created')[cursor:cursor+batch_size]
示例#20
0
    def get_queryset(self):
        """
        Extended to provide authorization filtering.
        """
        qs = super(ResourceViewSet, self).get_queryset()
        qs = authorization.apply_filter(ResourceAuthorization.VIEW,
                                        self.request.user, qs)

        if not self.kwargs.get('pk', None):
            uri = self.request.query_params.get('uri', None)
            if uri:
                qs = qs.filter(
                    Q(uri=uri, content_resource=False)
                    | Q(content__content_resource__uri=uri))
            else:
                qs = qs.filter(content_resource=False).filter(
                    is_primary_for__isnull=False)

        query = self.request.query_params.get('search', None)
        if query:
            qs = qs.filter(name__icontains=query)

        related = self.request.query_params.get('related', None)

        if related:
            entities = ConceptEntity.objects.filter(concept__uri=related)\
                .values_list('id', flat=True)

            entity_ctype = ContentType.objects.get_for_model(ConceptEntity)
            q = Q(relations_from__target_type=entity_ctype,
                  relations_from__target_instance_id__in=entities)
            q |= Q(relations_to__source_type=entity_ctype,
                   relations_to__source_instance_id__in=entities)
            qs = qs.filter(q)

        content_type = self.request.query_params.get('content_type')
        if content_type:
            qs = qs.filter(
                Q(content__content_resource__content_type=content_type))
        return qs
示例#21
0
def entity_merge(request):
    entity_ids = request.GET.getlist('entity', [])
    if len(entity_ids) <= 1:
        raise ValueError('')

    qs = ConceptEntity.objects.filter(pk__in=entity_ids)
    qs = authorization.apply_filter(request.user, 'change_conceptentity', qs)
    # q = authorization.get_auth_filter('merge_conceptentities', request.user)
    if qs.count() < 2:
        # TODO: make this pretty and informative.
        return HttpResponseForbidden('Only the owner can do that')

    if request.GET.get('confirm', False) == 'true':
        master_id = request.GET.get('master', None)
        master = operations.merge_conceptentities(qs, master_id)
        return HttpResponseRedirect(
            reverse('entity-details', args=(master.id, )))

    context = RequestContext(request, {
        'entities': qs,
    })
    template = loader.get_template('entity_merge.html')
    return HttpResponse(template.render(context))
示例#22
0
def create_resource_details(request, content_id):
    content_resource = get_object_or_404(Resource, pk=content_id)
    context = {}
    if request.method == 'GET':
        form = UserResourceForm(
            initial={
                'name': content_resource.name,
                'uri': content_resource.location,
                'collection': content_resource.container.part_of,
                'public':
                True,  # If the resource is already online, it's public.
            })
        form.fields['collection'].queryset = auth.apply_filter(
            *(CollectionAuthorization.ADD, request.user,
              form.fields['collection'].queryset))
        # It wouldn't mean much for the user to indicate that the resource was
        #  non-public, given that we are accessing it over a public connection.
        # form.fields['public'].widget.attrs.update({'disabled': True})
    elif request.method == 'POST':
        form = UserResourceForm(request.POST)
        if form.is_valid():
            resource_data = copy.copy(form.cleaned_data)
            with transaction.atomic():
                resource = _create_resource_details(request, content_resource,
                                                    resource_data,
                                                    Resource.INTERFACE_WEB)
            return HttpResponseRedirect(
                reverse('resource', args=(resource.id, )))

    context.update({
        'form': form,
        'content_resource': content_resource,
    })

    template = 'create_resource_details.html'

    return render(request, template, context)
示例#23
0
def resource_merge(request):
    """
    Curator can merge resources.
    """
    resource_ids = request.GET.getlist('resource', [])
    if len(resource_ids) <= 1:
        raise ValueError('Need more than one resource')

    qs = Resource.objects.filter(pk__in=resource_ids)
    qs = auth.apply_filter(ResourceAuthorization.EDIT, request.user, qs)
    if qs.count() == 0:
        # TODO: make this pretty and informative.
        return HttpResponseForbidden('Only the owner can do that')

    if request.GET.get('confirm', False) == 'true':
        master_id = request.GET.get('master', None)
        master = operations.merge_resources(qs, master_id, user=request.user)
        return HttpResponseRedirect(master.get_absolute_url())

    context = {
        'resources': qs,
    }
    template = 'resource_merge.html'
    return render(request, template, context)
示例#24
0
def create_snapshot_async(self,
                          dataset_id,
                          snapshot_id,
                          export_structure,
                          job=None):
    if job:
        job.result_id = self.request.id
        job.save()

    logging.debug(
        'tasks.create_snapshot_async with dataset %i and snapshot %i' %
        (dataset_id, snapshot_id))
    dataset = Dataset.objects.get(pk=dataset_id)
    snapshot = DatasetSnapshot.objects.get(pk=snapshot_id)

    user = snapshot.created_by
    if dataset.dataset_type == Dataset.EXPLICIT:
        containers = authorization.apply_filter(ResourceAuthorization.VIEW,
                                                user, dataset.resources.all())
        collections = Collection.objects.none()
    else:
        collections, containers = apply_dataset_filters(
            user, dataset.filter_parameters)

    snapshot.state = DatasetSnapshot.IN_PROGRESS
    snapshot.save()

    methods = {
        'flat': aggregate.export_zip,
        'collection': aggregate.export_with_collection_structure,
        'parts': aggregate.export_with_resource_structure,
    }

    with transaction.atomic():
        now = timezone.now().strftime('%Y-%m-%d-%H-%m-%s')
        fname = 'dataset-%s-%s.zip' % (slugify(dataset.name), now)
        target_path = os.path.join(settings.MEDIA_ROOT, 'upload', fname)
        object_iterator = chain(
            containers, (container for collection in collections
                         for container in aggregate.get_collection_containers(
                             user, collection)))
        if snapshot.has_content:
            methods[export_structure](
                (obj.primary for obj in object_iterator if obj.primary),
                target_path,
                content_type=snapshot.content_type.split(','),
                has_metadata=snapshot.has_metadata,
            )
        else:
            aggregate.export_metadata(
                (obj.primary for obj in object_iterator if obj.primary),
                target_path,
            )

        container = ResourceContainer.objects.create(
            created_by=snapshot.created_by)
        resource = Resource.objects.create(
            name='Snapshot for dataset %s, %s' % (dataset.name, now),
            created_by=snapshot.created_by,
            container=container,
            entity_type=Type.objects.get_or_create(
                uri='http://dbpedia.org/ontology/File')[0],
        )
        container.primary = resource
        container.save()
        content = Resource.objects.create(
            name='Snapshot for dataset %s, %s' % (dataset.name, now),
            content_resource=True,
            entity_type=Type.objects.get_or_create(
                uri='http://dbpedia.org/ontology/File')[0],
            created_by=snapshot.created_by,
            container=container,
            content_type='application/zip')
        ContentRelation.objects.create(for_resource=resource,
                                       content_resource=content,
                                       content_type='application/zip',
                                       created_by=snapshot.created_by,
                                       container=container)
        logging.debug('tasks.create_snapshot_async: export to %s' %
                      (target_path))
        with open(target_path, 'r') as f:
            archive = File(f)
            content.file = archive
            content.save()
        logging.debug('tasks.create_snapshot_async: export complete')
        snapshot.resource = resource
        snapshot.state = DatasetSnapshot.DONE
        snapshot.save()
    if job:
        job.result = jsonpickle.encode({'view': 'resource', 'id': resource.id})
        job.save()
示例#25
0
def handle_bulk(self,
                file_path,
                form_data,
                file_name,
                job=None,
                ingester='cookies.accession.zotero.ZoteroIngest'):
    """
    Process resource data in a RDF document.

    Parameters
    ----------
    file_path : str
        Local path to a RDF document, or a ZIP file containing a Zotero RDF
        export (with files).
    form_data : dict
        Valid data from a :class:`cookies.forms.BulkResourceForm`\.
    file_name : str
        Name of the target file at ``file_path``\.
    job : :class:`.UserJob`
        Used to update progress.
    """
    if job:
        job.result_id = self.request.id
        job.save()

    logger.debug('handle bulk')
    creator = form_data.pop('created_by')

    # The user can either add these new records to an existing collection, or
    #  create a new one.
    collection = form_data.pop('collection', None)
    collection_name = form_data.pop('name', None)
    if not collection:
        collection = Collection.objects.create(**{
            'name': collection_name,
            'created_by': creator,
        })

    operations.add_creation_metadata(collection, creator)

    # User can indicate a default Type to assign to each new Resource.
    default_type = form_data.pop('default_type', None)
    ingester = IngesterFactory().get(ingester)(file_path)
    ingester.Resource = authorization.apply_filter(creator, 'change_resource',
                                                   ingester.Resource)
    ingester.Collection = authorization.apply_filter(creator,
                                                     'change_collection',
                                                     ingester.Collection)
    ingester.ConceptEntity = authorization.apply_filter(
        creator, 'change_conceptentity', ingester.ConceptEntity)
    ingester.set_resource_defaults(entity_type=default_type,
                                   created_by=creator,
                                   **form_data)

    N = len(ingester)
    for resource in ingester:
        collection.resources.add(resource)
        operations.add_creation_metadata(resource, creator)
        authorization.update_authorizations(Resource.DEFAULT_AUTHS,
                                            creator,
                                            resource,
                                            propagate=True)
        if job:
            job.progress += 1. / N
            job.save()
    job.result = jsonpickle.encode({'view': 'collection', 'id': collection.id})
    job.save()

    return {'view': 'collection', 'id': collection.id}
示例#26
0
 def get_queryset(self, *args, **kwargs):
     qs = super(CollectionViewSet, self).get_queryset(*args, **kwargs)
     return authorization.apply_filter(self.request.user, 'view_resource',
                                       qs)
示例#27
0
def entity_details(request, entity_id):
    entity = _get_entity_by_id(request, entity_id)
    template = 'entity_details.html'
    if entity.identities.count() == 0:
        qs = ConceptEntity.objects.all()
        qs = auth.apply_filter(ResourceAuthorization.VIEW, request.user, qs)
        similar_entities = entities.suggest_similar(entity, qs=qs)
    else:
        similar_entities = []

    entity_ctype = ContentType.objects.get_for_model(ConceptEntity)

    # Aggregate all relations for this entity and any subordinate entities.
    #  A subordinate entity is one that belongs to an Identity instance for
    #  which this (current) entity is the representative.
    subordinate = list(entity.represents.values_list('entities__id',
                                                     flat=True))
    query = Q(source_type=entity_ctype, source_instance_id=entity_id)\
            | Q(source_type=entity_ctype, source_instance_id__in=subordinate)
    relations_from = Relation.objects.filter(query).order_by('predicate')
    relations_from = auth.apply_filter(ResourceAuthorization.VIEW,
                                       request.user, relations_from)
    # TODO: seems like we could use aggregation/annotation here.
    _by_target = lambda r: r.target.name
    relations_from = [(predicate, [
        (target_name, len([rel for rel in rels]))
        for target_name, rels in groupby(sorted(relations, key=_by_target),
                                         key=_by_target)
    ]) for predicate, relations in groupby(relations_from,
                                           key=lambda r: r.predicate)]

    relations_to_qs = Relation.objects.filter(
        Q(target_type=entity_ctype, target_instance_id=entity_id)
        | Q(target_type=entity_ctype,
            target_instance_id__in=list(
                entity.represents.values_list('entities__id', flat=True)))
    ).order_by('predicate')
    relations_to_qs = auth.apply_filter(ResourceAuthorization.VIEW,
                                        request.user, relations_to_qs)
    predicates = relations_to_qs.order_by().distinct('predicate_id').values(
        'predicate_id', 'predicate__uri', 'predicate__name')
    relations_to = []
    for predicate in predicates:
        qs = relations_to_qs.filter(predicate_id=predicate['predicate_id'])
        relations_to.append((predicate, qs.count(), qs[:5]))

    # relations_to = [(predicate, [rel for rel in relations]) for predicate, relations in groupby(relations_to, key=lambda r: r.predicate)]

    represents = entity.represents.values_list(
        'entities__id', 'entities__name',
        'entities__container__primary__name').distinct('entities__id')
    represented_by = entity.identities.filter(~Q(
        representative=entity)).values_list(
            'representative_id',
            'representative__name').distinct('representative_id')

    context = {
        'user_can_edit': request.user.is_staff,  # TODO: change this!
        'entity': entity,
        'similar_entities': similar_entities,
        'entity_type': ContentType.objects.get_for_model(ConceptEntity),
        'relations_from': relations_from,
        'relations_to': relations_to,
        'represents': represents,
        'represented_by': represented_by
    }
    return render(request, template, context)
示例#28
0
def handle_bulk(self,
                file_path,
                form_data,
                file_name,
                job=None,
                ingester='cookies.accession.zotero.ZoteroIngest'):
    """
    Process resource data in a RDF document.

    Parameters
    ----------
    file_path : str
        Local path to a RDF document, or a ZIP file containing a Zotero RDF
        export (with files).
    form_data : dict
        Valid data from a :class:`cookies.forms.BulkResourceForm`\.
    file_name : str
        Name of the target file at ``file_path``\.
    job : :class:`.UserJob`
        Used to update progress.
    """
    if job:
        job.result_id = self.request.id
        job.save()

    logger.debug('handle bulk')
    creator = form_data.pop('created_by')

    # The user can either add these new records to an existing collection, or
    #  create a new one.
    collection = form_data.pop('collection', None)
    collection_name = form_data.pop('name', None)
    public_policy = False
    if not collection:
        collection = Collection.objects.create(**{
            'name': collection_name,
            'created_by': creator,
        })
        operations.add_creation_metadata(collection, creator)
        if form_data.get('public'):
            #  Create an authoirzation for AnonymousUser.
            CollectionAuthorization.objects.create(
                granted_by=creator,
                granted_to=None,
                for_resource=collection,
                policy=CollectionAuthorization.ALLOW,
                action=CollectionAuthorization.VIEW)
            public_policy = True

    # User can indicate a default Type to assign to each new Resource.
    default_type = form_data.pop('default_type', None)
    upload_resource = Resource.objects.create(
        created_by=creator,
        name=file_name,
    )
    with open(file_path, 'r') as f:
        upload_resource.file.save(file_name, File(f), True)

    ingester = IngesterFactory().get(ingester)(upload_resource.file.path)
    ingester.Resource = authorization.apply_filter(ResourceAuthorization.EDIT,
                                                   creator, ingester.Resource)
    ingester.Collection = authorization.apply_filter(
        ResourceAuthorization.EDIT, creator, ingester.Collection)
    ingester.ConceptEntity = authorization.apply_filter(
        ResourceAuthorization.EDIT, creator, ingester.ConceptEntity)
    ingester.set_resource_defaults(entity_type=default_type,
                                   collection=collection,
                                   created_by=creator,
                                   **form_data)
    ingester.set_collection(collection)

    N = len(ingester)
    resource_auths = []
    for resource in ingester:
        resource.container.part_of = collection
        if form_data.get('public') and not public_policy:
            resource_auths.append(
                ResourceAuthorization(granted_by=creator,
                                      granted_to=None,
                                      for_resource=resource.container,
                                      policy=ResourceAuthorization.ALLOW,
                                      action=ResourceAuthorization.VIEW))
        resource.container.save()
        # collection.resources.add(resource)
        operations.add_creation_metadata(resource, creator)

        if job:
            job.progress += 1. / N
            job.save()
    ResourceAuthorization.objects.bulk_create(resource_auths)
    job.result = jsonpickle.encode({'view': 'collection', 'id': collection.id})
    job.save()

    return {'view': 'collection', 'id': collection.id}