Skip to content

Commit bb4ba2c

Browse files
committed
Make pdf ticket files downloadable
1 parent 5c21553 commit bb4ba2c

File tree

6 files changed

+41
-25
lines changed

6 files changed

+41
-25
lines changed

backend/views/routes.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
'expiration_date': fields.DateTime(dt_format='iso8601'),
1818
'price': fields.Float,
1919
'qr': fields.String,
20+
'pdf': fields.String,
2021
'order_id': fields.String,
2122
'ticket_type': fields.String,
2223
'reserved': fields.DateTime(dt_format='iso8601'),

backend/views/upload.py

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323

2424
class UploadView(Resource):
25-
def base64_encode_qrcode(self, qrcode):
25+
def base64_encode(self, qrcode):
2626
try:
2727
with open(qrcode, "rb") as image_file:
2828
return base64.b64encode(image_file.read())
@@ -58,7 +58,7 @@ def get_ticket_id(self, soup):
5858
ticket_id = re.search("- (.+) -", soup.text)
5959
if not ticket_id:
6060
abort(422)
61-
return ticket_id.groups()[0]
61+
return ticket_id.groups()[0].strip()
6262

6363
def get_route(self, soup):
6464
route = re.search("\d+ / \d+(.+) - (.*)Aikuinen", soup.text)
@@ -94,43 +94,49 @@ def is_square(fn):
9494
if 'file' not in args:
9595
abort(422)
9696

97-
# Danger Zone, parsing PDF files is dirty and this one definately ain't
98-
# the prettiest creature alive. Cleanse yourself with strong liqueur
99-
# afterwards.
100-
10197
tmp_dir = tempfile.mkdtemp()
10298
tmp_src_file = tmp_dir + '/in.pdf'
10399
with open(tmp_src_file, 'wb') as fd:
104100
fd.write(args['file'].read())
105-
106-
pages = self.get_pages(tmp_src_file)
107-
if not pages:
108-
return {"message": "Could not parse the uploaded file, is this actually the PDF file with tickets?"}, 422
109101

110-
first_page = pages[0]
111-
ticket_count = mongo.db.tickets.find({"order_id": self.get_order_id(first_page)}).count()
102+
qr_codes = []
103+
pdf_files = []
112104

113-
qr_codes = iter([])
114-
if ticket_count:
115-
return {"message": "Ticket already uploaded"}, 400
116105
try:
106+
# Danger Zone, parsing PDF files is dirty and this one definately ain't
107+
# the prettiest creature alive. Cleanse yourself with strong liqueur
108+
# afterwards.
117109
os.popen('pdfimages -png ' + tmp_src_file + ' ' + tmp_dir + '/out')
118-
ims = os.popen("ls " + tmp_dir + "/out*").read().split()
119-
qr_codes = iter([fn for fn in ims if is_square(fn)])
120-
# qr_codes = iter(ims[1:len(ims):2])
110+
ims = os.popen("ls " + tmp_dir + "/out*.png").read().split()
111+
qr_codes = [fn for fn in ims if is_square(fn)]
112+
os.popen("pdfseparate " + tmp_src_file + ' ' + tmp_dir + "/pdfout-%d.pdf")
113+
pdfs = os.popen("ls " + tmp_dir + "/pdfout-*.pdf").read().split()
114+
pdf_files = [fn for fn in pdfs]
121115
except:
122116
print("XXX: No poppler installed, unable to produce 2D barcodes")
123117

118+
if len(qr_codes) != len(pdf_files) != len(pages):
119+
return {"message": "Invalid ticket file"}, 400
120+
124121
tickets = []
125-
for page in pages:
122+
for qr_code, pdf_file in iter(zip(qr_codes, pdf_files)):
123+
pages = self.get_pages(pdf_file)
124+
if not pages:
125+
return {"message": "Could not parse the uploaded file, is this actually the PDF file with tickets?"}, 422
126+
page = pages[0]
127+
ticket_count = mongo.db.tickets.find({"order_id": self.get_order_id(page)}).count()
128+
if ticket_count:
129+
return {"message": "Ticket already uploaded"}, 400
126130
route = self.get_route(page)
127131
ticket_type, expires = self.get_ticket_type_and_expiration(page)
128-
qr_base64 = self.base64_encode_qrcode(qr_codes.next())
132+
qr_base64 = self.base64_encode(qr_code)
133+
pdf_base64 = self.base64_encode(pdf_file)
129134
tickets.append({
130135
'ticket_id': uuid.uuid4().hex,
131136
'src': route[0].upper(),
132137
'dest': route[1].upper(),
133138
'qr': 'data:image/png;base64,' + qr_base64,
139+
'pdf': 'data:application/pdf;base64,' + pdf_base64,
134140
'order_id': self.get_order_id(page),
135141
'price': self.get_price(page) / len(pages),
136142
'ticket_type': ticket_type,

docker-compose.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,15 @@ services:
88
- "27017"
99

1010
web:
11-
build: .
11+
build:
12+
context: .
13+
args:
14+
CONFIG_FILE: config/app-docker.cfg
1215
restart: always
1316
volumes:
1417
- ./config:/webapps/sarjalipputasku/config:ro
15-
- ./backend:/webapps/sarjalipputasku/backend:ro
18+
- ./backend:/webapps/sarjalipputasku/source:ro
19+
- ./frontend:/webapps/sarjalipputasku/static:ro
1620
expose:
1721
- "8000"
1822
depends_on:

docker-entrypoint.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#!/bin/bash
22
export OAUTHLIB_INSECURE_TRANSPORT=1
33
export OAUTHLIB_RELAX_TOKEN_SCOPE=1
4-
/usr/local/bin/gunicorn -w 2 -b 0.0.0.0:8000 server:app
4+
export ENV SARJALIPPUTASKU_DIR=/webapps/sarjalipputasku/config/app.cfg
5+
/usr/local/bin/gunicorn -w 2 -b 0.0.0.0:8000 --reload server:app

frontend/src/components/MyTickets.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
<span>{{ ticket.src }} - {{ ticket.dest }}</span><br />
99
Varattu: <span>{{ formatDate(ticket.reserved) }}</span><br />
1010
Hinta: <span>{{ ticket.price }} &euro; (alv 0%)</span><br />
11-
<span>{{ ticket.order_id }} - {{ ticket.vr_id }}</span><br />
11+
<span>{{ ticket.order_id }} - {{ ticket.vr_id }} -
12+
<a download="biljet.pdf" v-bind:href="ticket.pdf" title="Download pdf">pdf</a>
13+
</span><br />
1214
</div>
1315
<div class="col-md-2">
1416
<button class="btn btn-success" v-on:click="useTicket(ticket.id)" v-if="!ticket.used">Käytä</button>

frontend/src/components/ticket-item.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
<span>{{ ticket.src }} - {{ ticket.dest }} {{ ticket.ticket_type }}</span><br />
55
Voimassa: <span>{{ formatDate(ticket.expiration_date) }}</span><br />
66
Hinta: <span>{{ ticket.price }} &euro; (alv 0%)</span><br />
7-
<span>{{ ticket.vr_id }}</span><br />
7+
<span>{{ ticket.vr_id }}</span>
8+
<a download="biljet.pdf" v-bind:href="ticket.pdf" title="Download pdf">pdf</a>
9+
<br />
810
<p>
911
<img v-bind:src="ticket.qr" />
1012
</p>

0 commit comments

Comments
 (0)