Exemplo n.º 1
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()}