Import stations.csv file from Trainline
This commit is contained in:
parent
6884084f2a
commit
0486234b9f
|
@ -0,0 +1,23 @@
|
|||
from django.contrib import admin
|
||||
|
||||
from trainvel.core.models import Station
|
||||
|
||||
|
||||
class StationInline(admin.TabularInline):
|
||||
model = Station
|
||||
extra = 0
|
||||
autocomplete_fields = ('parent_station', 'same_as',)
|
||||
show_change_link = True
|
||||
ordering = ('name',)
|
||||
readonly_fields = ('id',)
|
||||
fk_name = 'parent_station'
|
||||
|
||||
|
||||
@admin.register(Station)
|
||||
class StationAdmin(admin.ModelAdmin):
|
||||
list_display = ('name', 'country', 'uic', 'latitude', 'longitude',)
|
||||
list_filter = ('country', 'is_city', 'is_main_station', 'is_airport', 'is_suggestable',
|
||||
'country_hint', 'main_station_hint',)
|
||||
search_fields = ('name', 'slug',)
|
||||
autocomplete_fields = ('parent_station', 'same_as',)
|
||||
inlines = [StationInline]
|
|
@ -0,0 +1,8 @@
|
|||
from django.apps import AppConfig
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class CoreConfig(AppConfig):
|
||||
default_auto_field = "django.db.models.BigAutoField"
|
||||
name = "trainvel.core"
|
||||
verbose_name = _("Trainvel - Core")
|
|
@ -0,0 +1,325 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 1.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-05-09 22:04+0200\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Emmy D'Anello <ynerant@emy.lu>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
#: trainvel/core/apps.py:8
|
||||
msgid "Trainvel - Core"
|
||||
msgstr "Trainvel - Cœur"
|
||||
|
||||
#: trainvel/core/models.py:15
|
||||
msgid "name"
|
||||
msgstr "nom"
|
||||
|
||||
#: trainvel/core/models.py:20
|
||||
msgid "slug"
|
||||
msgstr "slug"
|
||||
|
||||
#: trainvel/core/models.py:24
|
||||
msgid "UIC"
|
||||
msgstr "UIC"
|
||||
|
||||
#: trainvel/core/models.py:31
|
||||
msgid "UIC8 SNCF"
|
||||
msgstr "UIC8 SNCF"
|
||||
|
||||
#: trainvel/core/models.py:38
|
||||
msgid "latitude"
|
||||
msgstr "latitude"
|
||||
|
||||
#: trainvel/core/models.py:45
|
||||
msgid "longitude"
|
||||
msgstr "longitude"
|
||||
|
||||
#: trainvel/core/models.py:54
|
||||
msgid "parent station"
|
||||
msgstr "gare parente"
|
||||
|
||||
#: trainvel/core/models.py:63
|
||||
msgid "country"
|
||||
msgstr "pays"
|
||||
|
||||
#: trainvel/core/models.py:69
|
||||
msgid "timezone"
|
||||
msgstr "fuseau horaire"
|
||||
|
||||
#: trainvel/core/models.py:73
|
||||
msgid "is city"
|
||||
msgstr "est une ville"
|
||||
|
||||
#: trainvel/core/models.py:77
|
||||
msgid "is main station"
|
||||
msgstr "est une gare principale"
|
||||
|
||||
#: trainvel/core/models.py:81
|
||||
msgid "is airport"
|
||||
msgstr "est un aéroport"
|
||||
|
||||
#: trainvel/core/models.py:85
|
||||
msgid "is suggestable"
|
||||
msgstr "est suggérable"
|
||||
|
||||
#: trainvel/core/models.py:89
|
||||
msgid "country hint"
|
||||
msgstr "indice de pays"
|
||||
|
||||
#: trainvel/core/models.py:93
|
||||
msgid "main station hint"
|
||||
msgstr "indice de gare principale"
|
||||
|
||||
#: trainvel/core/models.py:98
|
||||
msgid "SNCF ID"
|
||||
msgstr "ID SNCF"
|
||||
|
||||
#: trainvel/core/models.py:106
|
||||
msgid "SNCF TVS ID"
|
||||
msgstr "ID SNCF TVS"
|
||||
|
||||
#: trainvel/core/models.py:113
|
||||
msgid "SNCF is enabled"
|
||||
msgstr "SNCF est activé"
|
||||
|
||||
#: trainvel/core/models.py:118
|
||||
msgid "Entur ID"
|
||||
msgstr "ID Entur"
|
||||
|
||||
#: trainvel/core/models.py:125
|
||||
msgid "Entur is enabled"
|
||||
msgstr "Entur est activé"
|
||||
|
||||
#: trainvel/core/models.py:129
|
||||
msgid "DB ID"
|
||||
msgstr "ID DB"
|
||||
|
||||
#: trainvel/core/models.py:136
|
||||
msgid "DB is enabled"
|
||||
msgstr "DB est activé"
|
||||
|
||||
#: trainvel/core/models.py:141
|
||||
msgid "Busbud ID"
|
||||
msgstr "ID Busbud"
|
||||
|
||||
#: trainvel/core/models.py:148
|
||||
msgid "Busbud is enabled"
|
||||
msgstr "Busbud est activé"
|
||||
|
||||
#: trainvel/core/models.py:153
|
||||
msgid "distribusion ID"
|
||||
msgstr "ID distribusion"
|
||||
|
||||
#: trainvel/core/models.py:160
|
||||
msgid "distribusion is enabled"
|
||||
msgstr "distribusion est activé"
|
||||
|
||||
#: trainvel/core/models.py:164
|
||||
msgid "Flixbus ID"
|
||||
msgstr "ID Flixbus"
|
||||
|
||||
#: trainvel/core/models.py:171
|
||||
msgid "Flixbus is enabled"
|
||||
msgstr "Flixbus est activé"
|
||||
|
||||
#: trainvel/core/models.py:175
|
||||
msgid "CFF ID"
|
||||
msgstr "ID CFF"
|
||||
|
||||
#: trainvel/core/models.py:182
|
||||
msgid "CFF is enabled"
|
||||
msgstr "CFF est activé"
|
||||
|
||||
#: trainvel/core/models.py:187
|
||||
msgid "Leo Express ID"
|
||||
msgstr "ID Leo Express"
|
||||
|
||||
#: trainvel/core/models.py:194
|
||||
msgid "Leo Express is enabled"
|
||||
msgstr "Leo Express est activé"
|
||||
|
||||
#: trainvel/core/models.py:198
|
||||
msgid "ÖBB ID"
|
||||
msgstr "ID ÖBB"
|
||||
|
||||
#: trainvel/core/models.py:205
|
||||
msgid "ÖBB is enabled"
|
||||
msgstr "ÖBB est activé"
|
||||
|
||||
#: trainvel/core/models.py:210
|
||||
msgid "Ouigo ID"
|
||||
msgstr "ID Ouigo"
|
||||
|
||||
#: trainvel/core/models.py:217
|
||||
msgid "Ouigo is enabled"
|
||||
msgstr "Ouigo est activé"
|
||||
|
||||
#: trainvel/core/models.py:221
|
||||
msgid "Trenitalia ID"
|
||||
msgstr "ID Trenitalia"
|
||||
|
||||
#: trainvel/core/models.py:228
|
||||
msgid "Trenitalia is enabled"
|
||||
msgstr "Trenitalia est activé"
|
||||
|
||||
#: trainvel/core/models.py:233
|
||||
msgid "Trenitalia RTVT ID"
|
||||
msgstr "ID Trenitalia RTVT"
|
||||
|
||||
#: trainvel/core/models.py:241
|
||||
msgid "Trenord ID"
|
||||
msgstr "ID Trenord"
|
||||
|
||||
#: trainvel/core/models.py:249
|
||||
msgid "NTV RTIV ID"
|
||||
msgstr "ID NTV RTIV"
|
||||
|
||||
#: trainvel/core/models.py:257
|
||||
msgid "NTV ID"
|
||||
msgstr "ID NTV"
|
||||
|
||||
#: trainvel/core/models.py:264
|
||||
msgid "NTV is enabled"
|
||||
msgstr "NTV est activé"
|
||||
|
||||
#: trainvel/core/models.py:269
|
||||
msgid "HKX ID"
|
||||
msgstr "ID HKX"
|
||||
|
||||
#: trainvel/core/models.py:276
|
||||
msgid "HKX is enabled"
|
||||
msgstr "HKX est activé"
|
||||
|
||||
#: trainvel/core/models.py:280
|
||||
msgid "Renfe ID"
|
||||
msgstr "ID Renfe"
|
||||
|
||||
#: trainvel/core/models.py:287
|
||||
msgid "Renfe is enabled"
|
||||
msgstr "Renfe est activé"
|
||||
|
||||
#: trainvel/core/models.py:292
|
||||
msgid "ATOC ID"
|
||||
msgstr "ID ATOC"
|
||||
|
||||
#: trainvel/core/models.py:299
|
||||
msgid "ATOC is enabled"
|
||||
msgstr "ATOC est activé"
|
||||
|
||||
#: trainvel/core/models.py:304
|
||||
msgid "Benerail ID"
|
||||
msgstr "ID Benerail"
|
||||
|
||||
#: trainvel/core/models.py:311
|
||||
msgid "Benerail is enabled"
|
||||
msgstr "Benerail est activé"
|
||||
|
||||
#: trainvel/core/models.py:316
|
||||
msgid "Westbahn ID"
|
||||
msgstr "ID Westbahn"
|
||||
|
||||
#: trainvel/core/models.py:323
|
||||
msgid "Westbahn is enabled"
|
||||
msgstr "Westbahn est activé"
|
||||
|
||||
#: trainvel/core/models.py:327
|
||||
msgid "SNCF self-service machine"
|
||||
msgstr "Automate self-service SNCF"
|
||||
|
||||
#: trainvel/core/models.py:333
|
||||
msgid "same as"
|
||||
msgstr "identique à"
|
||||
|
||||
#: trainvel/core/models.py:342
|
||||
msgid "info (DE)"
|
||||
msgstr "info (DE)"
|
||||
|
||||
#: trainvel/core/models.py:350
|
||||
msgid "info (EN)"
|
||||
msgstr "info (EN)"
|
||||
|
||||
#: trainvel/core/models.py:358
|
||||
msgid "info (ES)"
|
||||
msgstr "info (ES)"
|
||||
|
||||
#: trainvel/core/models.py:366
|
||||
msgid "info (FR)"
|
||||
msgstr "info (FR)"
|
||||
|
||||
#: trainvel/core/models.py:374
|
||||
msgid "info (IT)"
|
||||
msgstr "info (IT)"
|
||||
|
||||
#: trainvel/core/models.py:382
|
||||
msgid "info (NB)"
|
||||
msgstr "info (NB)"
|
||||
|
||||
#: trainvel/core/models.py:390
|
||||
msgid "info (NL)"
|
||||
msgstr "info (NL)"
|
||||
|
||||
#: trainvel/core/models.py:398
|
||||
msgid "info (CS)"
|
||||
msgstr "info (CS)"
|
||||
|
||||
#: trainvel/core/models.py:406
|
||||
msgid "info (DA)"
|
||||
msgstr "info (DA)"
|
||||
|
||||
#: trainvel/core/models.py:414
|
||||
msgid "info (HU)"
|
||||
msgstr "info (HU)"
|
||||
|
||||
#: trainvel/core/models.py:422
|
||||
msgid "info (JA)"
|
||||
msgstr "info (JA)"
|
||||
|
||||
#: trainvel/core/models.py:430
|
||||
msgid "info (KO)"
|
||||
msgstr "info (KO)"
|
||||
|
||||
#: trainvel/core/models.py:438
|
||||
msgid "info (PL)"
|
||||
msgstr "info (PL)"
|
||||
|
||||
#: trainvel/core/models.py:446
|
||||
msgid "info (PT)"
|
||||
msgstr "info (PT)"
|
||||
|
||||
#: trainvel/core/models.py:454
|
||||
msgid "info (RU)"
|
||||
msgstr "info (RU)"
|
||||
|
||||
#: trainvel/core/models.py:462
|
||||
msgid "info (SV)"
|
||||
msgstr "info (SV)"
|
||||
|
||||
#: trainvel/core/models.py:470
|
||||
msgid "info (TR)"
|
||||
msgstr "info (TR)"
|
||||
|
||||
#: trainvel/core/models.py:478
|
||||
msgid "info (ZH)"
|
||||
msgstr "info (ZH)"
|
||||
|
||||
#: trainvel/core/models.py:486
|
||||
msgid "normalized code (Trainline)"
|
||||
msgstr "code normalisé (Trainline)"
|
||||
|
||||
#: trainvel/core/models.py:491
|
||||
msgid "IATA airport code"
|
||||
msgstr "code aéroport IATA"
|
||||
|
||||
#: trainvel/core/models.py:501
|
||||
msgid "station"
|
||||
msgstr "gare"
|
||||
|
||||
#: trainvel/core/models.py:502
|
||||
msgid "stations"
|
||||
msgstr "gares"
|
|
@ -0,0 +1,33 @@
|
|||
import csv
|
||||
|
||||
import requests
|
||||
from django.core.management import BaseCommand
|
||||
from tqdm import tqdm
|
||||
|
||||
from trainvel.core.models import Station
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
def handle(self, *args, **options):
|
||||
def convert_value(value: str) -> str:
|
||||
return True if value == 't' else False if value == 'f' else (value or None)
|
||||
|
||||
stations, stations_without_fk = [], []
|
||||
|
||||
STATIONS_URL = "https://raw.githubusercontent.com/trainline-eu/stations/master/stations.csv"
|
||||
with requests.get(STATIONS_URL, stream=True) as resp:
|
||||
for row in csv.DictReader(tqdm(resp.iter_lines(decode_unicode=True)), delimiter=';'):
|
||||
row: dict
|
||||
values = {k.replace(':', '_').replace('normalised_code', 'normalized_code_trainline')
|
||||
.replace('same_as', 'same_as_id'): convert_value(v)
|
||||
for k, v in row.items()}
|
||||
values_without_fk = values.copy()
|
||||
del values_without_fk['same_as_id']
|
||||
del values_without_fk['parent_station_id']
|
||||
stations.append(Station(**values))
|
||||
stations_without_fk.append(Station(**values_without_fk))
|
||||
|
||||
Station.objects.bulk_create(stations_without_fk, update_conflicts=True, unique_fields=['id'],
|
||||
update_fields=[k for k in values_without_fk.keys() if k != 'id'])
|
||||
Station.objects.bulk_create(stations, update_conflicts=True, unique_fields=['id'],
|
||||
update_fields=['same_as_id', 'parent_station_id'])
|
|
@ -0,0 +1,603 @@
|
|||
# Generated by Django 5.0.1 on 2024-05-09 22:15
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = []
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="Station",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("name", models.CharField(max_length=255, verbose_name="name")),
|
||||
("slug", models.SlugField(max_length=255, verbose_name="slug")),
|
||||
(
|
||||
"uic",
|
||||
models.IntegerField(
|
||||
blank=True, default=None, null=True, verbose_name="UIC"
|
||||
),
|
||||
),
|
||||
(
|
||||
"uic8_sncf",
|
||||
models.IntegerField(
|
||||
blank=True, default=None, null=True, verbose_name="UIC8 SNCF"
|
||||
),
|
||||
),
|
||||
(
|
||||
"latitude",
|
||||
models.FloatField(
|
||||
blank=True, default=None, null=True, verbose_name="latitude"
|
||||
),
|
||||
),
|
||||
(
|
||||
"longitude",
|
||||
models.FloatField(
|
||||
blank=True, default=None, null=True, verbose_name="longitude"
|
||||
),
|
||||
),
|
||||
(
|
||||
"country",
|
||||
models.CharField(
|
||||
choices=[
|
||||
("AL", "Albania"),
|
||||
("AD", "Andorra"),
|
||||
("AM", "Armenia"),
|
||||
("AT", "Austria"),
|
||||
("AZ", "Azerbaijan"),
|
||||
("BE", "Belgium"),
|
||||
("BA", "Bosnia and Herzegovina"),
|
||||
("BG", "Bulgaria"),
|
||||
("HR", "Croatia"),
|
||||
("CY", "Cyprus"),
|
||||
("CZ", "Czech Republic"),
|
||||
("DK", "Denmark"),
|
||||
("EE", "Estonia"),
|
||||
("FI", "Finland"),
|
||||
("FR", "France"),
|
||||
("GE", "Georgia"),
|
||||
("DE", "Germany"),
|
||||
("GR", "Greece"),
|
||||
("HU", "Hungary"),
|
||||
("IS", "Iceland"),
|
||||
("IE", "Ireland"),
|
||||
("IT", "Italy"),
|
||||
("LV", "Latvia"),
|
||||
("LI", "Liechtenstein"),
|
||||
("LT", "Lithuania"),
|
||||
("LU", "Luxembourg"),
|
||||
("MT", "Malta"),
|
||||
("MD", "Moldova"),
|
||||
("MC", "Monaco"),
|
||||
("ME", "Montenegro"),
|
||||
("NL", "Netherlands"),
|
||||
("MK", "North Macedonia"),
|
||||
("NO", "Norway"),
|
||||
("PL", "Poland"),
|
||||
("PT", "Portugal"),
|
||||
("RO", "Romania"),
|
||||
("SM", "San Marino"),
|
||||
("RS", "Serbia"),
|
||||
("SK", "Slovakia"),
|
||||
("SI", "Slovenia"),
|
||||
("ES", "Spain"),
|
||||
("SE", "Sweden"),
|
||||
("CH", "Switzerland"),
|
||||
("TR", "Turkey"),
|
||||
("GB", "United Kingdom"),
|
||||
("UA", "Ukraine"),
|
||||
],
|
||||
max_length=255,
|
||||
verbose_name="country",
|
||||
),
|
||||
),
|
||||
(
|
||||
"time_zone",
|
||||
models.CharField(max_length=255, verbose_name="timezone"),
|
||||
),
|
||||
("is_city", models.BooleanField(verbose_name="is city")),
|
||||
(
|
||||
"is_main_station",
|
||||
models.BooleanField(verbose_name="is main station"),
|
||||
),
|
||||
("is_airport", models.BooleanField(verbose_name="is airport")),
|
||||
("is_suggestable", models.BooleanField(verbose_name="is suggestable")),
|
||||
("country_hint", models.BooleanField(verbose_name="country hint")),
|
||||
(
|
||||
"main_station_hint",
|
||||
models.BooleanField(verbose_name="main station hint"),
|
||||
),
|
||||
(
|
||||
"sncf_id",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=5,
|
||||
null=True,
|
||||
verbose_name="SNCF ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"sncf_tvs_id",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=3,
|
||||
null=True,
|
||||
verbose_name="SNCF TVS ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"sncf_is_enabled",
|
||||
models.BooleanField(verbose_name="SNCF is enabled"),
|
||||
),
|
||||
(
|
||||
"entur_id",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="Entur ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"entur_is_enabled",
|
||||
models.BooleanField(verbose_name="Entur is enabled"),
|
||||
),
|
||||
(
|
||||
"db_id",
|
||||
models.IntegerField(
|
||||
blank=True, default=None, null=True, verbose_name="DB ID"
|
||||
),
|
||||
),
|
||||
("db_is_enabled", models.BooleanField(verbose_name="DB is enabled")),
|
||||
(
|
||||
"busbud_id",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="Busbud ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"busbud_is_enabled",
|
||||
models.BooleanField(verbose_name="Busbud is enabled"),
|
||||
),
|
||||
(
|
||||
"distribusion_id",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="distribusion ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"distribusion_is_enabled",
|
||||
models.BooleanField(verbose_name="distribusion is enabled"),
|
||||
),
|
||||
(
|
||||
"flixbus_id",
|
||||
models.IntegerField(
|
||||
blank=True, default=None, null=True, verbose_name="Flixbus ID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"flixbus_is_enabled",
|
||||
models.BooleanField(verbose_name="Flixbus is enabled"),
|
||||
),
|
||||
(
|
||||
"cff_id",
|
||||
models.IntegerField(
|
||||
blank=True, default=None, null=True, verbose_name="CFF ID"
|
||||
),
|
||||
),
|
||||
("cff_is_enabled", models.BooleanField(verbose_name="CFF is enabled")),
|
||||
(
|
||||
"leoexpress_id",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="Leo Express ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"leoexpress_is_enabled",
|
||||
models.BooleanField(verbose_name="Leo Express is enabled"),
|
||||
),
|
||||
(
|
||||
"obb_id",
|
||||
models.IntegerField(
|
||||
blank=True, default=None, null=True, verbose_name="ÖBB ID"
|
||||
),
|
||||
),
|
||||
("obb_is_enabled", models.BooleanField(verbose_name="ÖBB is enabled")),
|
||||
(
|
||||
"ouigo_id",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="Ouigo ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"ouigo_is_enabled",
|
||||
models.BooleanField(verbose_name="Ouigo is enabled"),
|
||||
),
|
||||
(
|
||||
"trenitalia_id",
|
||||
models.IntegerField(
|
||||
blank=True,
|
||||
default=None,
|
||||
null=True,
|
||||
verbose_name="Trenitalia ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"trenitalia_is_enabled",
|
||||
models.BooleanField(verbose_name="Trenitalia is enabled"),
|
||||
),
|
||||
(
|
||||
"trenitalia_rtvt_id",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="Trenitalia RTVT ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"trenord_id",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="Trenord ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"ntv_rtiv_id",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="NTV RTIV ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"ntv_id",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="NTV ID",
|
||||
),
|
||||
),
|
||||
("ntv_is_enabled", models.BooleanField(verbose_name="NTV is enabled")),
|
||||
(
|
||||
"hkx_id",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="HKX ID",
|
||||
),
|
||||
),
|
||||
("hkx_is_enabled", models.BooleanField(verbose_name="HKX is enabled")),
|
||||
(
|
||||
"renfe_id",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="Renfe ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"renfe_is_enabled",
|
||||
models.BooleanField(verbose_name="Renfe is enabled"),
|
||||
),
|
||||
(
|
||||
"atoc_id",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="ATOC ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"atoc_is_enabled",
|
||||
models.BooleanField(verbose_name="ATOC is enabled"),
|
||||
),
|
||||
(
|
||||
"benerail_id",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="Benerail ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"benerail_is_enabled",
|
||||
models.BooleanField(verbose_name="Benerail is enabled"),
|
||||
),
|
||||
(
|
||||
"westbahn_id",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="Westbahn ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"westbahn_is_enabled",
|
||||
models.BooleanField(verbose_name="Westbahn is enabled"),
|
||||
),
|
||||
(
|
||||
"sncf_self_service_machine",
|
||||
models.BooleanField(verbose_name="SNCF self-service machine"),
|
||||
),
|
||||
(
|
||||
"info_de",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="info (DE)",
|
||||
),
|
||||
),
|
||||
(
|
||||
"info_en",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="info (EN)",
|
||||
),
|
||||
),
|
||||
(
|
||||
"info_es",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="info (ES)",
|
||||
),
|
||||
),
|
||||
(
|
||||
"info_fr",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="info (FR)",
|
||||
),
|
||||
),
|
||||
(
|
||||
"info_it",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="info (IT)",
|
||||
),
|
||||
),
|
||||
(
|
||||
"info_nb",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="info (NB)",
|
||||
),
|
||||
),
|
||||
(
|
||||
"info_nl",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="info (NL)",
|
||||
),
|
||||
),
|
||||
(
|
||||
"info_cs",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="info (CS)",
|
||||
),
|
||||
),
|
||||
(
|
||||
"info_da",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="info (DA)",
|
||||
),
|
||||
),
|
||||
(
|
||||
"info_hu",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="info (HU)",
|
||||
),
|
||||
),
|
||||
(
|
||||
"info_ja",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="info (JA)",
|
||||
),
|
||||
),
|
||||
(
|
||||
"info_ko",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="info (KO)",
|
||||
),
|
||||
),
|
||||
(
|
||||
"info_pl",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="info (PL)",
|
||||
),
|
||||
),
|
||||
(
|
||||
"info_pt",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="info (PT)",
|
||||
),
|
||||
),
|
||||
(
|
||||
"info_ru",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="info (RU)",
|
||||
),
|
||||
),
|
||||
(
|
||||
"info_sv",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="info (SV)",
|
||||
),
|
||||
),
|
||||
(
|
||||
"info_tr",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="info (TR)",
|
||||
),
|
||||
),
|
||||
(
|
||||
"info_zh",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="info (ZH)",
|
||||
),
|
||||
),
|
||||
(
|
||||
"normalized_code_trainline",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="normalized code (Trainline)",
|
||||
),
|
||||
),
|
||||
(
|
||||
"iata_airport_code",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="IATA airport code",
|
||||
),
|
||||
),
|
||||
(
|
||||
"parent_station",
|
||||
models.ForeignKey(
|
||||
blank=True,
|
||||
default=None,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="children",
|
||||
to="core.station",
|
||||
verbose_name="parent station",
|
||||
),
|
||||
),
|
||||
(
|
||||
"same_as",
|
||||
models.ForeignKey(
|
||||
blank=True,
|
||||
default=None,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="same_as_other",
|
||||
to="core.station",
|
||||
verbose_name="same as",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "station",
|
||||
"verbose_name_plural": "stations",
|
||||
},
|
||||
),
|
||||
]
|
|
@ -0,0 +1,506 @@
|
|||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from trainvel.gtfs.models import Country
|
||||
|
||||
|
||||
class Station(models.Model):
|
||||
"""
|
||||
Describes the content of the stations CSV file generated by Trainline.
|
||||
The CSV file can be found at https://raw.githubusercontent.com/trainline-eu/stations/master/stations.csv
|
||||
"""
|
||||
|
||||
name = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("name"),
|
||||
)
|
||||
|
||||
slug = models.SlugField(
|
||||
max_length=255,
|
||||
verbose_name=_("slug"),
|
||||
)
|
||||
|
||||
uic = models.IntegerField(
|
||||
verbose_name=_("UIC"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
uic8_sncf = models.IntegerField(
|
||||
verbose_name=_("UIC8 SNCF"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
latitude = models.FloatField(
|
||||
verbose_name=_("latitude"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
longitude = models.FloatField(
|
||||
verbose_name=_("longitude"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
parent_station = models.ForeignKey(
|
||||
"Station",
|
||||
on_delete=models.CASCADE,
|
||||
verbose_name=_("parent station"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
related_name="children",
|
||||
)
|
||||
|
||||
country = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("country"),
|
||||
choices=Country,
|
||||
)
|
||||
|
||||
time_zone = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("timezone"),
|
||||
)
|
||||
|
||||
is_city = models.BooleanField(
|
||||
verbose_name=_("is city"),
|
||||
)
|
||||
|
||||
is_main_station = models.BooleanField(
|
||||
verbose_name=_("is main station"),
|
||||
)
|
||||
|
||||
is_airport = models.BooleanField(
|
||||
verbose_name=_("is airport"),
|
||||
)
|
||||
|
||||
is_suggestable = models.BooleanField(
|
||||
verbose_name=_("is suggestable"),
|
||||
)
|
||||
|
||||
country_hint = models.BooleanField(
|
||||
verbose_name=_("country hint"),
|
||||
)
|
||||
|
||||
main_station_hint = models.BooleanField(
|
||||
verbose_name=_("main station hint"),
|
||||
)
|
||||
|
||||
sncf_id = models.CharField(
|
||||
max_length=5,
|
||||
verbose_name=_("SNCF ID"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
sncf_tvs_id = models.CharField(
|
||||
max_length=3,
|
||||
verbose_name=_("SNCF TVS ID"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
sncf_is_enabled = models.BooleanField(
|
||||
verbose_name=_("SNCF is enabled"),
|
||||
)
|
||||
|
||||
entur_id = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("Entur ID"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
entur_is_enabled = models.BooleanField(
|
||||
verbose_name=_("Entur is enabled"),
|
||||
)
|
||||
|
||||
db_id = models.IntegerField(
|
||||
verbose_name=_("DB ID"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
db_is_enabled = models.BooleanField(
|
||||
verbose_name=_("DB is enabled"),
|
||||
)
|
||||
|
||||
busbud_id = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("Busbud ID"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
busbud_is_enabled = models.BooleanField(
|
||||
verbose_name=_("Busbud is enabled"),
|
||||
)
|
||||
|
||||
distribusion_id = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("distribusion ID"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
distribusion_is_enabled = models.BooleanField(
|
||||
verbose_name=_("distribusion is enabled"),
|
||||
)
|
||||
|
||||
flixbus_id = models.IntegerField(
|
||||
verbose_name=_("Flixbus ID"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
flixbus_is_enabled = models.BooleanField(
|
||||
verbose_name=_("Flixbus is enabled"),
|
||||
)
|
||||
|
||||
cff_id = models.IntegerField(
|
||||
verbose_name=_("CFF ID"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
cff_is_enabled = models.BooleanField(
|
||||
verbose_name=_("CFF is enabled"),
|
||||
)
|
||||
|
||||
leoexpress_id = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("Leo Express ID"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
leoexpress_is_enabled = models.BooleanField(
|
||||
verbose_name=_("Leo Express is enabled"),
|
||||
)
|
||||
|
||||
obb_id = models.IntegerField(
|
||||
verbose_name=_("ÖBB ID"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
obb_is_enabled = models.BooleanField(
|
||||
verbose_name=_("ÖBB is enabled"),
|
||||
)
|
||||
|
||||
ouigo_id = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("Ouigo ID"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
ouigo_is_enabled = models.BooleanField(
|
||||
verbose_name=_("Ouigo is enabled"),
|
||||
)
|
||||
|
||||
trenitalia_id = models.IntegerField(
|
||||
verbose_name=_("Trenitalia ID"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
trenitalia_is_enabled = models.BooleanField(
|
||||
verbose_name=_("Trenitalia is enabled"),
|
||||
)
|
||||
|
||||
trenitalia_rtvt_id = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("Trenitalia RTVT ID"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
trenord_id = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("Trenord ID"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
ntv_rtiv_id = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("NTV RTIV ID"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
ntv_id = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("NTV ID"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
ntv_is_enabled = models.BooleanField(
|
||||
verbose_name=_("NTV is enabled"),
|
||||
)
|
||||
|
||||
hkx_id = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("HKX ID"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
hkx_is_enabled = models.BooleanField(
|
||||
verbose_name=_("HKX is enabled"),
|
||||
)
|
||||
|
||||
renfe_id = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("Renfe ID"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
renfe_is_enabled = models.BooleanField(
|
||||
verbose_name=_("Renfe is enabled"),
|
||||
)
|
||||
|
||||
atoc_id = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("ATOC ID"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
atoc_is_enabled = models.BooleanField(
|
||||
verbose_name=_("ATOC is enabled"),
|
||||
)
|
||||
|
||||
benerail_id = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("Benerail ID"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
benerail_is_enabled = models.BooleanField(
|
||||
verbose_name=_("Benerail is enabled"),
|
||||
)
|
||||
|
||||
westbahn_id = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("Westbahn ID"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
westbahn_is_enabled = models.BooleanField(
|
||||
verbose_name=_("Westbahn is enabled"),
|
||||
)
|
||||
|
||||
sncf_self_service_machine = models.BooleanField(
|
||||
verbose_name=_("SNCF self-service machine"),
|
||||
)
|
||||
|
||||
same_as = models.ForeignKey(
|
||||
"Station",
|
||||
on_delete=models.CASCADE,
|
||||
verbose_name=_("same as"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
related_name="same_as_other",
|
||||
)
|
||||
|
||||
info_de = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("info (DE)"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
info_en = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("info (EN)"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
info_es = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("info (ES)"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
info_fr = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("info (FR)"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
info_it = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("info (IT)"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
info_nb = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("info (NB)"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
info_nl = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("info (NL)"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
info_cs = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("info (CS)"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
info_da = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("info (DA)"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
info_hu = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("info (HU)"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
info_ja = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("info (JA)"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
info_ko = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("info (KO)"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
info_pl = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("info (PL)"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
info_pt = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("info (PT)"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
info_ru = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("info (RU)"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
info_sv = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("info (SV)"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
info_tr = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("info (TR)"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
info_zh = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("info (ZH)"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
normalized_code_trainline = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("normalized code (Trainline)"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
iata_airport_code = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("IATA airport code"),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("station")
|
||||
verbose_name_plural = _("stations")
|
|
@ -0,0 +1,3 @@
|
|||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
|
@ -0,0 +1,3 @@
|
|||
from django.shortcuts import render
|
||||
|
||||
# Create your views here.
|
|
@ -155,7 +155,7 @@ class Command(BaseCommand):
|
|||
unique_fields=['id'])
|
||||
routes.clear()
|
||||
|
||||
# Calendar.objects.filter(gtfs_feed=gtfs_feed).delete()
|
||||
Calendar.objects.filter(gtfs_feed=gtfs_feed).delete()
|
||||
calendars = {}
|
||||
if "calendar.txt" in zipfile.namelist():
|
||||
for calendar_dict in csv.DictReader(tqdm(read_file("calendar.txt"), desc="Calendars")):
|
||||
|
|
|
@ -45,6 +45,7 @@ INSTALLED_APPS = [
|
|||
"rest_framework",
|
||||
|
||||
"trainvel.api",
|
||||
"trainvel.core",
|
||||
"trainvel.gtfs",
|
||||
]
|
||||
|
||||
|
|
Loading…
Reference in New Issue