Exemplo n.º 1
0
    def RecordDrink(self,
                    tap_name,
                    ticks,
                    volume_ml=None,
                    username=None,
                    pour_time=None,
                    duration=0,
                    auth_token=None,
                    spilled=False,
                    do_postprocess=True):

        tap = self._GetTapFromName(tap_name)
        if not tap:
            raise BackendError, "Tap unknown"

        if volume_ml is None:
            volume_ml = float(ticks) * tap.ml_per_tick

        user = None
        if username:
            user = self._GetUserObjFromUsername(username)

        if not pour_time:
            pour_time = datetime.datetime.now()

        keg = None
        if tap.current_keg and tap.current_keg.status == 'online':
            keg = tap.current_keg

        if spilled:
            if not keg:
                self._logger.warning(
                    'Got spilled pour for tap missing keg; ignoring')
                return
            keg.spilled_ml += volume_ml
            keg.save()
            return

        d = models.Drink(ticks=ticks,
                         site=self._site,
                         keg=keg,
                         user=user,
                         volume_ml=volume_ml,
                         starttime=pour_time,
                         duration=duration,
                         auth_token=auth_token)
        models.DrinkingSession.AssignSessionForDrink(d)
        d.save()
        if do_postprocess:
            d.PostProcess()
            hook_url = self._site.settings.event_web_hook
            if hook_url:
                events = models.SystemEvent.objects.filter(drink=d)
                if events:
                    event_list = [protolib.ToDict(e) for e in events]
                    tasks.post_webhook_event.delay(hook_url, event_list)

        return protolib.ToProto(d)
Exemplo n.º 2
0
  def RecordDrink(self, tap_name, ticks, volume_ml=None, username=None,
      pour_time=None, duration=0, auth_token=None, spilled=False,
      shout='', do_postprocess=True):

    tap = self._GetTapFromName(tap_name)
    if not tap:
      raise backend.BackendError("Tap unknown")

    if volume_ml is None:
      volume_ml = float(ticks) * tap.ml_per_tick

    user = None
    if username:
      user = self._GetUserObjFromUsername(username)
    elif self._site.settings.default_user:
      user = self._site.settings.default_user

    if not pour_time:
      pour_time = datetime.datetime.now()

    keg = None
    if tap.current_keg and tap.current_keg.status == 'online':
      keg = tap.current_keg

    if spilled:
      if not keg:
        self._logger.warning('Got spilled pour for tap missing keg; ignoring')
        return
      keg.spilled_ml += volume_ml
      keg.save()
      return

    d = models.Drink(ticks=ticks, site=self._site, keg=keg, user=user,
        volume_ml=volume_ml, time=pour_time, duration=duration,
        auth_token=auth_token, shout=shout)
    models.DrinkingSession.AssignSessionForDrink(d)
    d.save()
    if do_postprocess:
      d.PostProcess()
      event_list = [e for e in models.SystemEvent.objects.filter(drink=d).order_by('id')]
      if settings.HAVE_CELERY:
        tasks.handle_new_events.delay(self._site, event_list)

    return d
