128 lines
3.6 KiB
Python
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())
|