From b70223896c9c38b4fbab716f4ba6474229e57e70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Kv=C3=A1=C4=8Dek?= Date: Sat, 26 Aug 2023 11:46:28 +0200 Subject: [PATCH] Resize obrazku, deploy, bugfixing --- .dockerignore | 5 + .env.dist | 8 + alembic/env.py | 5 + db/init.sql | 457 ++++++++++++++++++ deploy.sh | 12 + docker-compose.prod.yml | 13 + src/database/config.py | 21 +- src/decorators/endpoints.py | 1 - src/dependencies/db.py | 2 +- src/graphql_schema/entities/flight.py | 21 +- src/graphql_schema/entities/helpers/flight.py | 33 +- src/graphql_schema/entities/photo.py | 6 +- src/graphql_schema/entities/user.py | 9 +- src/upload_utils.py | 37 +- 14 files changed, 593 insertions(+), 37 deletions(-) create mode 100644 .dockerignore create mode 100644 .env.dist create mode 100755 deploy.sh create mode 100644 docker-compose.prod.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..8e4214f --- /dev/null +++ b/.dockerignore @@ -0,0 +1,5 @@ +.mypy_cache +venv +uploads +!uploads/.gitkeep +test_requests \ No newline at end of file diff --git a/.env.dist b/.env.dist new file mode 100644 index 0000000..39e5c13 --- /dev/null +++ b/.env.dist @@ -0,0 +1,8 @@ +TZ: "Europe/Prague" +API_URL: "https://api.poletani.cz" +ALLOW_CORS_ORIGINS: "https://poletani.cz" +APP_SECRET_KEY: "****" +MYSQL_HOST: "127.0.0.1" +MYSQL_DATABASE: "poletani_cz" +MYSQL_USER: "mysql_user" +MYSQL_PASSWORD: "****" diff --git a/alembic/env.py b/alembic/env.py index 8c585bd..a1d05fc 100644 --- a/alembic/env.py +++ b/alembic/env.py @@ -6,15 +6,20 @@ from sqlalchemy.ext.asyncio import async_engine_from_config from alembic import context import os, sys + BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR+"/src") import database.models +from database.config import get_database_url + # this is the Alembic Config object, which provides # access to the values within the .ini file in use. config = context.config +config.set_main_option('sqlalchemy.url', get_database_url()) + # Interpret the config file for Python logging. # This line sets up loggers basically. if config.config_file_name is not None: diff --git a/db/init.sql b/db/init.sql index e69de29..baf69e7 100644 --- a/db/init.sql +++ b/db/init.sql @@ -0,0 +1,457 @@ +INSERT INTO `airport` (name, icao_code, gps_latitude, gps_longitude, elevation, is_public, created_at, created_by_id, deleted) VALUES +('Benešov','LKBE',49.7408,14.6447,1322,1,'2023-08-14 10:04:18',NULL,0), +('Bohuňovice','LKBO',49.6706,17.295,774,1,'2023-08-14 10:04:18',NULL,0), +('BRNO/Tuřany','LKTB',49.1514,16.6939,778,1,'2023-08-14 10:04:18',NULL,0), +('Broumov','LKBR',50.5619,16.3428,1342,1,'2023-08-14 10:04:18',NULL,0), +('Břeclav','LKBA',48.7908,16.8925,525,1,'2023-08-14 10:04:18',NULL,0), +('Bubovice','LKBU',49.9744,14.1781,1398,1,'2023-08-14 10:04:18',NULL,0), +('Česká Lípa','LKCE',50.7094,14.5667,929,1,'2023-08-14 10:04:18',NULL,0), +('České Budějovice','LKCS',48.9464,14.4275,1417,1,'2023-08-14 10:04:18',NULL,0), +('Dvůr Králové','LKDK',50.4142,15.8369,925,1,'2023-08-14 10:04:18',NULL,0), +('Erpužice','LKER',49.8028,13.0381,1568,1,'2023-08-14 10:04:18',NULL,0), +('Frýdlant','LKFR',49.5894,18.3792,1440,1,'2023-08-14 10:04:18',NULL,0), +('Havlíčkův Brod','LKHB',49.5972,15.5492,1519,1,'2023-08-14 10:04:18',NULL,0), +('Hodkovice','LKHD',50.6572,15.0778,1480,1,'2023-08-14 10:04:18',NULL,0), +('Hořice','LKHC',50.3567,15.5772,917,1,'2023-08-14 10:04:18',NULL,0), +('Hořovice','LKHV',49.8447,13.8858,1214,1,'2023-08-14 10:04:18',NULL,0), +('Hosín','LKHS',49.04,14.495,1621,1,'2023-08-14 10:04:18',NULL,0), +('Hradec Králové','LKHK',50.2533,15.8453,791,1,'2023-08-14 10:04:18',NULL,0), +('Hranice','LKHN',49.5461,17.7044,797,1,'2023-08-14 10:04:18',NULL,0), +('Cheb','LKCB',50.0664,12.4128,1585,1,'2023-08-14 10:04:18',NULL,0), +('Chomutov','LKCH',50.4689,13.4681,1132,1,'2023-08-14 10:04:18',NULL,0), +('Chotěboř','LKCT',49.6858,15.6761,1946,1,'2023-08-14 10:04:18',NULL,0), +('Chrudim','LKCR',49.9364,15.7806,978,1,'2023-08-14 10:04:18',NULL,0), +('Jaroměř','LKJA',50.3314,15.9539,891,1,'2023-08-14 10:04:18',NULL,0), +('Jičín','LKJC',50.43,15.3331,863,1,'2023-08-14 10:04:18',NULL,0), +('Jihlava','LKJI',49.4197,15.6356,1821,1,'2023-08-14 10:04:18',NULL,0), +('Jindřichův Hradec','LKJH',49.1508,14.9717,1683,1,'2023-08-14 10:04:18',NULL,0), +('Karlovy Vary','LKKV',50.2031,12.915,1989,1,'2023-08-14 10:04:18',NULL,0), +('Kladno','LKKL',50.1128,14.0897,1419,1,'2023-08-14 10:04:18',NULL,0), +('Klatovy','LKKT',49.4183,13.3219,1299,1,'2023-08-14 10:04:18',NULL,0), +('Kolín','LKKO',50.0019,15.1733,925,1,'2023-08-14 10:04:18',NULL,0), +('Krnov','LKKR',50.0744,17.6953,1204,1,'2023-08-14 10:04:18',NULL,0), +('Kroměříž','LKKM',49.2856,17.4158,617,1,'2023-08-14 10:04:18',NULL,0), +('Křižanov','LKKA',49.3683,16.1161,1834,1,'2023-08-14 10:04:18',NULL,0), +('Kunovice','LKKU',49.0294,17.4397,581,1,'2023-08-14 10:04:18',NULL,0), +('Kyjov','LKKY',48.98,17.1247,686,1,'2023-08-14 10:04:18',NULL,0), +('Letkov','LKPL',49.7231,13.4522,1374,1,'2023-08-14 10:04:18',NULL,0), +('Letňany','LKLT',50.1314,14.5256,912,1,'2023-08-14 10:04:18',NULL,0), +('Liberec','LKLB',50.7683,15.025,1329,1,'2023-08-14 10:04:18',NULL,0), +('Luhačovice','LKLU',49.0922,17.7247,1127,1,'2023-08-14 10:04:18',NULL,0), +('Mariánské Lázně','LKMR',49.9228,12.7247,1768,1,'2023-08-14 10:04:18',NULL,0), +('Medlánky','LKCM',49.2369,16.5553,925,1,'2023-08-14 10:04:18',NULL,0), +('Mikulovice','LKMI',50.3017,17.2975,1375,1,'2023-08-14 10:04:18',NULL,0), +('Mladá Boleslav','LKMB',50.3983,14.8983,765,1,'2023-08-14 10:04:18',NULL,0), +('Mnichovo Hradiště','LKMH',50.54,15.0067,801,1,'2023-08-14 10:04:18',NULL,0), +('Moravská Třebová','LKMK',49.7983,16.6878,1322,1,'2023-08-14 10:04:18',NULL,0), +('Most','LKMO',50.525,13.6831,1086,1,'2023-08-14 10:04:18',NULL,0), +('Nové Město','LKNM',50.3642,16.1136,1001,1,'2023-08-14 10:04:18',NULL,0), +('Olomouc','LKOL',49.5872,17.21,869,1,'2023-08-14 10:04:18',NULL,0), +('OSTRAVA/Mošnov','LKMT',49.6961,18.1108,844,1,'2023-08-14 10:04:18',NULL,0), +('Panenský Týnec','LKPC',50.3064,13.935,1207,1,'2023-08-14 10:04:18',NULL,0), +('Pardubice','LKPD',50.0133,15.7383,741,1,'2023-08-14 10:04:18',NULL,0), +('Plasy','LKPS',49.9203,13.3769,1434,1,'2023-08-14 10:04:18',NULL,0), +('Plzeň/Líně','LKLN',49.6753,13.2744,1188,1,'2023-08-14 10:04:18',NULL,0), +('Podhořany','LKPN',49.9392,15.5497,1250,1,'2023-08-14 10:04:18',NULL,0), +('Polička','LKPA',49.7394,16.2589,1978,1,'2023-08-14 10:04:18',NULL,0), +('PRAHA/Ruzyně','LKPR',50.1008,14.26,1234,1,'2023-08-14 10:04:18',NULL,0), +('PRAHA/Vodochody','LKVO',50.2167,14.3956,919,1,'2023-08-14 10:04:18',NULL,0), +('Prostějov','LKPJ',49.4478,17.1339,702,1,'2023-08-14 10:04:18',NULL,0), +('Přerov','LKPO',49.4258,17.4047,676,1,'2023-08-14 10:04:18',NULL,0), +('Příbram','LKPM',49.72,14.1003,1529,1,'2023-08-14 10:04:18',NULL,0), +('Přibyslav','LKPI',49.5808,15.7628,1742,1,'2023-08-14 10:04:18',NULL,0), +('Rakovník','LKRK',50.0942,13.6889,1273,1,'2023-08-14 10:04:18',NULL,0), +('Raná','LKRA',50.4039,13.7519,883,1,'2023-08-14 10:04:18',NULL,0), +('Rokycany','LKRY',49.7519,13.5897,1329,1,'2023-08-14 10:04:18',NULL,0), +('Roudnice','LKRO',50.4106,14.2261,728,1,'2023-08-14 10:04:18',NULL,0), +('Sazená','LKSZ',50.3247,14.2589,765,1,'2023-08-14 10:04:18',NULL,0), +('Skuteč','LKSK',49.8278,16.0058,1601,1,'2023-08-14 10:04:18',NULL,0), +('Slaný','LKSN',50.2167,14.0886,1079,1,'2023-08-14 10:04:18',NULL,0), +('Soběslav','LKSO',49.2467,14.7136,1335,1,'2023-08-14 10:04:18',NULL,0), +('Staňkov','LKSA',49.5667,13.0486,1404,1,'2023-08-14 10:04:18',NULL,0), +('Stichovice','LKSB',49.4861,17.0556,837,1,'2023-08-14 10:04:18',NULL,0), +('Strakonice','LKST',49.2517,13.8928,1378,1,'2023-08-14 10:04:18',NULL,0), +('Strunkovice','LKSR',49.0825,14.0758,1565,1,'2023-08-14 10:04:18',NULL,0), +('Šumperk','LKSU',49.9606,17.0178,1099,1,'2023-08-14 10:04:18',NULL,0), +('Tábor','LKTA',49.3911,14.7083,1440,1,'2023-08-14 10:04:18',NULL,0), +('Tachov','LKTD',49.7978,12.7069,1639,1,'2023-08-14 10:04:18',NULL,0), +('Točná','LKTC',49.9853,14.4256,1027,1,'2023-08-14 10:04:18',NULL,0), +('Toužim','LKTO',50.0864,12.9528,2123,1,'2023-08-14 10:04:18',NULL,0), +('Ústí nad Labem','LKUL',50.6997,13.9697,787,1,'2023-08-14 10:04:18',NULL,0), +('Ústí nad Orlicí','LKUO',49.9786,16.4264,1342,1,'2023-08-14 10:04:18',NULL,0), +('Velké Poříčí','LKVP',50.4678,16.2056,1326,1,'2023-08-14 10:04:18',NULL,0), +('Vlašim','LKVL',49.7289,14.8789,1421,1,'2023-08-14 10:04:18',NULL,0), +('Vrchlabí','LKVR',50.6242,15.6464,1611,1,'2023-08-14 10:04:18',NULL,0), +('Vysoké Mýto','LKVM',49.9269,16.1858,988,1,'2023-08-14 10:04:18',NULL,0), +('Vyškov','LKVY',49.3003,17.0253,915,1,'2023-08-14 10:04:18',NULL,0), +('Zábřeh','LKZA',49.9283,18.0783,794,1,'2023-08-14 10:04:18',NULL,0), +('Zbraslavice','LKZB',49.8142,15.2017,1618,1,'2023-08-14 10:04:18',NULL,0), +('Zlín','LKZL',49.1983,17.5178,604,1,'2023-08-14 10:04:18',NULL,0), +('Znojmo','LKZN',48.8178,16.0658,827,1,'2023-08-14 10:04:18',NULL,0), +('Žamberk','LKZM',50.0839,16.4439,1408,1,'2023-08-14 10:04:18',NULL,0), +('Žatec/Macerka','LKZD',50.3175,13.5128,883,1,'2023-08-14 10:04:18',NULL,0), +('Borek','LKBORE',50.2108,14.6575,557,1,'2023-08-14 10:04:18',NULL,0), +('Boleradice','LKBOLE',48.9619,16.8317,650,1,'2023-08-14 10:04:18',NULL,0), +('Brťov','LKBRTO',49.4108,16.4994,1610,1,'2023-08-14 10:04:18',NULL,0), +('Březí Falcon','LKBREZ',49.3383,16.2328,1680,1,'2023-08-14 10:04:18',NULL,0), +('Budkovice','LKBUDK',49.0786,16.3558,870,1,'2023-08-14 10:04:18',NULL,0), +('Bynovec','LKBYNO',50.8219,14.2714,1266,1,'2023-08-14 10:04:18',NULL,0), +('Bystřice nad Pernštejnem','LKBYST',49.5228,16.2322,1942,1,'2023-08-14 10:04:18',NULL,0), +('Částkovice','LKCAST',49.4092,15.1442,1925,1,'2023-08-14 10:04:18',NULL,0), +('Čebín','LKCEBI',49.3189,16.4967,1004,1,'2023-08-14 10:04:18',NULL,0), +('Český Dub','LKCDUB',50.6781,14.9997,1303,1,'2023-08-14 10:04:19',NULL,0), +('Dětřichov Oáza','LKDETR',49.7292,17.1181,751,1,'2023-08-14 10:04:19',NULL,0), +('Doudleby','LKDOUD',48.885,14.4864,1541,1,'2023-08-14 10:04:19',NULL,0), +('Druzcov u Lípy','LKDRUZ',50.7281,14.9247,1509,1,'2023-08-14 10:04:19',NULL,0), +('Dušníky','LKDUSN',50.4128,14.1981,728,1,'2023-08-14 10:04:19',NULL,0), +('Hatě Excalibur','LKEXCA',48.7617,16.0553,777,1,'2023-08-14 10:04:19',NULL,0), +('Hať u Hlučína','LKHATH',49.95,18.2647,774,1,'2023-08-14 10:04:19',NULL,0), +('Hláska','LKHLAS',49.0669,14.2414,1430,1,'2023-08-14 10:04:19',NULL,0), +('Horní Počaply','LKPOCA',50.4181,14.3842,524,1,'2023-08-14 10:04:19',NULL,0), +('Horní Přím','LKPRIM',50.2294,15.7036,885,1,'2023-08-14 10:04:19',NULL,0), +('Hradčany','LKHRAD',50.6194,14.7328,912,1,'2023-08-14 10:04:19',NULL,0), +('Charvátce','LKCHAR',50.4336,13.8108,922,1,'2023-08-14 10:04:19',NULL,0), +('Choceň','LKCHOC',49.9775,16.1853,866,1,'2023-08-14 10:04:19',NULL,0), +('Chornice','LKCHOR',49.6856,16.7314,1129,1,'2023-08-14 10:04:19',NULL,0), +('Choteč','LKCHOT',50.4339,15.5306,1076,1,'2023-08-14 10:04:19',NULL,0), +('Chotěšov','LKCHOV',49.6517,13.1897,1207,1,'2023-08-14 10:04:19',NULL,0), +('Chrášťany','LKCHRA',50.0586,14.9231,879,1,'2023-08-14 10:04:19',NULL,0), +('Chřibská','LKCHRI',50.8581,14.4669,1256,1,'2023-08-14 10:04:19',NULL,0), +('Chvojenec','LKCHVO',50.1086,15.9272,793,1,'2023-08-14 10:04:19',NULL,0), +('Kaplice','LKKAPL',48.7189,14.4503,2100,1,'2023-08-14 10:04:19',NULL,0), +('Kejžlice','LKKEJZ',49.5922,15.4014,1594,1,'2023-08-14 10:04:19',NULL,0), +('Kostomlaty','LKKOST',50.2081,14.9286,700,1,'2023-08-14 10:04:19',NULL,0), +('Kotvrdovice','LKKOTV',49.3642,16.7842,1860,1,'2023-08-14 10:04:19',NULL,0), +('Kozmice','LKKOZY',49.9133,18.1642,885,1,'2023-08-14 10:04:19',NULL,0), +('Kramolín','LKKRAM',48.915,14.7264,1650,1,'2023-08-14 10:04:19',NULL,0), +('Krpy','LKKRPY',50.3275,14.6636,803,1,'2023-08-14 10:04:19',NULL,0), +('Křelovice - Jiřičky','LKJIRI',49.5522,15.1556,1683,1,'2023-08-14 10:04:19',NULL,0), +('Kříženec','LKKRIZ',49.8708,12.7739,2076,1,'2023-08-14 10:04:19',NULL,0), +('Kunětice','LKKUNE',50.0683,15.8122,718,1,'2023-08-14 10:04:19',NULL,0), +('Letovice','LKLETO',49.5467,16.5986,1246,1,'2023-08-14 10:04:19',NULL,0), +('Libáň','LKLIBA',50.3706,15.2011,738,1,'2023-08-14 10:04:19',NULL,0), +('Lomnice nad Popelkou','LKLOMN',50.54,15.3881,1673,1,'2023-08-14 10:04:19',NULL,0), +('Loučeň','LKLOUC',50.2792,15.0611,636,1,'2023-08-14 10:04:19',NULL,0), +('Milovice','LKMILO',50.2378,14.9103,652,1,'2023-08-14 10:04:19',NULL,0), +('Miroslav','LKMIRO',48.9314,16.2986,780,1,'2023-08-14 10:04:19',NULL,0), +('Miroslav AirCon','LKMIRA',48.9317,16.3397,715,1,'2023-08-14 10:04:19',NULL,0), +('Místek','LKMIST',49.6528,18.3458,1066,1,'2023-08-14 10:04:19',NULL,0), +('Mladá','LKMLAD',50.2436,14.8556,738,1,'2023-08-14 10:04:19',NULL,0), +('Náchod','LKNACH',50.4131,16.1217,1443,1,'2023-08-14 10:04:19',NULL,0), +('Napajedla','LKNAPA',49.1989,13.6,1761,1,'2023-08-14 10:04:19',NULL,0), +('Nová Včelnice','LKNVCE',49.2672,15.0778,1771,1,'2023-08-14 10:04:19',NULL,0), +('Nučice','LKNUCI',49.9511,14.87,1374,1,'2023-08-14 10:04:19',NULL,0), +('Nymburk','LKNYMB',50.1692,15.0522,610,1,'2023-08-14 10:04:19',NULL,0), +('Opava','LKOPAV',49.9406,17.9861,872,1,'2023-08-14 10:04:19',NULL,0), +('Osičiny','LKOSIC',50.0158,14.7722,1280,1,'2023-08-14 10:04:19',NULL,0), +('Ostrov','LKOSTR',50.3367,12.9697,1676,1,'2023-08-14 10:04:19',NULL,0), +('Písek - Krašovice','LKPISK',49.3394,14.1139,1351,1,'2023-08-14 10:04:19',NULL,0), +('Polepy','LKPOLE',50.5206,14.2722,696,1,'2023-08-14 10:04:19',NULL,0), +('Ramš','LKRAMS',50.6417,14.5414,984,1,'2023-08-14 10:04:19',NULL,0), +('Slušovice','LKSLUS',49.2589,17.8133,1165,1,'2023-08-14 10:04:19',NULL,0), +('Strážnice','LKSTRZ',48.8878,17.2944,613,1,'2023-08-14 10:04:19',NULL,0), +('Štětí','LKSTET',50.465,14.4061,787,1,'2023-08-14 10:04:19',NULL,0), +('Teplice','LKTEPL',50.6208,13.8106,1148,1,'2023-08-14 10:04:19',NULL,0), +('Terezín','LKTERE',50.5194,14.1558,482,1,'2023-08-14 10:04:19',NULL,0), +('Trutnov','LKTRUT',50.5675,15.8653,1489,1,'2023-08-14 10:04:19',NULL,0), +('Třebihošť','LKTRBH',50.4353,15.6931,1624,1,'2023-08-14 10:04:19',NULL,0), +('Velké Pavlovice','LKPAVL',48.8806,16.825,564,1,'2023-08-14 10:04:19',NULL,0), +('Vrátkov','LKVRAT',50.0397,14.8219,1033,1,'2023-08-14 10:04:19',NULL,0), +('Zlín - Štípa','LKSTIP',49.2728,17.7464,1102,1,'2023-08-14 10:04:19',NULL,0), +('Blansko','LKBL',49.3624,16.654,1038,1,'2023-08-14 10:04:19',NULL,0), +('Boskovice','LKBS',49.4896,16.6463,1198,1,'2023-08-14 10:04:19',NULL,0), +('Brno - Bohunice MAIN','LKBG',49.1763,16.5722,951,1,'2023-08-14 10:04:19',NULL,0), +('Brno - Bohunice RESERVE','LKBN',49.1757,16.5693,967,1,'2023-08-14 10:04:19',NULL,0), +('Brno - Černá Pole','LKBP',49.2034,16.6165,791,1,'2023-08-14 10:04:19',NULL,0), +('Brno - Sv. Anna','LKBV',49.1907,16.6008,764,1,'2023-08-14 10:04:19',NULL,0), +('Brodek u Přerova','LKBD',49.4839,17.3269,668,1,'2023-08-14 10:04:19',NULL,0), +('Břeclav - Nemocnice','LKBI',48.7523,16.8779,518,1,'2023-08-14 10:04:19',NULL,0), +('České Budějovice - Nemocnice','LKCC',48.962,14.4627,1280,1,'2023-08-14 10:04:19',NULL,0), +('České Budějovice - Základna HEMS','LKCA',48.9445,14.4451,1340,1,'2023-08-14 10:04:19',NULL,0), +('Domažlice','LKDO',49.4384,12.907,1521,1,'2023-08-14 10:04:19',NULL,0), +('Frýdek - Místek','LKFM',49.691,18.355,1200,1,'2023-08-14 10:04:19',NULL,0), +('Havířov','LKHA',49.7837,18.4397,919,1,'2023-08-14 10:04:19',NULL,0), +('Havlíčkův Brod - Nemocnice','LKHL',49.6104,15.5705,1535,1,'2023-08-14 10:04:19',NULL,0), +('Hradec Králové - Nemocnice','LKHR',50.1983,15.8285,807,1,'2023-08-14 10:04:19',NULL,0), +('Hradec Králové - Základna HEMS','LKHH',50.1933,15.8255,751,1,'2023-08-14 10:04:19',NULL,0), +('Chodová Planá','LKCP',49.9012,12.7417,1783,1,'2023-08-14 10:04:19',NULL,0), +('Chomutov - Nemocnice','LKCU',50.4536,13.4118,1099,1,'2023-08-14 10:04:19',NULL,0), +('Chotouň','LKCO',50.0591,14.9577,830,1,'2023-08-14 10:04:19',NULL,0), +('Chrudim - Nemocnice','LKCD',49.9411,15.8083,925,1,'2023-08-14 10:04:19',NULL,0), +('Jeseník','LKJE',50.2216,17.1866,1511,1,'2023-08-14 10:04:19',NULL,0), +('Jihlava - Základna HEMS','LKJL',49.3985,15.5679,1752,1,'2023-08-14 10:04:19',NULL,0), +('Jindřichův Hradec - Nemocnice','LKJR',49.1393,15.0057,1620,1,'2023-08-14 10:04:19',NULL,0), +('Karlov','LKKE',49.1638,13.427,2577,1,'2023-08-14 10:04:19',NULL,0), +('Karlovy Vary - Nemocnice','LKKN',50.2328,12.8765,1409,1,'2023-08-14 10:04:19',NULL,0), +('Krnov - Nemocnice','LKKI',50.097,17.6852,1046,1,'2023-08-14 10:04:19',NULL,0), +('Kroměříž - Nemocnice','LKKZ',49.2912,17.3797,666,1,'2023-08-14 10:04:19',NULL,0), +('Kyjov - Nemocnice','LKKJ',49.0084,17.1107,730,1,'2023-08-14 10:04:19',NULL,0), +('Liberec - ACL','LKLA',50.7339,15.0376,1405,1,'2023-08-14 10:04:19',NULL,0), +('Liberec - Nemocnice','LKLC',50.77,15.0639,1358,1,'2023-08-14 10:04:19',NULL,0), +('Liberec - Základna HEMS','LKLH',50.7689,15.0242,1307,1,'2023-08-14 10:04:19',NULL,0), +('Litoměřice','LKLO',50.5417,14.1461,617,1,'2023-08-14 10:04:19',NULL,0), +('Mělník','LKME',50.3518,14.4868,557,1,'2023-08-14 10:04:19',NULL,0), +('Mladá Boleslav - Nemocnice','LKML',50.419,14.9071,761,1,'2023-08-14 10:04:19',NULL,0), +('Náchod','LKNC',50.4103,16.1666,1217,1,'2023-08-14 10:04:19',NULL,0), +('Nedanice','LKNE',49.4556,13.385,1585,1,'2023-08-14 10:04:19',NULL,0), +('Neratovice','LKNR',50.2526,14.5212,558,1,'2023-08-14 10:04:19',NULL,0), +('Nová Amerika','LKNK',50.3806,15.8635,1086,1,'2023-08-14 10:04:19',NULL,0), +('Nové Město na Moravě','LKNO',49.5615,16.0631,2047,1,'2023-08-14 10:04:19',NULL,0), +('Olomouc - Nemocnice','LKOC',49.5841,17.2365,873,1,'2023-08-14 10:04:19',NULL,0), +('Olomouc - Základna HEMS','LKOT',49.5836,17.2203,853,1,'2023-08-14 10:04:19',NULL,0), +('Opava','LKOV',49.9362,17.8759,900,1,'2023-08-14 10:04:19',NULL,0), +('Ostrava - Nemocnice','LKOP',49.8297,18.1603,866,1,'2023-08-14 10:04:19',NULL,0), +('Ostrava - Základna HEMS','LKOZ',49.8033,18.2305,758,1,'2023-08-14 10:04:19',NULL,0), +('Pelhřimov','LKPE',49.4354,15.2312,1709,1,'2023-08-14 10:04:19',NULL,0), +('Písek','LKPF',49.3006,14.1588,1266,1,'2023-08-14 10:04:19',NULL,0), +('Plzeň - MAIN','LKPZ',49.7619,13.3791,1105,1,'2023-08-14 10:04:19',NULL,0), +('Plzeň - RESERVE','LKPV',49.7636,13.377,1135,1,'2023-08-14 10:04:19',NULL,0), +('Praha 10 - Vinohrady','LKPY',50.0746,14.482,781,1,'2023-08-14 10:04:19',NULL,0), +('Praha 19 - Kbely','LKLK',50.1336,14.5367,908,1,'2023-08-14 10:04:19',NULL,0), +('Praha 4 - Krč','LKPK',50.0319,14.4571,755,1,'2023-08-14 10:04:19',NULL,0), +('Praha 5 - Motol','LKPH',50.0736,14.3424,1142,1,'2023-08-14 10:04:19',NULL,0), +('Praha 6 - Střešovice (MIL)','LKPT',50.0889,14.3631,1202,1,'2023-08-14 10:04:19',NULL,0), +('Praha 8 - Bulovka','LKPB',50.1162,14.4625,845,1,'2023-08-14 10:04:19',NULL,0), +('Prachatice','LKPG',49.0071,14.0096,1995,1,'2023-08-14 10:04:19',NULL,0), +('Přední Kopanina','LKPP',50.1196,14.303,1125,1,'2023-08-14 10:04:19',NULL,0), +('Rakovník - Nemocnice','LKRV',50.1077,13.7186,1112,1,'2023-08-14 10:04:19',NULL,0), +('Rozvadov','LKRZ',49.6687,12.5599,1815,1,'2023-08-14 10:04:19',NULL,0), +('Solnice - ACL','LKSL',50.1954,16.248,1112,1,'2023-08-14 10:04:19',NULL,0), +('Svitavy','LKSV',49.7638,16.4626,1449,1,'2023-08-14 10:04:19',NULL,0), +('Šumperk - Nemocnice','LKSP',49.9577,16.963,1023,1,'2023-08-14 10:04:19',NULL,0), +('Tábor - Nemocnice','LKTR',49.4159,14.6522,1450,1,'2023-08-14 10:04:19',NULL,0), +('Těchonín (MIL)','LKTH',50.0601,16.6122,1679,1,'2023-08-14 10:04:19',NULL,0), +('Trutnov','LKTU',50.5861,15.8787,1526,1,'2023-08-14 10:04:19',NULL,0), +('Uherské Hradiště - Mařatice','LKUH',49.0799,17.4851,590,1,'2023-08-14 10:04:19',NULL,0), +('Ústí nad Labem - Nemocnice','LKUS',50.6799,14.0207,932,1,'2023-08-14 10:04:19',NULL,0), +('Ústí nad Labem - Základna HEMS','LKUB',50.6774,14.024,919,1,'2023-08-14 10:04:19',NULL,0), +('Vyškov - Nemocnice','LKVN',49.2781,16.9815,869,1,'2023-08-14 10:04:19',NULL,0), +('Zlín - Nemocnice','LKZI',49.2262,17.7051,738,1,'2023-08-14 10:04:19',NULL,0), +('Benešov','LKBE',49.7408,14.6447,1322,1,'2023-08-14 10:19:26',NULL,0), +('Bohuňovice','LKBO',49.6706,17.295,774,1,'2023-08-14 10:19:26',NULL,0), +('Bubovice','LKBU',49.9744,14.1781,1398,1,'2023-08-14 10:19:26',NULL,0), +('Dvůr Králové','LKDK',50.4142,15.8369,925,1,'2023-08-14 10:19:26',NULL,0), +('BRNO/Tuřany','LKTB',49.1514,16.6939,778,1,'2023-08-14 10:19:26',NULL,0), +('Broumov','LKBR',50.5619,16.3428,1342,1,'2023-08-14 10:19:26',NULL,0), +('Břeclav','LKBA',48.7908,16.8925,525,1,'2023-08-14 10:19:26',NULL,0), +('Havlíčkův Brod','LKHB',49.5972,15.5492,1519,1,'2023-08-14 10:19:26',NULL,0), +('Hodkovice','LKHD',50.6572,15.0778,1480,1,'2023-08-14 10:19:26',NULL,0), +('Hořice','LKHC',50.3567,15.5772,917,1,'2023-08-14 10:19:26',NULL,0), +('Česká Lípa','LKCE',50.7094,14.5667,929,1,'2023-08-14 10:19:26',NULL,0), +('České Budějovice','LKCS',48.9464,14.4275,1417,1,'2023-08-14 10:19:26',NULL,0), +('Hořovice','LKHV',49.8447,13.8858,1214,1,'2023-08-14 10:19:26',NULL,0), +('Hosín','LKHS',49.04,14.495,1621,1,'2023-08-14 10:19:26',NULL,0), +('Hradec Králové','LKHK',50.2533,15.8453,791,1,'2023-08-14 10:19:26',NULL,0), +('Chomutov','LKCH',50.4689,13.4681,1132,1,'2023-08-14 10:19:26',NULL,0), +('Cheb','LKCB',50.0664,12.4128,1585,1,'2023-08-14 10:19:26',NULL,0), +('Hranice','LKHN',49.5461,17.7044,797,1,'2023-08-14 10:19:26',NULL,0), +('Chrudim','LKCR',49.9364,15.7806,978,1,'2023-08-14 10:19:26',NULL,0), +('Chotěboř','LKCT',49.6858,15.6761,1946,1,'2023-08-14 10:19:26',NULL,0), +('Jaroměř','LKJA',50.3314,15.9539,891,1,'2023-08-14 10:19:26',NULL,0), +('Erpužice','LKER',49.8028,13.0381,1568,1,'2023-08-14 10:19:26',NULL,0), +('Jičín','LKJC',50.43,15.3331,863,1,'2023-08-14 10:19:26',NULL,0), +('Frýdlant','LKFR',49.5894,18.3792,1440,1,'2023-08-14 10:19:26',NULL,0), +('Jihlava','LKJI',49.4197,15.6356,1821,1,'2023-08-14 10:19:26',NULL,0), +('Jindřichův Hradec','LKJH',49.1508,14.9717,1683,1,'2023-08-14 10:19:26',NULL,0), +('Karlovy Vary','LKKV',50.2031,12.915,1989,1,'2023-08-14 10:19:26',NULL,0), +('Kladno','LKKL',50.1128,14.0897,1419,1,'2023-08-14 10:19:26',NULL,0), +('Klatovy','LKKT',49.4183,13.3219,1299,1,'2023-08-14 10:19:26',NULL,0), +('Kolín','LKKO',50.0019,15.1733,925,1,'2023-08-14 10:19:26',NULL,0), +('Krnov','LKKR',50.0744,17.6953,1204,1,'2023-08-14 10:19:26',NULL,0), +('Kroměříž','LKKM',49.2856,17.4158,617,1,'2023-08-14 10:19:26',NULL,0), +('Křižanov','LKKA',49.3683,16.1161,1834,1,'2023-08-14 10:19:26',NULL,0), +('Kunovice','LKKU',49.0294,17.4397,581,1,'2023-08-14 10:19:26',NULL,0), +('Kyjov','LKKY',48.98,17.1247,686,1,'2023-08-14 10:19:26',NULL,0), +('Letkov','LKPL',49.7231,13.4522,1374,1,'2023-08-14 10:19:26',NULL,0), +('Letňany','LKLT',50.1314,14.5256,912,1,'2023-08-14 10:19:26',NULL,0), +('Liberec','LKLB',50.7683,15.025,1329,1,'2023-08-14 10:19:26',NULL,0), +('Luhačovice','LKLU',49.0922,17.7247,1127,1,'2023-08-14 10:19:26',NULL,0), +('Mariánské Lázně','LKMR',49.9228,12.7247,1768,1,'2023-08-14 10:19:26',NULL,0), +('Medlánky','LKCM',49.2369,16.5553,925,1,'2023-08-14 10:19:26',NULL,0), +('Mikulovice','LKMI',50.3017,17.2975,1375,1,'2023-08-14 10:19:26',NULL,0), +('Mladá Boleslav','LKMB',50.3983,14.8983,765,1,'2023-08-14 10:19:26',NULL,0), +('Mnichovo Hradiště','LKMH',50.54,15.0067,801,1,'2023-08-14 10:19:26',NULL,0), +('Moravská Třebová','LKMK',49.7983,16.6878,1322,1,'2023-08-14 10:19:26',NULL,0), +('Most','LKMO',50.525,13.6831,1086,1,'2023-08-14 10:19:26',NULL,0), +('Nové Město','LKNM',50.3642,16.1136,1001,1,'2023-08-14 10:19:26',NULL,0), +('Olomouc','LKOL',49.5872,17.21,869,1,'2023-08-14 10:19:26',NULL,0), +('OSTRAVA/Mošnov','LKMT',49.6961,18.1108,844,1,'2023-08-14 10:19:26',NULL,0), +('Panenský Týnec','LKPC',50.3064,13.935,1207,1,'2023-08-14 10:19:26',NULL,0), +('Pardubice','LKPD',50.0133,15.7383,741,1,'2023-08-14 10:19:26',NULL,0), +('Plasy','LKPS',49.9203,13.3769,1434,1,'2023-08-14 10:19:26',NULL,0), +('Plzeň/Líně','LKLN',49.6753,13.2744,1188,1,'2023-08-14 10:19:26',NULL,0), +('Podhořany','LKPN',49.9392,15.5497,1250,1,'2023-08-14 10:19:26',NULL,0), +('Polička','LKPA',49.7394,16.2589,1978,1,'2023-08-14 10:19:26',NULL,0), +('PRAHA/Ruzyně','LKPR',50.1008,14.26,1234,1,'2023-08-14 10:19:26',NULL,0), +('PRAHA/Vodochody','LKVO',50.2167,14.3956,919,1,'2023-08-14 10:19:26',NULL,0), +('Prostějov','LKPJ',49.4478,17.1339,702,1,'2023-08-14 10:19:26',NULL,0), +('Přerov','LKPO',49.4258,17.4047,676,1,'2023-08-14 10:19:26',NULL,0), +('Příbram','LKPM',49.72,14.1003,1529,1,'2023-08-14 10:19:26',NULL,0), +('Přibyslav','LKPI',49.5808,15.7628,1742,1,'2023-08-14 10:19:26',NULL,0), +('Rakovník','LKRK',50.0942,13.6889,1273,1,'2023-08-14 10:19:26',NULL,0), +('Raná','LKRA',50.4039,13.7519,883,1,'2023-08-14 10:19:26',NULL,0), +('Rokycany','LKRY',49.7519,13.5897,1329,1,'2023-08-14 10:19:26',NULL,0), +('Roudnice','LKRO',50.4106,14.2261,728,1,'2023-08-14 10:19:26',NULL,0), +('Sazená','LKSZ',50.3247,14.2589,765,1,'2023-08-14 10:19:26',NULL,0), +('Skuteč','LKSK',49.8278,16.0058,1601,1,'2023-08-14 10:19:26',NULL,0), +('Slaný','LKSN',50.2167,14.0886,1079,1,'2023-08-14 10:19:26',NULL,0), +('Soběslav','LKSO',49.2467,14.7136,1335,1,'2023-08-14 10:19:26',NULL,0), +('Staňkov','LKSA',49.5667,13.0486,1404,1,'2023-08-14 10:19:26',NULL,0), +('Stichovice','LKSB',49.4861,17.0556,837,1,'2023-08-14 10:19:26',NULL,0), +('Strakonice','LKST',49.2517,13.8928,1378,1,'2023-08-14 10:19:26',NULL,0), +('Strunkovice','LKSR',49.0825,14.0758,1565,1,'2023-08-14 10:19:26',NULL,0), +('Šumperk','LKSU',49.9606,17.0178,1099,1,'2023-08-14 10:19:26',NULL,0), +('Tábor','LKTA',49.3911,14.7083,1440,1,'2023-08-14 10:19:26',NULL,0), +('Tachov','LKTD',49.7978,12.7069,1639,1,'2023-08-14 10:19:26',NULL,0), +('Točná','LKTC',49.9853,14.4256,1027,1,'2023-08-14 10:19:26',NULL,0), +('Toužim','LKTO',50.0864,12.9528,2123,1,'2023-08-14 10:19:26',NULL,0), +('Ústí nad Labem','LKUL',50.6997,13.9697,787,1,'2023-08-14 10:19:26',NULL,0), +('Ústí nad Orlicí','LKUO',49.9786,16.4264,1342,1,'2023-08-14 10:19:26',NULL,0), +('Velké Poříčí','LKVP',50.4678,16.2056,1326,1,'2023-08-14 10:19:26',NULL,0), +('Vrchlabí','LKVR',50.6242,15.6464,1611,1,'2023-08-14 10:19:26',NULL,0), +('Vlašim','LKVL',49.7289,14.8789,1421,1,'2023-08-14 10:19:26',NULL,0), +('Vysoké Mýto','LKVM',49.9269,16.1858,988,1,'2023-08-14 10:19:26',NULL,0), +('Vyškov','LKVY',49.3003,17.0253,915,1,'2023-08-14 10:19:26',NULL,0), +('Zábřeh','LKZA',49.9283,18.0783,794,1,'2023-08-14 10:19:26',NULL,0), +('Zbraslavice','LKZB',49.8142,15.2017,1618,1,'2023-08-14 10:19:26',NULL,0), +('Zlín','LKZL',49.1983,17.5178,604,1,'2023-08-14 10:19:26',NULL,0), +('Znojmo','LKZN',48.8178,16.0658,827,1,'2023-08-14 10:19:26',NULL,0), +('Žamberk','LKZM',50.0839,16.4439,1408,1,'2023-08-14 10:19:26',NULL,0), +('Žatec/Macerka','LKZD',50.3175,13.5128,883,1,'2023-08-14 10:19:26',NULL,0), +('Borek','LKBORE',50.2108,14.6575,557,1,'2023-08-14 10:19:26',NULL,0), +('Boleradice','LKBOLE',48.9619,16.8317,650,1,'2023-08-14 10:19:26',NULL,0), +('Brťov','LKBRTO',49.4108,16.4994,1610,1,'2023-08-14 10:19:26',NULL,0), +('Březí Falcon','LKBREZ',49.3383,16.2328,1680,1,'2023-08-14 10:19:26',NULL,0), +('Budkovice','LKBUDK',49.0786,16.3558,870,1,'2023-08-14 10:19:26',NULL,0), +('Bynovec','LKBYNO',50.8219,14.2714,1266,1,'2023-08-14 10:19:26',NULL,0), +('Bystřice nad Pernštejnem','LKBYST',49.5228,16.2322,1942,1,'2023-08-14 10:19:26',NULL,0), +('Částkovice','LKCAST',49.4092,15.1442,1925,1,'2023-08-14 10:19:26',NULL,0), +('Čebín','LKCEBI',49.3189,16.4967,1004,1,'2023-08-14 10:19:26',NULL,0), +('Český Dub','LKCDUB',50.6781,14.9997,1303,1,'2023-08-14 10:19:27',NULL,0), +('Dětřichov Oáza','LKDETR',49.7292,17.1181,751,1,'2023-08-14 10:19:27',NULL,0), +('Doudleby','LKDOUD',48.885,14.4864,1541,1,'2023-08-14 10:19:27',NULL,0), +('Druzcov u Lípy','LKDRUZ',50.7281,14.9247,1509,1,'2023-08-14 10:19:27',NULL,0), +('Dušníky','LKDUSN',50.4128,14.1981,728,1,'2023-08-14 10:19:27',NULL,0), +('Hatě Excalibur','LKEXCA',48.7617,16.0553,777,1,'2023-08-14 10:19:27',NULL,0), +('Hať u Hlučína','LKHATH',49.95,18.2647,774,1,'2023-08-14 10:19:27',NULL,0), +('Hláska','LKHLAS',49.0669,14.2414,1430,1,'2023-08-14 10:19:27',NULL,0), +('Horní Počaply','LKPOCA',50.4181,14.3842,524,1,'2023-08-14 10:19:27',NULL,0), +('Horní Přím','LKPRIM',50.2294,15.7036,885,1,'2023-08-14 10:19:27',NULL,0), +('Hradčany','LKHRAD',50.6194,14.7328,912,1,'2023-08-14 10:19:27',NULL,0), +('Charvátce','LKCHAR',50.4336,13.8108,922,1,'2023-08-14 10:19:27',NULL,0), +('Choceň','LKCHOC',49.9775,16.1853,866,1,'2023-08-14 10:19:27',NULL,0), +('Chornice','LKCHOR',49.6856,16.7314,1129,1,'2023-08-14 10:19:27',NULL,0), +('Choteč','LKCHOT',50.4339,15.5306,1076,1,'2023-08-14 10:19:27',NULL,0), +('Chotěšov','LKCHOV',49.6517,13.1897,1207,1,'2023-08-14 10:19:27',NULL,0), +('Chřibská','LKCHRI',50.8581,14.4669,1256,1,'2023-08-14 10:19:27',NULL,0), +('Chrášťany','LKCHRA',50.0586,14.9231,879,1,'2023-08-14 10:19:27',NULL,0), +('Chvojenec','LKCHVO',50.1086,15.9272,793,1,'2023-08-14 10:19:27',NULL,0), +('Kaplice','LKKAPL',48.7189,14.4503,2100,1,'2023-08-14 10:19:27',NULL,0), +('Kejžlice','LKKEJZ',49.5922,15.4014,1594,1,'2023-08-14 10:19:27',NULL,0), +('Kostomlaty','LKKOST',50.2081,14.9286,700,1,'2023-08-14 10:19:27',NULL,0), +('Kotvrdovice','LKKOTV',49.3642,16.7842,1860,1,'2023-08-14 10:19:27',NULL,0), +('Kozmice','LKKOZY',49.9133,18.1642,885,1,'2023-08-14 10:19:27',NULL,0), +('Kramolín','LKKRAM',48.915,14.7264,1650,1,'2023-08-14 10:19:27',NULL,0), +('Krpy','LKKRPY',50.3275,14.6636,803,1,'2023-08-14 10:19:27',NULL,0), +('Křelovice - Jiřičky','LKJIRI',49.5522,15.1556,1683,1,'2023-08-14 10:19:27',NULL,0), +('Kříženec','LKKRIZ',49.8708,12.7739,2076,1,'2023-08-14 10:19:27',NULL,0), +('Kunětice','LKKUNE',50.0683,15.8122,718,1,'2023-08-14 10:19:27',NULL,0), +('Letovice','LKLETO',49.5467,16.5986,1246,1,'2023-08-14 10:19:27',NULL,0), +('Libáň','LKLIBA',50.3706,15.2011,738,1,'2023-08-14 10:19:27',NULL,0), +('Lomnice nad Popelkou','LKLOMN',50.54,15.3881,1673,1,'2023-08-14 10:19:27',NULL,0), +('Loučeň','LKLOUC',50.2792,15.0611,636,1,'2023-08-14 10:19:27',NULL,0), +('Milovice','LKMILO',50.2378,14.9103,652,1,'2023-08-14 10:19:27',NULL,0), +('Miroslav','LKMIRO',48.9314,16.2986,780,1,'2023-08-14 10:19:27',NULL,0), +('Miroslav AirCon','LKMIRA',48.9317,16.3397,715,1,'2023-08-14 10:19:27',NULL,0), +('Místek','LKMIST',49.6528,18.3458,1066,1,'2023-08-14 10:19:27',NULL,0), +('Mladá','LKMLAD',50.2436,14.8556,738,1,'2023-08-14 10:19:27',NULL,0), +('Náchod','LKNACH',50.4131,16.1217,1443,1,'2023-08-14 10:19:27',NULL,0), +('Napajedla','LKNAPA',49.1989,13.6,1761,1,'2023-08-14 10:19:27',NULL,0), +('Nová Včelnice','LKNVCE',49.2672,15.0778,1771,1,'2023-08-14 10:19:27',NULL,0), +('Nučice','LKNUCI',49.9511,14.87,1374,1,'2023-08-14 10:19:27',NULL,0), +('Nymburk','LKNYMB',50.1692,15.0522,610,1,'2023-08-14 10:19:27',NULL,0), +('Opava','LKOPAV',49.9406,17.9861,872,1,'2023-08-14 10:19:27',NULL,0), +('Osičiny','LKOSIC',50.0158,14.7722,1280,1,'2023-08-14 10:19:27',NULL,0), +('Ostrov','LKOSTR',50.3367,12.9697,1676,1,'2023-08-14 10:19:27',NULL,0), +('Písek - Krašovice','LKPISK',49.3394,14.1139,1351,1,'2023-08-14 10:19:27',NULL,0), +('Ramš','LKRAMS',50.6417,14.5414,984,1,'2023-08-14 10:19:27',NULL,0), +('Polepy','LKPOLE',50.5206,14.2722,696,1,'2023-08-14 10:19:27',NULL,0), +('Slušovice','LKSLUS',49.2589,17.8133,1165,1,'2023-08-14 10:19:27',NULL,0), +('Strážnice','LKSTRZ',48.8878,17.2944,613,1,'2023-08-14 10:19:27',NULL,0), +('Štětí','LKSTET',50.465,14.4061,787,1,'2023-08-14 10:19:27',NULL,0), +('Teplice','LKTEPL',50.6208,13.8106,1148,1,'2023-08-14 10:19:27',NULL,0), +('Terezín','LKTERE',50.5194,14.1558,482,1,'2023-08-14 10:19:27',NULL,0), +('Trutnov','LKTRUT',50.5675,15.8653,1489,1,'2023-08-14 10:19:27',NULL,0), +('Třebihošť','LKTRBH',50.4353,15.6931,1624,1,'2023-08-14 10:19:27',NULL,0), +('Velké Pavlovice','LKPAVL',48.8806,16.825,564,1,'2023-08-14 10:19:27',NULL,0), +('Vrátkov','LKVRAT',50.0397,14.8219,1033,1,'2023-08-14 10:19:27',NULL,0), +('Zlín - Štípa','LKSTIP',49.2728,17.7464,1102,1,'2023-08-14 10:19:27',NULL,0), +('Blansko','LKBL',49.3624,16.654,1038,1,'2023-08-14 10:19:27',NULL,0), +('Boskovice','LKBS',49.4896,16.6463,1198,1,'2023-08-14 10:19:27',NULL,0), +('Brno - Bohunice MAIN','LKBG',49.1763,16.5722,951,1,'2023-08-14 10:19:27',NULL,0), +('Brno - Bohunice RESERVE','LKBN',49.1757,16.5693,967,1,'2023-08-14 10:19:27',NULL,0), +('Brno - Černá Pole','LKBP',49.2034,16.6165,791,1,'2023-08-14 10:19:27',NULL,0), +('Brno - Sv. Anna','LKBV',49.1907,16.6008,764,1,'2023-08-14 10:19:27',NULL,0), +('Brodek u Přerova','LKBD',49.4839,17.3269,668,1,'2023-08-14 10:19:27',NULL,0), +('Břeclav - Nemocnice','LKBI',48.7523,16.8779,518,1,'2023-08-14 10:19:27',NULL,0), +('České Budějovice - Nemocnice','LKCC',48.962,14.4627,1280,1,'2023-08-14 10:19:27',NULL,0), +('České Budějovice - Základna HEMS','LKCA',48.9445,14.4451,1340,1,'2023-08-14 10:19:27',NULL,0), +('Domažlice','LKDO',49.4384,12.907,1521,1,'2023-08-14 10:19:27',NULL,0), +('Frýdek - Místek','LKFM',49.691,18.355,1200,1,'2023-08-14 10:19:27',NULL,0), +('Havířov','LKHA',49.7837,18.4397,919,1,'2023-08-14 10:19:27',NULL,0), +('Havlíčkův Brod - Nemocnice','LKHL',49.6104,15.5705,1535,1,'2023-08-14 10:19:27',NULL,0), +('Hradec Králové - Nemocnice','LKHR',50.1983,15.8285,807,1,'2023-08-14 10:19:27',NULL,0), +('Hradec Králové - Základna HEMS','LKHH',50.1933,15.8255,751,1,'2023-08-14 10:19:27',NULL,0), +('Chodová Planá','LKCP',49.9012,12.7417,1783,1,'2023-08-14 10:19:27',NULL,0), +('Chomutov - Nemocnice','LKCU',50.4536,13.4118,1099,1,'2023-08-14 10:19:27',NULL,0), +('Chotouň','LKCO',50.0591,14.9577,830,1,'2023-08-14 10:19:27',NULL,0), +('Chrudim - Nemocnice','LKCD',49.9411,15.8083,925,1,'2023-08-14 10:19:27',NULL,0), +('Jeseník','LKJE',50.2216,17.1866,1511,1,'2023-08-14 10:19:27',NULL,0), +('Jihlava - Základna HEMS','LKJL',49.3985,15.5679,1752,1,'2023-08-14 10:19:27',NULL,0), +('Jindřichův Hradec - Nemocnice','LKJR',49.1393,15.0057,1620,1,'2023-08-14 10:19:27',NULL,0), +('Karlov','LKKE',49.1638,13.427,2577,1,'2023-08-14 10:19:27',NULL,0), +('Karlovy Vary - Nemocnice','LKKN',50.2328,12.8765,1409,1,'2023-08-14 10:19:27',NULL,0), +('Krnov - Nemocnice','LKKI',50.097,17.6852,1046,1,'2023-08-14 10:19:27',NULL,0), +('Kroměříž - Nemocnice','LKKZ',49.2912,17.3797,666,1,'2023-08-14 10:19:27',NULL,0), +('Kyjov - Nemocnice','LKKJ',49.0084,17.1107,730,1,'2023-08-14 10:19:27',NULL,0), +('Liberec - ACL','LKLA',50.7339,15.0376,1405,1,'2023-08-14 10:19:27',NULL,0), +('Liberec - Nemocnice','LKLC',50.77,15.0639,1358,1,'2023-08-14 10:19:27',NULL,0), +('Liberec - Základna HEMS','LKLH',50.7689,15.0242,1307,1,'2023-08-14 10:19:27',NULL,0), +('Litoměřice','LKLO',50.5417,14.1461,617,1,'2023-08-14 10:19:27',NULL,0), +('Mělník','LKME',50.3518,14.4868,557,1,'2023-08-14 10:19:27',NULL,0), +('Mladá Boleslav - Nemocnice','LKML',50.419,14.9071,761,1,'2023-08-14 10:19:27',NULL,0), +('Náchod','LKNC',50.4103,16.1666,1217,1,'2023-08-14 10:19:27',NULL,0), +('Nedanice','LKNE',49.4556,13.385,1585,1,'2023-08-14 10:19:27',NULL,0), +('Neratovice','LKNR',50.2526,14.5212,558,1,'2023-08-14 10:19:27',NULL,0), +('Nová Amerika','LKNK',50.3806,15.8635,1086,1,'2023-08-14 10:19:27',NULL,0), +('Nové Město na Moravě','LKNO',49.5615,16.0631,2047,1,'2023-08-14 10:19:27',NULL,0), +('Olomouc - Nemocnice','LKOC',49.5841,17.2365,873,1,'2023-08-14 10:19:27',NULL,0), +('Olomouc - Základna HEMS','LKOT',49.5836,17.2203,853,1,'2023-08-14 10:19:27',NULL,0), +('Opava','LKOV',49.9362,17.8759,900,1,'2023-08-14 10:19:27',NULL,0), +('Ostrava - Nemocnice','LKOP',49.8297,18.1603,866,1,'2023-08-14 10:19:27',NULL,0), +('Ostrava - Základna HEMS','LKOZ',49.8033,18.2305,758,1,'2023-08-14 10:19:27',NULL,0), +('Pelhřimov','LKPE',49.4354,15.2312,1709,1,'2023-08-14 10:19:27',NULL,0), +('Písek','LKPF',49.3006,14.1588,1266,1,'2023-08-14 10:19:27',NULL,0), +('Plzeň - MAIN','LKPZ',49.7619,13.3791,1105,1,'2023-08-14 10:19:27',NULL,0), +('Plzeň - RESERVE','LKPV',49.7636,13.377,1135,1,'2023-08-14 10:19:27',NULL,0), +('Praha 10 - Vinohrady','LKPY',50.0746,14.482,781,1,'2023-08-14 10:19:27',NULL,0), +('Praha 19 - Kbely','LKLK',50.1336,14.5367,908,1,'2023-08-14 10:19:27',NULL,0), +('Praha 4 - Krč','LKPK',50.0319,14.4571,755,1,'2023-08-14 10:19:27',NULL,0), +('Praha 5 - Motol','LKPH',50.0736,14.3424,1142,1,'2023-08-14 10:19:27',NULL,0), +('Praha 6 - Střešovice (MIL)','LKPT',50.0889,14.3631,1202,1,'2023-08-14 10:19:27',NULL,0), +('Praha 8 - Bulovka','LKPB',50.1162,14.4625,845,1,'2023-08-14 10:19:27',NULL,0), +('Prachatice','LKPG',49.0071,14.0096,1995,1,'2023-08-14 10:19:27',NULL,0), +('Přední Kopanina','LKPP',50.1196,14.303,1125,1,'2023-08-14 10:19:27',NULL,0), +('Rakovník - Nemocnice','LKRV',50.1077,13.7186,1112,1,'2023-08-14 10:19:27',NULL,0), +('Rozvadov','LKRZ',49.6687,12.5599,1815,1,'2023-08-14 10:19:27',NULL,0), +('Solnice - ACL','LKSL',50.1954,16.248,1112,1,'2023-08-14 10:19:27',NULL,0), +('Svitavy','LKSV',49.7638,16.4626,1449,1,'2023-08-14 10:19:27',NULL,0), +('Šumperk - Nemocnice','LKSP',49.9577,16.963,1023,1,'2023-08-14 10:19:27',NULL,0), +('Tábor - Nemocnice','LKTR',49.4159,14.6522,1450,1,'2023-08-14 10:19:27',NULL,0), +('Těchonín (MIL)','LKTH',50.0601,16.6122,1679,1,'2023-08-14 10:19:27',NULL,0), +('Trutnov','LKTU',50.5861,15.8787,1526,1,'2023-08-14 10:19:27',NULL,0), +('Uherské Hradiště - Mařatice','LKUH',49.0799,17.4851,590,1,'2023-08-14 10:19:27',NULL,0), +('Ústí nad Labem - Nemocnice','LKUS',50.6799,14.0207,932,1,'2023-08-14 10:19:27',NULL,0), +('Ústí nad Labem - Základna HEMS','LKUB',50.6774,14.024,919,1,'2023-08-14 10:19:27',NULL,0), +('Vyškov - Nemocnice','LKVN',49.2781,16.9815,869,1,'2023-08-14 10:19:27',NULL,0), +('Zlín - Nemocnice','LKZI',49.2262,17.7051,738,1,'2023-08-14 10:19:27',NULL,0); diff --git a/deploy.sh b/deploy.sh new file mode 100755 index 0000000..f1e7e5c --- /dev/null +++ b/deploy.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +IMAGE_NAME="poletani/api" +TAG="latest" + +DOCKER_REGISTRY="docker.kvacek.cz" +CONTAINER_IMAGE="$DOCKER_REGISTRY/$IMAGE_NAME:$TAG" + +docker login $DOCKER_REGISTRY + +docker build -t $CONTAINER_IMAGE . +docker push $CONTAINER_IMAGE diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000..05aac65 --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,13 @@ +version: "3.3" +services: + api: + image: "docker.kvacek.cz/poletani/api:latest" + ports: + - 8000:8000 + command: "uvicorn src.asgi:app --port=8000 --host=0.0.0.0 -k uvicorn.workers.UvicornWorker" + network_mode: "host" + restart: "always" + env_file: + - .env + volumes: + - ./uploads:/app/uploads diff --git a/src/database/config.py b/src/database/config.py index a82469e..0aad836 100644 --- a/src/database/config.py +++ b/src/database/config.py @@ -1,15 +1,20 @@ +import os from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession from sqlalchemy.orm import sessionmaker -def create_db_engine( - user: str = "root", - password: str = "", - host: str = "db", - port: int = 3306, - database: str = "ull_tracker", -): - database_url = f'mysql+aiomysql://{user}:{password}@{host}:{port}/{database}?charset=utf8' +def get_database_url(): + user = os.environ.get("MYSQL_USER", "root") + password = os.environ.get("MYSQL_PASSWORD", "") + host = os.environ.get("MYSQL_HOST", "db") + port = int(os.environ.get("MYSQL_PORT", 3306)) + database = os.environ.get("MYSQL_DATABASE", "ull_tracker") + + return f'mysql+aiomysql://{user}:{password}@{host}:{port}/{database}?charset=utf8' + + +def create_db_engine(): + database_url = get_database_url() return create_async_engine(database_url, future=True, echo=True) diff --git a/src/decorators/endpoints.py b/src/decorators/endpoints.py index 48ceb21..ace7e88 100644 --- a/src/decorators/endpoints.py +++ b/src/decorators/endpoints.py @@ -17,7 +17,6 @@ def authenticated_user_only(raise_when_unauthorized: bool = True, return_value_u raise HTTPException(HTTP_401_UNAUTHORIZED, "Not authorized") else: return return_value_unauthorized - return await func(*args, **kwargs) return decorator diff --git a/src/dependencies/db.py b/src/dependencies/db.py index 5db0448..80edb7e 100644 --- a/src/dependencies/db.py +++ b/src/dependencies/db.py @@ -5,5 +5,5 @@ async def db_session(): async with async_session() as session: async with session.begin(): yield session - await session.commit() await session.flush() + await session.commit() diff --git a/src/graphql_schema/entities/flight.py b/src/graphql_schema/entities/flight.py index b2b8fc0..fe6435b 100644 --- a/src/graphql_schema/entities/flight.py +++ b/src/graphql_schema/entities/flight.py @@ -1,3 +1,4 @@ +import asyncio from datetime import timedelta from typing import List, Optional, Annotated, TYPE_CHECKING, Tuple import strawberry @@ -161,14 +162,21 @@ class CreateFlightMutation: @authenticated_user_only() async def create_flight(self, info, input: CreateFlightInput) -> Flight: db = info.context.db - aircraft_id = await handle_aircraft_save(db, info.context.user_id, input.aircraft) - data = input.to_dict() - takeoff_airport, landing_airport = await get_airports(db, input.takeoff_airport.id, input.landing_airport.id) - weather_takeoff = await handle_weather_info(db, data['takeoff_datetime'], takeoff_airport) - weather_landing = await handle_weather_info(db, data['landing_datetime'], landing_airport) - return await models.Flight.create(db, data={ + takeoff_airport, landing_airport = await get_airports(db, input.takeoff_airport.id, input.landing_airport.id) + + aircraft_id = await handle_aircraft_save(db, info.context.user_id, input.aircraft) + weather_takeoff,weather_landing = await asyncio.gather( + handle_weather_info(db, data['takeoff_datetime'], takeoff_airport), + handle_weather_info(db, data['landing_datetime'], landing_airport) + ) + await db.flush() + + print("XXXXXXXXXXXXX", weather_takeoff, weather_takeoff.id) + + + flight = await models.Flight.create(db, data={ **data, "takeoff_weather_info_id": weather_takeoff.id, "landing_weather_info_id": weather_landing.id, @@ -177,6 +185,7 @@ class CreateFlightMutation: "aircraft_id": aircraft_id, "created_by_id": info.context.user_id }) + return flight @strawberry.type diff --git a/src/graphql_schema/entities/helpers/flight.py b/src/graphql_schema/entities/helpers/flight.py index 01bf11d..7928972 100644 --- a/src/graphql_schema/entities/helpers/flight.py +++ b/src/graphql_schema/entities/helpers/flight.py @@ -16,7 +16,7 @@ weather_api = Weather() async def handle_weather_info(db: AsyncSession, date_time: datetime, airport: models.Airport) -> models.WeatherInfo: weather = await weather_api.get_weather_for_hour(date_time.astimezone(), (airport.gps_latitude, airport.gps_longitude)) - return await models.WeatherInfo.create(db_session=db, data={ + model = models.WeatherInfo(**{ "datetime": weather['datetime'], "qnh": weather['pressure_msl'], "temperature_surface": weather['temperature_2m'], @@ -27,6 +27,9 @@ async def handle_weather_info(db: AsyncSession, date_time: datetime, airport: mo "wind_speed_surface": weather['windspeed_10m'], "wind_direction_surface": weather['winddirection_10m'], }) + db.add(model) + + return model async def handle_track_edit(db: AsyncSession, flight: models.Flight, track: List[ComboboxInput], user_id: int): @@ -48,7 +51,7 @@ async def handle_track_edit(db: AsyncSession, flight: models.Flight, track: List poi_object = poi_map.get(item.id) if not poi_object: - poi_object = await models.PointOfInterest.create(db, data=dict(created_by_id=user_id, name=item.name)) + poi_object = await models.PointOfInterest.create(db, data=dict(created_by_id=user_id, name=item.name, description="")) await db.flush() await models.FlightTrack.create( @@ -63,19 +66,15 @@ async def handle_track_edit(db: AsyncSession, flight: models.Flight, track: List async def handle_aircraft_save(db: AsyncSession, user_id: int, aircraft: ComboboxInput): - if aircraft.id: - return aircraft.id - else: - obj = await models.Aircraft.create(db, { - "call_sign": aircraft.name, + return await handle_combobox_save( + db, models.Aircraft, aircraft, user_id, + name_column="call_sign", + extra_data={ "description": "", "model": "", + "seats": 2, "manufacturer": "", - "created_by_id": user_id - }) - await db.flush() - return obj.id async def get_airports(db, takeoff_airport_id: int, landing_airport_id: int) -> Tuple[models.Airport, models.Airport]: @@ -127,15 +126,21 @@ async def handle_copilots_edit(db: AsyncSession, copilots: List[ComboboxInput], async def handle_combobox_save( - db: AsyncSession, model: Type[models.BaseModel], + db: AsyncSession, + model: Type[models.BaseModel], input: ComboboxInput, user_id: int, - name_column: str = "name" + name_column: str = "name", + extra_data: Optional[dict] = None ) -> int: if input.id: return input.id else: - data = {name_column: input.name} + + if not extra_data: + extra_data = {} + + data = {name_column: input.name, **extra_data} if hasattr(model, "created_by_id"): data["created_by_id"] = user_id diff --git a/src/graphql_schema/entities/photo.py b/src/graphql_schema/entities/photo.py index 7b99fde..97033a1 100644 --- a/src/graphql_schema/entities/photo.py +++ b/src/graphql_schema/entities/photo.py @@ -5,7 +5,7 @@ from strawberry.file_uploads import Upload from database import models from decorators.endpoints import authenticated_user_only from graphql_schema.sqlalchemy_to_strawberry_type import strawberry_sqlalchemy_type, strawberry_sqlalchemy_input -from upload_utils import get_public_url, handle_file_upload, delete_file, parse_exif_info, generate_thumbnail, file_exists +from upload_utils import get_public_url, handle_file_upload, delete_file, parse_exif_info, generate_thumbnail, file_exists, resize_image @strawberry_sqlalchemy_type(models.Photo) @@ -57,7 +57,9 @@ class UploadPhotoMutation: async def upload_photo(self, info, input: UploadPhotoInput) -> Photo: path = get_photo_basepath(input.flight_id) filename = await handle_file_upload(input.photo, path) - info.context.background_tasks.add_task(generate_thumbnail, path=path, filename=filename, size=(300, 200)) + + info.context.background_tasks.add_task(resize_image, path=path, filename=filename, new_width=2500) + info.context.background_tasks.add_task(generate_thumbnail, path=path, filename=filename, new_width=300) exif_info = await parse_exif_info(path, filename) diff --git a/src/graphql_schema/entities/user.py b/src/graphql_schema/entities/user.py index 8a7108e..68d78d5 100644 --- a/src/graphql_schema/entities/user.py +++ b/src/graphql_schema/entities/user.py @@ -11,7 +11,7 @@ from database.models import User from decorators.endpoints import authenticated_user_only from decorators.error_logging import error_logging from graphql_schema.sqlalchemy_to_strawberry_type import strawberry_sqlalchemy_type, strawberry_sqlalchemy_input -from upload_utils import handle_file_upload, delete_file, get_public_url +from upload_utils import handle_file_upload, delete_file, get_public_url, resize_image @strawberry_sqlalchemy_type(User, exclude_fields=['password_hashed']) @@ -81,6 +81,9 @@ class EditUserMutation: delete_file(f"{user_image_path}/{user.avatar_image_filename}", silent=True) data['avatar_image_filename'] = await handle_file_upload(input.avatar_image, user_image_path) + info.context.background_tasks.add_task( + resize_image, path=user_image_path, filename=data['avatar_image_filename'], new_width=400 + ) if input.title_image: if user.title_image_filename: @@ -88,6 +91,10 @@ class EditUserMutation: data['title_image_filename'] = await handle_file_upload(input.title_image, user_image_path) + info.context.background_tasks.add_task( + resize_image, path=user_image_path, filename=data['title_image_filename'], new_width=800 + ) + if input.old_password and input.new_password: if not bcrypt.verify(input.old_password, user.password_hashed): raise GraphQLError("Bad password") diff --git a/src/upload_utils.py b/src/upload_utils.py index 8b569a0..a8cf28c 100644 --- a/src/upload_utils.py +++ b/src/upload_utils.py @@ -62,15 +62,44 @@ async def parse_exif_info(path: str, filename: str) -> dict: return exif_info -async def generate_thumbnail(path: str, filename: str, size: Tuple[int, int]): +async def resize_image(path: str, filename: str, new_width: int, quality: int = 90, dest_path: str = None, dest_filename: str = None): + print("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") + if not dest_path: + dest_path = path + + if not dest_filename: + dest_filename = filename + try: image = Image.open(f"{path}/{filename}") - image.thumbnail(size) + + width, height = image.size + new_height = int(new_width * height / width) + + image = image.resize((new_width, new_height), Image.LANCZOS) + check_directories(dest_path) + image.save(f"{dest_path}/{dest_filename}", 'JPEG', quality=quality) + except UnidentifiedImageError as e : + pass + print(e) + + print("AAA^^^^^^^^^^^^AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") + +async def generate_thumbnail(path: str, filename: str, size: Tuple[int, int], quality: int = 90): + try: + image = Image.open(f"{path}/{filename}") + image = image.thumbnail(size, Image.LANCZOS) check_directories(f"{path}/thumbs/") - image.save(f"{path}/thumbs/{filename}") + image.save(f"{path}/thumbs/{filename}", 'JPEG', quality=quality) + + return await resize_image(path, filename, size, dest_path=f"{path}/thumbs/", dest_filename=filename) except UnidentifiedImageError: pass def delete_file(path: str, silent: bool = False): - os.remove(path) + try: + os.remove(path) + except Exception: + if not silent: + raise