Ejemplo n.º 1
0
    def test_get_resource_types(self):
        # first time gets them anew
        self.assertListEqual(
            [GenericResource],
            utils.get_resource_types(),
            msg="Resource types was more than just [GenericResource]")

        # second time gets cached instances
        self.assertListEqual(
            [GenericResource],
            utils.get_resource_types(),
            msg="Resource types was more than just [GenericResource] using cached resource types")
Ejemplo n.º 2
0
def sitemap(request):
    resource_types = ((rt.__name__, {
        "resources":
        rt.objects.filter(
            Q(raccess__public=True) | Q(raccess__discoverable=True)),
    }) for rt in get_resource_types())
    return render(request, "sitemap.html", {
        "resource_types": resource_types,
    })
Ejemplo n.º 3
0
def sitemap(request):
    resource_types = (
        (rt.__name__, {
            "resources": rt.objects.filter(Q(raccess__public=True) | Q(raccess__discoverable=True)),
        })
        for rt in get_resource_types()
    )
    return render(request, "sitemap.html", {
        "resource_types": resource_types,
    })
Ejemplo n.º 4
0
def check_resource_type(resource_type):
    """
    internally used method to check the resource type

    Parameters:
    resource_type: the resource type string to check
    Returns:  the resource type class matching the resource type string; if no match is found, returns None
    """
    for tp in get_resource_types():
        if resource_type == tp.__name__:
            res_cls = tp
            break
    else:
        raise NotImplementedError("Type {resource_type} does not exist".format(resource_type=resource_type))
    return res_cls
Ejemplo n.º 5
0
def get_SupportedResTypes_choices():
    """
    This function harvests all existing resource types in system,
    and puts them in a list (except for WebApp (ToolResource) Resource type):
    [
        ["RESOURCE_CLASS_NAME_1", "RESOURCE_VERBOSE_NAME_1"],
        ["RESOURCE_CLASS_NAME_2", "RESOURCE_VERBOSE_NAME_2"],
        ...
        ["RESOURCE_CLASS_NAME_N", "RESOURCE_VERBOSE_NAME_N"],
    ]
    """

    result_list = []
    res_types_list = get_resource_types()
    for r_type in res_types_list:
        class_name = r_type.__name__
        verbose_name = r_type._meta.verbose_name
        if "toolresource" != class_name.lower():
            result_list.append([class_name, verbose_name])
    return result_list
Ejemplo n.º 6
0
def get_SupportedResTypes_choices():
    """
    This function harvests all existing resource types in system,
    and puts them in a list (except for WebApp (ToolResource) Resource type):
    [
        ["RESOURCE_CLASS_NAME_1", "RESOURCE_VERBOSE_NAME_1"],
        ["RESOURCE_CLASS_NAME_2", "RESOURCE_VERBOSE_NAME_2"],
        ...
        ["RESOURCE_CLASS_NAME_N", "RESOURCE_VERBOSE_NAME_N"],
    ]
    """

    result_list = []
    res_types_list = get_resource_types()
    for r_type in res_types_list:
        class_name = r_type.__name__
        verbose_name = r_type._meta.verbose_name
        if "toolresource" != class_name.lower():
            result_list.append([class_name, verbose_name])
    return result_list
Ejemplo n.º 7
0
 def get_queryset(self):
     return [serializers.ResourceType(resource_type=rtype.__name__) for rtype in
             get_resource_types()]
Ejemplo n.º 8
0
from collections import namedtuple

from django.contrib.auth.models import Group, User
from rest_framework import serializers

from hs_core.hydroshare import utils
from hs_core import hydroshare
from .utils import validate_json, validate_user_name, validate_group_name

RESOURCE_TYPES = [rtype.__name__ for rtype in utils.get_resource_types()]


class StringListField(serializers.ListField):
    child = serializers.CharField()


class ResourceUpdateRequestValidator(serializers.Serializer):
    title = serializers.CharField(required=False)
    metadata = serializers.CharField(validators=[validate_json],
                                     required=False)
    extra_metadata = serializers.CharField(validators=[validate_json],
                                           required=False)
    edit_users = serializers.CharField(required=False)
    edit_groups = serializers.CharField(required=False)
    view_users = serializers.CharField(required=False)
    view_groups = serializers.CharField(required=False)
    keywords = StringListField(required=False)
    abstract = serializers.CharField(required=False)

    def validate_edit_users(self, value):
        return self._validate_users(value)
