mirror of https://github.com/snachodog/mybuddy.git
377 lines
12 KiB
Python
377 lines
12 KiB
Python
# -*- coding: utf-8 -*-
|
|
from random import choice, choices, randint, uniform
|
|
from datetime import timedelta
|
|
from decimal import Decimal
|
|
|
|
from django.db import transaction
|
|
from django.db.utils import IntegrityError
|
|
from django.core.management.base import BaseCommand
|
|
from django.utils import timezone
|
|
|
|
from faker import Factory
|
|
|
|
from core import models
|
|
|
|
|
|
class Command(BaseCommand):
|
|
help = "Generates fake children and related entries."
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(Command, self).__init__(*args, **kwargs)
|
|
self.faker = Factory.create()
|
|
self.child = None
|
|
self.weight = None
|
|
self.tags = []
|
|
self.time = None
|
|
self.time_now = timezone.localtime()
|
|
|
|
def add_arguments(self, parser):
|
|
parser.add_argument(
|
|
"--children",
|
|
dest="children",
|
|
default=1,
|
|
help="The number of fake children to create.",
|
|
)
|
|
parser.add_argument(
|
|
"--days",
|
|
dest="days",
|
|
default=31,
|
|
help="How many days of fake entries to create.",
|
|
)
|
|
|
|
def handle(self, *args, **kwargs):
|
|
verbosity = int(kwargs["verbosity"])
|
|
children = int(kwargs["children"]) or 1
|
|
days = int(kwargs["days"]) or 31
|
|
|
|
for word in self.faker.words(10, unique=True):
|
|
try:
|
|
tag = models.Tag.objects.create(name=word)
|
|
tag.save()
|
|
self.tags.append(tag)
|
|
except IntegrityError:
|
|
pass
|
|
|
|
birth_date = timezone.localtime() - timedelta(days=days)
|
|
for i in range(0, children):
|
|
self.child = models.Child.objects.create(
|
|
first_name=self.faker.first_name(),
|
|
last_name=self.faker.last_name(),
|
|
birth_date=birth_date,
|
|
)
|
|
self.child.save()
|
|
self._add_child_data()
|
|
|
|
if verbosity > 0:
|
|
self.stdout.write(self.style.SUCCESS("Successfully added fake data."))
|
|
|
|
@transaction.atomic
|
|
def _add_child_data(self):
|
|
"""
|
|
Adds fake data for child from child.birth_date to now. The fake data
|
|
follows a semi-regular pattern of sleep, feed, change, tummy time,
|
|
change, tummy time, sleep, etc.
|
|
:returns:
|
|
"""
|
|
self.time = self.child.birth_date
|
|
|
|
self.breastpump = round(uniform(95.0, 102.0), 2)
|
|
self._add_breastpump_entry()
|
|
|
|
self.temperature = round(uniform(95.0, 102.0), 2)
|
|
self._add_temperature_entry()
|
|
|
|
self.weight = round(uniform(8.0, 12.0), 2)
|
|
self._add_weight_entry()
|
|
last_weight_entry_time = self.time
|
|
|
|
self.height = round(uniform(8.0, 12.0), 2)
|
|
self._add_height_entry()
|
|
last_height_entry_time = self.time
|
|
|
|
self.head_circumference = round(uniform(8.0, 12.0), 2)
|
|
self._add_head_circumference_entry()
|
|
last_head_circumference_entry_time = self.time
|
|
|
|
self.bmi = round(uniform(8.0, 12.0), 2)
|
|
self._add_bmi_entry()
|
|
last_bmi_entry_time = self.time
|
|
|
|
self._add_note_entry()
|
|
last_note_entry_time = self.time
|
|
|
|
while self.time < self.time_now:
|
|
self._add_sleep_entry()
|
|
if choice([True, False]):
|
|
self._add_diaperchange_entry()
|
|
self._add_feeding_entry()
|
|
self._add_diaperchange_entry()
|
|
self._add_breastpump_entry()
|
|
if choice([True, False]):
|
|
self._add_tummytime_entry()
|
|
if choice([True, False]):
|
|
self._add_diaperchange_entry()
|
|
self._add_tummytime_entry()
|
|
if choice([True, False]):
|
|
self._add_temperature_entry()
|
|
if choice([True, False]):
|
|
self._add_breastpump_entry()
|
|
if (self.time - last_note_entry_time).days > 1 and choice([True, False]):
|
|
self._add_note_entry()
|
|
last_note_entry_time = self.time
|
|
if (self.time - last_weight_entry_time).days > 6:
|
|
self._add_weight_entry()
|
|
last_weight_entry_time = self.time
|
|
if (self.time - last_height_entry_time).days > 6:
|
|
self._add_height_entry()
|
|
last_height_entry_time = self.time
|
|
if (self.time - last_head_circumference_entry_time).days > 6:
|
|
self._add_head_circumference_entry()
|
|
last_head_circumference_entry_time = self.time
|
|
if (self.time - last_bmi_entry_time).days > 6:
|
|
self._add_bmi_entry()
|
|
last_bmi_entry_time = self.time
|
|
|
|
@transaction.atomic
|
|
def _add_breastpump_entry(self):
|
|
"""
|
|
Add a Breastpump entry. This assumes a weekly interval.
|
|
:returns:
|
|
"""
|
|
self.amount = round(uniform(95.0, 102.0), 2)
|
|
|
|
notes = ""
|
|
if choice([True, False, False, False]):
|
|
notes = " ".join(self.faker.sentences(randint(1, 5)))
|
|
|
|
models.Breastpump.objects.create(
|
|
child=self.child, amount=self.amount, time=self.time, notes=notes
|
|
).save()
|
|
|
|
@transaction.atomic
|
|
def _add_diaperchange_entry(self):
|
|
"""
|
|
Add a Diaper Change entry and advance self.time.
|
|
:returns:
|
|
"""
|
|
solid = choice([True, False, False, False])
|
|
wet = choice([True, False])
|
|
color = ""
|
|
if solid:
|
|
color = choice(models.DiaperChange._meta.get_field("color").choices)[0]
|
|
if not wet and not solid:
|
|
wet = True
|
|
amount = Decimal("%d.%d" % (randint(0, 6), randint(1, 9)))
|
|
time = self.time + timedelta(minutes=randint(1, 60))
|
|
|
|
notes = ""
|
|
if choice([True, False, False, False]):
|
|
notes = " ".join(self.faker.sentences(randint(1, 5)))
|
|
|
|
if time < self.time_now:
|
|
instance = models.DiaperChange.objects.create(
|
|
child=self.child,
|
|
time=time,
|
|
wet=wet,
|
|
solid=solid,
|
|
color=color,
|
|
amount=amount,
|
|
notes=notes,
|
|
)
|
|
instance.save()
|
|
self._add_tags(instance)
|
|
self.time = time
|
|
|
|
@transaction.atomic
|
|
def _add_feeding_entry(self):
|
|
"""
|
|
Add a Feeding entry and advance self.time.
|
|
:returns:
|
|
"""
|
|
method = choice(models.Feeding._meta.get_field("method").choices)[0]
|
|
amount = None
|
|
if method == "bottle":
|
|
amount = Decimal("%d.%d" % (randint(0, 6), randint(0, 9)))
|
|
start = self.time + timedelta(minutes=randint(1, 60))
|
|
end = start + timedelta(minutes=randint(5, 20))
|
|
|
|
notes = ""
|
|
if choice([True, False, False, False]):
|
|
notes = " ".join(self.faker.sentences(randint(1, 5)))
|
|
|
|
if end < self.time_now:
|
|
instance = models.Feeding.objects.create(
|
|
child=self.child,
|
|
start=start,
|
|
end=end,
|
|
type=choice(models.Feeding._meta.get_field("type").choices)[0],
|
|
method=method,
|
|
amount=amount,
|
|
notes=notes,
|
|
)
|
|
instance.save()
|
|
self._add_tags(instance)
|
|
self.time = end
|
|
|
|
@transaction.atomic
|
|
def _add_note_entry(self):
|
|
"""
|
|
Add a Note entry.
|
|
:returns:
|
|
"""
|
|
note = self.faker.sentence()
|
|
instance = models.Note.objects.create(child=self.child, note=note)
|
|
instance.save()
|
|
self._add_tags(instance)
|
|
|
|
@transaction.atomic
|
|
def _add_sleep_entry(self):
|
|
"""
|
|
Add a Sleep entry and advance self.time. Between the hours of 18 and 6,
|
|
extend the minimum and maximum sleep duration settings.
|
|
:returns:
|
|
"""
|
|
if self.time.hour < 6 or self.time.hour > 18:
|
|
minutes = randint(60 * 2, 60 * 6)
|
|
else:
|
|
minutes = randint(30, 60 * 2)
|
|
end = self.time + timedelta(minutes=minutes)
|
|
|
|
notes = ""
|
|
if choice([True, False, False, False]):
|
|
notes = " ".join(self.faker.sentences(randint(1, 5)))
|
|
|
|
if end < self.time_now:
|
|
instance = models.Sleep.objects.create(
|
|
child=self.child, start=self.time, end=end, notes=notes
|
|
)
|
|
instance.save()
|
|
self._add_tags(instance)
|
|
self.time = end
|
|
|
|
@transaction.atomic
|
|
def _add_temperature_entry(self):
|
|
"""
|
|
Add a Temperature entry. This assumes a weekly interval.
|
|
:returns:
|
|
"""
|
|
self.temperature = round(uniform(95.0, 102.0), 2)
|
|
|
|
notes = ""
|
|
if choice([True, False, False, False]):
|
|
notes = " ".join(self.faker.sentences(randint(1, 5)))
|
|
|
|
instance = models.Temperature.objects.create(
|
|
child=self.child, temperature=self.temperature, time=self.time, notes=notes
|
|
)
|
|
instance.save()
|
|
self._add_tags(instance)
|
|
|
|
@transaction.atomic
|
|
def _add_tummytime_entry(self):
|
|
"""
|
|
Add a Tummy time entry and advance self.time.
|
|
:returns:
|
|
"""
|
|
milestone = ""
|
|
if choice([True, False]):
|
|
milestone = self.faker.sentence()
|
|
start = self.time + timedelta(minutes=randint(1, 60))
|
|
end = start + timedelta(minutes=randint(0, 10), seconds=randint(0, 59))
|
|
if (end - start).seconds < 20:
|
|
end = start + timedelta(minutes=1, seconds=30)
|
|
|
|
if end < self.time_now:
|
|
instance = models.TummyTime.objects.create(
|
|
child=self.child, start=start, end=end, milestone=milestone
|
|
)
|
|
instance.save()
|
|
self._add_tags(instance)
|
|
self.time = end
|
|
|
|
@transaction.atomic
|
|
def _add_weight_entry(self):
|
|
"""
|
|
Add a Weight entry. This assumes a weekly interval.
|
|
:returns:
|
|
"""
|
|
self.weight += uniform(0.1, 0.3)
|
|
|
|
notes = ""
|
|
if choice([True, False, False, False]):
|
|
notes = " ".join(self.faker.sentences(randint(1, 5)))
|
|
|
|
instance = models.Weight.objects.create(
|
|
child=self.child,
|
|
weight=round(self.weight, 2),
|
|
date=self.time.date(),
|
|
notes=notes,
|
|
)
|
|
instance.save()
|
|
self._add_tags(instance)
|
|
|
|
@transaction.atomic
|
|
def _add_height_entry(self):
|
|
"""
|
|
Add a height entry. This assumes a weekly interval.
|
|
:returns:
|
|
"""
|
|
self.height += uniform(0.1, 0.3)
|
|
|
|
notes = ""
|
|
if choice([True, False, False, False]):
|
|
notes = " ".join(self.faker.sentences(randint(1, 5)))
|
|
|
|
instance = models.Height.objects.create(
|
|
child=self.child,
|
|
height=round(self.height, 2),
|
|
date=self.time.date(),
|
|
notes=notes,
|
|
)
|
|
instance.save()
|
|
self._add_tags(instance)
|
|
|
|
@transaction.atomic
|
|
def _add_head_circumference_entry(self):
|
|
"""
|
|
Add a head circumference entry. This assumes a weekly interval.
|
|
:returns:
|
|
"""
|
|
self.head_circumference += uniform(0.1, 0.3)
|
|
|
|
notes = ""
|
|
if choice([True, False, False, False]):
|
|
notes = " ".join(self.faker.sentences(randint(1, 5)))
|
|
|
|
instance = models.HeadCircumference.objects.create(
|
|
child=self.child,
|
|
head_circumference=round(self.head_circumference, 2),
|
|
date=self.time.date(),
|
|
notes=notes,
|
|
)
|
|
instance.save()
|
|
self._add_tags(instance)
|
|
|
|
@transaction.atomic
|
|
def _add_bmi_entry(self):
|
|
"""
|
|
Add a BMI entry. This assumes a weekly interval.
|
|
:returns:
|
|
"""
|
|
self.bmi += uniform(0.1, 0.3)
|
|
|
|
notes = ""
|
|
if choice([True, False, False, False]):
|
|
notes = " ".join(self.faker.sentences(randint(1, 5)))
|
|
|
|
instance = models.BMI.objects.create(
|
|
child=self.child, bmi=round(self.bmi, 2), date=self.time.date(), notes=notes
|
|
)
|
|
instance.save()
|
|
self._add_tags(instance)
|
|
|
|
@transaction.atomic
|
|
def _add_tags(self, instance):
|
|
if choice([True, False, False, False]):
|
|
instance.tags.add(*choices(self.tags, k=randint(1, 5)))
|