Exemplo n.º 1
0
 def get_collection_class(self, typename=None):
     """Returns the collection class, or subclass designated by typename"""
     cls = self.collection_class
     if typename is not None:
         other_cls = get_named_class(typename)
         if other_cls and issubclass(other_cls, cls):
             return other_cls
     return cls
Exemplo n.º 2
0
def votes_collection_add_json(request):
    ctx = request.context
    user_id = authenticated_userid(request)
    if not user_id:
        raise HTTPUnauthorized
    permissions = ctx.get_permissions()
    check_permissions(ctx, user_id, CrudPermissions.CREATE)
    spec = ctx.get_instance_of_class(AbstractVoteSpecification)
    if spec:
        required = spec.get_vote_class()
    else:
        required = ctx.collection_class
    widget = ctx.get_instance_of_class(VotingWidget)
    if not widget and spec:
        widget = spec.widget
    if not widget:
        raise HTTPBadRequest("Please provide a reference to a widget")
    if widget.activity_state != 'active':
        raise HTTPUnauthorized("Not in voting period")
    typename = request.json_body.get('@type', None)
    if typename:
        cls = get_named_class(typename)
        if not issubclass(cls, required):
            raise HTTPBadRequest("@type is %s, should be in %s" % (
                typename, spec.get_vote_class().__name__))
    else:
        typename = required.external_typename()
    json = request.json_body
    json['voter'] = User.uri_generic(user_id)
    if "@type" not in json:
        json["@type"] = typename
    else:
        pass  # TODO: Check subclass
    try:
        instances = ctx.create_object(typename, json)
    except Exception as e:
        raise HTTPBadRequest(e)
    if instances:
        first = instances[0]
        db = first.db
        for instance in instances:
            db.add(instance)
        db.flush()
        # validate after flush so we can check validity with DB constraints
        if not first.is_valid():
            raise HTTPBadRequest("Invalid vote")
        view = request.GET.get('view', None) or 'default'
        return Response(
            dumps(first.generic_json(view, user_id, permissions)),
            location=first.uri_generic(first.id),
            status_code=201)
Exemplo n.º 3
0
def votes_collection_add(request):
    ctx = request.context
    user_id = authenticated_userid(request)
    if not user_id:
        raise HTTPUnauthorized
    permissions = get_permissions(
        user_id, ctx.get_discussion_id())
    check_permissions(ctx, user_id, permissions, CrudPermissions.CREATE)
    widget = ctx.get_instance_of_class(MultiCriterionVotingWidget)
    if widget.activity_state != 'active':
        raise HTTPUnauthorized("Not in voting period")
    args = request.params
    spec = ctx.get_instance_of_class(AbstractVoteSpecification)
    if spec:
        required = spec.get_vote_class()
    else:
        required = ctx.collection_class
    if 'type' in args:
        args = dict(args)
        typename = args['type']
        del args['type']
        cls = get_named_class(typename)
        if not issubclass(cls, required):
            raise HTTPBadRequest("@type is %s, should be in %s" % (
                typename, spec.get_vote_class().__name__))
    else:
        typename = required.external_typename()
    args['voter_id'] = user_id
    try:
        instances = ctx.create_object(typename, None, user_id, **args)
    except Exception as e:
        raise HTTPBadRequest(e)
    if instances:
        first = instances[0]
        if not first.is_valid():
            raise HTTPBadRequest("Invalid vote")
        db = first.db
        for instance in instances:
            db.add(instance)
        print "before flush"
        db.flush()
        print "after flush"
        return Response(
            dumps(first.generic_json('default', user_id, permissions)),
            location=first.uri_generic(first.id),
            status_code=201)
    raise HTTPBadRequest()
