class BaseNDBUserModel(koalacore.NDBResource): """ User model to store authentication credentials or authorization ids. """ auth_ids = ndb.ComputedProperty( func=lambda self: [self.username, self.email_address], repeated=True) password = ndb.StringProperty('up', indexed=False) username = ndb.StringProperty('un', indexed=False) email_address = ndb.StringProperty('upe', indexed=False) email_address_verified = ndb.BooleanProperty('upev', default=False, indexed=False) recovery_email_address = ndb.StringProperty('upre', indexed=False) recovery_email_address_verified = ndb.BooleanProperty('uprev', default=False, indexed=False) first_name = ndb.StringProperty('ufn', indexed=False) last_name = ndb.StringProperty('uln', indexed=False) language_preference = ndb.StringProperty('ulp', indexed=False)
class Report(ndb.Model): """Identifies a Report. Key name: concatenation of period and gbifdatasetid: YYYYMM|0000-0000-0000-0000 Ancestor: Period """ created = ndb.DateProperty(required=True) # url = ndb.StringProperty() sha = ndb.StringProperty(default="") reported_period = ndb.KeyProperty(kind=Period, required=True) reported_resource = ndb.KeyProperty(kind=Dataset, required=True) searches = ndb.StructuredProperty(Search) downloads = ndb.StructuredProperty(Download, default=Download()) year_data = ndb.StructuredProperty(YearData) history_data = ndb.StructuredProperty(HistoryData) stored = ndb.BooleanProperty() issue_sent = ndb.BooleanProperty() done = ndb.ComputedProperty( lambda self: # self.downloads.status == 'done' and # self.searches.status == 'done' and self.issue_sent is True and self.stored is True)
class Item(ndb.Expando): item_id = ndb.GenericProperty() name = ndb.StringProperty() image = ndb.StringProperty() link = ndb.StringProperty() quantity = ndb.IntegerProperty(default=1) price = ndb.FloatProperty(default=0.00) local_price = ndb.FloatProperty(default=0.00) total_cost = ndb.FloatProperty(default=0.00) shipping_cost = ndb.FloatProperty(default=0.00) overall_cost = ndb.ComputedProperty( lambda self: self.total_cost + self.shipping_cost) shipping_info = ndb.StructuredProperty(ShippingInfo) created_at = ndb.DateTimeProperty(auto_now_add=True) updated_at = ndb.DateTimeProperty(auto_now=True) # Others - size, color, asin, model_no def _pre_put_hook(self): self.item_id = str(self.item_id) self.total_cost = self.local_price * self.quantity
class GlobalStats(NdbModel): NAMESPACE = NAMESPACE name = ndb.StringProperty() token_count = ndb.IntegerProperty() unlocked_count = ndb.IntegerProperty() value = ndb.FloatProperty() # Value in dollar # Value per other currency currencies = ndb.LocalStructuredProperty(CurrencyValue, repeated=True) # type: list[CurrencyValue] market_cap = ndb.ComputedProperty(lambda self: (self.value or 0) * self.unlocked_count, indexed=False) @property def id(self): return self.key.id().decode('utf-8') @classmethod def create_key(cls, currency): return ndb.Key(cls, currency, namespace=NAMESPACE) @classmethod def list(cls): return cls.query()
class Device(ndb.Model): owner = ndb.UserProperty(required=True) jid = ndb.StringProperty(required=True) # TODO validate JID format resource = ndb.StringProperty(required=True) presence = ndb.StringProperty(default='available') relays = ndb.JsonProperty( default=dict()) # dict of {relay_name:state} items id = ndb.ComputedProperty(lambda self: self.key.id() if self.key else None) @property def full_jid(self): return '%s/%s' % (self.jid, self.full_resource) @property def full_resource(self): result = memcache.get(CACHE_RESOURCE_KEY % (self.jid, self.resource)) return result or self.resource @classmethod def from_resource(cls, resource, jid=None): if jid is None: q = cls.query(cls.resource == resource, cls.owner == users.get_current_user()) else: q = cls.query(cls.resource == resource, cls.jid == jid) return q.get() @classmethod def all_by_jid(cls, jid): return cls.query(cls.jid == jid).fetch() @classmethod def all_by_user(cls): return cls.query(cls.owner == users.get_current_user()).fetch() @classmethod def all(cls, limit=20, offset=None): return cls.query(cls.owner == users.get_current_user()).fetch( limit=limit, offset=offset)
class User(ndb.Model): """ Authentication class - stores account credentials - stores game related bonuses - technologies - stores game related metadata - race - gold and turns """ username = ndb.StringProperty(required=True, indexed=False) password = ndb.StringProperty(required=True, indexed=False, validator=hash_password) date_created = ndb.DateTimeProperty(auto_now_add=True) date_updated = ndb.DateTimeProperty(auto_now=True) profile = ndb.LocalStructuredProperty(UserProfile, required=True) username_lc = ndb.ComputedProperty(lambda self: self.username.lower()) @classmethod def get_by_password(cls, username, password): user = cls.query(cls.username_lc == username.lower()).get() if user is not None and user.check_password(password): return user return None @classmethod def exists(cls, username): query = cls.username_lc == username.lower() return cls.query(query).count() > 0 @classmethod def new(cls, username, password, race): return cls(username=username, password=password, profile=UserProfile(race_id=race)) def check_password(self, password): return security.check_password_hash(password, self.password)
class Sarja(ndb.Model): def validate_kesto(prop, value): if not value > 0: raise ValueError(u"Keston on oltava suurempi kuin nolla") nimi = ndb.StringProperty(required=True) kesto = ndb.IntegerProperty(required=True, validator=validate_kesto, default=4) kilpailu = ndb.KeyProperty(kind=Kilpailu, required=True) nimi_lower = ndb.ComputedProperty(lambda self: nimistin(self.nimi)) def __init__(self, *args, **kwargs): if "kilpailu" in kwargs and isinstance(kwargs['kilpailu'], basestring): # jos kilpailu on merkkijono, muuta se relaatioavaimeksi. kwargs['kilpailu'] = Kilpailu.query(Kilpailu.nimi == kwargs['kilpailu']).get().key return super(Sarja, self).__init__(*args, **kwargs) @property def joukkueet(self): return Joukkue.query(Joukkue.sarja == self.key)
class Invoice(ndb.Model): on = ndb.StringProperty() order = ndb.KeyProperty(kind=SalesOrder) customer = ndb.KeyProperty(kind=Customer) amount = ndb.FloatProperty(default=0) paid = ndb.FloatProperty(default=0) payments = ndb.KeyProperty(kind='Payment', repeated=True) credit = ndb.FloatProperty(default=0) credits = ndb.KeyProperty(kind='Credit', repeated=True) balance = ndb.ComputedProperty(lambda self: (self.amount or 0) - (self.paid or 0) + (self.credit or 0)) category = ndb.StringProperty(default='Cash') status = ndb.StringProperty(choices=['Recorded', 'Cancelled'], default='Recorded') createdAt = ndb.DateTimeProperty(auto_now_add=True) modifiedAt = ndb.DateTimeProperty(auto_now=True)
class Entry(ndb.Model): # Need to set Account as the parent of every entry date = ndb.DateProperty(required = True) datakind = ndb.StringProperty(choices = ["work", "event"], indexed = False) isAchievement = ndb.BooleanProperty(default = False) #indexed notes = ndb.TextProperty() tags = ndb.StringProperty(repeated = True, indexed = False) # normalized tags eg. "App Engine" --> "appengine" - computed property normtags = ndb.ComputedProperty(lambda self: self._normalize_tags(), repeated = True) project = ndb.KeyProperty(Projects) projectName = ndb.StringProperty(indexed = False) #isWorkProductive = ndb.BooleanProperty(indexed = False) hoursWorked = ndb.FloatProperty(indexed = False) def _normalize_tags(self): tags = self.tags first_level = [t.lower().replace(' ', '') for t in tags] # hajj house as hajjhouse #second_level = [] # 'hajj house' as 'hajj' and 'house' #for tag in tags: # second_level += [t.lower() for t in tag.split(' ') if t] return first_level# + second_level
class User(ndb.Model): first_name = ndb.StringProperty(verbose_name='First Name') middle_name = ndb.StringProperty(verbose_name='Middle Name', default='') last_name = ndb.StringProperty(verbose_name='Last Name') raw_name = ndb.StringProperty(verbose_name='Name') name = ndb.ComputedProperty(form_name) password = ndb.BlobProperty(indexed=False, verbose_name='Password') is_temporary_password = ndb.BooleanProperty(default=True) email = EmailProperty(verbose_name='Email', unique=True) phone = MobilePhoneProperty(verbose_name='Personal Mobile Number', unique=True) account_verified = ndb.BooleanProperty(default=False) verification_code = ndb.StringProperty() org = ndb.KeyProperty(kind=Organization, repeated=True) createdAt = ndb.DateTimeProperty(auto_now_add=True) modifiedAt = ndb.DateTimeProperty(auto_now=True) active = ndb.BooleanProperty(default=True)
class VM(BaseModel, TimestampedModel): """ A small model representing a Compute Engine VM, as well as some associated properties. Key('VM', 'vm-instance-name') """ instance_name = ndb.ComputedProperty(lambda self: self.key.id()) deployment_name = ndb.StringProperty(required=True) expires_at = ndb.DateTimeProperty(required=True) @classmethod def create(cls, id, **kwargs): """ Because the key id of a VM model is the Compute Engine instance name, we want to make sure it is always supplied to the create method. """ if not isinstance(id, basestring): raise ValueError("'id' must be of type basestring") kwargs['id'] = id return super(VM, self).create(**kwargs)
class Patient(base.Base): """Patient specific details.""" account_id = ndb.IntegerProperty(required=True) care_type = msgprop.EnumProperty(CareService, repeated=True, indexed=False) prefix = ndb.StringProperty(indexed=False) first = ndb.StringProperty(required=True, indexed=False) last = ndb.StringProperty(required=True, indexed=False) names = ndb.ComputedProperty(lower_names, repeated=True) nickname = ndb.StringProperty(indexed=False) relationship = ndb.StringProperty(indexed=False) address = ndb.StructuredProperty(Address, indexed=False) phone_number = ndb.IntegerProperty(indexed=False) notes = ndb.TextProperty() age = ndb.IntegerProperty(indexed=False) pets = ndb.StringProperty(indexed=False) allergies = ndb.StringProperty(indexed=False) hobbies = ndb.StringProperty(indexed=False) caregiver_expertise = msgprop.EnumProperty(Expertise, repeated=True, indexed=False) caregiver_gender = msgprop.EnumProperty(Gender, indexed=False) soft_delete = ndb.BooleanProperty(default=False, indexed=False)
class Rasti(ndb.Model): def validate_lat(prop, value): r""" Latituden on oltava liukuluku väliltä -90 - 90 """ return max(-90, min(90, value)) def validate_lon(prop, value): r""" Longituden on oltava liukuluku väliltä -180 - 180 """ return max(-180, min(180, value)) koodi = ndb.StringProperty(required=True) kilpailu = ndb.KeyProperty(kind=Kilpailu, required=True) lat = ndb.FloatProperty(required=True, validator=validate_lat) lon = ndb.FloatProperty(required=True, validator=validate_lon) nimi = ndb.ComputedProperty(lambda self: self.koodi)
class StoryCode(ndb.Model): story_uid = ndb.StringProperty(required=True) word_string = ndb.StringProperty(required=True) uid = ndb.ComputedProperty(lambda s: StoryCode.gen_key(s.word_string)) used = ndb.BooleanProperty(default=False) single_use = ndb.BooleanProperty(default=False) created_at = ndb.DateTimeProperty(auto_now_add=True) note = ndb.StringProperty(default="") SERIALIZERS = [serialize_datetime] @staticmethod def gen_key(words): return re.sub(NON_ALPHA, '', ''.join(words).lower()) @classmethod def build_key(cls, words): code = StoryCode.gen_key(words) return ndb.Key(cls, code) @classmethod def from_words(cls, words, **kwargs): return cls(key=cls.build_key(words), word_string=words, **kwargs) def use(self): if self.single_use: self.used = True self.put() def toJSON(self): return { 'word_string': self.word_string, 'used': (self.used), 'single_use': (self.single_use), 'story_uid': self.story_uid, 'created_at': str(self.created_at), 'note': self.note }
class Student(ndb.Model): date = ndb.DateTimeProperty(auto_now_add=True) studentId = ndb.StringProperty(indexed=False, required=True) courseId = ndb.StringProperty(indexed=True, required=True) fullName = ndb.StringProperty(indexed=True) role = ndb.StringProperty(required=True, indexed=True, default='STUDENT') initials = ndb.ComputedProperty( lambda self: ''.join([x[0].upper() for x in self.fullName.split(' ')])) color = ndb.StringProperty(indexed=False) avatarUrl = ndb.StringProperty(indexed=False) opentokSessionId = ndb.StringProperty(indexed=False) opentokToken = ndb.StringProperty(indexed=False) def info(self): return { 'avatarUrl': self.avatarUrl, 'fullName': self.fullName, 'initials': self.initials, 'color': self.color } @classmethod def get_students_by_course(cls, courseId): return json.dumps([ l.to_dict() for l in cls.query( ndb.AND(cls.courseId == courseId, cls.role == 'STUDENT')).order(cls.fullName).fetch() ], cls=DateTimeEncoder) @classmethod def get_teacher_by_course(cls, courseId): return cls.query( ndb.AND(cls.courseId == courseId, cls.role == 'TEACHER')).fetch()[0]
class User(ndb.Model): """ User Entity """ """ Code for the country from where the user plays """ country_code = ndb.StringProperty( 'c', indexed=True, required=True, validator=lambda prop, value: value.upper()) """ Total experienced the player has earned """ experience = ndb.IntegerProperty( 'e', default=0, indexed=True, required=True, validator=lambda prop, value: _validate_non_negative_int(value)) """ Rank or level for the player, based on the experienced """ rank = ndb.ComputedProperty( lambda self: int(sqrt(self.experience / float(_PERFECT_SCORE)))) """ Timestamp from when the user was created """ timestamp = ndb.DateTimeProperty('t', auto_now_add=True, indexed=False, required=True)
class AuthorizationCode(ndb.Model): code = ndb.StringProperty(required=True) client_id = ndb.StringProperty(required=True) user_key = ndb.KeyProperty() scope = ndb.StringProperty(repeated=True) expires_in = ndb.IntegerProperty(default=0) expires = ndb.ComputedProperty( lambda self: self.created + datetime.timedelta(seconds=self.expires_in) if self.expires_in else None ) created = ndb.DateTimeProperty(auto_now_add=True) updated = ndb.DateTimeProperty(auto_now=True) @property def is_expired(self): return datetime.datetime.utcnow() > self.expires if self.expires is not None else False @classmethod def get_key_name(cls, client_id, code): return '{0}-{1}'.format(client_id, code) @classmethod def get_key(cls, client_id, code): return ndb.Key(cls, cls.get_key_name(client_id, code))
class Word(ndb.Model): word = ndb.StringProperty() day = ndb.DateProperty(auto_now_add=True) definition = ndb.TextProperty() len = ndb.ComputedProperty(lambda self: len( self.word)) #creates a field from the word length automatically @staticmethod def allWords(): return Word.query() #returns a word matching the string passed, None is word doesnt exist @staticmethod def wordByString(str): word = Word.query(Word.word == str).get() return word """ This function gets the word of the day from the databse, or gets one from the api if no word for today was found api docs: http://developer.wordnik.com/docs.html#!/words/getWordOfTheDay_get_1 """ @staticmethod def todaysWord(): today = datetime.date.today() word = Word.query( Word.day == today).get() #try to fetch today's word from db if word is None: #if not found, we fetch from the api requestURL = URL_PATTERN.format(today.year, today.month, today.day, API_KEY) reply = requests.get(requestURL).json() word = Word() word.word = reply['word'] word.definition = reply['definitions'][0]['text'] word.put() return word
class Assignment(Base): """Assignments are particular to courses and have unique names.""" name = ndb.StringProperty() # E.g., cal/cs61a/fa14/proj1 display_name = ndb.StringProperty() url = ndb.StringProperty() points = ndb.FloatProperty() templates = ndb.JsonProperty() creator = ndb.KeyProperty(User) course = ndb.KeyProperty(Course) max_group_size = ndb.IntegerProperty() due_date = ndb.DateTimeProperty() lock_date = ndb.DateTimeProperty() # no submissions after this date active = ndb.ComputedProperty( lambda a: a.due_date and datetime.datetime.now() <= a.due_date) revision = ndb.BooleanProperty(default=False) autograding_enabled = ndb.BooleanProperty(default=False) grading_script_file = ndb.TextProperty() zip_file_url = ndb.StringProperty() # TODO Add services requested @classmethod def _can(cls, user, need, obj, query): if need.action == "index": return query if user.is_admin: return True if need.action == "get": return True elif need.action in ["grade", 'delete', 'create', 'put']: if obj and isinstance(obj, Assignment): return Participant.has_role(user, obj.course, STAFF_ROLE) return False def __lt__(self, other): """ Allows us to sort assignments - reverse order so that latest due dates come first """ return self.due_date > other.due_date
class Token(ndb.Model): access_token = ndb.StringProperty(required=True) refresh_token = ndb.StringProperty(required=True) client_id = ndb.StringProperty(required=True) user_key = ndb.KeyProperty() scope = ndb.StringProperty(repeated=True) token_type = ndb.StringProperty() expires_in = ndb.IntegerProperty(default=0) expires = ndb.ComputedProperty( lambda self: self.created + datetime.timedelta(seconds=self.expires_in) if self.expires_in is not None else None ) created = ndb.DateTimeProperty(auto_now_add=True) updated = ndb.DateTimeProperty(auto_now=True) @property def is_expired(self): return datetime.datetime.utcnow() > self.expires if self.expires is not None else False def validate_scope(self, scope): if scope is None: return False if scope == self.scope: return True if not scope: return False for s in scope.split(): if s not in self.scope: return False return True @classmethod def get_key(cls, access_token): return ndb.Key(cls, access_token) @classmethod def query_expired(cls, expires): return cls.query().filter(cls.expires < expires)
class Image(ndb.Expando): full_size_image = ndb.BlobProperty(indexed=False, required=True) title = ndb.StringProperty(indexed=True, required=False) url = ndb.StringProperty(indexed=True, required=False) # unique parent_key = ndb.ComputedProperty(lambda self: self.key.parent()) @classmethod def fetch_keys(cls, limit, start_cursor, ancestor): return cls.query(cls.parent_key == ancestor).fetch_page( limit, start_cursor=start_cursor, keys_only=True) @classmethod def get(cls, image_key): image = '' try: image_model = image_key.get() image = image_model.url except: pass return image def build(self): return {'title': self.title, 'url': self.url}
class InstanceGroupManager(ndb.Model): """An instance group manager in the config. Key: id: zone of the proto.config_pb2.InstanceGroupManagerConfig.InstanceGroupManager this entity represents. parent: InstanceTemplateRevision. """ # Current number of instances managed by the instance group manager created # from this entity. current_size = ndb.ComputedProperty(lambda self: len(self.instances)) # ndb.Keys for the active Instances. instances = ndb.KeyProperty(kind=Instance, repeated=True) # Maximum number of instances the instance group manager created from this # entity can maintain. Must be at least equal to minimum_size. Leave # unspecified for unlimited. maximum_size = ndb.IntegerProperty(indexed=False) # Minimum number of instances the instance group manager created from this # entity should maintain. Must be positive. Also defines the initial size # when first creating the instance group manager. minimum_size = ndb.IntegerProperty(indexed=False) # URL of the instance group manager created from this entity. url = ndb.StringProperty(indexed=False)
class Lead(ndb.Model): """A main model for representing an individual lead.""" id = ndb.ComputedProperty(lambda self: self.key.urlsafe()) email = ndb.StringProperty(indexed=False) first_name = ndb.StringProperty(indexed=False) last_name = ndb.StringProperty(indexed=False) comment = ndb.StringProperty(indexed=False) date = ndb.DateTimeProperty(auto_now_add=True) version = ndb.StringProperty(indexed=False) token = ndb.StringProperty(indexed=True) @classmethod def query_all(cls, ancestor_key): return cls.query(ancestor=ancestor_key).order(-cls.key) @classmethod def query_by_token(cls, ancestor_key, token): return cls.query(ancestor=ancestor_key).filter(Lead.token == token) def calc_token(self): h = hashlib.new('sha224') h.update(str(random.randint(1000, 10000000))) h.update(self.key.urlsafe()) self.token = h.hexdigest()
class BlobKeyMapping(ndb.Model): """ Stores a mapping from the old blob key to a new Google Cloud Storage filename, as well as a new blob key for the Cloud Storage file that can be used in legacy blobstore APIs. """ old_blob_key = ndb.ComputedProperty(lambda self: self.key.id()) gcs_filename = ndb.StringProperty(required=True) new_blob_key = ndb.StringProperty(required=True) _use_cache = False _use_memcache = False @classmethod def _get_kind(cls): """Returns the kind name.""" return config.config.MAPPING_DATASTORE_KIND_NAME @classmethod def build_key(cls, key_str): """Builds a key.""" if not key_str: raise ValueError('key_str is required.') return ndb.Key(cls, key_str)
class Account(base.Base, auth_models.User): """Account associated with an email address. This model expands the webapp2 user model used for authentication. """ # Email address associated with the account (unique). email = ndb.StringProperty(required=True) # Primary account type. account_type = msgprop.EnumProperty(AccountType) first = ndb.StringProperty(indexed=False) last = ndb.StringProperty(indexed=False) names = ndb.ComputedProperty(lower_names, repeated=True) # Facebook ID associated with the account. fbid = ndb.StringProperty(indexed=False) # Whether the email has been verified or not. email_verified = ndb.BooleanProperty(default=False, indexed=False) # Whether the account is soft deleted. soft_delete = ndb.BooleanProperty(default=False, indexed=False) # Phone number. Eventually switch to this: # https://github.com/daviddrysdale/python-phonenumbers phone_number = ndb.IntegerProperty() phone_number_verified = ndb.IntegerProperty(indexed=False) # accounts.Caregiver ID. caregiver_id = ndb.IntegerProperty() # accounts.Patient IDs. patient_ids = ndb.IntegerProperty(repeated=True, indexed=False) # accounts.Payment ID. payment_id = ndb.IntegerProperty(indexed=False) # connections.ConnList ID. connlist_id = ndb.IntegerProperty(indexed=False) @property def verification_token(self): """Returns the email verification token for this account.""" return hashlib.md5( (configs.VERIF_SECRET + self.email).encode('utf-8')).hexdigest()
class StoryCode(ndb.Model): story_uid = ndb.StringProperty(required=True) word_string = ndb.StringProperty(required=True) uid = ndb.ComputedProperty(lambda s: StoryCode.gen_key(s.word_string)) used = ndb.BooleanProperty(default=False) single_use = ndb.BooleanProperty(default=False) @staticmethod def gen_key(words): return re.sub(NON_ALPHA, '', ''.join(words).lower()) @classmethod def build_key(cls, words): code = StoryCode.gen_key(words) return ndb.Key(cls, code) @classmethod def from_words(cls, words, **kwargs): return cls(key=cls.build_key(words), word_string=words, **kwargs) def use(self): if self.single_use: self.used = True self.put()
class FirstAidActivityTopic(ndb.Model): """Hold the list of topic """ data = ndb.JsonProperty(required=True) name = ndb.ComputedProperty(lambda self: self.data.get('name')) def summary(self): name = self.data.get('name') step = self.data.get('step') label = '%s (%s)' % ( name, step, ) if step else name return { 'id': self.key.id(), 'label': label, } @classmethod def new_topic(cls, data, commit=True): topic = cls(id=str(data.get('id', '')), data=data) if commit: topic.put() return topic @staticmethod def validate(data): education.api.validate('FirstAidTopicData', data) def _pre_put_hook(self): self.validate(self.data) @classmethod def get_topics(cls): return cls.query().order(cls.name)
class BasicModel(ndb.Model): """Common data/operations for all storage models """ int_field = ndb.IntegerProperty() float_field = ndb.FloatProperty() boolean_field = ndb.BooleanProperty() string_field = ndb.StringProperty() text_field = ndb.TextProperty() blob_field = ndb.BlobProperty() datetime_field = ndb.DateTimeProperty() date_field = ndb.DateProperty() time_field = ndb.TimeProperty() geopt_field = ndb.GeoPtProperty() key_field = ndb.KeyProperty() blobkey_field = ndb.BlobKeyProperty() user_field = ndb.UserProperty() single_structured_field = ndb.StructuredProperty(ChildModel) repeated_structured_field = ndb.StructuredProperty(ChildModel, repeated=True) json_field = ndb.JsonProperty() pickle_field = ndb.PickleProperty() computed_field = ndb.ComputedProperty( lambda self: self.string_field.upper())
class Comment(ndb.Model): comment_text = ndb.TextProperty(indexed=True) date_created = ndb.DateTimeProperty(auto_now_add=True) author = ndb.KeyProperty(kind=User) post = ndb.KeyProperty(kind=Post) votes = ndb.IntegerProperty() parent = ndb.KeyProperty(kind='Comment') ago = ndb.ComputedProperty(lambda self: time_ago(self.date_created)) deleted = ndb.BooleanProperty() def add(self, text, author, post, parent=None): self.comment_text = text self.author = author self.post = post self.parent = parent self.votes = 0 self.deleted = False self.put() def partial_delete(self): self.deleted = True self.comment_text = "" self.votes = 0 self.put()
class User(ndb.Model): # Added upon first startup age = ndb.IntegerProperty(required=True) income = ndb.IntegerProperty(required=True) is_income_stable = ndb.BooleanProperty(required=True) balance = ndb.FloatProperty(required=True) # Added later desired_saving = ndb.FloatProperty() assets = ndb.StructuredProperty(Asset, repeated=True) periodic_spending = ndb.StructuredProperty(PeriodicSpending, repeated=True) budget = ndb.StructuredProperty(Budget, repeated=True) all_investments = ndb.StructuredProperty(Investment, repeated=True) all_insurances = ndb.StructuredProperty(Insurance, repeated=True) all_expenditure = ndb.StructuredProperty(Expenditure, repeated=True) all_goals = ndb.StructuredProperty(Goal, repeated=True) # Calculated calculated_balance = ndb.ComputedProperty(functions.calc_balance) total_passive_income = ndb.ComputedProperty(functions.calc_passive_income) total_periodic_spending = ndb.ComputedProperty(functions.calc_periodic_spending) insurance_coverage = ndb.ComputedProperty(functions.calc_insurance_coverage) risk_factor = ndb.ComputedProperty(functions.calc_risk_factor) recommended_savings = ndb.ComputedProperty(functions.calc_recommended_savings) net_worth = ndb.ComputedProperty(functions.calc_net_worth)