'Apply CRUD methods
@param r: the S3Request
@param attr: dictionary of parameters for the method handler
The attributes that it knows about are:
* componentname
* formname
* list_fields
* report_groupby
* report_hide_comments
@return: output object to send to the view'

def apply_method(self, r, **attr):

    def getParam(key):
        "\n                                                                nested    function    to    get    the    parameters    passed    into    apply_method\n\n                                                                @todo    find    out    if    this    has    been    done    better    elsewhere!    :(\n\n                                                                This    will    first    try    and    get    the    argument    from    the    attr    parameter,\n                                                                if    it's    not    here    then    try    self._config()\n                                                "
        value = attr.get(key)
        if (value != None):
            return value
        return self._config(key)
    T = current.T
    self.ERROR = ERROR = Storage(NO_RECORDS=T('No    records    in    this    resource.    Add    one    more    records    manually    and    then    retry.'), TESSERACT_ERROR=(T('%(app)s    not    installed.    Ask    the    Server    Administrator    to    install    on    Server.') % dict(app='Tesseract    3.01')), EMPTY_OCR_FORM=T('Selected    OCR    Form    has    no    pages.    Use    another    revision    of    create    a    new    revision    by    downloading    a    new    Form.'), INVALID_IMAGE_TYPE=T("Uploaded    file(s)    are    not    Image(s).    Supported    image    formats    are    '.png',    '.jpg',    '.bmp',    '.gif'."), OCR_DISABLED=T('OCR    module    is    disabled.    Ask    the    Server    Administrator    to    enable    it.'), IMAGE_MAGICK_ERROR=(T('%(app)s    not    installed.    Ask    the    Server    Administrator    to    install    on    Server.') % dict(app='ImageMagick')), NOT_PDF_FILE=T('Uploaded    file    is    not    a    PDF    file.    Provide    a    Form    in    valid    PDF    Format.'), INVALID_PDF=T('Uploaded    PDF    file    has    more/less    number    of    page(s)    than    required.    Check    if    you    have    provided    appropriate    revision    for    your    Form    as    well    as    check    the    Form    contains    appropriate    number    of    pages.'), NO_UTC_OFFSET=T("No    UTC    offset    found.    Please    set    UTC    offset    in    your    'User    Profile'    details.    Example:    UTC+0530"), INVALID_JOBID=T("The    provided    'jobuuid'    is    invalid.    The    session    of    Form    upload    is    invalid.    You    should    retry    uploading."), INVALID_FORMID=T("The    provided    'formuuid'    is    invalid.    You    have    selected    a    Form    revision    which    does    not    exist    on    this    server."), UNRECOVERABLE_ERROR=T('The    uploaded    Form    is    unreadable,    please    do    manual    data    entry.'), JOB_COMPLETE=T('This    job    has    already    been    finished    successfully.'))
    self.r = r
    checkDependencies(r)
    settings = current.deployment_settings
    request = current.request
    response = current.response
    session = current.session
    db = current.db
    if DEBUG:
        content_disposition = 'inline'
    else:
        content_disposition = 'attachment'
    if (settings.get_paper_size() == 'Letter'):
        self.paper_size = LETTER
    else:
        self.paper_size = A4
    try:
        self.logo = os.path.join(request.folder, settings.get_pdf_logo())
    except:
        self.logo = None
    self.headerBanner = None
    method = self.method
    callback = getParam('callback')
    if (callback != None):
        title = getParam('formname')
        if (title == None):
            title = self.defaultTitle(self.resource)
        header = getParam('header')
        if (header == None):
            header = self.pageHeader
        footer = getParam('footer')
        if (footer == None):
            footer = self.pageFooter
        filename = getParam('filename')
        if (filename == None):
            filename = title
        self.newDocument(title, header=header, footer=footer, filename=filename)
        try:
            id = r.component_id
            if (id == None):
                id = r.id
        except:
            try:
                id = r.id
            except:
                id = None
        callback(self, id=id)
        doc = self.buildDoc()
        if response:
            response.headers['Content-Type'] = contenttype('.pdf')
            response.headers['Content-disposition'] = ('%s;    filename="%s"' % (content_disposition, self.filename))
        return doc
    elif (r.http == 'GET'):
        if (self.method in ('read', 'list')):
            componentname = getParam('componentname')
            title = getParam('formname')
            list_fields = getParam('list_fields')
            report_groupby = getParam('report_groupby')
            report_hide_comments = getParam('report_hide_comments')
            filename = getParam('filename')
            if (filename == None):
                filename = title
            if (title == None):
                title = self.defaultTitle(self.resource)
            self.newDocument(title, header=self.pageHeader, footer=self.pageFooter, filename=filename)
            if ('report_landscape' in attr):
                self.setLandscape()
            if (('rheader' in attr) and attr['rheader']):
                self.extractrHeader(attr['rheader'])
                self.addSpacer(3)
            elif componentname:
                self.addrHeader(self.resource, list_fields, report_hide_comments=report_hide_comments)
                self.addSpacer(3)
            if (componentname == None):
                self.addTable(self.resource, list_fields=list_fields, report_groupby=report_groupby, report_hide_comments=report_hide_comments)
            else:
                ptable = self.resource.table
                ctable = db[componentname]
                raw_data = []
                linkfield = None
                for link in ptable._referenced_by:
                    if (link[0] == componentname):
                        linkfield = link[1]
                        break
                if (linkfield != None):
                    query = (ctable[linkfield] == self.record_id)
                    records = db(query).select()
                    find_fields = []
                    for component in self.resource.components.values():
                        find_fields += component.readable_fields()
                    fields = []
                    if list_fields:
                        for lf in list_fields:
                            for field in find_fields:
                                if (field.name == lf):
                                    fields.append(field)
                                    break
                    else:
                        for field in find_fields:
                            if (field.type == 'id'):
                                continue
                            if (report_hide_comments and (field.name == 'comments')):
                                continue
                            fields.append(field)
                    if (not fields):
                        fields = [table.id]
                    label_fields = [f.label for f in fields]
                    for record in records:
                        data = []
                        for field in fields:
                            value = record[field.name]
                            text = s3_represent_value(field, value=value, strip_markup=True, non_xml_output=True, extended_comments=True)
                            data.append(text)
                        raw_data.append(data)
                    self.addTable(raw_data=raw_data, list_fields=label_fields)
            if ('report_footer' in attr):
                self.addSpacer(3)
                self.extractrHeader(attr['report_footer'])
            doc = self.buildDoc()
            if response:
                response.headers['Content-Type'] = contenttype('.pdf')
                response.headers['Content-disposition'] = ('%s;    filename="%s"' % (content_disposition, self.filename))
            return doc
        elif (method == 'create'):
            if current.deployment_settings.has_module('ocr'):
                import uuid
                formUUID = uuid.uuid1()
                self.newOCRForm(formUUID)
                self.OCRPDFManager()
                doc = self.buildDoc()
                numPages = self.doc.numPages
                layoutXML = self.__getOCRLayout()
                self.__update_dbmeta(formUUID, layoutXML, numPages)
                if response:
                    response.headers['Content-Type'] = contenttype('.pdf')
                    response.headers['Content-disposition'] = ('%s;    filename="%s"' % (content_disposition, self.filename))
                return doc
            else:
                r.error(501, self.ERROR.OCR_DISABLED)
        elif (method == 'import'):
            if (not current.deployment_settings.has_module('ocr')):
                r.error(501, self.ERROR.OCR_DISABLED)
            authorised = self._permitted(method='create')
            if (not authorised):
                r.unauthorised()
            try:
                if r.component:
                    trigger = r.args[3]
                else:
                    trigger = r.args[1]
            except IndexError:
                trigger = None
            if (trigger == 'review'):
                try:
                    jobuuid = r.vars['jobuuid']
                except KeyError:
                    r.error(501, current.ERROR.BAD_REQUEST)
                current.s3db.table('ocr_meta')
                statustable = db.ocr_form_status
                query = (statustable.job_uuid == jobuuid)
                row = db(query).select(statustable.review_status, statustable.job_has_errors, statustable.image_set_uuid, statustable.form_uuid, limitby=(0, 1)).first()
                if (not row):
                    r.error(501, self.ERROR.INVALID_JOBID)
                if (row.review_status == 1):
                    r.error(501, self.ERROR.JOB_COMPLETE)
                if (row.job_has_errors == 1):
                    job_has_errors = True
                else:
                    job_has_errors = False
                self.setuuid = row.image_set_uuid
                formuuid = row.form_uuid
                metatable = db.ocr_meta
                row = db((metatable.form_uuid == formuuid)).select(metatable.s3ocrxml_file, limitby=(0, 1)).first()
                if (not row):
                    r.error(501, self.ERROR.INVALID_FORMID)
                s3ocrxml_filename = row.s3ocrxml_file
                f = open(os.path.join(r.folder, 'uploads', 'ocr_meta', s3ocrxml_filename), 'rb')
                s3ocrxml = f.read()
                f.close()
                s3ocrdict = self.__s3ocrxml2dict(s3ocrxml)
                import_job = self.resource.import_tree(None, None, job_id=jobuuid, commit_job=False, ignore_errors=True)
                s3import_enabled = True
                if s3import_enabled:
                    s3ocrdata = self.__importjob2data(import_job)
                else:
                    table = db.ocr_data_xml
                    query = (table.image_set_uuid == self.setuuid)
                    row = db(query).select(table.data_file, limitby=(0, 1)).first()
                    if (not row):
                        r.error(501, current.ERROR.BAD_RECORD)
                    s3ocrdataxml_filename = row.data_file
                    f = open(os.path.join(r.folder, 'uploads', 'ocr_payload', s3ocrdataxml_filename), 'rb')
                    s3ocrdataxml = f.read()
                    f.close()
                    s3ocrdata = self.__temp_ocrdataxml_parser(s3ocrdataxml)
                reviewform = self.__create_review_form(s3ocrdict, s3ocrdata)
                return response.render('_ocr_review.html', dict(reviewform=reviewform))
            elif (trigger == 'image'):
                try:
                    setuuid = r.vars['setuuid']
                    resource_table = r.vars['resource_table']
                    field_name = r.vars['field_name']
                except KeyError:
                    r.error(501, current.ERROR.BAD_REQUEST)
                try:
                    value = r.vars['value']
                except KeyError:
                    value = None
                    try:
                        sequence = r.vars['sequence']
                    except KeyError:
                        r.error(501, current.ERROR.BAD_REQUEST)
                current.s3db.table('ocr_meta')
                table = db.ocr_field_crops
                if value:
                    query = ((((table.image_set_uuid == setuuid) & (table.resource_table == resource_table)) & (table.field_name == field_name)) & (table.value == value))
                    row = db(query).select(table.image_file, limitby=(0, 1)).first()
                else:
                    query = ((((table.image_set_uuid == setuuid) & (table.resource_table == resource_table)) & (table.field_name == field_name)) & (table.sequence == sequence))
                    row = db(query).select(table.image_file, limitby=(0, 1)).first()
                if (not row):
                    r.error(501, current.ERROR.BAD_RECORD)
                format = row.image_file[(-4):]
                image_file = open(os.path.join(r.folder, 'uploads', 'ocr_payload', row.image_file))
                image_file_content = image_file.read()
                image_file.close()
                if response:
                    response.headers['Content-Type'] = contenttype(format)
                    response.headers['Content-disposition'] = ('%s;    filename="%s"' % ('inline', ('tempimage%s' % format)))
                return image_file_content
            elif (trigger == 'import'):
                try:
                    setuuid = r.vars['setuuid']
                except KeyError:
                    r.error(501, current.ERROR.BAD_REQUEST)
                statustable = s3db.ocr_form_status
                query = (statustable.image_set_uuid == setuuid)
                row = db(query).select(statustable.job_uuid, limitby=(0, 1)).first()
                if row:
                    jobuuid = row.job_uuid
                    if r.component:
                        request_args = request.get('args', ['', ''])
                        record_id = request_args[0]
                        component_name = request_args[1]
                        urlprefix = ('%s/%s/%s' % (request.function, record_id, component_name))
                    else:
                        urlprefix = request.function
                    redirect(URL(request.controller, ('%s/upload.pdf' % urlprefix), args='review', vars={'jobuuid': jobuuid}))
                table = db.ocr_data_xml
                row = db((table.image_set_uuid == setuuid)).select(table.data_file, table.form_uuid, limitby=(0, 1)).first()
                if (not row):
                    r.error(501, current.ERROR.BAD_RECORD)
                data_file = open(os.path.join(r.folder, 'uploads', 'ocr_payload', row.data_file))
                formuuid = row.form_uuid
                datafile_content = data_file.read()
                data_file.close()
                metatable = db.ocr_meta
                row = db((metatable.form_uuid == formuuid)).select(metatable.s3ocrxml_file, limitby=(0, 1)).first()
                if (not row):
                    r.error(501, self.ERROR.INVALID_FORMID)
                s3ocrxml_filename = row.s3ocrxml_file
                f = open(os.path.join(r.folder, 'uploads', 'ocr_meta', s3ocrxml_filename), 'rb')
                s3ocrxml = f.read()
                f.close()
                s3ocrdict = self.__s3ocrxml2dict(s3ocrxml)
                crosslimit_options = {}
                for resourcename in s3ocrdict['$resource_seq']:
                    resource = s3ocrdict[resourcename]
                    for fieldname in resource['$field_seq']:
                        field = resource[fieldname]
                        if field.has_options:
                            if (field.options and (field.options.count > MAX_FORM_OPTIONS_LIMIT)):
                                if (not crosslimit_options.has_key(resourcename)):
                                    crosslimit_options[resourcename] = [fieldname]
                                else:
                                    crosslimit_options[resourcename].append(fieldname)
                if (len(crosslimit_options) != 0):
                    s3xml_root = etree.fromstring(datafile_content)
                    resource_element = s3xml_root.getchildren()[0]
                    resourcename = resource_element.attrib.get('name')
                    for field in resource_element:
                        if (field.tag == 'data'):
                            if crosslimit_options.has_key(resourcename):
                                fieldname = field.attrib.get('field')
                                if (fieldname in crosslimit_options[resourcename]):
                                    match_status = {}
                                    value = field.text.encode('utf-8').lower()
                                    for option in s3ocrdict[resourcename][fieldname].options.list:
                                        try:
                                            fieldtext = option.label.lower()
                                        except:
                                            fieldtext = ''
                                        match_status[option.value] = self.dameraulevenshtein(cast2ascii(fieldtext), cast2ascii(value))
                                    closematch_value = 1000000000
                                    closematch = []
                                    for match in match_status.keys():
                                        if (match_status[match] < closematch_value):
                                            closematch = [match]
                                            closematch_value = match_status[match]
                                        elif (match_status[match] == closematch_value):
                                            closematch.append(match)
                                    if (len(closematch) > 0):
                                        value = closematch[0]
                                    else:
                                        value = ''
                                    field.text = value
                                    field.attrib['value'] = value
                        elif (field.tag == 'resource'):
                            resourcename = field.attrib.get('name')
                            for subfield in field:
                                if (subfield.tag == 'data'):
                                    fieldname = subfield.attrib.get('field')
                                    if ((resourcename in crosslimit_options.keys()) and (fieldname in crosslimit_options[resourcename])):
                                        match_status = {}
                                        value = subfield.text.encode('utf-8').lower()
                                        for option in s3ocrdict[resourcename][fieldname].options.list:
                                            try:
                                                fieldtext = option.label.lower()
                                            except:
                                                fieldtext = ''
                                            match_status[option.value] = self.dameraulevenshtein(cast2ascii(fieldtext), cast2ascii(value))
                                        closematch_value = 1000000000
                                        closematch = []
                                        for match in match_status.keys():
                                            if (match_status[match] < closematch_value):
                                                closematch = [match]
                                                closematch_value = match_status[match]
                                            elif (match_status[match] == closematch_value):
                                                closematch.append(match)
                                        if (len(closematch) > 0):
                                            value = closematch[0]
                                        else:
                                            value = ''
                                        subfield.text = value
                                        subfield.attrib['value'] = value
                    datafile_content = etree.tostring(s3xml_root)
                outputjson = self.resource.import_xml(StringIO(datafile_content), commit_job=False, ignore_errors=True)
                jobuuid = self.resource.job.job_id
                json2dict = json.loads(outputjson, strict=False)
                if json2dict.has_key('message'):
                    jobhaserrors = 1
                else:
                    jobhaserrors = 0
                if (json2dict.get('statuscode') != '200'):
                    r.error(501, self.ERROR.UNRECOVERABLE_ERROR)
                db.ocr_form_status.insert(image_set_uuid=setuuid, form_uuid=formuuid, job_uuid=jobuuid, job_has_errors=jobhaserrors)
                if r.component:
                    request_args = request.get('args', ['', ''])
                    record_id = request_args[0]
                    component_name = request_args[1]
                    urlprefix = ('%s/%s/%s' % (request.function, record_id, component_name))
                else:
                    urlprefix = request.function
                redirect(URL(request.controller, ('%s/upload.pdf' % urlprefix), args='review', vars={'jobuuid': jobuuid}))
            else:
                auth = current.auth
                if auth.user:
                    utc_offset = auth.user.utc_offset
                else:
                    r.error(501, self.ERROR.NO_UTC_OFFSET)
                current.s3db.ocr_meta
                formuuid = r.vars.get('formuuid', None)
                uploadformat = r.vars.get('uploadformat', None)
                requesturl = request.env.path_info
                createurl = ('%s/create.pdf' % requesturl[0:requesturl.rfind('/')])
                if (not (formuuid and uploadformat)):
                    availForms = self.__getResourceForms()
                    return response.render('_ocr_upload.html', dict(availForms=availForms, createurl=createurl))
                else:
                    try:
                        numpages = self.__getNumPages(formuuid)
                    except:
                        r.error(501, current.ERROR.BAD_RECORD)
                    if (not numpages):
                        r.error(501, self.ERROR.EMPTY_OCR_FORM)
                    return response.render('_ocr_page_upload.html', dict(numpages=numpages, posturl=createurl, formuuid=formuuid, uploadformat=uploadformat))
                numpages = self.__getNumPages(formuuid)
                if (not numpages):
                    r.error(501, self.ERROR.EMPTY_OCR_FORM)
                return response.render('_ocr_page_upload.html', dict(numpages=numpages, posturl=createurl, formuuid=formuuid, uploadformat=uploadformat))
        else:
            r.error(405, current.ERROR.BAD_METHOD)
    elif (r.http == 'POST'):
        if (method == 'create'):
            if (not current.deployment_settings.has_module('ocr')):
                r.error(501, self.ERROR.OCR_DISABLED)
            formuuid = r.vars.formuuid
            numpages = int(r.vars.numpages)
            uploadformat = r.vars.uploadformat
            import uuid
            setuuid = uuid.uuid1()
            current.s3db.ocr_meta
            if (uploadformat == 'image'):
                payloadtable = db.ocr_payload
                for eachpage in xrange(1, (numpages + 1)):
                    varname = ('page%s' % eachpage)
                    fileholder = r.vars[varname]
                    pagenumber = eachpage
                    imgfilename = fileholder.filename
                    extension = (lambda m: m[(m.rfind('.') + 1):])
                    imageformats = ['jpg', 'png', 'gif', 'bmp']
                    if (extension(imgfilename) not in imageformats):
                        r.error(501, self.ERROR.INVALID_IMAGE_TYPE)
                    payloadtable.insert(image_set_uuid=setuuid, image_file=payloadtable['image_file'].store(fileholder.file, fileholder.filename), page_number=pagenumber)
            elif (uploadformat == 'pdf'):
                fileholder = r.vars['pdffile']
                filename = fileholder.filename
                extension = (lambda m: m[(m.rfind('.') + 1):])
                if (extension(filename) != 'pdf'):
                    r.error(501, self.ERROR.NOT_PDF_FILE)
                uniqueuuid = setuuid
                inputfilename = ('%s_%s' % (uniqueuuid, fileholder.filename))
                outputfilename = ('%s_%s.png' % (uniqueuuid, fileholder.filename[:(-4)]))
                ocr_temp_dir = os.path.join(self.r.folder, 'uploads', 'ocr_temp')
                try:
                    os.mkdir(ocr_temp_dir)
                except OSError:
                    pass
                f = open(os.path.join(ocr_temp_dir, inputfilename), 'w')
                f.write(fileholder.file.read())
                f.close()
                success = subprocess.call(['convert', os.path.join(ocr_temp_dir, inputfilename), os.path.join(ocr_temp_dir, outputfilename)])
                if (success != 0):
                    self.r.error(501, self.ERROR.IMAGE_MAGICK_ERROR)
                payloadtable = db.ocr_payload
                if (numpages == 1):
                    imagefilename = outputfilename
                    imgfilepath = os.path.join(ocr_temp_dir, imagefilename)
                    try:
                        imgfile = open(imgfilepath)
                    except IOError:
                        self.r.error(501, self.ERROR.INVALID_PDF)
                    pagenumber = 1
                    payloadtable.insert(image_set_uuid=setuuid, image_file=payloadtable['image_file'].store(imgfile, imagefilename), page_number=pagenumber)
                    imgfile.close()
                    os.remove(imgfilepath)
                else:
                    for eachpage in xrange(0, numpages):
                        imagefilename = ('%s-%s.png' % (outputfilename[:(-4)], eachpage))
                        imgfilepath = os.path.join(ocr_temp_dir, imagefilename)
                        try:
                            imgfile = open(imgfilepath, 'r')
                        except IOError:
                            self.r.error(501, self.ERROR.INVALID_PDF)
                        pagenumber = (eachpage + 1)
                        payloadtable.insert(image_set_uuid=setuuid, image_file=payloadtable['image_file'].store(imgfile, imagefilename), page_number=pagenumber)
                        imgfile.close()
                        os.remove(imgfilepath)
                os.remove(os.path.join(ocr_temp_dir, inputfilename))
                try:
                    os.rmdir(ocr_temp_dir)
                except OSError:
                    import shutil
                    shutil.rmtree(ocr_temp_dir)
            else:
                r.error(501, self.ERROR.INVALID_IMAGE_TYPE)
            s3ocrimageparser = S3OCRImageParser(self, r)
            output = s3ocrimageparser.parse(formuuid, setuuid)
            table = db.ocr_data_xml
            table.insert(image_set_uuid=setuuid, data_file=table['data_file'].store(StringIO(output), ('%s-data.xml' % setuuid)), form_uuid=formuuid)
            if r.component:
                request_args = current.request.get('args', ['', ''])
                record_id = request_args[0]
                component_name = request_args[1]
                urlprefix = ('%s/%s/%s' % (request.function, record_id, component_name))
            else:
                urlprefix = request.function
            redirect(URL(request.controller, ('%s/import.pdf' % urlprefix), args='import', vars={'setuuid': setuuid}))
        elif (method == 'import'):
            if (not current.deployment_settings.has_module('ocr')):
                r.error(501, self.ERROR.OCR_DISABLED)
            authorised = self._permitted(method='create')
            if (not authorised):
                r.unauthorised()
            try:
                if r.component:
                    trigger = r.args[3]
                else:
                    trigger = r.args[1]
            except IndexError:
                trigger = None
            if (trigger == 'review'):
                jobuuid = r.vars.pop('jobuuid')
                statustable = current.s3db.ocr_form_status
                query = (statustable.job_uuid == jobuuid)
                row = db(query).select(statustable.review_status, limitby=(0, 1)).first()
                if (not row):
                    r.error(501, self.ERROR.INVALID_JOBID)
                if (row.review_status == 1):
                    r.error(501, self.ERROR.JOB_COMPLETE)
                try:
                    r.vars.pop('_utc_offset')
                except:
                    pass
                try:
                    ignore_fields = r.vars.pop('ignore-fields-list')
                except:
                    ignore_fields = None
                if (not ignore_fields):
                    ignore_fields = []
                else:
                    try:
                        ignore_fields = ignore_fields.split('|')
                    except:
                        ignore_fields = [ignore_fields]
                datadict = Storage()
                for field in r.vars.keys():
                    (resourcetable, fieldname) = field.split('-')
                    if (not datadict.has_key(resourcetable)):
                        datadict[resourcetable] = Storage()
                    datadict[resourcetable][fieldname] = r.vars[field]
                for field in ignore_fields:
                    (resourcetable, fieldname) = field.split('-')
                    datadict[resourcetable].pop(fieldname)
                    if (len(datadict[resourcetable]) == 0):
                        datadict.pop(resourcetable)
                s3xml_etree_dict = Storage()
                for resource in datadict.keys():
                    s3xml_root = etree.Element('s3xml')
                    resource_element = etree.SubElement(s3xml_root, 'resource')
                    resource_element.attrib['name'] = resource
                    for field in datadict[resource].keys():
                        fieldvalue = datadict[resource][field]
                        fieldvalue = (str(fieldvalue) if fieldvalue else '')
                        fieldtype = db[resource][field].type
                        if fieldtype.startswith('reference    '):
                            reference_resource_name = fieldtype[len('reference    '):]
                            reference_element = etree.SubElement(resource_element, 'reference')
                            reference_element.attrib['field'] = field
                            reference_element.attrib['resource'] = reference_resource_name
                            ref_res_element = etree.SubElement(reference_element, 'resource')
                            ref_res_element.attrib['name'] = reference_resource_name
                            ref_res_data_element = etree.SubElement(ref_res_element, 'data')
                            ref_res_data_element.attrib['field'] = 'name'
                            try:
                                ref_res_data_element.text = cast2ascii(fieldvalue)
                            except ValueError:
                                ref_res_data_element.text = ''
                        else:
                            field_element = etree.SubElement(resource_element, 'data')
                            field_element.attrib['field'] = field
                            try:
                                field_element.attrib['value'] = cast2ascii(fieldvalue)
                            except ValueError:
                                field_element.attrib['value'] = ''
                            try:
                                field_element.text = cast2ascii(fieldvalue)
                            except ValueError:
                                field_element.text = ''
                    s3xml_etree_dict[resource] = s3xml_root
                errordict = {}
                _record = current.xml.record
                s3record_dict = Storage()
                for tablename in s3xml_etree_dict.keys():
                    record = _record(db[tablename], s3xml_etree_dict[tablename].getchildren()[0])
                    s3record_dict[tablename] = record
                import_job = r.resource.import_tree(None, None, job_id=jobuuid, ignore_errors=False, commit_job=False)
                response.headers['Content-Type'] = contenttype('.json')
                for tablename in s3record_dict.keys():
                    record = s3record_dict[tablename]
                    possible_items = []
                    our_item = None
                    for eachitem in import_job.items.keys():
                        item = import_job.items[eachitem]
                        if (item.table == tablename):
                            if (item.data and (len(item.data) > 0)):
                                our_item = item
                            elif (item.data and (len(item.data) == 0)):
                                possible_items.append(item)
                    if our_item:
                        our_item.update(record)
                    elif (len(possible_items) > 0):
                        possible_items[0].update(record)
                    else:
                        import_job.add_item(s3xml_etree_dict[tablename].getchildren()[0])
                    for resourcename in datadict.keys():
                        table = db[resourcename]
                        for field in datadict[resourcename].keys():
                            if (not table[field].type.startswith('reference    ')):
                                (value, error) = s3_validate(table, field, datadict[resourcename][field])
                                if error:
                                    errordict[('%s-%s' % (resourcename, field))] = str(error)
                if (not import_job.error_tree):
                    store_success = import_job.store()
                    if store_success:
                        if import_job.error_tree:
                            errordict = self.__parse_job_error_tree(import_job.error_tree)
                            success = False
                        else:
                            for resourcename in datadict.keys():
                                table = db[resourcename]
                                for field in datadict[resourcename].keys():
                                    if (not table[field].type.startswith('reference    ')):
                                        (value, error) = s3_validate(table, field, datadict[resourcename][field])
                                        if error:
                                            errordict[('%s-%s' % (resourcename, field))] = str(error)
                            if (len(errordict) > 0):
                                success = False
                            else:
                                success = True
                                import_job.commit()
                    else:
                        errordict = self.__parse_job_error_tree(import_job.error_tree)
                        success = False
                else:
                    errordict = self.__parse_job_error_tree(import_job.error_tree)
                    success = False
                if success:
                    session.confirmation = T('OCR    review    data    has    been    stored    into    the    database    successfully.')
                    statustable = db['ocr_form_status']
                    query = (statustable.job_uuid == jobuuid)
                    row = db(query).select(statustable.image_set_uuid).first()
                    image_set_uuid = row.image_set_uuid
                    db(query).update(review_status=1)
                    cropstable = db.ocr_field_crops
                    query = (cropstable.image_set_uuid == image_set_uuid)
                    rows = db(query).select(cropstable.image_file)
                    for row in rows:
                        filename = row.image_file
                        filepath = os.path.join(self.r.folder, 'uploads', 'ocr_payload', filename)
                        os.remove(filepath)
                    db(query).delete()
                return json.dumps({'success': success, 'error': errordict})
        else:
            r.error(405, current.ERROR.BAD_METHOD)
    else:
        r.error(501, current.ERROR.BAD_REQUEST)
