コード例 #1
0
ファイル: coffee_tests.py プロジェクト: bixel/coffee
 def setUp(self):
     testuser = User(username='******', email='*****@*****.**')
     testuser.save()
     self.testuser = testuser
     User(username='******', email='*****@*****.**', admin=True).save()
     testpayment = Transaction(diff=1000, user=testuser)
     testpayment.save()
     testexpense = Transaction(diff=-500)
     testexpense.save()
     testcons = Consumption(units=1, price_per_unit=50, user=testuser)
     testcons.save()
     self.app = coffee.app.test_client()
コード例 #2
0
ファイル: coffee.py プロジェクト: VukanJ/coffee
def global_api(function):
    if function == 'personal_data':
        user = User.objects.get(username=current_user.username)
        return jsonify(data=user.consumption_list())

    if function == 'global_data':
        # some renaming
        actual_curve = [
            dict(date=t['_id'], amount=t['total'])
            for t in Transaction.dailyTransactions()
        ]
        consumption_curve = Consumption.dailyConsumptions()

        expense_curve = Transaction.dailyExpenses()
        # get all unique dates
        unique_dates = set([t['_id'] for t in expense_curve
                            ]).union(set([t['_id']
                                          for t in consumption_curve]))
        target_curve = []
        for date in unique_dates:
            amount = (next(
                (x['total']
                 for x in expense_curve if x['_id'] == date), 0) + next(
                     (x['total']
                      for x in consumption_curve if x['_id'] == date), 0))
            target_curve.append(dict(date=date, amount=amount))
        target_curve = sorted(target_curve, key=lambda x: x['date'])
        return jsonify(actual_curve=actual_curve, target_curve=target_curve)

    if function == 'consumption_times':
        """ return a list of consumtion daytimes, in seconds """
        def getSecondsOfDay(dates):
            for d in dates:
                yield d.subtract(years=d.year - 1970,
                                 months=d.month - 1,
                                 days=d.day - 1).timestamp()

        consumptions = Consumption.objects(date__gte=pendulum.now().subtract(
            days=28))
        consumptions4Weeks = [pendulum.instance(c.date) for c in consumptions]
        consumptions1Week = [
            c for c in consumptions4Weeks
            if pendulum.now().subtract(days=7) < c
        ]
        return jsonify(last_four_weeks=list(
            getSecondsOfDay(consumptions4Weeks)),
                       last_week=list(getSecondsOfDay(consumptions1Week)))

    return abort(404)
コード例 #3
0
ファイル: coffee.py プロジェクト: VukanJ/coffee
 def get_userlist():
     # always calculate user list
     today = pendulum.today(app.config['TZ'])
     users = []
     for user in User.objects(active=True).order_by('-vip', 'name'):
         # build user dictionary manually
         user_dict = {
             'name':
             user.name,
             'username':
             user.username,
             'id':
             str(user.id),
             'consume': [],
             # fill in all of todays achievements
             'achievements': [{
                 'key': a.key,
                 'date': a.date,
             } for a in user.achievements if a.date > pendulum.today()]
         }
         # perform a query for todays consumptions for each user
         # @TODO: try to move this to the mongo query... instead of hitting
         # the DB n + 1 times.
         for consume in Consumption.objects(user=user, date__gte=today):
             if consume.price_per_unit in prices:
                 user_dict['consume'].extend(
                     consume.units * [prices.get(consume.price_per_unit)])
         users.append(user_dict)
     return users
コード例 #4
0
ファイル: coffee.py プロジェクト: VukanJ/coffee
def administrate_consumption():
    cform = ConsumptionForm()
    cform.uid.choices = User.get_uids()
    if not cform.validate_on_submit():
        return 'Form not valid'

    uid = cform.uid.data
    user = User.objects.get(id=uid)
    user.active = True
    user.save()

    # Check if there was any useful input
    if True not in [x and x > 0 for x in cform.units.data]:
        flash('No updates given.')
        return redirect(url_for('coffee.admin'))

    for u, c in zip(cform.units.data, app.config['COFFEE_PRICES']):
        if (u):
            consumption = Consumption(units=u, price_per_unit=c[0], user=user)
            consumption.save()
    flash('Consumptions for user %s added.' % user)
    balance = user.balance
    if balance < app.config['BUDGET_WARN_BELOW']:
        if user.email:
            msg = EmailMessage()
            msg['Subject'] = f'[Kaffeeministerium] Geringes Guthaben!'
            msg['From'] = app.config['MAIL_DEFAULT_SENDER']
            msg['To'] = user.email
            msg.set_content(
                render_template(
                    'mail/lowbudget',
                    balance=euros(balance),
                    minister_name=app.config['MAIL_MINISTER_NAME']))
            if not app.config['DEBUG']:
                s = getMailServer()
                s.send_message(msg)
            else:
                print(u'Sending mail \n{}'.format(msg.as_string()))
            flash('Warning mail sent. Balance is {}'.format(euros(balance)))
        else:
            flash(f'Balance is {euros(balance)}. User {user.name} could not be'
                  ' notified, no mail address available.')

    return redirect(url_for('coffee.admin'))