Exemplo n.º 4
0
def votes_collection_add(request):
    ctx = request.context
    user_id = authenticated_userid(request)
    if not user_id:
        raise HTTPUnauthorized
    permissions = get_permissions(
        user_id, ctx.get_discussion_id())
    check_permissions(ctx, user_id, permissions, CrudPermissions.CREATE)
    widget = ctx.get_instance_of_class(MultiCriterionVotingWidget)
    if widget.activity_state != 'active':
        raise HTTPUnauthorized("Not in voting period")
    args = request.params
    spec = ctx.get_instance_of_class(AbstractVoteSpecification)
    if spec:
        required = spec.get_vote_class()
    else:
        required = ctx.collection_class
    if 'type' in args:
        args = dict(args)
        typename = args['type']
        del args['type']
        cls = get_named_class(typename)
        if not issubclass(cls, required):
            raise HTTPBadRequest("@type is %s, should be in %s" % (
                typename, spec.get_vote_class().__name__))
    else:
        typename = required.external_typename()
    args['voter_id'] = user_id
    try:
        instances = ctx.create_object(typename, None, user_id, **args)
    except Exception as e:
        raise HTTPBadRequest(e)
    if instances:
        first = instances[0]
        if not first.is_valid():
            raise HTTPBadRequest("Invalid vote")
        db = first.db
        for instance in instances:
            db.add(instance)
        print "before flush"
        db.flush()
        print "after flush"
        return Response(
            dumps(first.generic_json('default', user_id, permissions)),
            location=first.uri_generic(first.id),
            status_code=201)
    raise HTTPBadRequest()
Exemplo n.º 5
0
    def read(self, jsonld, discussion, admin_user_id, base=None):
        if isinstance(jsonld, (str, unicode)):
            jsonld = json.loads(jsonld)
        c = jsonld['@context']
        # Avoid loading the main context.
        if c == context_url:
            c = local_context_loc
        elif context_url in c:
            c.remove(context_url)
            c.append(local_context_loc)
        c = Context(c, base=base)
        by_id = dict()
        site_iri = None

        def find_objects(j):
            if isinstance(jsonld, (str, unicode)):
                return
            if isinstance(j, list):
                for x in j:
                    find_objects(x)
            if isinstance(j, dict):
                jid = j.get('@id', None)
                if jid:
                    by_id[jid] = j
                for x in j.values():
                    find_objects(x)
        find_objects(jsonld)
        for json in by_id.itervalues():
            if json.get('@type', None) == 'Site':
                site_iri = json['@id']
                break
        site_iri = site_iri or base
        assert site_iri is not None
        handler = ImportRecordHandler(discussion, site_iri)
        for json in by_id.itervalues():
            cls = self.class_from_type(json['@type'])
            if not cls:
                print "missing cls for :", json['@type']
                continue
            if cls:
                cls = get_named_class(cls)
            cls.create_from_json(
                json, admin_user_id, aliases=handler,
                parse_def_name='readcif.json', jsonld=by_id)
Exemplo n.º 6
0
def votes_collection_add_json(request):
    ctx = request.context
    user_id = authenticated_userid(request)
    if not user_id:
        raise HTTPUnauthorized
    permissions = get_permissions(
        user_id, ctx.get_discussion_id())
    check_permissions(ctx, user_id, permissions, CrudPermissions.CREATE)
    widget = ctx.get_instance_of_class(MultiCriterionVotingWidget)
    if widget.activity_state != 'active':
        raise HTTPUnauthorized("Not in voting period")
    spec = ctx.get_instance_of_class(AbstractVoteSpecification)
    if spec:
        required = spec.get_vote_class()
    else:
        required = ctx.collection_class
    typename = request.json_body.get('@type', None)
    if typename:
        cls = get_named_class(typename)
        if not issubclass(cls, required):
            raise HTTPBadRequest("@type is %s, should be in %s" % (
                typename, spec.get_vote_class().__name__))
    else:
        typename = required.external_typename()
    json = request.json_body
    json['voter'] = User.uri_generic(user_id)
    try:
        instances = ctx.create_object(typename, json, user_id)
    except Exception as e:
        raise HTTPBadRequest(e)
    if instances:
        first = instances[0]
        db = first.db
        for instance in instances:
            db.add(instance)
        db.flush()
        # validate after flush so we can check validity with DB constraints
        if not first.is_valid():
            raise HTTPBadRequest("Invalid vote")
        view = request.GET.get('view', None) or 'default'
        return Response(
            dumps(first.generic_json(view, user_id, permissions)),
            location=first.uri_generic(first.id),
            status_code=201)