Exemplo n.º 3
0
def restore(input_fp, kbsite, log_cb=_no_log):
    def _log(obj):
        obj_cls = obj.__class__
        obj_name = obj_cls.__name__
        log_cb('  +++ %s: %s' % (obj_name, obj))

    data = kbjson.loads(input_fp.read())

    brewer_map = {}
    for rec in data.get('bdb_brewers', []):
        try:
            brewer = bdb_models.Brewer.objects.get(id=rec.id)
        except bdb_models.Brewer.DoesNotExist:
            brewer = bdb_models.Brewer(id=rec.id)
        brewer.name = rec.name
        brewer.country = rec.get('country')
        brewer.origin_state = rec.get('origin_state')
        brewer.origin_city = rec.get('origin_city')
        brewer.production = rec.production
        brewer.url = rec.get('url')
        brewer.description = rec.get('description')
        brewer.save()
        _log(brewer)
        brewer_map[rec.id] = brewer

    style_map = {}
    for rec in data.get('bdb_styles', []):
        try:
            style = bdb_models.BeerStyle.objects.get(id=rec.id)
        except bdb_models.BeerStyle.DoesNotExist:
            style = bdb_models.BeerStyle(id=rec.id)
        style.name = rec.name
        style.save()
        _log(style)
        style_map[rec.id] = style

    type_map = {}
    for rec in data.get('bdb_beertypes', []):
        try:
            btype = bdb_models.BeerType.objects.get(id=rec.id)
        except bdb_models.BeerType.DoesNotExist:
            btype = bdb_models.BeerType(id=rec.id)
        btype.name = rec.name
        btype.brewer = brewer_map[rec.brewer_id]
        btype.style = style_map[rec.style_id]
        btype.edition = rec.get('edition')
        btype.abv = rec.get('abv')
        btype.calories_oz = rec.get('calories_oz')
        btype.carbs_oz = rec.get('carbs_oz')
        btype.save()
        _log(btype)
        type_map[rec.id] = btype

    kbsite.thermosensors.all().delete()
    for rec in data.get('thermosensors', []):
        sensor = models.ThermoSensor(site=kbsite, seqn=int(rec.id))
        sensor.raw_name = rec.sensor_name
        sensor.nice_name = rec.nice_name
        sensor.save()
        _log(sensor)

    kbsite.kegs.all().delete()
    for rec in data['kegs']:
        keg = models.Keg(site=kbsite, seqn=int(rec.id))
        keg.type = type_map[rec.type_id]
        keg.startdate = rec.started_time
        keg.enddate = rec.finished_time
        keg.status = rec.status
        keg.description = rec.get('description')
        keg.spilled_ml = rec.spilled_ml

        size, created = models.KegSize.objects.get_or_create(
            name=rec.size_name, volume_ml=rec.size_volume_ml)
        size.save()
        keg.size = size

        keg.save()
        _log(keg)

    kbsite.taps.all().delete()
    for rec in data['taps']:
        tap = models.KegTap(site=kbsite, seqn=int(rec.id))
        tap.name = rec.name
        tap.meter_name = rec.meter_name
        tap.ml_per_tick = rec.ml_per_tick
        tap.description = rec.get('description')
        keg_id = int(rec.get('current_keg_id', 0))
        if keg_id:
            tap.current_keg = models.Keg.objects.get(site=kbsite, seqn=keg_id)
        thermo_id = int(rec.get('thermo_sensor_id', 0))
        if thermo_id:
            tap.temperature_sensor = models.ThermoSensor.objects.get(
                site=kbsite, seqn=thermo_id)
        tap.save()
        _log(tap)

    kbsite.sessions.all().delete()
    for rec in data.get('sessions', []):
        session = models.DrinkingSession(site=kbsite, seqn=int(rec.id))
        session.starttime = rec.start_time
        session.endtime = rec.end_time
        session.volume_ml = rec.volume_ml
        session.name = rec.get('name')
        session.slug = rec.get('slug')
        session.save()
        _log(session)

    for rec in data.get('thermologs', []):
        log = models.Thermolog(site=kbsite, seqn=int(rec.id))
        log.sensor = models.ThermoSensor.objects.get(site=kbsite,
                                                     seqn=int(rec.sensor_id))
        log.temp = rec.temperature_c
        log.time = rec.record_time
        log.save()
        _log(log)

    kbsite.thermosummarylogs.all().delete()
    for rec in data.get('thermosummarylogs', []):
        log = models.ThermoSummaryLog(site=kbsite, seqn=int(rec.sensor_id))
        log.site = kbsite
        log.seqn = rec.id
        log.sensor = models.ThermoSensor.objects.get(site=kbsite,
                                                     seqn=int(rec.sensor_id))
        log.date = rec.date
        log.period = rec.period
        log.num_readings = rec.num_readings
        log.min_temp = rec.min_temp
        log.max_temp = rec.max_temp
        log.mean_temp = rec.mean_temp
        log.save()
        _log(log)

    user_map = {}
    for rec in data.get('users', []):
        user = None

        # If there's already a user registered with this e-mail address, use it.
        if rec.email:
            user_qs = models.User.objects.filter(email=rec.email)
            if user_qs.count():
                user = user_qs[0]
                user_map[rec.username] = user
                _log(user)
                continue

        # Create a new user, creating a new unique username if necessary.
        iter = 0
        username = rec.username
        while True:
            username_qs = models.User.objects.filter(username=username)
            if not username_qs.count():
                break
            iter += 1
            username = '******' % (rec.username[:30], iter)

        user = models.User(username=username)
        user.first_name = rec.first_name
        user.last_name = rec.last_name
        user.email = rec.email
        user.password = rec.password
        user.is_active = rec.is_active
        user.last_login = rec.last_login
        user.date_joined = rec.date_joined

        # XXX non-prod
        user.is_staff = rec.is_staff
        user.is_superuser = rec.is_superuser

        user.save()
        user_map[rec.username] = user
        _log(user)

    for rec in data.get('profiles', []):
        user = user_map.get(rec.username)
        if not user:
            print 'Warning: profile for non-existant user: %s' % rec.username
            continue
        profile, created = models.UserProfile.objects.get_or_create(user=user)
        profile.gender = rec.gender
        profile.weight = rec.weight
        profile.save()
        _log(profile)

    kbsite.tokens.all().delete()
    for rec in data.get('tokens', []):
        token = models.AuthenticationToken(site=kbsite, seqn=int(rec.id))
        token.auth_device = rec.auth_device
        token.token_value = rec.token_value
        username = rec.get('username')
        if username:
            token.user = user_map[username]
        token.enabled = rec.enabled
        token.created = rec.created_time
        token.pin = rec.get('pin')
        token.save()
        _log(token)

    kbsite.drinks.all().delete()
    for rec in data.get('drinks', []):
        drink = models.Drink(site=kbsite, seqn=int(rec.id))
        drink.ticks = rec.ticks
        drink.volume_ml = rec.volume_ml
        drink.session = models.DrinkingSession.objects.get(site=kbsite,
                                                           seqn=int(
                                                               rec.session_id))
        drink.starttime = rec.pour_time
        drink.duration = rec.get('duration')
        drink.status = rec.status
        keg_id = int(rec.get('keg_id', 0))
        if keg_id:
            drink.keg = models.Keg.objects.get(site=kbsite, seqn=keg_id)
        username = rec.get('user_id')
        if username:
            drink.user = user_map[username]
        drink.auth_token = rec.get('auth_token')
        drink.save()
        _log(drink)

    log_cb('Regenerating sessions ...')
    _RegenSessions(kbsite)
    log_cb('Regenerating stats ...')
    _RegenStats(kbsite)
    log_cb('Regenerating events ...')
    _RegenEvents(kbsite)