コード例 #5
0
ファイル: achievements.py プロジェクト: bixel/coffee
def SymmetricCoffee(consumption):
    key = 'symmetric_coffee'
    # first get all of todays coffees for current user
    coffees = Consumption.objects(user=consumption.user,
                                  date__gte=pendulum.today)
    p1, p2 = [p[0] for p in COFFEE_PRICES]
    todays_coffees = ([c.price_per_unit
                       for c in coffees] + [consumption.price_per_unit])
    if todays_coffees == [p1, p2, p1, p1, p2, p1]:
        new = Achievement(**get_kwargs_for_key(key))
        consumption.user.achievements.append(new)
        consumption.user.save()
コード例 #6
0
ファイル: achievements.py プロジェクト: bixel/coffee
def stalker(consumption, target_username, key, min_consumptions=5):
    target_user = User.objects.get(username=target_username)
    todays_target_consumptions = (Consumption.objects(
        user=target_user, date__gte=pendulum.today()).order_by('-date'))
    todays_user_consumptions = list(
        Consumption.objects(
            user=consumption.user,
            date__gte=pendulum.today()).order_by('-date')) + [consumption]
    if (len(todays_target_consumptions) ==
            min_consumptions  # at least X consumptions
            and ([c.price_per_unit for c in todays_target_consumptions]
                 == [c.price_per_unit
                     for c in todays_user_consumptions])  # same products
            and all([
                t.date < u.date.replace(tzinfo=t.date.tzinfo) for t, u in zip(
                    todays_target_consumptions, todays_user_consumptions)
            ])  # alternating
        ):
        new = Achievement(**get_kwargs_for_key(key))
        consumption.user.achievements.append(new)
        consumption.user.save()
コード例 #7
0
ファイル: achievements.py プロジェクト: bixel/coffee
def Minimalist(consumption):
    key = 'minimalist'
    n_consumptions_total = len(Consumption.objects(user=consumption.user))

    if n_consumptions_total < 5:
        return

    today = consumption.date
    p1, p2 = [p[0] for p in COFFEE_PRICES]

    last_consumption_date = Consumption.objects(
        user=consumption.user).order_by('-date').first().date

    if not last_consumption_date.weekday() == 4:
        return

    if last_consumption_date.date() == today.date():
        return

    shift = 1 if n_consumptions_total == 5 else 0
    if (Consumption.objects(user=consumption.user).order_by('-date')[4-shift].date.date() == \
        Consumption.objects(user=consumption.user).order_by('-date')[5-shift].date.date()):
        return

    complete_week_deltas = [datetime.timedelta(i) for i in range(0, 5, 1)]

    consumptions_to_check = Consumption.objects(
        user=consumption.user).order_by('-date')[0:5]
    for consumption_to_check, delta in zip(consumptions_to_check,
                                           complete_week_deltas):
        if consumption_to_check.date.date() != (last_consumption_date -
                                                delta).date():
            return

        if consumption_to_check.price_per_unit != p1:
            return

    new = Achievement(**get_kwargs_for_key(key))
    consumption.user.achievements.append(new)
    consumption.user.save()
コード例 #8
0
ファイル: coffee.py プロジェクト: Kecksdose/coffee
def administrate_consumption():
    cform = ConsumptionForm()
    cform.uid.choices = User.get_uids()
    if not cform.validate_on_submit():
        return 'Form not valid'

    uid = cform.uid.data
    user = User.objects.get(id=uid)
    user.active = True
    user.save()

    # Check if there was any useful input
    if True not in [x and x > 0 for x in cform.units.data]:
        flash('No updates given.')
        return redirect(url_for('coffee.admin'))

    for u, c in zip(cform.units.data, app.config['COFFEE_PRICES']):
        if (u):
            consumption = Consumption(units=u, price_per_unit=c[0], user=user)
            consumption.save()
    flash('Consumptions for user %s added.' % user)
    balance = user.balance
    if balance < app.config['BUDGET_WARN_BELOW']:
        if user.email:
            msg = Message(u"[Kaffeeministerium] Geringes Guthaben!")
            msg.charset = 'utf-8'
            msg.add_recipient(user.email)
            msg.body = render_template('mail/lowbudget',
                                       balance=euros(balance))
            if not app.config['DEBUG']:
                mail.send(msg)
            else:
                print(u'Sending mail \n{}'.format(msg.as_string()))
            flash('Warning mail sent. Balance is {}'.format(euros(balance)))
        else:
            flash('Balance is {}. User could not be notified.'.format(
                euros(balance)))

    return redirect(url_for('coffee.admin'))
コード例 #9
0
ファイル: coffee.py プロジェクト: Kecksdose/coffee
 def get_userlist():
     # always calculate user list
     today = pendulum.today(app.config['TZ'])
     users = []
     for user in User.objects(active=True).order_by('-vip', 'name'):
         user_dict = {
             'name': user.name,
             'username': user.username,
             'id': str(user.id),
             'consume': []
         }
         for consume in Consumption.objects(user=user, date__gte=today):
             if consume.price_per_unit in prices:
                 user_dict['consume'].extend(
                     consume.units * [prices.get(consume.price_per_unit)])
         users.append(user_dict)
     return users
