class EvalExpressionSpec(JsonObject): type = TypeProperty('evaluator') statement = StringProperty(required=True) context_variables = DictProperty(required=True) datatype = DataTypeProperty(required=False) def configure(self, context_variables): self._context_variables = context_variables def __call__(self, item, context=None): var_dict = self.get_variables(item, context) try: untransformed_value = eval_statements(self.statement, var_dict) return transform_from_datatype(self.datatype)(untransformed_value) except (InvalidExpression, SyntaxError, TypeError, ZeroDivisionError): return None def get_variables(self, item, context): var_dict = { slug: variable_expression(item, context) for slug, variable_expression in self._context_variables.items() } return var_dict def __str__(self): value = self.statement for name, exp in self._context_variables.items(): value.replace(name, str(exp)) if self.datatype: value = "({}){}".format(self.datatype, value) return value
class PropertyPathGetterSpec(JsonObject): type = TypeProperty('property_path') property_path = ListProperty(six.text_type, required=True) datatype = DataTypeProperty(required=False) def __call__(self, item, context=None): transform = transform_from_datatype(self.datatype) return transform(safe_recursive_lookup(item, self.property_path))
class PropertyNameGetterSpec(JsonObject): type = TypeProperty('property_name') property_name = StringProperty(required=True) datatype = DataTypeProperty(required=False) def __call__(self, item, context=None): raw_value = item.get(self.property_name, None) if isinstance(item, dict) else None return transform_from_datatype(self.datatype)(raw_value)
class DynamicChoiceListFilterSpec(FilterSpec): type = TypeProperty('dynamic_choice_list') show_all = BooleanProperty(default=True) datatype = DataTypeProperty(default='string') @property def choices(self): return []
class PropertyNameGetterSpec(JsonObject): type = TypeProperty('property_name') property_name = DefaultProperty(required=True) datatype = DataTypeProperty(required=False) def configure(self, property_name_expression): self._property_name_expression = property_name_expression def __call__(self, item, context=None): raw_value = item.get(self._property_name_expression(item, context)) if isinstance(item, dict) else None return transform_from_datatype(self.datatype)(raw_value)
class DynamicChoiceListFilterSpec(FilterSpec): type = TypeProperty('dynamic_choice_list') show_all = BooleanProperty(default=True) datatype = DataTypeProperty(default='string') choice_provider = DictProperty() def get_choice_provider_spec(self): return self.choice_provider or {'type': DATA_SOURCE_COLUMN} @property def choices(self): return []
class PropertyPathGetterSpec(JsonObject): type = TypeProperty('property_path') property_path = ListProperty(unicode, required=True) datatype = DataTypeProperty(required=False) @property def expression(self): transform = transform_from_datatype(self.datatype) getter = NestedDictGetter(self.property_path) return TransformedGetter(getter, transform) def __call__(self, item, context=None): return self.expression(item, context)
class PropertyNameGetterSpec(JsonObject): type = TypeProperty('property_name') property_name = StringProperty(required=True) datatype = DataTypeProperty(required=False) @property def expression(self): transform = transform_from_datatype(self.datatype) getter = DictGetter(self.property_name) return TransformedGetter(getter, transform) def __call__(self, item, context=None): return self.expression(item, context)
class PropertyPathGetterSpec(JsonObject): type = TypeProperty('property_path') property_path = ListProperty(six.text_type, required=True) datatype = DataTypeProperty(required=False) def __call__(self, item, context=None): transform = transform_from_datatype(self.datatype) return transform(safe_recursive_lookup(item, self.property_path)) def __str__(self): value = "/".join(self.property_path) if self.datatype: "({datatype}){value}".format(datatype=self.datatype, value=value) return value
class FilterSpec(JsonObject): """ This is the spec for a report filter - a thing that should show up as a UI filter element in a report (like a date picker or a select list). """ type = StringProperty(required=True, choices=['date', 'numeric', 'pre', 'choice_list', 'dynamic_choice_list']) # this shows up as the ID in the filter HTML. slug = StringProperty(required=True) field = StringProperty(required=True) # this is the actual column that is queried display = DefaultProperty() datatype = DataTypeProperty(default='string') def get_display(self): return self.display or self.slug
class ChoiceListFilterSpec(FilterSpec): type = TypeProperty('choice_list') show_all = BooleanProperty(default=True) datatype = DataTypeProperty(default='string') choices = ListProperty(FilterChoice)