Exemplo n.º 7
0
def votes_collection_add_json(request):
    ctx = request.context
    user_id = authenticated_userid(request)
    if not user_id:
        raise HTTPUnauthorized
    permissions = get_permissions(
        user_id, ctx.get_discussion_id())
    check_permissions(ctx, user_id, permissions, CrudPermissions.CREATE)
    widget = ctx.get_instance_of_class(MultiCriterionVotingWidget)
    if widget.activity_state != 'active':
        raise HTTPUnauthorized("Not in voting period")
    spec = ctx.get_instance_of_class(AbstractVoteSpecification)
    if spec:
        required = spec.get_vote_class()
    else:
        required = ctx.collection_class
    typename = request.json_body.get('@type', None)
    if typename:
        cls = get_named_class(typename)
        if not issubclass(cls, required):
            raise HTTPBadRequest("@type is %s, should be in %s" % (
                typename, spec.get_vote_class().__name__))
    else:
        typename = required.external_typename()
    json = request.json_body
    json['voter'] = User.uri_generic(user_id)
    try:
        instances = ctx.create_object(typename, json, user_id)
    except Exception as e:
        raise HTTPBadRequest(e)
    if instances:
        first = instances[0]
        if not first.is_valid():
            raise HTTPBadRequest("Invalid vote")
        db = first.db
        for instance in instances:
            db.add(instance)
        db.flush()
        view = request.GET.get('view', None) or 'default'
        return Response(
            dumps(first.generic_json(view, user_id, permissions)),
            location=first.uri_generic(first.id),
            status_code=201)
Exemplo n.º 8
0
 def __getitem__(self, key):
     cls = get_named_class(key)
     if not cls:
         raise KeyError()
     return ClassContext(self, cls)
Exemplo n.º 9
0
def post_extract(request):
    """
    Create a new extract.
    """
    extract_data = json.loads(request.body)
    discussion = request.context
    db = discussion.db
    user_id = authenticated_userid(request)
    if not user_id:
        # Straight from annotator
        token = request.headers.get('X-Annotator-Auth-Token')
        if token:
            token = decode_token(token,
                                 request.registry.settings['session.secret'])
            if token:
                user_id = token['userId']
        user_id = user_id or Everyone
        permissions = get_permissions(user_id, discussion_id)
    else:
        permissions = request.permissions
    if P_ADD_EXTRACT not in permissions:
        #TODO: maparent:  restore this code once it works:
        #raise HTTPForbidden(result=ACLDenied(permission=P_ADD_EXTRACT))
        raise HTTPForbidden()
    if not user_id or user_id == Everyone:
        # TODO: Create an anonymous user.
        raise HTTPServerError("Anonymous extracts are not implemeted yet.")
    content = None
    uri = extract_data.get('uri')
    important = extract_data.get('important', False)
    annotation_text = extract_data.get('text')
    target = extract_data.get('target')
    if not uri:
        # Extract from an internal post
        if not target:
            raise HTTPBadRequest("No target")

        target_class = sqla.get_named_class(target.get('@type'))
        if issubclass(target_class, Post):
            post_id = target.get('@id')
            post = Post.get_instance(post_id)
            if not post:
                raise HTTPNotFound("Post with id '%s' not found." % post_id)
            content = post
        elif issubclass(target_class, Webpage):
            uri = target.get('url')
    if uri and not content:
        content = Webpage.get_instance(uri)
        if not content:
            # TODO: maparent:  This is actually a singleton pattern, should be
            # handled by the AnnotatorSource now that it exists...
            source = db.query(AnnotatorSource).filter_by(
                discussion=discussion).filter(
                    cast(AnnotatorSource.name, Unicode) ==
                    'Annotator').first()
            if not source:
                source = AnnotatorSource(name='Annotator',
                                         discussion=discussion)
                db.add(source)
            content = Webpage(url=uri, discussion=discussion)
            db.add(content)
    extract_body = extract_data.get('quote', None)

    idea_id = extract_data.get('idIdea', None)
    if idea_id:
        idea = Idea.get_instance(idea_id)
        if (idea.discussion.id != discussion.id):
            raise HTTPBadRequest(
                "Extract from discussion %s cannot be associated with an idea from a different discussion."
                % extract.get_discussion_id())
        if not idea.has_permission_req(P_ASSOCIATE_EXTRACT):
            raise HTTPForbidden("Cannot associate extact with this idea")
    else:
        idea = None

    new_extract = Extract(creator_id=user_id,
                          owner_id=user_id,
                          discussion=discussion,
                          idea=idea,
                          important=important,
                          annotation_text=annotation_text,
                          content=content)
    db.add(new_extract)

    for range_data in extract_data.get('ranges', []):
        range = TextFragmentIdentifier(extract=new_extract,
                                       body=extract_body,
                                       xpath_start=range_data['start'],
                                       offset_start=range_data['startOffset'],
                                       xpath_end=range_data['end'],
                                       offset_end=range_data['endOffset'])
        db.add(range)
    db.flush()

    return {'ok': True, '@id': new_extract.uri()}
