1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
from flask import Blueprint, render_template, redirect, request, flash, url_for
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.auth import try_login
from bitvend.forms import TransferForm
from flask_login import login_required, current_user, logout_user
bp = Blueprint('bitvend', __name__, template_folder='templates')
@bp.route('/')
def index():
transactions = []
hallofshame = User.query \
.order_by(User.balance.asc()) \
.filter(User.balance < 0) \
.limit(5) \
.all()
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,
)
@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('/login')
def login():
return render_template('login.html')
@bp.route('/login', methods=['POST'])
def login_submit():
if try_login(request.form.get('username'), request.form.get('password')):
flash('Login successful', 'success')
return redirect('/')
flash('Login failed', 'danger')
return redirect(url_for('.login'))
@bp.route('/logout')
@login_required
def logout():
logout_user()
return redirect(url_for('.index'))
@bp.route('/log')
@login_required
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',
}
|