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
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)
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()
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)
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)
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)
def __getitem__(self, key): cls = get_named_class(key) if not cls: raise KeyError() return ClassContext(self, cls)
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()}
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()}