Exemplo n.º 4
0
    def record_drink(self, tap, ticks, volume_ml=None, username=None,
            pour_time=None, duration=0, shout='', tick_time_series='', photo=None,
            spilled=False):
        """Records a new drink against a given tap.

        The tap must have a Keg assigned to it (KegTap.current_keg), and the keg
        must be active.

        Args:
            tap: A KegTap or matching meter name.
            ticks: The number of ticks observed by the flow sensor for this drink.
            volume_ml: The volume, in milliliters, of the pour.  If specifed, this
                value is saved as the Drink's actual value.  If not specified, a
                volume is computed based on `ticks` and the meter's
                `ticks_per_ml` setting.
            username: The username with which to associate this Drink, or None for
                an anonymous Drink.
            pour_time: The datetime of the drink.  If not supplied, the current
                date and time will be used.
            duration: Number of seconds it took to pour this Drink.  This is
                optional information not critical to the record.
            shout: A short comment left by the user about this Drink.  Optional.
            tick_time_series: Vector of flow update data, used for diagnostic
                purposes.
            spilled: If drink is recorded as spill, the volume is added to spilled_ml
                and the "drink" is not saved as an event.

        Returns:
            The newly-created Drink instance.
        """
        tap = self._get_tap(tap)
        if not tap.is_active or not tap.current_keg:
            raise exceptions.BackendError("No active keg at this tap")

        keg = tap.current_keg

        if spilled:
            keg.spilled_ml += volume_ml
            keg.save(update_fields=['spilled_ml'])
            return None

        if volume_ml is None:
            meter = tap.current_meter()
            if not meter:
                raise exceptions.BackendError("Tap has no meter, can't compute volume")
            volume_ml = float(ticks) / meter.ticks_per_ml

        user = None
        if username:
            user = self.get_user(username)
        else:
            user = models.User.objects.get(username='******')

        if not pour_time:
            pour_time = timezone.now()

        if tick_time_series:
            try:
                # Validate the time series by parsing it; canonicalize it by generating
                # it again.  If malformed, just junk it; it's non-essential information.
                tick_time_series = time_series.to_string(time_series.from_string(tick_time_series))
            except ValueError as e:
                self._logger.warning('Time series invalid, ignoring. Error was: %s' % e)
                tick_time_series = ''

        d = models.Drink(ticks=ticks, keg=keg, user=user,
            volume_ml=volume_ml, time=pour_time, duration=duration,
            shout=shout, tick_time_series=tick_time_series)
        models.DrinkingSession.AssignSessionForDrink(d)
        d.save()

        keg.served_volume_ml += volume_ml
        keg.save(update_fields=['served_volume_ml'])

        if photo:
            pic = models.Picture.objects.create(
                image=photo,
                user=d.user,
                keg=d.keg,
                session=d.session
            )
            d.picture = pic
            d.save()

        events = models.SystemEvent.build_events_for_drink(d)
        tasks.schedule_tasks(events)
        self.build_stats(d.id)

        signals.drink_recorded.send_robust(sender=self.__class__, drink=d)
        return d