Ejemplo n.º 9
0
def autocomplete(request):
    term = request.GET.get('term')
    resp = []

    types = [t for t in get_resource_types() if term.lower() in t.__name__.lower()]
    resp += [{'label': 'type', 'value': t.__name__, 'id': t.__name__} for t in types]

    # Party calculations are expensive and complicated. Deferring to focus on lower hanging fruit
    #
    parties = []
    def get_party_type(party):
        if Contributor.objects.filter(id=party.id).exists():
            return 'Contributor'
        elif Creator.objects.filter(id=party.id).exists():
            return 'Author'
        else:
            return None
    seen = set()
    filter_types = {
        'name': 'name__istartswith',
        'email': 'email__iexact',
    }
    for model in (Creator, Contributor):
        for filter_type in filter_types:
            for party in model.objects.filter(**{filter_types[filter_type]: term}):
                party_type = get_party_type(party)
                if party_type:
                    name = model.__name__
                    if model is Creator:
                        name = "Author"
                    if (name, party.name) not in seen:
                        seen.add((name, party.name))
                        resp.append({
                            'label': name,
                            'type': 'party',
                            'id': getattr(party, filter_type, 'id'),
                            'value': party.name,
                        })

    owners = User.objects.filter(username__istartswith=term)
    for owner in owners:
        if owner.first_name and owner.last_name:
            name = "%s %s (%s)" % (owner.first_name, owner.last_name, owner.username)
        elif owner.first_name:
            name = "%s (%s)" % (owner.first_name, owner.username)
        elif owner.last_name:
            name = "%s (%s)" % (owner.last_name, owner.username)
        else:
            name = owner.username
        resp.append({
            'label': 'Owner',
            'type': 'owner',
            'id': owner.username,
            'value': name,
        })

    subjects = Subject.objects.filter(value__istartswith=term)
    for subject in subjects:
        if ('subject', subject.value) not in seen:
            seen.add(('subject', subject.value))
            resp.append({
                'label': 'Subject',
                'type': 'subject',
                'id': subject.value,
                'value': subject.value,
            })

    # resources = get_resource_list(
    #     full_text_search=term,
    # )

    # todo: users
    # todo: groups
    # todo: other conditions?

    return json_or_jsonp(request, resp)
Ejemplo n.º 10
0
    def test_get_resource_types(self):
        res_types = utils.get_resource_types()
        self.assertIn(GenericResource, res_types)

        for res_type in res_types:
            self.assertTrue(issubclass(res_type, BaseResource))
