def __set__(self, inst, value): field = self._field.bind(inst) field.validate(value) if field.readonly: raise ValueError(self._field.__name__, 'field is readonly') if isinstance(value, datetime): # The ensures that the converted DateTime value is in the # server's local timezone rather than GMT. value = DateTime(value.year, value.month, value.day, value.hour, value.minute) elif value is not None: if IText.providedBy(self._field): value = value.encode('utf-8') elif ISequence.providedBy(self._field): if IText.providedBy(self._field.value_type): value = type(value)( item.encode('utf-8') for item in value ) if self._set_name: getattr(inst.context, self._set_name)(value) elif inst.context.hasProperty(self._get_name): inst.context._updateProperty(self._get_name, value) else: setattr(inst.context, self._get_name, value)
def get_collection_schema_from_interface_schema(self, schema): collection = {} for name in schema: if IDate.providedBy(schema[name]) or \ IDatetime.providedBy(schema[name]): collection['field.'+name] = 'time' elif IDecimal.providedBy(schema[name]) or \ IFloat.providedBy(schema[name]) or \ IInt.providedBy(schema[name]): collection['field.'+name] = 'number' elif IBool.providedBy(schema[name]): collection['field.'+name] = 'bool' elif ICollection.providedBy(schema[name]): if not ICollection.providedBy(schema[name].value_type) and not \ IDict.providedBy(schema[name].value_type): collection['field.'+name] = 'array' elif IDict.providedBy(schema[name]): if IText.providedBy(schema[name].key_type) and \ IText.providedBy(schema[name].value_type): collection['field.'+name] = 'array' # this is a pretty weak check for a IP address field. We might want # to update this to look for a field validator based on the ipaddress package # or mark this field with a special interface indicating it is an # IP address elif IDottedName.providedBy(schema[name]) and \ (schema[name].min_dots == schema[name].max_dots == 3): collection['field.'+name] = 'cidr' elif IText.providedBy(schema[name]) or \ INativeString.providedBy(schema[name]): collection['field.'+name] = 'string' return collection
def __get__(self, inst, klass): if inst is None: return self attribute = getattr(inst.context, self._get_name, _marker) if attribute is _marker: field = self._field.bind(inst) attribute = getattr(field, 'default', _marker) if attribute is _marker: raise AttributeError(self._field.__name__) elif callable(attribute): attribute = attribute() if isinstance(attribute, DateTime): # Ensure datetime value is stripped of any timezone and seconds # so that it can be compared with the value returned by the widget return datetime(*map(int, attribute.parts()[:6])) if attribute is None: return if IText.providedBy(self._field): return attribute.decode('utf-8') if ISequence.providedBy(self._field): if IText.providedBy(self._field.value_type): return type(attribute)( item.decode('utf-8') for item in attribute ) return attribute
def __get__(self, inst, klass): if inst is None: return self attribute = getattr(inst.context, self._get_name, _marker) if attribute is _marker: field = self._field.bind(inst) attribute = getattr(field, 'default', _marker) if attribute is _marker: raise AttributeError(self._field.__name__) elif callable(attribute): attribute = attribute() if isinstance(attribute, DateTime): # Ensure datetime value is stripped of any timezone and seconds # so that it can be compared with the value returned by the widget return datetime(*list(map(int, attribute.parts()[:6]))) if attribute is None: return if IText.providedBy(self._field): if six.PY2: return attribute.decode('utf-8') if ISequence.providedBy(self._field): if IText.providedBy(self._field.value_type): if six.PY2: return type(attribute)(item.decode('utf-8') for item in attribute) return attribute
def filter_batch_on_properties(self, batch): reverse = True if (self.sort_dir == "desc") else False if self.sort_on in self.filter_property_fields: sort_on = self.sort_on[5:] if sort_on not in self.utk: batch.sort(key=lambda x: getattr(x, sort_on), reverse=reverse) for field_name in self.filter_property_fields: md_field = self.domain_annotation.get(field_name) ff_name = "filter_%s" % (field_name) ff = self.request.get(ff_name, None) if ff and md_field: if (IDate.providedBy(md_field.property) or IDatetime.providedBy(md_field.property)): start_date_str, end_date_str = get_date_strings(ff) start_date = string_to_date(start_date_str) end_date = string_to_date(end_date_str) if start_date: batch = [ x for x in batch if (getattr(x, field_name) and getattr(x, field_name).date() >= start_date) ] if end_date: batch = [ x for x in batch if (getattr(x, field_name) and getattr(x, field_name).date() <= end_date) ] elif IText.providedBy(md_field.property): batch = [x for x in batch if ff in getattr(x, field_name)] return batch
def details(self): fields = IRoadworksDirectoryItem.names() def title(field): return utils.translate(self.context, self.request, IRoadworksDirectoryItem[field].title) titles = dict(zip(fields, map(title, fields))) items = [] order = lambda f: IRoadworksDirectoryItem.get(f).order for field in sorted(fields, key=order): # Show only fields whose string representation makes sense. if IText.providedBy(IRoadworksDirectoryItem[field]) and getattr(self.context, field): items.append((titles[field], getattr(self.context, field))) if self.context.attachment: attachment = self.context.attachment link = '<a href="%s/@@download/attachment">%s (%s KB)</a>' % ( self.context.absolute_url(), attachment.filename, attachment.getSize() / 1024, ) items.append((titles["attachment"], link)) return items
def _getTextFields(self, obj): # Get all text fields, except ones that are handled separately. text_fields = [] if getattr(aq_base(obj), 'Schema', None): # Archetypes for field in obj.Schema().values(): if field.__name__ in CUSTOM_HANDLED_TEXT_FIELDS: continue if not ITextField.providedBy(field): continue text_fields.append(field) elif HAS_DEXTERITY: # Dexterity for schemata in iterSchemata(obj): fields = getFieldsInOrder(schemata) for name, field in fields: if name in CUSTOM_HANDLED_TEXT_FIELDS: continue if IRichText.providedBy(field): text_fields.append(field) continue # ITextLine inherits from IText. # We want to replace in texts, but not textlines. # Maybe this can be made configurable. if ITextLine.providedBy(field): continue if not IText.providedBy(field): continue text_fields.append(field) return text_fields
def filter_batch_on_properties(self, batch): reverse = True if (self.sort_dir == "desc") else False if self.sort_on in self.filter_property_fields: sort_on = self.sort_on[5:] if sort_on not in self.utk: batch.sort(key=lambda x: getattr(x, sort_on), reverse=reverse) for field_name in self.filter_property_fields: md_field = self.domain_annotation.get(field_name) ff_name = "filter_%s" % (field_name) ff = self.request.get(ff_name, None) if ff and md_field: if (IDate.providedBy(md_field.property) or IDatetime.providedBy(md_field.property)): start_date_str, end_date_str = get_date_strings(ff) start_date = string_to_date(start_date_str) end_date = string_to_date(end_date_str) if start_date: batch = [x for x in batch if ( getattr(x, field_name) and getattr(x, field_name).date() >= start_date) ] if end_date: batch = [x for x in batch if ( getattr(x, field_name) and getattr(x, field_name).date() <= end_date) ] elif IText.providedBy(md_field.property): batch = [x for x in batch if ff in getattr(x, field_name)] return batch
def test(self): field = Text(title=u"Foo thing") class I(Interface): getFoo, setFoo = accessors(field) class Bad(object): implements(I) class Good(object): implements(I) def __init__(self): self.set = 0 def getFoo(self): return u"foo" def setFoo(self, v): self.set += 1 names = I.names() names.sort() self.assertEqual(names, ['getFoo', 'setFoo']) self.assertEqual(I['getFoo'].field, field) self.assertEqual(I['getFoo'].__name__, 'getFoo') self.assertEqual(I['getFoo'].__doc__, u'get Foo thing') self.assertEqual(I['getFoo'].__class__, FieldReadAccessor) self.assertEqual(I['getFoo'].writer, I['setFoo']) # test some field attrs for attr in ('title', 'description', 'readonly'): self.assertEqual(getattr(I['getFoo'], attr), getattr(field, attr)) self.assert_(IText.providedBy(I['getFoo'])) self.assert_(IMethod.providedBy(I['getFoo'])) self.assert_(IMethod.providedBy(I['setFoo'])) self.assertEqual(I['setFoo'].field, field) self.assertEqual(I['setFoo'].__name__, 'setFoo') self.assertEqual(I['setFoo'].__doc__, u'set Foo thing') self.assertEqual(I['setFoo'].__class__, FieldWriteAccessor) self.assertRaises(Exception, verifyClass, I, Bad) self.assertRaises(Exception, verifyObject, I, Bad()) self.assertEquals(I['getFoo'].query(Bad(), 42), 42) self.assertRaises(AttributeError, I['getFoo'].get, Bad()) verifyClass(I, Good) verifyObject(I, Good()) self.assertEquals(I['getFoo'].query(Good(), 42), u'foo') self.assertEquals(I['getFoo'].get(Good()), u'foo') instance = Good() I['getFoo'].set(instance, u'whatever') self.assertEquals(instance.set, 1)
def htmlIDs(self): ids = [] fields = self._ce_fields.items() for name, field in fields: if ITextLine.providedBy(field) or IText.providedBy(field): ids.append('form-widgets-%s' % name) elif IRichText.providedBy(field): ids.append('form.widgets.%s' % name) # Talk about uniformity ;) return ids
def _ce_fields(self): field_dict = {} for schemata in iterSchemata(self.context): for name, field in getFieldsInOrder(schemata): if ITextLine.providedBy(field) or \ IText.providedBy(field) or \ IRichText.providedBy(field): field_dict[name] = field return field_dict
def set_semantic_data(obj, event): text = [] for schema in iterSchemata(obj): fields = getFieldsInOrder(schema) for name, field in fields: if IText.providedBy(field): text.append(field.get(obj)) full_text = "\n".join(text) pos_tags = tag(full_text) obj.semantic = extract_keywords(pos_tags)
def __set__(self, inst, value): field = self._field.bind(inst) field.validate(value) if field.readonly: raise ValueError(self._field.__name__, 'field is readonly') if isinstance(value, datetime): # The ensures that the converted DateTime value is in the # server's local timezone rather than GMT. value = DateTime(value.year, value.month, value.day, value.hour, value.minute) elif value is not None: if IText.providedBy(self._field): value = value.encode('utf-8') elif ISequence.providedBy(self._field): if IText.providedBy(self._field.value_type): value = type(value)(item.encode('utf-8') for item in value) if self._set_name: getattr(inst.context, self._set_name)(value) elif inst.context.hasProperty(self._get_name): inst.context._updateProperty(self._get_name, value) else: setattr(inst.context, self._get_name, value)
def update(self): """ Checks if we have Modified errors and renders split view with display widgets for db values and normal for input """ super(DiffEditForm, self).update() for error in self.errors: if error.__class__ == Modified: # Set flag that form is in diff mode if not self.diff: self.diff = True if self.diff: # Set last timestamp which we store in hidden field because # document may be modified during diff and from.timestamp field # contains old value self.last_timestamp = self.context.timestamp for widget in self.widgets: try: value = widget.getInputValue() except: value = "" # Get widget's field form_field = self.form_fields.get(widget.context.__name__) field = form_field.field.bind(self.context) # Form display widget for our field if form_field.custom_widget is not None: display_widget = form_field.custom_widget( field, self.request) else: display_widget = component.getMultiAdapter( (field, self.request), IDisplayWidget) # If field is Text or TextLine we display HTML diff if IText.providedBy(field) or ITextLine.providedBy(field): if value: diff_val = textDiff(field.get(self.context), value) else: diff_val = "" display_widget = component.getMultiAdapter( (field, self.request), IDiffDisplayWidget) display_widget.setRenderedValue(diff_val) else: display_widget.setRenderedValue(field.get(self.context)) display_widget.name = widget.name + ".diff.display" # Add display - input widgets pair to list of diff widgets self.diff_widgets.append((widget, display_widget))
def update(self): """ Checks if we have Modified errors and renders split view with display widgets for db values and normal for input """ super(DiffEditForm, self).update() for error in self.errors: if error.__class__ == Modified: # Set flag that form is in diff mode if not self.diff: self.diff=True if self.diff: # Set last timestamp which we store in hidden field because # document may be modified during diff and from.timestamp field # contains old value self.last_timestamp = self.context.timestamp for widget in self.widgets: try: value = widget.getInputValue() except: value = "" # Get widget's field form_field = self.form_fields.get(widget.context.__name__) field = form_field.field.bind(self.context) # Form display widget for our field if form_field.custom_widget is not None: display_widget = form_field.custom_widget( field, self.request) else: display_widget = component.getMultiAdapter( (field, self.request), IDisplayWidget) # If field is Text or TextLine we display HTML diff if IText.providedBy(field) or ITextLine.providedBy(field): if value: diff_val = textDiff(field.get(self.context), value) else: diff_val = "" display_widget = component.getMultiAdapter( (field, self.request), IDiffDisplayWidget) display_widget.setRenderedValue(diff_val) else: display_widget.setRenderedValue(field.get(self.context)) display_widget.name = widget.name + ".diff.display" # Add display - input widgets pair to list of diff widgets self.diff_widgets.append((widget, display_widget))
def get_fieldtype_by_schema(self, field): type_field = "" if IRelationList.providedBy(field): type_field = "relation" elif "ListField" in str(field): type_field = "datagridfield" self.datagrids[field.__name__] = False elif IChoice.providedBy(field): type_field = "choice" elif ITextLine.providedBy(field): type_field = "text" elif IList.providedBy(field): type_field = "list" elif IText.providedBy(field): type_field = "text" elif IRichText.providedBy(field): type_field = "text" else: type_field = "unknown" return type_field
def get_default_value_by_schema(self, field): type_field = " " if IRelationList.providedBy(field): type_field = [] elif "ListField" in str(field): type_field = [] self.datagrids[field.__name__] = False elif IChoice.providedBy(field): type_field = " " elif ITextLine.providedBy(field): type_field = " " elif IList.providedBy(field): type_field = [] elif IText.providedBy(field): type_field = " " elif IRichText.providedBy(field): type_field = " " else: type_field = " " return type_field
def getTextFields(obj): include_textline_fields = settings().include_textline_fields include_lines_fields = settings().include_lines_fields text_fields = [] if HAS_ARCHETYPES and getattr(aq_base(obj), "Schema", None): # Archetypes for field in obj.Schema().values(): if field.__name__ in CUSTOM_HANDLED_TEXT_FIELDS: continue if include_textline_fields and IStringField.providedBy(field): text_fields.append(field) continue if ITextField.providedBy(field): text_fields.append(field) if include_lines_fields and ILinesField.providedBy(field): text_fields.append(field) elif HAS_DEXTERITY: # Dexterity for schemata in iterSchemata(obj): fields = getFieldsInOrder(schemata) for name, field in fields: if name in CUSTOM_HANDLED_TEXT_FIELDS: continue if IRichText.providedBy(field): text_fields.append(field) continue # ITextLine inherits from IText. # That we want to replace in texts, but not textlines # is by configuration. if not include_textline_fields and ITextLine.providedBy(field): continue if IText.providedBy(field): text_fields.append(field) if (include_lines_fields and ITuple.providedBy(field) and ITextLine.providedBy(field.value_type)): text_fields.append(field) return text_fields