Пример #1
0
 def _get_tap(self, keg_tap_or_meter_name):
     if isinstance(keg_tap_or_meter_name, models.KegTap):
         return keg_tap_or_meter_name
     try:
         return models.KegTap.get_from_meter_name(keg_tap_or_meter_name)
     except models.KegTap.DoesNotExist, e:
         raise exceptions.BackendError('Invalid tap: %s: %s' % (repr(keg_tap_or_meter_name), e))
Пример #2
0
 def create_new_user(self, username, email, password=None, photo=None):
     """Creates and returns a User for the given username."""
     try:
         user = get_auth_backend().register(username=username, email=email,
                 password=password, photo=photo)
         signals.user_created.send_robust(sender=self.__class__, user=user)
         return user
     except UserExistsException as e:
         raise exceptions.UserExistsError(e)
     except AuthException as e:
         raise exceptions.BackendError(e)
Пример #3
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