Ejemplo n.º 11
0
def create_resource(
        resource_type, owner, title,
        edit_users=None, view_users=None, edit_groups=None, view_groups=None,
        keywords=None, dublin_metadata=None, metadata=None,
        files=(), **kwargs):
    """
    Called by a client to add a new resource to HydroShare. The caller must have authorization to write content to
    HydroShare. The pid for the resource is assigned by HydroShare upon inserting the resource.  The create method
    returns the newly-assigned pid.

    REST URL:  POST /resource

    Parameters:
    resource - The data bytes of the resource to be added to HydroShare

    Returns:    The pid assigned to the newly created resource

    Return Type:    pid

    Raises:
    Exceptions.NotAuthorized - The user is not authorized to write to HydroShare
    Exceptions.InvalidContent - The content of the resource is incomplete
    Exception.ServiceFailure - The service is unable to process the request

    Note:  The calling user will automatically be set as the owner of the created resource.

    Implementation notes:

    1. pid is called short_id.  This is because pid is a UNIX term for Process ID and could be confusing.

    2. return type is an instance of a subclass of hs_core.models.AbstractResource.  This is for efficiency in the
       native API.  The native API should return actual instance rather than IDs wherever possible to avoid repeated
       lookups in the database when they are unnecessary.

    3. resource_type is a string: see parameter list

    :param resource_type: string. the classname of the resource type, such as GenericResource
    :param owner: email address, username, or User instance. The owner of the resource
    :param title: string. the title of the resource
    :param edit_users: list of email addresses, usernames, or User instances who will be given edit permissions
    :param view_users: list of email addresses, usernames, or User instances who will be given view permissions
    :param edit_groups: list of group names or Group instances who will be given edit permissions
    :param view_groups: list of group names or Group instances who will be given view permissions
    :param keywords: string list. list of keywords to add to the resource
    :param dublin_metadata: list of dicts containing keys { 'term', 'content' } respecting dublin core std.
    :param metadata: list of dicts containing keys (element names) and corresponding values as dicts { 'creator': {'name':'John Smith'}}.
    :param files: list of Django File or UploadedFile objects to be attached to the resource
    :param kwargs: extra arguments to fill in required values in AbstractResource subclasses

    :return: a new resource which is an instance of resource_type.
    """
    for tp in get_resource_types():
        if resource_type == tp.__name__:
            cls = tp
            break
    else:
        raise NotImplementedError("Type {resource_type} does not exist".format(resource_type=resource_type))

    # Send pre-create resource signal
    pre_create_resource.send(sender=cls, dublin_metadata=dublin_metadata, files=files,
                             **kwargs)

    owner = utils.user_from_id(owner)

    # create the resource
    resource = cls.objects.create(
        user=owner,
        creator=owner,
        title=title,
        last_changed_by=owner,
        in_menus=[],
        **kwargs
    )
    for file in files:
        ResourceFile.objects.create(content_object=resource, resource_file=file)

    resource.view_users.add(owner)
    resource.edit_users.add(owner)
    resource.owners.add(owner)

    if edit_users:   
        for user in edit_users:
            user = utils.user_from_id(user)
            resource.edit_users.add(user)
            resource.view_users.add(user)
    if view_users:
        for user in view_users:
            user = utils.user_from_id(user)
            resource.view_users.add(user)
    
    if edit_groups:   
        for group in edit_groups:
            group = utils.group_from_id(group)
            resource.edit_groups.add(group)
            resource.view_groups.add(group)
    if view_groups:
        for group in view_groups:
            group = utils.group_from_id(group)
            resource.view_groups.add(group)

    if keywords:
        ks = [Keyword.objects.get_or_create(title=k) for k in keywords]
        ks = zip(*ks)[0]  # ignore whether something was created or not.  zip is its own inverse

        for k in ks:
            AssignedKeyword.objects.create(content_object=resource, keyword=k)

    # for creating metadata elements based on the old metadata implementation
    if dublin_metadata:
        for d in dublin_metadata:
            QualifiedDublinCoreElement.objects.create(
                term=d['term'],
                content=d['content'],
                content_object=resource
            )

    # for creating metadata elements based on the new metadata implementation
    if metadata:
        for element in metadata:
            # here k is the name of the element
            # v is a dict of all element attributes/field names and field values
            k, v = element.items()[0]
            resource.metadata.create_element(k, **v)

    # add the subject elements from the AssignedKeywords (new metadata implementation)
    for akw in AssignedKeyword.objects.filter(object_pk=resource.id).all():
        resource.metadata.create_element('subject', value=akw.keyword.title)

    hs_bagit.create_bag(resource)

    # Send post-create resource signal
    post_create_resource.send(sender=cls, resource=resource)

    return resource
