Initial
This commit is contained in:
commit
30059dd43a
16
docker-compose.yml
Normal file
16
docker-compose.yml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
version: '3'
|
||||||
|
|
||||||
|
services:
|
||||||
|
gtfs2qr:
|
||||||
|
build:
|
||||||
|
context: ./gtfs2qr
|
||||||
|
container_name: gtfs2qr
|
||||||
|
environment:
|
||||||
|
- DB_HOST=localhost
|
||||||
|
- DB_PORT=3304
|
||||||
|
- DB_NAME=gtfs
|
||||||
|
- DB_USER=default
|
||||||
|
- DB_PASS=secret
|
||||||
|
- FTP_HOST=localhost
|
||||||
|
- FTP_USER=user
|
||||||
|
- FTP_PASS=secret
|
19
gtfs2qr/Dockerfile
Normal file
19
gtfs2qr/Dockerfile
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
FROM python:3.8
|
||||||
|
|
||||||
|
ENV TZ=Europe/Moscow
|
||||||
|
ENV TERM=xterm-color
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y --no-install-recommends cron python3-pymysql python3-qrcode p7zip && \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
RUN \
|
||||||
|
cp /usr/share/zoneinfo/${TZ} /etc/localtime && \
|
||||||
|
echo "${TZ}" > /etc/timezone && date
|
||||||
|
|
||||||
|
COPY cron /etc/cron.d/gtfs2qr
|
||||||
|
RUN chmod 0755 /etc/cron.d/gtfs2qr && crontab /etc/cron.d/gtfs2qr
|
||||||
|
|
||||||
|
COPY gtfs2qr /opt/gtfs2qr
|
||||||
|
|
||||||
|
CMD ["cron", "-f"]
|
1
gtfs2qr/cron
Normal file
1
gtfs2qr/cron
Normal file
@ -0,0 +1 @@
|
|||||||
|
* * * * * root python3 /opt/gtfs2qr/gtfs2qr.py > /opt/gtfs2qr/logs.log 2>&1
|
120
gtfs2qr/gtfs2qr/gtfs2qr.py
Normal file
120
gtfs2qr/gtfs2qr/gtfs2qr.py
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import ftplib
|
||||||
|
import os
|
||||||
|
import os.path as op
|
||||||
|
import re
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
from ftplib import FTP
|
||||||
|
|
||||||
|
import pymysql
|
||||||
|
import qrcode
|
||||||
|
from PIL import ImageFont, ImageDraw
|
||||||
|
|
||||||
|
|
||||||
|
DB_HOST = os.getenv('DB_HOST', 'default')
|
||||||
|
DB_PORT = os.getenv('DB_PORT', 'default')
|
||||||
|
DB_NAME = os.getenv('DB_NAME', 'default')
|
||||||
|
DB_USER = os.getenv('DB_USER', 'default')
|
||||||
|
DB_PASS = os.getenv('DB_PASS', 'default')
|
||||||
|
|
||||||
|
URL_TEMPLATE = 'http://rasp.orgp.spb.ru/%i'
|
||||||
|
|
||||||
|
FTP_HOST = os.getenv('FTP_HOST', 'default')
|
||||||
|
FTP_USER = os.getenv('FTP_USER', 'default')
|
||||||
|
FTP_PASS = os.getenv('FTP_PASS', 'default')
|
||||||
|
|
||||||
|
transport_type = {
|
||||||
|
'bus': 'Автобус',
|
||||||
|
'trolley': 'Троллейбус',
|
||||||
|
'tram': 'Трамвай',
|
||||||
|
'ship': 'Теплоход',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
|
||||||
|
qr = qrcode.QRCode(
|
||||||
|
version=3,
|
||||||
|
error_correction=qrcode.constants.ERROR_CORRECT_L,
|
||||||
|
box_size=10,
|
||||||
|
border=4,
|
||||||
|
)
|
||||||
|
|
||||||
|
conn = pymysql.connect(
|
||||||
|
host=DB_HOST,
|
||||||
|
port=DB_PORT,
|
||||||
|
user=DB_USER,
|
||||||
|
password=DB_PASS,
|
||||||
|
db=DB_NAME,
|
||||||
|
charset='utf8mb4',
|
||||||
|
cursorclass=pymysql.cursors.DictCursor
|
||||||
|
)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
if op.exists('codes.7z'):
|
||||||
|
os.unlink('codes.7z')
|
||||||
|
|
||||||
|
shutil.rmtree('codes', ignore_errors=True)
|
||||||
|
|
||||||
|
cursor.execute('SELECT * FROM routes ORDER BY route_short_name;')
|
||||||
|
for route in cursor.fetchall():
|
||||||
|
for d in (0, 1):
|
||||||
|
route_path = op.join(
|
||||||
|
'codes',
|
||||||
|
transport_type[route['transport_type']],
|
||||||
|
route['route_short_name'],
|
||||||
|
'туда' if d == 0 else 'обратно'
|
||||||
|
)
|
||||||
|
print(route_path, flush=True)
|
||||||
|
cursor.execute(
|
||||||
|
'SELECT * FROM route_stops WHERE route_id=%s AND direction_id=%s ORDER BY stop_sequence;',
|
||||||
|
(route['route_id'], d)
|
||||||
|
)
|
||||||
|
|
||||||
|
stops = cursor.fetchall()
|
||||||
|
if len(stops) == 0:
|
||||||
|
print('<empty>', flush=True)
|
||||||
|
continue
|
||||||
|
|
||||||
|
for stop in stops:
|
||||||
|
os.makedirs(route_path, exist_ok=True)
|
||||||
|
stop_name = re.sub(r'\s+', ' ', stop['stop_name'].strip())
|
||||||
|
code_name = [
|
||||||
|
str(stop['stop_sequence']),
|
||||||
|
re.sub(r'[\?\"/\\<>*|:~]+', '', stop_name),
|
||||||
|
route['route_short_name'],
|
||||||
|
transport_type[route['transport_type']],
|
||||||
|
str(stop['stop_id']),
|
||||||
|
]
|
||||||
|
image_path = op.join(route_path, '-'.join(code_name) + '.jpeg')
|
||||||
|
|
||||||
|
qr.add_data(URL_TEMPLATE % stop['stop_id'])
|
||||||
|
qr.make(fit=True)
|
||||||
|
|
||||||
|
img = qr.make_image(fill_color="black", back_color="white")
|
||||||
|
|
||||||
|
draw = ImageDraw.Draw(img)
|
||||||
|
font = ImageFont.truetype("Verdana.ttf", 12)
|
||||||
|
stop_name += ' (%i)' % stop['stop_id']
|
||||||
|
text_size = font.getsize(stop_name)
|
||||||
|
draw.text(((img.size[0] - text_size[0]) / 2, img.size[1] - 25), stop_name, font=font)
|
||||||
|
|
||||||
|
with open(image_path, 'wb') as dest:
|
||||||
|
img.save(dest)
|
||||||
|
|
||||||
|
qr.clear()
|
||||||
|
|
||||||
|
subprocess.run(['7za', 'a', 'codes', 'codes'], check=True)
|
||||||
|
|
||||||
|
with ftplib.FTP(host=FTP_HOST, user=FTP_USER, passwd=FTP_PASS) as ftp:
|
||||||
|
if 'codes.7z' in ftp.nlst():
|
||||||
|
ftp.delete('codes.7z')
|
||||||
|
|
||||||
|
with open('codes.7z', 'rb') as arch:
|
||||||
|
ftp.storbinary('STOR codes.7z', arch)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
0
gtfs2qr/gtfs2qr/logs.log
Normal file
0
gtfs2qr/gtfs2qr/logs.log
Normal file
Loading…
Reference in New Issue
Block a user