Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
"""
form_field_class = 'BooleanField'
@validator
def inflate(self, value):
return bool(value)
@validator
def deflate(self, value):
return bool(value)
def default_value(self):
return bool(super(BooleanProperty, self).default_value())
class DateProperty(Property):
"""
Stores a date
"""
form_field_class = 'DateField'
@validator
def inflate(self, value):
return datetime.strptime(unicode(value), "%Y-%m-%d").date()
@validator
def deflate(self, value):
if not isinstance(value, date):
msg = 'datetime.date object expected, got {0}'.format(repr(value))
raise ValueError(msg)
return value.isoformat()
def __init__(self, base_property=None, **kwargs):
"""
Store a list of values, optionally of a specific type.
:param base_property: List item type e.g StringProperty for string
:type: Property
"""
# list item type
if base_property is not None:
if not isinstance(base_property, Property):
raise TypeError('Expecting neomodel Property')
if isinstance(base_property, ArrayProperty):
raise TypeError('Cannot have nested ArrayProperty')
for ilegal_attr in ['default', 'index', 'unique_index', 'required']:
if getattr(base_property, ilegal_attr, None):
raise ValueError('ArrayProperty base_property cannot have "{0}" set'.format(ilegal_attr))
self.base_property = base_property
super(ArrayProperty, self).__init__(**kwargs)
Stores a date
"""
form_field_class = 'DateField'
@validator
def inflate(self, value):
return datetime.strptime(unicode(value), "%Y-%m-%d").date()
@validator
def deflate(self, value):
if not isinstance(value, date):
msg = 'datetime.date object expected, got {0}'.format(repr(value))
raise ValueError(msg)
return value.isoformat()
class DateTimeFormatProperty(Property):
"""
Store a datetime by custome format
:param default_now: If ``True``, the creation time (Local) will be used as default.
Defaults to ``False``.
:param format: Date format string, default is %Y-%m-%d
:type default_now: :class:`bool`
:type format: :class:`str`
"""
form_field_class = 'DateTimeFormatField'
def __init__(self, default_now=False, format="%Y-%m-%d", **kwargs):
if default_now:
if 'default' in kwargs:
raise ValueError('too many defaults')
kwargs['default'] = lambda: datetime.now()
The structure will be inflated when a node is retrieved.
"""
def __init__(self, *args, **kwargs):
super(JSONProperty, self).__init__(*args, **kwargs)
@validator
def inflate(self, value):
return json.loads(value)
@validator
def deflate(self, value):
return json.dumps(value)
class AliasProperty(property, Property):
"""
Alias another existing property
"""
def __init__(self, to=None):
"""
Create new alias
:param to: name of property aliasing
:type: str
"""
self.target = to
self.required = False
self.has_default = False
def aliased_to(self):
@validator
def deflate(self, value):
if not isinstance(value, datetime):
raise ValueError('datetime object expected, got {0}.'.format(type(value)))
if value.tzinfo:
value = value.astimezone(pytz.utc)
epoch_date = datetime(1970, 1, 1, tzinfo=pytz.utc)
elif config.FORCE_TIMEZONE:
raise ValueError("Error deflating {0}: No timezone provided.".format(value))
else:
# No timezone specified on datetime object.. assuming UTC
epoch_date = datetime(1970, 1, 1)
return float((value - epoch_date).total_seconds())
class JSONProperty(Property):
"""
Store a data structure as a JSON string.
The structure will be inflated when a node is retrieved.
"""
def __init__(self, *args, **kwargs):
super(JSONProperty, self).__init__(*args, **kwargs)
@validator
def inflate(self, value):
return json.loads(value)
@validator
def deflate(self, value):
return json.dumps(value)
return [self.base_property.inflate(item, rethrow=False) for item in value]
return list(value)
@validator
def deflate(self, value):
if self.base_property:
return [self.base_property.deflate(item, rethrow=False) for item in value]
return list(value)
def default_value(self):
return list(super(ArrayProperty, self).default_value())
class FloatProperty(Property):
"""
Store a floating point value
"""
form_field_class = 'FloatField'
@validator
def inflate(self, value):
return float(value)
@validator
def deflate(self, value):
return float(value)
def default_value(self):
return float(super(FloatProperty, self).default_value())
def inflate(cls, node):
props = {}
for key, prop in items(cls._class_properties()):
if (issubclass(prop.__class__, Property)
and not isinstance(prop, AliasProperty)):
if key in node.__metadata__['data']:
props[key] = prop.inflate(node.__metadata__['data'][key], node_id=node.id)
elif prop.has_default:
props[key] = prop.default_value()
else:
props[key] = None
snode = cls(**props)
snode.__node__ = node
return snode
def __get__(self, obj, cls):
return getattr(obj, self.aliased_to()) if obj else self
def __set__(self, obj, value):
setattr(obj, self.aliased_to(), value)
@property
def index(self):
return getattr(self.owner, self.aliased_to()).index
@property
def unique_index(self):
return getattr(self.owner, self.aliased_to()).unique_index
class UniqueIdProperty(Property):
"""
A unique identifier, a randomly generated uid (uuid4) with a unique index
"""
def __init__(self, **kwargs):
for item in ['required', 'unique_index', 'index', 'default']:
if item in kwargs:
raise ValueError('{0} argument ignored by {1}'.format(item, self.__class__.__name__))
kwargs['unique_index'] = True
kwargs['default'] = lambda: uuid.uuid4().hex
super(UniqueIdProperty, self).__init__(**kwargs)
@validator
def inflate(self, value):
return unicode(value)
def __new__(mcs, name, bases, dct):
dct.update({'DoesNotExist': type('DoesNotExist', (DoesNotExist,), dct)})
inst = super(StructuredNodeMeta, mcs).__new__(mcs, name, bases, dct)
if hasattr(inst, '__abstract_node__'):
delattr(inst, '__abstract_node__')
else:
for key, value in dct.items():
if issubclass(value.__class__, Property):
value.name = key
value.owner = inst
# support for 'magic' properties
if hasattr(value, 'setup') and hasattr(value.setup, '__call__'):
value.setup()
if '__index__' in dct or hasattr(inst, '__index__'):
name = dct['__index__'] if '__index__' in dct else getattr(inst, '__index__')
inst.index = NodeIndexManager(inst, name)
return inst
:return: the value
"""
if self.has_default:
if hasattr(self.default, '__call__'):
return self.default()
else:
return self.default
else:
raise Exception("No default value specified")
@property
def is_indexed(self):
return self.unique_index or self.index
class NormalizedProperty(Property):
"""
Base class for normalized properties. These use the same normalization
method to in- or deflating.
"""
@validator
def inflate(self, value):
return self.normalize(value)
@validator
def deflate(self, value):
return self.normalize(value)
def default_value(self):
default = super(NormalizedProperty, self).default_value()
return self.normalize(default)