Ejemplo n.º 12
0
def create_resource(resource_type,
                    owner,
                    title,
                    edit_users=None,
                    view_users=None,
                    edit_groups=None,
                    view_groups=None,
                    keywords=None,
                    dublin_metadata=None,
                    metadata=None,
                    files=(),
                    **kwargs):
    """
    Called by a client to add a new resource to HydroShare. The caller must have authorization to write content to
    HydroShare. The pid for the resource is assigned by HydroShare upon inserting the resource.  The create method
    returns the newly-assigned pid.

    REST URL:  POST /resource

    Parameters:
    resource - The data bytes of the resource to be added to HydroShare

    Returns:    The pid assigned to the newly created resource

    Return Type:    pid

    Raises:
    Exceptions.NotAuthorized - The user is not authorized to write to HydroShare
    Exceptions.InvalidContent - The content of the resource is incomplete
    Exception.ServiceFailure - The service is unable to process the request

    Note:  The calling user will automatically be set as the owner of the created resource.

    Implementation notes:

    1. pid is called short_id.  This is because pid is a UNIX term for Process ID and could be confusing.

    2. return type is an instance of a subclass of hs_core.models.AbstractResource.  This is for efficiency in the
       native API.  The native API should return actual instance rather than IDs wherever possible to avoid repeated
       lookups in the database when they are unnecessary.

    3. resource_type is a string: see parameter list

    :param resource_type: string. the classname of the resource type, such as GenericResource
    :param owner: email address, username, or User instance. The owner of the resource
    :param title: string. the title of the resource
    :param edit_users: list of email addresses, usernames, or User instances who will be given edit permissions
    :param view_users: list of email addresses, usernames, or User instances who will be given view permissions
    :param edit_groups: list of group names or Group instances who will be given edit permissions
    :param view_groups: list of group names or Group instances who will be given view permissions
    :param keywords: string list. list of keywords to add to the resource
    :param dublin_metadata: list of dicts containing keys { 'term', 'content' } respecting dublin core std.
    :param metadata: list of dicts containing keys (element names) and corresponding values as dicts { 'creator': {'name':'John Smith'}}.
    :param files: list of Django File or UploadedFile objects to be attached to the resource
    :param kwargs: extra arguments to fill in required values in AbstractResource subclasses

    :return: a new resource which is an instance of resource_type.
    """
    for tp in get_resource_types():
        if resource_type == tp.__name__:
            cls = tp
            break
    else:
        raise NotImplementedError("Type {resource_type} does not exist".format(
            resource_type=resource_type))

    # Send pre-create resource signal
    pre_create_resource.send(sender=cls,
                             dublin_metadata=dublin_metadata,
                             files=files,
                             **kwargs)

    owner = utils.user_from_id(owner)

    # create the resource
    resource = cls.objects.create(user=owner,
                                  creator=owner,
                                  title=title,
                                  last_changed_by=owner,
                                  in_menus=[],
                                  **kwargs)
    for file in files:
        ResourceFile.objects.create(content_object=resource,
                                    resource_file=file)

    resource.view_users.add(owner)
    resource.edit_users.add(owner)
    resource.owners.add(owner)

    if edit_users:
        for user in edit_users:
            user = utils.user_from_id(user)
            resource.edit_users.add(user)
            resource.view_users.add(user)
    if view_users:
        for user in view_users:
            user = utils.user_from_id(user)
            resource.view_users.add(user)

    if edit_groups:
        for group in edit_groups:
            group = utils.group_from_id(group)
            resource.edit_groups.add(group)
            resource.view_groups.add(group)
    if view_groups:
        for group in view_groups:
            group = utils.group_from_id(group)
            resource.view_groups.add(group)

    if keywords:
        ks = [Keyword.objects.get_or_create(title=k) for k in keywords]
        ks = zip(
            *ks
        )[0]  # ignore whether something was created or not.  zip is its own inverse

        for k in ks:
            AssignedKeyword.objects.create(content_object=resource, keyword=k)

    # for creating metadata elements based on the old metadata implementation
    if dublin_metadata:
        for d in dublin_metadata:
            QualifiedDublinCoreElement.objects.create(term=d['term'],
                                                      content=d['content'],
                                                      content_object=resource)

    # for creating metadata elements based on the new metadata implementation
    if metadata:
        for element in metadata:
            # here k is the name of the element
            # v is a dict of all element attributes/field names and field values
            k, v = element.items()[0]
            resource.metadata.create_element(k, **v)

    # add the subject elements from the AssignedKeywords (new metadata implementation)
    for akw in AssignedKeyword.objects.filter(object_pk=resource.id).all():
        resource.metadata.create_element('subject', value=akw.keyword.title)

    hs_bagit.create_bag(resource)

    # Send post-create resource signal
    post_create_resource.send(sender=cls, resource=resource)

    return resource
Ejemplo n.º 13
0
    def test_get_resource_types(self):
        res_types = utils.get_resource_types()
        self.assertIn(GenericResource, res_types)

        for res_type in res_types:
            self.assertTrue(issubclass(res_type, BaseResource))
Ejemplo n.º 14
0
__author__ = 'Pabitra'

from collections import namedtuple

from django.contrib.auth.models import Group, User
from rest_framework import serializers

from hs_core.hydroshare import utils
from hs_core import hydroshare
from .utils import validate_json, validate_user_name,  validate_group_name

RESOURCE_TYPES = [rtype.__name__ for rtype in utils.get_resource_types()]

class StringListField(serializers.ListField):
    child = serializers.CharField()

class ResourceUpdateRequestValidator(serializers.Serializer):
    title = serializers.CharField(required=False)
    #metadata = serializers.CharField(validators=[validate_json], required=False)
    edit_users = serializers.CharField(required=False)
    edit_groups = serializers.CharField(required=False)
    view_users = serializers.CharField(required=False)
    view_groups = serializers.CharField(required=False)
    keywords = StringListField(required=False)
    abstract = serializers.CharField(required=False)

    def validate_edit_users(self, value):
        return self._validate_users(value)

    def validate_view_users(self, value):
        return self._validate_users(value)
