From 30059dd43a3ecd4cb276c17fd684e02d5ffe7a23 Mon Sep 17 00:00:00 2001 From: Anton Zadvorny Date: Mon, 20 Jan 2020 12:07:51 +0300 Subject: [PATCH] Initial --- docker-compose.yml | 16 +++++ gtfs2qr/Dockerfile | 19 ++++++ gtfs2qr/cron | 1 + gtfs2qr/gtfs2qr/gtfs2qr.py | 120 +++++++++++++++++++++++++++++++++++++ gtfs2qr/gtfs2qr/logs.log | 0 5 files changed, 156 insertions(+) create mode 100644 docker-compose.yml create mode 100644 gtfs2qr/Dockerfile create mode 100644 gtfs2qr/cron create mode 100644 gtfs2qr/gtfs2qr/gtfs2qr.py create mode 100644 gtfs2qr/gtfs2qr/logs.log diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..1d47d80 --- /dev/null +++ b/docker-compose.yml @@ -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 diff --git a/gtfs2qr/Dockerfile b/gtfs2qr/Dockerfile new file mode 100644 index 0000000..778f8dc --- /dev/null +++ b/gtfs2qr/Dockerfile @@ -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"] diff --git a/gtfs2qr/cron b/gtfs2qr/cron new file mode 100644 index 0000000..6dfb358 --- /dev/null +++ b/gtfs2qr/cron @@ -0,0 +1 @@ +* * * * * root python3 /opt/gtfs2qr/gtfs2qr.py > /opt/gtfs2qr/logs.log 2>&1 diff --git a/gtfs2qr/gtfs2qr/gtfs2qr.py b/gtfs2qr/gtfs2qr/gtfs2qr.py new file mode 100644 index 0000000..2826185 --- /dev/null +++ b/gtfs2qr/gtfs2qr/gtfs2qr.py @@ -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('', 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() diff --git a/gtfs2qr/gtfs2qr/logs.log b/gtfs2qr/gtfs2qr/logs.log new file mode 100644 index 0000000..e69de29