Skip to content

Commit

Permalink
Accomplishing todos
Browse files Browse the repository at this point in the history
  • Loading branch information
tilalis committed Feb 18, 2018
1 parent 8198a53 commit 6c2ec1c
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 42 deletions.
57 changes: 47 additions & 10 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
'password': 'password'
},
firebase={
'cred': 'cred.json',
'cred': '',
'database': 'https://fr.firebaseio.com/',
'bucket': 'fr.appspot.com',

Expand Down Expand Up @@ -51,12 +51,14 @@ def presentation(cls, document):
class Incident(Document):
_container = '/incidents'

incident_id = StringField(id=True, presentational=True)
incident_id = StringField(id=True, presentation=True)
confirmed = BooleanField(default=False)
owner = StringField(presentational=True)
reliability = IntField(default=0, presentational=True)
confidence = IntField(default=0, presentational=True)
created = DateField(presentational=True)
action = StringField()
firstResponder = StringField(presentation=True)
owner = StringField(presentation=True)
reliability = IntField(default=0, presentation=True)
confidence = IntField(default=0, presentation=True)
created = DateField(presentation=True)

@staticmethod
def on_save(document):
Expand Down Expand Up @@ -95,12 +97,47 @@ def presentation(cls, document):
'id': document.incident_id,
'rel': document.reliability * document.confidence,
'created': document.created.isoformat(),
'owner': document.owner.replace(' ', '-')
'owner': document.owner.replace(' ', '-'),
'firstResponder': document.firstResponder
}


if __name__ == "__main__":
# TODO: Add unit tests

import datetime
from enum import Enum

class Type(Enum):
CREATE = 1
DELETE = 2
UPDATE_PRESENTATION = 3
UPDATE_CACHE = 4
UPDATE_FULL = 5

action = Type.UPDATE_PRESENTATION

for i in range(0, 20):
with Incident().get(i) as incident:
incident.reliability = 3
incident.confirmed = not incident.confirmed
if action == Type.CREATE:
Incident(
incident_id=i,
owner='123',
reliability=i % 3,
confidence=i * 2,
confirmed=not bool(i % 2),
created=datetime.datetime.utcnow()
).save()
elif action == Type.DELETE:
Incident.get(i).delete()
elif action == Type.UPDATE_PRESENTATION:
with Incident.get(i) as incident:
incident.reliability = i / 4
elif action == Type.UPDATE_CACHE:
with Incident.get(i) as incident:
incident.confirmed = not incident.confirmed
elif action == Type.UPDATE_FULL:
with Incident.get(i) as incident:
incident.firstResponder = 'AAB'
incident.action = 'cleared'


56 changes: 31 additions & 25 deletions orm/document.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,31 @@ def __new__(mcs, name, bases, attrs):
if isinstance(item, BaseField)
]

presentational = set()
presentation_fields = set()

for fieldname in fieldnames:
field = attrs[fieldname]
fields[fieldname] = field

if field.presentational:
presentational.add(fieldname)
if field.presentation:
presentation_fields.add(fieldname)

if field.is_id:
id_field = copy.copy(field)
id_field._presentation = False
id_field._id = False
fields['id'] = id_field

del attrs[fieldname]

attrs['__fields__'] = fields
attrs['_presentational'] = presentational

# If we have "presentation" in class name, then all of its fields are presentational
# Should think of a better way
if "presentation" not in name.lower():
attrs['_presentation_fields'] = presentation_fields
else:
attrs['_presentation_fields'] = set(fieldnames)

return super().__new__(mcs, name, bases, attrs)

Expand Down Expand Up @@ -79,15 +91,16 @@ def __init__(self, ignore_non_existing=False, override=False, **kwargs):
self._fetched = override
self._changed = set()

def get(self, id):
# TODO: Make this method static

@classmethod
def get(cls, id):
if id is None:
raise AttributeError("Document must have id field!")

if self._redis.exists(id):
object.__setattr__(self, '_id', id)
return self._fetch()
document = cls(id=id)

if document._redis.exists(id):
object.__setattr__(document, '_id', id)
return document._fetch()

raise LookupError('No such document with id: {}'.format(id))

Expand Down Expand Up @@ -146,8 +159,9 @@ def save(self, force=False):

if any((
force,
self._presentational and self._changed & self._presentational,
not self._presentational and self._changed
self._presentation_fields and self._changed & self._presentation_fields,
not self._presentation_fields and self._changed,
not exists
)):
self._firebase.update(self._path, self._id, presentation)

Expand All @@ -170,17 +184,14 @@ def presentation(cls, document):
return {
key: value
for key, value in document
if key in cls._presentational
if key in cls._presentation_fields
}

on_save = None
on_presentation_save = None # NOTE: Inactive yet

on_delete = None


class DocumentView(dict):
# TODO: Add __changed__ field
def __init__(self, document: Document):
super().__init__()

Expand All @@ -189,17 +200,17 @@ def __init__(self, document: Document):
for key, item in document._fields.items()
})

self.__changed__ = frozenset(document._changed)
self.__presentation_changed__ = frozenset(document._changed & document._presentation_fields)

def __getattr__(self, item):
if item in self:
return self[item]

raise AttributeError("No such attribute: {}!".format(item))


class PresentationDocument(Document, metaclass=abc.ABCMeta):
# TODO: Create another metaclass
# TODO: Make fields presentational by default for PresentationDocument

class PresentationDocument(Document):
def __init__(self, ignore_non_existing=False, override=False, **kwargs):
super().__init__(ignore_non_existing, override, **kwargs)

Expand All @@ -223,8 +234,3 @@ def delete(self):
if self._redis.exists(self._id):
self._redis.delete(self._id)
self._firebase.delete(self._path, self._view_id)

@classmethod
@abstractmethod
def presentation(cls, document: DocumentView):
pass
19 changes: 12 additions & 7 deletions orm/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ def __new__(mcs, name, bases, namespace, **kwargs):
class BaseField(metaclass=FieldMeta):
__field_type__ = None

def __init__(self, id=False, default=None, presentational=False):
def __init__(self, id=False, default=None, presentation=False):
# TODO: add immutable option, make ids immutable by default
self._id = id
self._presentational = presentational
self._presentation = presentation

if default is None or isinstance(default, self.__field_type__):
self._value = default
Expand All @@ -27,12 +28,12 @@ def is_id(self):
return self._id

@property
def presentational(self):
return self._presentational
def presentation(self):
return self._presentation

@presentational.setter
def presentational(self, value):
self._presentational = bool(value)
@presentation.setter
def presentation(self, value):
self._presentation = bool(value)

@property
def value(self):
Expand All @@ -53,6 +54,10 @@ def value(self, value):

self._value = value

@value.deleter
def value(self):
self._value = None


class AnyField(BaseField):
__field_type__ = object
Expand Down

0 comments on commit 6c2ec1c

Please sign in to comment.