Exemplo n.º 10
0
def post_extract(request):
    """
    Create a new extract.
    """
    extract_data = json.loads(request.body)
    discussion_id = int(request.matchdict['discussion_id'])
    user_id = authenticated_userid(request)
    if not user_id:
        # Straight from annotator
        token = request.headers.get('X-Annotator-Auth-Token')
        if token:
            token = decode_token(
                token, request.registry.settings['session.secret'])
            if token:
                user_id = token['userId']
    user_id = user_id or Everyone
    if not user_has_permission(discussion_id, user_id, P_ADD_EXTRACT):
        #TODO: maparent:  restore this code once it works:
        #return HTTPForbidden(result=ACLDenied(permission=P_ADD_EXTRACT))
        return HTTPForbidden()
    if not user_id or user_id == Everyone:
        # TODO: Create an anonymous user.
        raise HTTPServerError("Anonymous extracts are not implemeted yet.")
    content = None
    uri = extract_data.get('uri')
    important = extract_data.get('important', False)
    annotation_text = None
    if uri:
        # Straight from annotator
        annotation_text = extract_data.get('text')
    else:
        target = extract_data.get('target')
        if not (target or uri):
            raise HTTPBadRequest("No target")

        target_class = sqla.get_named_class(target.get('@type'))
        if issubclass(target_class, Post):
            post_id = target.get('@id')
            post = Post.get_instance(post_id)
            if not post:
                raise HTTPNotFound(
                    "Post with id '%s' not found." % post_id)
            content = post
        elif issubclass(target_class, Webpage):
            uri = target.get('url')
    if uri and not content:
        content = Webpage.get_instance(uri)
        if not content:
            # TODO: maparent:  This is actually a singleton pattern, should be
            # handled by the AnnotatorSource now that it exists...
            source = AnnotatorSource.default_db.query(AnnotatorSource).filter_by(
                discussion_id=discussion_id).filter(
                cast(AnnotatorSource.name, Unicode) == 'Annotator').first()
            if not source:
                source = AnnotatorSource(
                    name='Annotator', discussion_id=discussion_id,
                    type='source')
            content = Webpage(url=uri, discussion_id=discussion_id)
    extract_body = extract_data.get('quote', '')

    idea_id = extract_data.get('idIdea', None)
    if idea_id:
        idea = Idea.get_instance(idea_id)
        if(idea.discussion.id != discussion_id):
            raise HTTPBadRequest(
                "Extract from discussion %s cannot be associated with an idea from a different discussion." % extract.get_discussion_id())
    else:
        idea = None


    new_extract = Extract(
        creator_id=user_id,
        owner_id=user_id,
        discussion_id=discussion_id,
        body=extract_body,
        idea=idea,
        important=important,
        annotation_text=annotation_text,
        content=content
    )
    Extract.default_db.add(new_extract)

    for range_data in extract_data.get('ranges', []):
        range = TextFragmentIdentifier(
            extract=new_extract,
            xpath_start=range_data['start'],
            offset_start=range_data['startOffset'],
            xpath_end=range_data['end'],
            offset_end=range_data['endOffset'])
        TextFragmentIdentifier.default_db.add(range)
    Extract.default_db.flush()

    return {'ok': True, '@id': new_extract.uri()}