Ejemplo n.º 15
0
def create_resource(
        resource_type, owner, title,
        edit_users=None, view_users=None, edit_groups=None, view_groups=None,
        keywords=None, dublin_metadata=None,
        *files, **kwargs):
    """
    Called by a client to add a new resource to HydroShare. The caller must have authorization to write content to
    HydroShare. The pid for the resource is assigned by HydroShare upon inserting the resource.  The create method
    returns the newly-assigned pid.

    REST URL:  POST /resource

    Parameters:
    resource - The data bytes of the resource to be added to HydroShare

    Returns:    The pid assigned to the newly created resource

    Return Type:    pid

    Raises:
    Exceptions.NotAuthorized - The user is not authorized to write to HydroShare
    Exceptions.InvalidContent - The content of the resource is incomplete
    Exception.ServiceFailure - The service is unable to process the request

    Note:  The calling user will automatically be set as the owner of the created resource.
    """
    for tp in get_resource_types():
        if resource_type == tp.__name__:
            cls = tp
            break
    else:
        raise NotImplemented("Type {resource_type} does not exist".format(**locals()))

    # create the resource
    resource = cls.objects.create(
        user=owner,
        author=owner,
        title=title,
        **kwargs
    )
    for file in files:
        ResourceFile.objects.create(content_object=resource, resource_file=file)

    resource.view_users.add(owner)
    resource.edit_users.add(owner)
    resource.owners.add(owner)

    if edit_users:   
        for user in edit_users:
            user = utils.user_from_id(user)
            resource.edit_users.add(user)
            resource.view_users.add(user)
    if view_users:
        for user in view_users:
            user = utils.user_from_id(user)
            resource.view_users.add(user)
    
    if edit_groups:   
        for group in edit_groups:
            group = utils.group_from_id(group)
            resource.edit_groups.add(group)
            resource.view_groups.add(group)
    if view_groups:
        for group in view_groups:
            group = utils.group_from_id(group)
            resource.view_groups.add(group)

    if keywords:
        ks = [Keyword.objects.get_or_create(k) for k in keywords]
        ks = zip(*ks)[0]  # ignore whether something was created or not.  zip is its own inverse

        for k in ks:
            AssignedKeyword.objects.create(content_object=resource, keyword=k)

    if dublin_metadata:
        for d in dublin_metadata:
            QualifiedDublinCoreElement.objects.create(
                term=d['term'],
                qualifier=d.get('qualifier'),
                content=d['content'],
                content_object=resource
            )

    return resource
Ejemplo n.º 16
0
 def get_queryset(self):
     return [
         serializers.ResourceType(resource_type=rtype.__name__)
         for rtype in get_resource_types()
     ]
Ejemplo n.º 17
0
def autocomplete(request):
    term = request.GET.get('term')
    resp = []

    types = [
        t for t in get_resource_types() if term.lower() in t.__name__.lower()
    ]
    resp += [{
        'label': 'type',
        'value': t.__name__,
        'id': t.__name__
    } for t in types]

    # Party calculations are expensive and complicated. Deferring to focus on lower hanging fruit
    #
    parties = []

    def get_party_type(party):
        if Contributor.objects.filter(id=party.id).exists():
            return 'Contributor'
        elif Creator.objects.filter(id=party.id).exists():
            return 'Author'
        else:
            return None

    seen = set()
    filter_types = {
        'name': 'name__istartswith',
        'email': 'email__iexact',
    }
    for model in (Creator, Contributor):
        for filter_type in filter_types:
            for party in model.objects.filter(
                    **{filter_types[filter_type]: term}):
                party_type = get_party_type(party)
                if party_type:
                    name = model.__name__
                    if model is Creator:
                        name = "Author"
                    if (name, party.name) not in seen:
                        seen.add((name, party.name))
                        resp.append({
                            'label': name,
                            'type': 'party',
                            'id': getattr(party, filter_type, 'id'),
                            'value': party.name,
                        })

    owners = User.objects.filter(username__istartswith=term)
    for owner in owners:
        if owner.first_name and owner.last_name:
            name = "%s %s (%s)" % (owner.first_name, owner.last_name,
                                   owner.username)
        elif owner.first_name:
            name = "%s (%s)" % (owner.first_name, owner.username)
        elif owner.last_name:
            name = "%s (%s)" % (owner.last_name, owner.username)
        else:
            name = owner.username
        resp.append({
            'label': 'Owner',
            'type': 'owner',
            'id': owner.username,
            'value': name,
        })

    subjects = Subject.objects.filter(value__istartswith=term)
    for subject in subjects:
        if ('subject', subject.value) not in seen:
            seen.add(('subject', subject.value))
            resp.append({
                'label': 'Subject',
                'type': 'subject',
                'id': subject.value,
                'value': subject.value,
            })

    # todo: users
    # todo: groups
    # todo: other conditions?

    return json_or_jsonp(request, resp)