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