Exemplo n.º 5
0
def gentestdata():
    """ default values (contents may change with schema) """
    sn = bdb.Brewer(name='Sierra Nevada Brewing Company',
                    country='USA',
                    origin_state='California',
                    origin_city='Chico',
                    production='commercial',
                    url='http://www.sierranevada.com/')
    sn.save()

    an = bdb.Brewer(name='Anchor Brewing Company',
                    country='USA',
                    origin_state='California',
                    origin_city='San Francisco',
                    production='commercial',
                    url='http://www.anchorsteam.com/')
    an.save()

    # beerstyle defaults
    pale_ale = bdb.BeerStyle(name='Pale Ale')
    pale_ale.save()

    # beertype defaults
    sn_pa = bdb.BeerType(name="Sierra Nevada Pale Ale",
                         brewer=sn,
                         style=pale_ale,
                         calories_oz=10,
                         carbs_oz=10,
                         abv=5.5)
    sn_pa.save()

    as_pa = bdb.BeerType(name="Anchor Liberty Ale",
                         brewer=an,
                         style=pale_ale,
                         calories_oz=10,
                         carbs_oz=10,
                         abv=5.0)
    as_pa.save()

    usernames = ['abe', 'bort', 'charlie']
    users = []
    b = backend.KegbotBackend()
    for name in usernames:
        users.append(b.CreateNewUser(name))

    half_barrel = models.KegSize(name="half barrel", volume_ml=10000)
    half_barrel.save()

    k = models.Keg(type=as_pa, size=half_barrel, status='online', origcost=100)
    k.save()

    drink_base = datetime.datetime(2007, 1, 1, 8, 0, 0)
    drink_interval = datetime.timedelta(seconds=600)
    drink_num = 0
    drink_vols = []
    for ml in (2200, 1100, 550, 715, 780):
        drink_vols.append(
            units.Quantity(ml, from_units=units.UNITS.KbMeterTick))

    # generate some drinks
    times = (drink_base, drink_base + datetime.timedelta(days=1))

    for drink_time in times:
        for rounds in range(3):
            for u in users:
                start = drink_time + drink_num * drink_interval
                end = start + datetime.timedelta(seconds=10)
                vol = drink_vols[drink_num % len(drink_vols)]
                drink = models.Drink(ticks=vol.InKbMeterTicks(),
                                     volume_ml=vol.Amount(units.RECORD_UNIT),
                                     starttime=start,
                                     user=u,
                                     keg=k,
                                     status='valid')
                drink.save()
                drink_num += 1

    # fake thermo data
    thermo_start = datetime.datetime.now() - datetime.timedelta(hours=24)
    sensor_name = "thermo-0000000000000000"
    sensor = models.ThermoSensor.objects.create(raw_name=sensor_name,
                                                nice_name='Test sensor')
    for minute in xrange(60 * 24):
        temp_time = thermo_start + datetime.timedelta(minutes=minute)
        slot = (minute + 1) / 30.0
        var = math.cos(2 * math.pi * slot)
        temp_value = 5.0 + 2.0 * var
        record = models.Thermolog(sensor=sensor,
                                  temp=temp_value,
                                  time=temp_time)
        record.save()