コード例 #10
0
ファイル: coffee_tests.py プロジェクト: bixel/coffee
 def tearDown(self):
     User.drop_collection()
     Transaction.drop_collection()
     Consumption.drop_collection()
コード例 #11
0
ファイル: coffee.py プロジェクト: VukanJ/coffee
def api(function):
    prices = {p[0]: p[1] for p in app.config['COFFEE_PRICES']}
    products = {p[1]: p[0] for p in app.config['COFFEE_PRICES']}

    def get_userlist():
        # always calculate user list
        today = pendulum.today(app.config['TZ'])
        users = []
        for user in User.objects(active=True).order_by('-vip', 'name'):
            # build user dictionary manually
            user_dict = {
                'name':
                user.name,
                'username':
                user.username,
                'id':
                str(user.id),
                'consume': [],
                # fill in all of todays achievements
                'achievements': [{
                    'key': a.key,
                    'date': a.date,
                } for a in user.achievements if a.date > pendulum.today()]
            }
            # perform a query for todays consumptions for each user
            # @TODO: try to move this to the mongo query... instead of hitting
            # the DB n + 1 times.
            for consume in Consumption.objects(user=user, date__gte=today):
                if consume.price_per_unit in prices:
                    user_dict['consume'].extend(
                        consume.units * [prices.get(consume.price_per_unit)])
            users.append(user_dict)
        return users

    def get_service():
        current_service = Service.current()
        last_cleaned = (Service.objects(
            master=True, cleaned=True).order_by('-date').first())
        service = {
            'uid':
            str(current_service.user.id),
            'last_cleaned':
            last_cleaned.date if last_cleaned else 'Never',
            'upcoming': [
                dict(week=s['_id'], user=str(s['user']))
                for s in Service.upcoming()
            ]
        } if current_service else None
        return service

    if function == 'user_list':
        return jsonify(users=get_userlist(), service=get_service())

    if function == 'add_consumption':
        data = request.get_json()
        user = User.objects.get(id=data.get('id'))
        created = Consumption(user=user,
                              price_per_unit=products.get(
                                  data['consumption_type']),
                              units=data['cur_consumption'],
                              date=datetime.now()).save()
        if user.balance < app.config['BUDGET_WARN_BELOW']:
            alert = {
                'text': 'Geringes Guthaben, bitte laden Sie bald wieder auf.',
                'type': 'warning',
            }
        else:
            alert = None
        status = 'success' if created else 'failure'
        return jsonify(status=status, users=get_userlist(), alert=alert)

    if function == 'finish_service':
        data = request.get_json()
        service = Service.current()
        service.__setattr__(data.get('service'), True)
        service.save()
        return jsonify(service=get_service(),
                       alert={
                           'text': 'Service eingetragen',
                           'type': 'success'
                       })

    return abort(404)
コード例 #12
0
ファイル: coffee.py プロジェクト: Kecksdose/coffee
def api(function):
    prices = {p[0]: p[1] for p in app.config['COFFEE_PRICES']}
    products = {p[1]: p[0] for p in app.config['COFFEE_PRICES']}

    def get_userlist():
        # always calculate user list
        today = pendulum.today(app.config['TZ'])
        users = []
        for user in User.objects(active=True).order_by('-vip', 'name'):
            user_dict = {
                'name': user.name,
                'username': user.username,
                'id': str(user.id),
                'consume': []
            }
            for consume in Consumption.objects(user=user, date__gte=today):
                if consume.price_per_unit in prices:
                    user_dict['consume'].extend(
                        consume.units * [prices.get(consume.price_per_unit)])
            users.append(user_dict)
        return users

    def get_service():
        current_service = Service.current()
        service = {
            'uid': str(current_service.user.id),
            'cleaned': current_service.cleaned,
            'cleaningProgram': current_service.cleaning_program,
            'decalcifyProgram': current_service.decalcify_program,
        } if current_service else None
        return service

    if function == 'user_list':
        return jsonify(users=get_userlist(), service=get_service())

    if function == 'add_consumption':
        data = request.get_json()
        user = User.objects.get(id=data.get('id'))
        created = Consumption(user=user,
                              price_per_unit=products.get(
                                  data['consumption_type']),
                              units=data['cur_consumption'],
                              date=datetime.now()).save()
        if user.balance < app.config['BUDGET_WARN_BELOW']:
            alert = {
                'text': 'Geringes Guthaben, bitte laden Sie bald wieder auf.',
                'type': 'warning',
            }
        else:
            alert = None
        status = 'success' if created else 'failure'
        return jsonify(status=status, users=get_userlist(), alert=alert)

    if function == 'finish_service':
        data = request.get_json()
        service = Service.current()
        service.__setattr__(data.get('service'), True)
        service.save()
        return jsonify(service=get_service(),
                       alert={
                           'text': 'Service eingetragen',
                           'type': 'success'
                       })

    return abort(404)