#!/usr/bin/env python3
import base64
import flask
import io
import random
import openpyxl
import os
import svgwrite
from svglib.svglib import svg2rlg
from reportlab.graphics import renderPDF
app = flask.Flask(__name__)
TEXT_STYLE = 'font-family: "Arial", "Helvetica", sans-serif;'
@app.route('/')
def index():
return flask.send_from_directory('.', 'page.html')
@app.route('/process', methods=['POST'])
def process():
if 'file' not in flask.request.files:
raise Exception('No file uploaded!')
f = flask.request.files['file']
if f.filename == '':
raise Exception('No file uploaded!')
choices = choices_from_excel(openpyxl.load_workbook(f.stream))
choice_str = base64.urlsafe_b64encode('\x1c'.join(choices).encode('utf-8'))
return flask.redirect('/bingo.pdf?choices={0}'.format(choice_str.decode('utf-8')))
@app.route('/bingo.svg')
@app.route('/bingo.pdf')
def generate():
choice_str = base64.urlsafe_b64decode(flask.request.args.get('choices'))
choices = choice_str.decode('utf-8').split('\x1c')
return mk_svg(choices), 200, {'Content-Type': 'application/pdf'}
def choices_from_excel(wb):
sheet = wb.get_sheet_by_name(wb.get_sheet_names()[0])
choices = []
for row in range(1, sheet.max_row + 1):
choices.append(sheet.cell(row=row, column=1).value)
return choices
def mk_svg(choices):
choices = list(choices)
if len(choices) < 24:
raise Exception('Must have at least 24 possible choices!')
random.shuffle(choices)
# make the empty drawing
d = svgwrite.Drawing(size=('8.5in', '11in'))
# draw the lines
for x in range(6):
d.add(d.line(('{0}in'.format(x*1.6), '0in'),
('{0}in'.format(x*1.6), '8in'),
stroke=svgwrite.rgb(0, 0, 0))).translate(22.5, 22.5)
for y in range(6):
d.add(d.line(('0in', '{0}in'.format(y*1.6)),
('8in', '{0}in'.format(y*1.6)),
stroke=svgwrite.rgb(0, 0, 0))).translate(22.5, 22.5)
# draw the text
for x in range(5):
for y in range(5):
if x == 2 and y == 2:
text = 'FREE SQUARE'
color = '#b00'
else:
text = choices.pop()
color = '#000'
d.add(d.text(text,
insert=
('{0}in'.format(x*1.6 + 0.8),
'{0}in'.format(y*1.6 + 0.8)),
text_anchor='middle',
alignment_baseline='central',
style=TEXT_STYLE,
fill=color)).translate(22.5, 22.5)
buf = io.StringIO(d.tostring())
r = svg2rlg(buf)
return renderPDF.drawToString(r)
# return d.tostring()
if __name__ == '__main__':
if os.getenv('DEBUG'):
app.run()
else:
from flup.server.fcgi import WSGIServer
WSGIServer(app, bindAddress='/var/run/www/bingo.sock').run()