<commit_before>import json
import datetime
import dateutil.parser
import mongoengine

from bson.dbref import DBRef
from bson.objectid import ObjectId
from flask import request, url_for
from urlparse import urlparse
from mongoengine.base.proxy import DocumentProxy
from mongoengine.fields import EmbeddedDocumentField, ListField, ReferenceField, GenericReferenceField, SafeReferenceField
from mongoengine.fields import DateTimeField, DictField
from werkzeug.datastructures import MultiDict

from cleancat import ValidationError as SchemaValidationError
from flask.ext.mongorest.exceptions import ValidationError, UnknownFieldError
from flask.ext.mongorest.utils import cmp_fields, isbound, isint, equal
from flask.ext.mongorest.utils import MongoEncoder


class ResourceMeta(type):
    def __init__(cls, name, bases, classdict):
        if classdict.get('__metaclass__') is not ResourceMeta:
            for document,resource in cls.child_document_resources.iteritems():
                if resource == name:
                    cls.child_document_resources[document] = cls
        type.__init__(cls, name, bases, classdict)

class Resource(object):
    document = None # required
    fields = None
    readonly_fields = ['id']
    schema = None
    related_resources = {}
    related_resources_hints = {} #@todo this should be integrated into the related_resources dict, possibly as a tuple
    save_related_fields = []
    rename_fields = {}
    child_document_resources = {}
    paginate = True
    select_related = False
    allowed_ordering = []
    uri_prefix = None # Must start and end with a "/"
    max_limit = 100 # cap the number of records in the _limit param to avoid DDoS'ing the API.
    default_limit = 100 # default limit if no _limit is specified

    __metaclass__ = ResourceMeta

    def __init__(self):
        doc_fields = self.document._fields.keys()
        if self.fields == None:
            self.fields = doc_fields
        self._related_resources = self.get_related_resources()
        self._rename_fields = self.get_rename_fields()
        self._reverse_rename_fields = {}
        for k, v in self._rename_fields.iteritems():
            self._reverse_rename_fields[v] = k
        assert len(self._rename_fields) == len(self._reverse_rename_fields), \
            'Cannot rename multiple fields to the same name'
        self._filters = self.get_filters()
        self._child_document_resources = self.get_child_document_resources()
        self.data = None
        self._dirty_fields = None

    @property
    def params(self):
        if not hasattr(self, '_params'):
            if '_params' in self.raw_data:
                self._params = self.raw_data['_params']
            else:
                try:
                    self._params = request.args.to_dict()
                except AttributeError: # mocked request with regular dict
                    self._params = request.args
        return self._params

    @property
    def raw_data(self):
        if not hasattr(self, '_raw_data'):
            if request.method in ('PUT', 'POST') or request.data:
                if request.mimetype and 'json' not in request.mimetype:
                    raise ValidationError({'error': "Please send valid JSON with a 'Content-Type: application/json' header."})
<commit_msg>Return a clearer error message when somebody uses Transfer-Encoding: chunked<commit_after>import json
import datetime
import dateutil.parser
import mongoengine

from bson.dbref import DBRef
from bson.objectid import ObjectId
from flask import request, url_for
from urlparse import urlparse
from mongoengine.base.proxy import DocumentProxy
from mongoengine.fields import EmbeddedDocumentField, ListField, ReferenceField, GenericReferenceField, SafeReferenceField
from mongoengine.fields import DateTimeField, DictField
from werkzeug.datastructures import MultiDict

from cleancat import ValidationError as SchemaValidationError
from flask.ext.mongorest.exceptions import ValidationError, UnknownFieldError
from flask.ext.mongorest.utils import cmp_fields, isbound, isint, equal
from flask.ext.mongorest.utils import MongoEncoder


class ResourceMeta(type):
    def __init__(cls, name, bases, classdict):
        if classdict.get('__metaclass__') is not ResourceMeta:
            for document,resource in cls.child_document_resources.iteritems():
                if resource == name:
                    cls.child_document_resources[document] = cls
        type.__init__(cls, name, bases, classdict)

class Resource(object):
    document = None # required
    fields = None
    readonly_fields = ['id']
    schema = None
    related_resources = {}
    related_resources_hints = {} #@todo this should be integrated into the related_resources dict, possibly as a tuple
    save_related_fields = []
    rename_fields = {}
    child_document_resources = {}
    paginate = True
    select_related = False
    allowed_ordering = []
    uri_prefix = None # Must start and end with a "/"
    max_limit = 100 # cap the number of records in the _limit param to avoid DDoS'ing the API.
    default_limit = 100 # default limit if no _limit is specified

    __metaclass__ = ResourceMeta

    def __init__(self):
        doc_fields = self.document._fields.keys()
        if self.fields == None:
            self.fields = doc_fields
        self._related_resources = self.get_related_resources()
        self._rename_fields = self.get_rename_fields()
        self._reverse_rename_fields = {}
        for k, v in self._rename_fields.iteritems():
            self._reverse_rename_fields[v] = k
        assert len(self._rename_fields) == len(self._reverse_rename_fields), \
            'Cannot rename multiple fields to the same name'
        self._filters = self.get_filters()
        self._child_document_resources = self.get_child_document_resources()
        self.data = None
        self._dirty_fields = None

    @property
    def params(self):
        if not hasattr(self, '_params'):
            if '_params' in self.raw_data:
                self._params = self.raw_data['_params']
            else:
                try:
                    self._params = request.args.to_dict()
                except AttributeError: # mocked request with regular dict
                    self._params = request.args
        return self._params

    @property
    def raw_data(self):
        if not hasattr(self, '_raw_data'):
            if request.method in ('PUT', 'POST') or request.data:
                if request.mimetype and 'json' not in request.mimetype:
                    raise ValidationError({'error': "Please send valid JSON with a 'Content-Type: application/json' header."})
                if request.headers.get('Transfer-Encoding') == 'chunked':
                    raise ValidationError({'error': "Chunked Transfer-Encoding is not supported."})

{'fraction_non_alphanumeric': 0.07701300599152419, 'fraction_numerical': 0.0017536168347216134, 'mean_word_length': 2.9265633964429143, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4011708', 'n_tokens_mistral': 1850, 'n_tokens_neox': 1801, 'n_words': 545}