bitvend/bitvend/views.py

128 lines
3.6 KiB
Python

from flask import Blueprint, render_template, redirect, request, flash, \
url_for, jsonify
from flask import current_app as app
import six
import qrcode
import qrcode.image.svg
from bitvend import dev, proc
from bitvend.models import db, User, Transaction, NoFunds
from bitvend.forms import TransferForm
from bitvend.graphs import gen_main_graph
from spaceauth import login_required, current_user, cap_required
bp = Blueprint('bitvend', __name__, template_folder='templates')
@bp.route('/')
def index():
transactions = []
hallofshame = User.query \
.with_entities(User, User.balance) \
.order_by(User.balance.asc()) \
.filter(User.balance < 0) \
.limit(5) \
.all()
hallofaddicts = User.query \
.with_entities(User, User.purchase_amount, User.purchase_count) \
.order_by(User.purchase_amount.desc()) \
.filter(User.purchase_amount > 0) \
.limit(5) \
.all()
bottles_purchased = Transaction.query \
.filter(Transaction.amount.in_([-500, -600]), Transaction.type == 'purchase') \
.count()
if current_user.is_authenticated:
transactions = current_user.transactions.order_by(Transaction.created.desc()).limit(10)
return render_template(
'index.html',
items=app.config['ITEMS'],
transactions=transactions,
transfer_form=TransferForm(),
hallofshame=hallofshame,
hallofaddicts=hallofaddicts,
bottles_purchased=bottles_purchased,
)
@bp.route('/transactions/', defaults={'page': 1})
@bp.route('/transactions/p/<int:page>')
def transactions(page):
return render_template('transactions.html',
transactions=current_user.transactions.paginate(page)
)
@bp.route('/transfer', methods=['GET', 'POST'])
def transfer():
transfer_form = TransferForm()
if transfer_form.validate_on_submit():
try:
current_user.transfer(User.query.get(transfer_form.target.data), transfer_form.amount.data)
db.session.commit()
flash('Transfer succeeded.', 'success')
except NoFunds:
flash('No funds.', 'danger')
return redirect(url_for('.index'))
flash('; '.join(sum(transfer_form.errors.values(), [])), 'danger')
return redirect(url_for('.index'))
@bp.route('/log')
@login_required
@cap_required('staff')
def log():
return render_template(
'log.html', transactions=Transaction.query.all())
@bp.route('/begin')
@login_required
def begin():
if Transaction.query.filter(Transaction.finished == False).count():
flash('Nope xD', 'danger')
return redirect(url_for('.index'))
if current_user.amount_available <= 0:
flash('Nope xD', 'danger')
return redirect(url_for('.index'))
tx = Transaction(type='purchase')
current_user.transactions.append(tx)
db.session.commit()
dev.begin_session(current_user.amount_available, tx.id)
return redirect(url_for('.index'))
@bp.route('/cancel')
@login_required
def cancel():
dev.cancel_session()
# FIXME racey
Transaction.query.filter(Transaction.finished == False).delete()
db.session.commit()
return redirect(url_for('.index'))
@bp.route('/qrcode/<path:data>')
def qrcode_gen(data):
bio = six.BytesIO()
qr = qrcode.QRCode(border=0, box_size=50)
qr.add_data(data)
img = qr.make_image(image_factory=qrcode.image.svg.SvgPathFillImage)
img.save(bio)
return bio.getvalue(), 200, {
'Content-Type': 'image/svg+xml',
'Cache-Control': 'public,max-age=3600',
}
@bp.route('/api/1/history.json')
def history():
return jsonify(gen_main_graph())