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()
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)
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 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'))
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()
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()
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()
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'))
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 tearDown(self): User.drop_collection() Transaction.drop_collection() Consumption.drop_collection()
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)
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)