def test_indent(self): h = [['blorpie'], ['whoops'], [], 'd-shtaeou', 'd-nthiouh', 'i-vhbjkhnth', {'nifty': 87}, {'field': 'yes', 'morefield': False} ] expect = textwrap.dedent("""\ [ [ "blorpie" ], [ "whoops" ], [], "d-shtaeou", "d-nthiouh", "i-vhbjkhnth", { "nifty": 87 }, { "field": "yes", "morefield": false } ]""") d1 = json.dumps(h) d2 = json.dumps(h, indent=2, sort_keys=True, separators=(',', ': ')) h1 = json.loads(d1) h2 = json.loads(d2) self.assertEquals(h1, h) self.assertEquals(h2, h) self.assertEquals(d2, expect)
def test_failures(self): for idx, doc in enumerate(JSONDOCS): idx = idx + 1 if idx in SKIPS: json.loads(doc) continue try: json.loads(doc) except ValueError: pass else: self.fail("Expected failure for fail%d.json: %r" % (idx, doc))
def getDatagridRowdata(context, REQUEST): """ Return rowdata for a datagrid on a modal popup In the context of a modal datagrid popup, return the rowdata on the REQUEST. """ # This is currently just used during creation of TemporaryDocument, # but may possibly be useful in formulas. I won't publish it yet though. if not REQUEST: return [], [] mapped_field_ids = [] rowdata = [] form_id = getattr(REQUEST, 'Plomino_Parent_Form', None) field_id = getattr(REQUEST, 'Plomino_Parent_Field', None) if form_id and field_id: form = context.getParentDatabase().getForm(form_id) field = form.getFormField(field_id) settings = field.getSettings() mapped_field_ids = [ f.strip() for f in settings.field_mapping.split(',') ] rowdata_json = getattr(REQUEST, 'Plomino_datagrid_rowdata', None) if rowdata_json: rowdata = json.loads( urllib.unquote(rowdata_json).decode('raw_unicode_escape')) return mapped_field_ids, rowdata
def __query_loads__(self, request_query): """ """ # Some fields might express a date # We try to convert those strings to datetime indexes = self.getParentDatabase().getIndex().Indexes request_query = json.loads(request_query) for key, value in request_query.iteritems(): if key in indexes: index = indexes[key] # This is lame: we should check if it quacks, not # if it's a duck! # XXX Use a more robust method to tell apart # date indexes from non-dates if isinstance(index, DateIndex): # convert value(s) to date(s) if isinstance(value, basestring): request_query[key] = parse_date(value) elif 'query' not in value: # it means value is a list of date values to be used # with the implicit default operator query OR request_query[key] = map(parse_date, value) else: # it means value is a dictionary if isinstance(value['query'], basestring): # query got a single comparison value request_query[key]['query'] = parse_date( value['query']) else: # query got a list of comparison values request_query[key]['query'] = map( parse_date, value['query'] ) return request_query
def processInput(self, submittedValue): """ """ try: return json.loads(submittedValue) except: return []
def getDatagridRowdata(context, REQUEST): """ Return rowdata for a datagrid on a modal popup In the context of a modal datagrid popup, return the rowdata on the REQUEST. """ # This is currently just used during creation of TemporaryDocument, # but may possibly be useful in formulas. I won't publish it yet though. if not REQUEST: return [], [] mapped_field_ids = [] rowdata = [] form_id = getattr(REQUEST, 'Plomino_Parent_Form', None) field_id = getattr(REQUEST, 'Plomino_Parent_Field', None) if form_id and field_id: form = context.getParentDatabase().getForm(form_id) field = form.getFormField(field_id) settings = field.getSettings() mapped_field_ids = [f.strip() for f in settings.field_mapping.split(',')] rowdata_json = getattr(REQUEST, 'Plomino_datagrid_rowdata', None) if rowdata_json: rowdata = json.loads( urllib.unquote(rowdata_json).decode('raw_unicode_escape')) return mapped_field_ids, rowdata
def getFieldValue(self, form, doc, editmode, creation, request): """ """ fieldName = self.context.id mode = self.context.getFieldMode() db = self.context.getParentDatabase() if doc is None: target = form else: target = doc fieldValue = None if mode == "EDITABLE": if doc is None: if creation and not self.context.Formula() == "": fieldValue = form.computeFieldValue(fieldName, target) elif request is None: fieldValue = "" else: row_data_json = request.get("Plomino_datagrid_rowdata", None) if row_data_json is not None: # datagrid form case parent_form = request.get("Plomino_Parent_Form", None) parent_field = request.get("Plomino_Parent_Field", None) data = json.loads(row_data_json) datagrid_fields = db.getForm(parent_form).getFormField( parent_field).getSettings().field_mapping.split( ',') if fieldName in datagrid_fields: fieldValue = data[datagrid_fields.index(fieldName)] else: fieldValue = "" else: fieldValue = asUnicode(request.get(fieldName, '')) else: fieldValue = doc.getItem(fieldName) if mode == "DISPLAY" or mode == "COMPUTED": fieldValue = form.computeFieldValue(fieldName, target) if mode == "CREATION": if creation: # Note: on creation, there is no doc, we use form as target # in formula fieldValue = form.computeFieldValue(fieldName, form) else: fieldValue = doc.getItem(fieldName) if mode == "COMPUTEDONSAVE" and doc: fieldValue = doc.getItem(fieldName) if fieldValue is None: fieldValue = "" return fieldValue
def addField(self): # specific field settings are managed as instance behaviors (using # collective.instancebehavior), but it is not supported by # plone.restapi, so we implement our own endpoint to create fields. self.request.RESPONSE.setHeader( 'content-type', 'text/plain; charset=utf-8') if self.request.method == "POST": alsoProvides( self.request, plone.protect.interfaces.IDisableCSRFProtection) data = json.loads(self.request.BODY) newfield = api.content.create( container=self.context, type="PlominoField", title=data['title'], ) return json.dumps({'created': newfield.id})
def addField(self): # specific field settings are managed as instance behaviors (using # collective.instancebehavior), but it is not supported by # plone.restapi, so we implement our own endpoint to create fields. self.request.RESPONSE.setHeader('content-type', 'text/plain; charset=utf-8') if self.request.method == "POST": alsoProvides(self.request, plone.protect.interfaces.IDisableCSRFProtection) data = json.loads(self.request.BODY) newfield = api.content.create( container=self.context, type="PlominoField", title=data['title'], ) return json.dumps({'created': newfield.id})
def _get_js_hidden_fields(self, REQUEST, doc): hidden_fields = [] hidewhens = json.loads(self.getHidewhenAsJSON(REQUEST)) html_content = self._get_html_content() for hidewhenName, doit in hidewhens.items(): if not doit: # Only consider True hidewhens continue start = '<span class="plominoHidewhenClass">start:' + hidewhenName + '</span>' end = '<span class="plominoHidewhenClass">end:' + hidewhenName + '</span>' for hiddensection in re.findall(start + '(.*?)' + end, html_content): hidden_fields += re.findall( '<span class="plominoFieldClass">([^<]+)</span>', hiddensection) for subformname in self.getSubforms(doc): subform = self.getParentDatabase().getForm(subformname) hidden_fields += subform._get_js_hidden_fields(REQUEST, doc) return hidden_fields
def getFieldValue(self, form, doc=None, editmode_obsolete=False, creation=False, request=None): """ Return the field as rendered by ``form`` on ``doc``. """ # XXX: The editmode_obsolete parameter is unused. fieldName = self.context.id mode = self.context.getFieldMode() db = self.context.getParentDatabase() if doc is None: target = form else: target = doc fieldValue = None # XXX This is super-ugly, sorry. The reason I do this is that # I changed some logic upper in the call chain to give a # properly populated TemporaryDocument to hideWhens # to avoid users coding defensively with unneeded # try: catch blocks. # A proper solution would probably be to factor out the logic # that finds a field value and use that logic to populate # the TemporaryDocument. # But *right now* (that is better than never) I see this solution # works without breaking any test. temporary_doc_in_overlay = ( isinstance(aq_base(doc), TemporaryDocument) and hasattr(self.context, 'REQUEST') and 'Plomino_Parent_Form' in self.context.REQUEST.form and not self.context.REQUEST.get('ACTUAL_URL').endswith( '/createDocument')) if temporary_doc_in_overlay: request = self.context.REQUEST if mode == "EDITABLE": if doc is None or creation or temporary_doc_in_overlay: # The aforementioned ugliness ends here if self.context.Formula(): fieldValue = form.computeFieldValue(fieldName, target) elif request is None: fieldValue = "" else: row_data_json = request.get("Plomino_datagrid_rowdata", None) if row_data_json is not None: # datagrid form case parent_form = request.get("Plomino_Parent_Form", None) parent_field = request.get("Plomino_Parent_Field", None) data = json.loads( unquote(row_data_json).decode( 'raw_unicode_escape')) datagrid_fields = ( db.getForm(parent_form).getFormField(parent_field). getSettings().field_mapping.split(',')) if fieldName in datagrid_fields: fieldValue = data[datagrid_fields.index(fieldName)] else: fieldValue = "" else: # if no doc context and no default formula, we accept # value passed in the REQUEST so we look for 'fieldName' # but also for 'fieldName_querystring' which allows to # pass value via the querystring without messing the # POST content request_value = request.get(fieldName, '') if not request_value: request_value = request.get( fieldName + '_querystring', '') fieldValue = asUnicode(request_value) else: fieldValue = doc.getItem(fieldName) elif mode in ["DISPLAY", "COMPUTED"]: if mode == "DISPLAY" and not self.context.Formula() and doc: fieldValue = doc.getItem(fieldName) else: fieldValue = form.computeFieldValue(fieldName, target) elif mode == "CREATION": if creation: # Note: on creation, there is no doc, we use form as target # in formula fieldValue = form.computeFieldValue(fieldName, form) else: fieldValue = doc.getItem(fieldName) elif mode == "COMPUTEDONSAVE" and doc: fieldValue = doc.getItem(fieldName) if fieldValue is None: fieldValue = "" return fieldValue
def json_loads(json_string): return json.loads(json_string)
def json_decode(jsonstr): try: return json.loads(jsonstr) except (ValueError, TypeError), le: raise DecodeError(jsonstr, le)
def getFieldValue(self, form, doc, editmode, creation, request): """ """ fieldName = self.context.id mode = self.context.getFieldMode() db = self.context.getParentDatabase() if doc is None: target = form else: target = doc fieldValue = None # XXX This is super-ugly, sorry. The reason I do this is that # I changed some logic upper in the call chain to give a # properly populated TemporaryDocument to hideWhens # to avoid users coding defensively with unneeded # try: catch blocks. # A proper solution would probably be to factor out the logic # that finds a field value and use that logic to populate # the TemporaryDocument. # But *right now* (that is better than never) I see this solution # works without breaking any test. temporary_doc_in_overlay = (isinstance(aq_base(doc), TemporaryDocument) and hasattr(self.context, 'REQUEST') and 'Plomino_Parent_Form' in self.context.REQUEST.form) if temporary_doc_in_overlay: request = self.context.REQUEST if mode == "EDITABLE": if doc is None or temporary_doc_in_overlay: # The aforemntioned ugliness ends here if creation and self.context.Formula(): fieldValue = form.computeFieldValue(fieldName, target) elif request is None: fieldValue = "" else: row_data_json = request.get("Plomino_datagrid_rowdata", None) if row_data_json is not None: # datagrid form case parent_form = request.get("Plomino_Parent_Form", None) parent_field = request.get("Plomino_Parent_Field", None) data = json.loads(row_data_json) datagrid_fields = db.getForm(parent_form).getFormField( parent_field).getSettings().field_mapping.split( ',') if fieldName in datagrid_fields: fieldValue = data[datagrid_fields.index(fieldName)] else: fieldValue = "" else: fieldValue = asUnicode(request.get(fieldName, '')) else: fieldValue = doc.getItem(fieldName) if mode == "DISPLAY" or mode == "COMPUTED": fieldValue = form.computeFieldValue(fieldName, target) if mode == "CREATION": if creation: # Note: on creation, there is no doc, we use form as target # in formula fieldValue = form.computeFieldValue(fieldName, form) else: fieldValue = doc.getItem(fieldName) if mode == "COMPUTEDONSAVE" and doc: fieldValue = doc.getItem(fieldName) if fieldValue is None: fieldValue = "" return fieldValue
result = {} target = TemporaryDocument(self.getParentDatabase(), self, REQUEST) for hidewhen in self.getHidewhenFormulas(): if getattr(hidewhen, 'isDynamicHidewhen', False): try: isHidden = self.runFormulaScript( "hidewhen_" + self.id + "_" + hidewhen.id + "_formula", target, hidewhen.Formula) except PlominoScriptException, e: e.reportError('%s hide-when formula failed' % hidewhen.id) #if error, we hide anyway isHidden = True result[hidewhen.id] = isHidden for subformname in self.getSubforms(): form = self.getParentDatabase().getForm(subformname) form_hidewhens = json.loads(form.getHidewhenAsJSON(REQUEST)) result.update(form_hidewhens) return json.dumps(result) security.declareProtected(READ_PERMISSION, 'applyCache') def applyCache(self, html_content, doc=None): """ Evaluate cache formula and return resulting layout """ to_be_cached = {} for cacheformula in self.getCacheFormulas(): cacheid = cacheformula.id try: if doc is None:
def code(self): if self.request.method == "GET": self.request.RESPONSE.setHeader( 'content-type', 'text/plain; charset=utf-8') type = self.request.form.keys()[0] if type not in ["Form", "FormField", "FormAction", "FormHidewhen", "View", "ViewAction", "ViewColumn", "Agent"]: return "Parameter error" element = self.getElementByType(type, self.request.form[type]) if not element: return "Name error" if type == "Agent": return json.dumps({"code" : element.content, "methods" : []}) if type == "FormHidewhen": return json.dumps({"code" : element.formula, "methods" : []}) methods = self.getMethods(type) code = "" for method in self.getMethodsId(type): formula = getattr(element, method, None) if formula: code+= "## START "+method+" {\n" code+= formula code+= "\n## END "+method+" }\n\r" elements = {"code" : code, "methods" : methods} return json.dumps(elements) if self.request.method == "POST": alsoProvides(self.request,plone.protect.interfaces.IDisableCSRFProtection) self.request.RESPONSE.setHeader( 'content-type', 'application/json; charset=utf-8') response = json.loads(self.request.BODY) type = response["Type"] id = response["Id"] code = response["Code"] if type == "Agent": self.context.getAgent(id).content = code return json.dumps({ "type": "OK" }) if type == "FormHidewhen": id = id.split('/') self.context.getForm(id[0]).getHidewhen(id[1]).formula = code return json.dumps({ "type": "OK" }) methodList = self.getMethodsId(type) content = "" contents = [] inside = False for lineNumber, line in enumerate(code.split('\n')): start_reg = re.match(r'^##\s*START\s+(.*){$', line) end_reg = re.match(r'^##\s*END\s+(.*)}$',line) if start_reg and not inside: if start_reg.group(1).strip() in methodList: methodName = start_reg.group(1).strip() inside = True else: return json.dumps({ "type": "Error", "error": "Method \""+start_reg.group(1).strip()+"\" doesn't exists", "line": lineNumber+1 }) elif end_reg and inside: if end_reg.group(1).strip() != methodName: return json.dumps({ "type": "Error", "error": "END tag doesn't match START tag", "line": lineNumber+1 }) contents.append({ "name": methodName, "code": content }) inside = False content = '' elif not start_reg and not end_reg and inside: content+= line+"\n" elif end_reg and not inside: return json.dumps({ "type": "Error", "error": "Unexpected END tag", "line": lineNumber+1 }) elif start_reg and inside: return json.dumps({ "type": "Error", "error": "Unexpected START tag", "line": lineNumber+1 }) element = self.getElementByType(type,id) for formula in methodList: setattr(element,formula,'') for formula in contents: setattr(element,formula['name'],formula['code'].rstrip()) return json.dumps({ "type": "OK" })
def test_decimal(self): rval = json.loads('1.1', parse_float=decimal.Decimal) self.assert_(isinstance(rval, decimal.Decimal)) self.assertEquals(rval, decimal.Decimal('1.1'))
def test_float(self): rval = json.loads('1', parse_int=float) self.assert_(isinstance(rval, float)) self.assertEquals(rval, 1.0)
def test_unicode_decode(self): for i in range(0, 0xd7ff): u = unichr(i) js = '"\\u%04x"' % (i,) self.assertEquals(json.loads(js), u)
def test_big_unicode_decode(self): u = u'z\U0001d120x' self.assertEquals(json.loads('"' + u + '"'), u) self.assertEquals(json.loads('"z\\ud834\\udd20x"'), u)
def test_no_exception_on_convergent_parse_float(self): self.failUnlessEqual(jsonutil.loads("0.1", parse_float=Decimal), zero_point_one)
def test_parse(self): # test in/out equivalence and parsing res = json.loads(JSON) out = json.dumps(res) self.assertEquals(res, json.loads(out))
def code(self): if self.request.method == "GET": self.request.RESPONSE.setHeader('content-type', 'text/plain; charset=utf-8') type = self.request.form.keys()[0] if type not in [ "Form", "FormField", "FormAction", "FormHidewhen", "View", "ViewAction", "ViewColumn", "Agent" ]: return "Parameter error" element = self.getElementByType(type, self.request.form[type]) if not element: return "Name error" if type == "Agent": return json.dumps({"code": element.content, "methods": []}) if type == "FormHidewhen": return json.dumps({"code": element.formula, "methods": []}) methods = self.getMethods(type) code = "" for method in self.getMethodsId(type): formula = getattr(element, method, None) if formula: code += "## START " + method + " {\n" code += formula code += "\n## END " + method + " }\n\r" elements = {"code": code, "methods": methods} return json.dumps(elements) if self.request.method == "POST": alsoProvides(self.request, plone.protect.interfaces.IDisableCSRFProtection) self.request.RESPONSE.setHeader('content-type', 'application/json; charset=utf-8') response = json.loads(self.request.BODY) type = response["Type"] id = response["Id"] code = response["Code"] if type == "Agent": self.context.getAgent(id).content = code return json.dumps({"type": "OK"}) if type == "FormHidewhen": id = id.split('/') self.context.getForm(id[0]).getHidewhen(id[1]).formula = code return json.dumps({"type": "OK"}) methodList = self.getMethodsId(type) content = "" contents = [] inside = False for lineNumber, line in enumerate(code.split('\n')): start_reg = re.match(r'^##\s*START\s+(.*){$', line) end_reg = re.match(r'^##\s*END\s+(.*)}$', line) if start_reg and not inside: if start_reg.group(1).strip() in methodList: methodName = start_reg.group(1).strip() inside = True else: return json.dumps({ "type": "Error", "error": "Method \"" + start_reg.group(1).strip() + "\" doesn't exists", "line": lineNumber + 1 }) elif end_reg and inside: if end_reg.group(1).strip() != methodName: return json.dumps({ "type": "Error", "error": "END tag doesn't match START tag", "line": lineNumber + 1 }) contents.append({"name": methodName, "code": content}) inside = False content = '' elif not start_reg and not end_reg and inside: content += line + "\n" elif end_reg and not inside: return json.dumps({ "type": "Error", "error": "Unexpected END tag", "line": lineNumber + 1 }) elif start_reg and inside: return json.dumps({ "type": "Error", "error": "Unexpected START tag", "line": lineNumber + 1 }) element = self.getElementByType(type, id) for formula in methodList: setattr(element, formula, '') for formula in contents: setattr(element, formula['name'], formula['code'].rstrip()) return json.dumps({"type": "OK"})
def test_parse(self): # test in/out equivalence and parsing res = json.loads(JSON) out = json.dumps(res) self.assertEquals(res, json.loads(out)) self.failUnless("2.3456789012E+676" in json.dumps(res, allow_nan=False))
def test_decode(self): self.failUnlessEqual(jsonutil.loads("0.1"), zero_point_one)
def search_json(self, REQUEST=None): """ Returns a JSON representation of view filtered data """ data = [] categorized = self.getCategorized() start = 1 search = None sort_index = None reverse = 1 if REQUEST: start = int(REQUEST.get('iDisplayStart', 1)) limit = REQUEST.get('iDisplayLength') limit = (limit and int(limit)) # In case limit == -1 we want it to be None if limit < 1: limit = None search = REQUEST.get('sSearch', '').lower() if search: search = " ".join([term+'*' for term in search.split(' ')]) sort_column = REQUEST.get('iSortCol_0') if sort_column: sort_index = self.getIndexKey(self.getColumns()[int(sort_column)-1].id) reverse = REQUEST.get('sSortDir_0') or 'asc' if reverse=='desc': reverse = 0 if reverse=='asc': reverse = 1 query_request = json.loads(REQUEST['query']) # Some fields might express a date # We try to convert those strings to datetime #indexes = self.aq_parent.aq_base.plomino_index.Indexes indexes = self.getParentDatabase().getIndex().Indexes for key, value in query_request.iteritems(): if key in indexes: index = indexes[key] # This is lame: we should check if it quacks, not # if it's a duck! # XXX Use a more robust method to tell apart # date indexes from non-dates # I'd use a solution like this one: http://getpython3.com/diveintopython3/examples/customserializer.py if isinstance(index, DateIndex): # convert value(s) to date(s) if isinstance(value, basestring): query_request[key] = parse_date(value) else: if isinstance(value['query'], basestring): value['query'] = parse_date(value['query']) else: query_request[key]['query'] = [parse_date(v) for v in value['query']] results, total = self.search_documents(start=1, limit=None, getObject=False, fulltext_query=search, sortindex=sort_index, reverse=reverse, query_request=query_request) if limit: if HAS_PLONE43: results = Batch(items=results, size=limit, start=int(start/limit)+1)*limit else: results = Batch(items=results, pagesize=limit, pagenumber=int(start/limit)+1) display_total = len(results) columnids = [col.id for col in self.getColumns() if not getattr(col, 'HiddenColumn', False)] for b in results: row = [b.getPath().split('/')[-1]] for colid in columnids: v = getattr(b, self.getIndexKey(colid), '') if isinstance(v, list): v = [asUnicode(e).encode('utf-8').replace('\r', '') for e in v] else: v = asUnicode(v).encode('utf-8').replace('\r', '') row.append(v or ' ') if categorized: for cat in asList(row[1]): entry = [c for c in row] entry[1] = cat data.append(entry) else: data.append(row) return json.dumps({ 'iTotalRecords': total, 'iTotalDisplayRecords': display_total, 'aaData': data })