From 036e1604bd3168cba9bfbdc1e04597ea79043eb5 Mon Sep 17 00:00:00 2001 From: Emmy D'Anello Date: Sun, 10 Nov 2024 16:34:18 +0100 Subject: [PATCH] Drop trainvel backend, this is now a frontend-only app --- .gitignore | 65 +- trainvel-front/README.md => README.md | 0 manage.py | 22 - .../package-lock.json => package-lock.json | 0 trainvel-front/package.json => package.json | 0 {trainvel-front/public => public}/bus.svg | 0 .../public => public}/eurostar.svg | 0 .../public => public}/eurostar_mini.svg | 0 {trainvel-front/public => public}/favicon.ico | Bin .../public => public}/frecciarossa.svg | 0 {trainvel-front/public => public}/ice.svg | 0 {trainvel-front/public => public}/index.html | 0 {trainvel-front/public => public}/logo192.png | Bin {trainvel-front/public => public}/logo512.png | Bin {trainvel-front/public => public}/lyria.svg | 0 .../public => public}/manifest.json | 0 .../public => public}/nightjet.svg | 0 {trainvel-front/public => public}/ouigo.svg | 0 {trainvel-front/public => public}/renfe.svg | 0 public/robots.txt | 3 + {trainvel-front/public => public}/ter.svg | 0 .../public => public}/tgv_inoui.svg | 0 .../public => public}/trenitalia.svg | 0 requirements.txt | 8 - {trainvel-front/src => src}/App.css | 0 {trainvel-front/src => src}/App.js | 0 .../src => src}/AutocompleteStation.jsx | 0 {trainvel-front/src => src}/Home.js | 0 {trainvel-front/src => src}/Station.js | 0 {trainvel-front/src => src}/Station.test.js | 0 {trainvel-front/src => src}/TrainsTable.js | 0 {trainvel-front/src => src}/TripsFilter.js | 0 {trainvel-front/src => src}/index.css | 0 {trainvel-front/src => src}/index.js | 0 {trainvel-front/src => src}/logo.svg | 0 .../src => src}/reportWebVitals.js | 0 {trainvel-front/src => src}/setupTests.js | 0 trainvel-front/.gitignore | 23 - trainvel/__init__.py | 0 trainvel/api/__init__.py | 0 trainvel/api/apps.py | 6 - trainvel/api/serializers.py | 91 -- trainvel/api/tests.py | 3 - trainvel/api/views.py | 357 ------ trainvel/asgi.py | 16 - trainvel/core/__init__.py | 0 trainvel/core/admin.py | 23 - trainvel/core/apps.py | 8 - trainvel/core/locale/fr/LC_MESSAGES/django.po | 325 ----- trainvel/core/management/__init__.py | 0 trainvel/core/management/commands/__init__.py | 0 .../commands/update_trainline_stations.py | 37 - trainvel/core/migrations/0001_initial.py | 603 ---------- ...on_parent_station_alter_station_same_as.py | 40 - trainvel/core/migrations/__init__.py | 0 trainvel/core/models.py | 519 -------- trainvel/core/tests.py | 3 - trainvel/core/views.py | 3 - trainvel/gtfs/__init__.py | 0 trainvel/gtfs/admin.py | 166 --- trainvel/gtfs/apps.py | 14 - trainvel/gtfs/fixtures/gtfs_feeds.json | 180 --- trainvel/gtfs/gtfs-realtime.proto | 1035 ---------------- trainvel/gtfs/gtfs_realtime_pb2.py | 89 -- trainvel/gtfs/gtfs_realtime_pb2.pyi | 436 ------- trainvel/gtfs/locale/fr/LC_MESSAGES/django.po | 825 ------------- trainvel/gtfs/management/__init__.py | 0 trainvel/gtfs/management/commands/__init__.py | 0 .../gtfs/management/commands/augment_data.py | 20 - .../commands/update_trainvel_gtfs.py | 430 ------- .../commands/update_trainvel_gtfs_rt.py | 204 ---- trainvel/gtfs/migrations/0001_initial.py | 911 -------------- .../0002_alter_stop_parent_station.py | 26 - ...003_gtfsfeed_categorize_routes_and_more.py | 72 -- ...rip_route_name_trip_route_type_and_more.py | 39 - ..._from_route_transfer_from_trip_and_more.py | 73 -- trainvel/gtfs/migrations/__init__.py | 0 trainvel/gtfs/models.py | 1068 ----------------- trainvel/gtfs/signals.py | 14 - trainvel/gtfs/tests.py | 3 - trainvel/settings.py | 163 --- trainvel/settings_local_example.py | 22 - trainvel/urls.py | 45 - trainvel/wsgi.py | 16 - 84 files changed, 22 insertions(+), 7984 deletions(-) rename trainvel-front/README.md => README.md (100%) delete mode 100755 manage.py rename trainvel-front/package-lock.json => package-lock.json (100%) rename trainvel-front/package.json => package.json (100%) rename {trainvel-front/public => public}/bus.svg (100%) rename {trainvel-front/public => public}/eurostar.svg (100%) rename {trainvel-front/public => public}/eurostar_mini.svg (100%) rename {trainvel-front/public => public}/favicon.ico (100%) rename {trainvel-front/public => public}/frecciarossa.svg (100%) rename {trainvel-front/public => public}/ice.svg (100%) rename {trainvel-front/public => public}/index.html (100%) rename {trainvel-front/public => public}/logo192.png (100%) rename {trainvel-front/public => public}/logo512.png (100%) rename {trainvel-front/public => public}/lyria.svg (100%) rename {trainvel-front/public => public}/manifest.json (100%) rename {trainvel-front/public => public}/nightjet.svg (100%) rename {trainvel-front/public => public}/ouigo.svg (100%) rename {trainvel-front/public => public}/renfe.svg (100%) create mode 100644 public/robots.txt rename {trainvel-front/public => public}/ter.svg (100%) rename {trainvel-front/public => public}/tgv_inoui.svg (100%) rename {trainvel-front/public => public}/trenitalia.svg (100%) delete mode 100644 requirements.txt rename {trainvel-front/src => src}/App.css (100%) rename {trainvel-front/src => src}/App.js (100%) rename {trainvel-front/src => src}/AutocompleteStation.jsx (100%) rename {trainvel-front/src => src}/Home.js (100%) rename {trainvel-front/src => src}/Station.js (100%) rename {trainvel-front/src => src}/Station.test.js (100%) rename {trainvel-front/src => src}/TrainsTable.js (100%) rename {trainvel-front/src => src}/TripsFilter.js (100%) rename {trainvel-front/src => src}/index.css (100%) rename {trainvel-front/src => src}/index.js (100%) rename {trainvel-front/src => src}/logo.svg (100%) rename {trainvel-front/src => src}/reportWebVitals.js (100%) rename {trainvel-front/src => src}/setupTests.js (100%) delete mode 100644 trainvel-front/.gitignore delete mode 100644 trainvel/__init__.py delete mode 100644 trainvel/api/__init__.py delete mode 100644 trainvel/api/apps.py delete mode 100644 trainvel/api/serializers.py delete mode 100644 trainvel/api/tests.py delete mode 100644 trainvel/api/views.py delete mode 100644 trainvel/asgi.py delete mode 100644 trainvel/core/__init__.py delete mode 100644 trainvel/core/admin.py delete mode 100644 trainvel/core/apps.py delete mode 100644 trainvel/core/locale/fr/LC_MESSAGES/django.po delete mode 100644 trainvel/core/management/__init__.py delete mode 100644 trainvel/core/management/commands/__init__.py delete mode 100644 trainvel/core/management/commands/update_trainline_stations.py delete mode 100644 trainvel/core/migrations/0001_initial.py delete mode 100644 trainvel/core/migrations/0002_alter_station_parent_station_alter_station_same_as.py delete mode 100644 trainvel/core/migrations/__init__.py delete mode 100644 trainvel/core/models.py delete mode 100644 trainvel/core/tests.py delete mode 100644 trainvel/core/views.py delete mode 100644 trainvel/gtfs/__init__.py delete mode 100644 trainvel/gtfs/admin.py delete mode 100644 trainvel/gtfs/apps.py delete mode 100644 trainvel/gtfs/fixtures/gtfs_feeds.json delete mode 100644 trainvel/gtfs/gtfs-realtime.proto delete mode 100644 trainvel/gtfs/gtfs_realtime_pb2.py delete mode 100644 trainvel/gtfs/gtfs_realtime_pb2.pyi delete mode 100644 trainvel/gtfs/locale/fr/LC_MESSAGES/django.po delete mode 100644 trainvel/gtfs/management/__init__.py delete mode 100644 trainvel/gtfs/management/commands/__init__.py delete mode 100644 trainvel/gtfs/management/commands/augment_data.py delete mode 100644 trainvel/gtfs/management/commands/update_trainvel_gtfs.py delete mode 100644 trainvel/gtfs/management/commands/update_trainvel_gtfs_rt.py delete mode 100644 trainvel/gtfs/migrations/0001_initial.py delete mode 100644 trainvel/gtfs/migrations/0002_alter_stop_parent_station.py delete mode 100644 trainvel/gtfs/migrations/0003_gtfsfeed_categorize_routes_and_more.py delete mode 100644 trainvel/gtfs/migrations/0004_trip_long_distance_trip_route_name_trip_route_type_and_more.py delete mode 100644 trainvel/gtfs/migrations/0005_transfer_from_route_transfer_from_trip_and_more.py delete mode 100644 trainvel/gtfs/migrations/__init__.py delete mode 100644 trainvel/gtfs/models.py delete mode 100644 trainvel/gtfs/signals.py delete mode 100644 trainvel/gtfs/tests.py delete mode 100644 trainvel/settings.py delete mode 100644 trainvel/settings_local_example.py delete mode 100644 trainvel/urls.py delete mode 100644 trainvel/wsgi.py diff --git a/.gitignore b/.gitignore index 3514b06..d8a62de 100644 --- a/.gitignore +++ b/.gitignore @@ -1,53 +1,26 @@ -# Byte-compiled / optimized / DLL files -dist -build -__pycache__ -*.py[cod] -*$py.class -*.swp -*.egg-info -_build -.tox -.coverage -coverage +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. -# Translations -*.mo -*.pot - -# Jupyter Notebook -.ipynb_checkpoints - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# PyCharm project settings .idea - -# VSCode project settings .vscode -# Local data -secrets.py -settings_local.py -*.log -*.txt -media/ -output/ -/static/ -/static_files/ +# dependencies +/node_modules +/.pnp +.pnp.js -# Virtualenv -.env/ -env/ -.venv/ -venv/ -db.sqlite3 -db.sqlite3-journal +# testing +/coverage -node_modules/ +# production +/build +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/trainvel-front/README.md b/README.md similarity index 100% rename from trainvel-front/README.md rename to README.md diff --git a/manage.py b/manage.py deleted file mode 100755 index 764ca67..0000000 --- a/manage.py +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env python -"""Django's command-line utility for administrative tasks.""" -import os -import sys - - -def main(): - """Run administrative tasks.""" - os.environ.setdefault("DJANGO_SETTINGS_MODULE", "trainvel.settings") - try: - from django.core.management import execute_from_command_line - except ImportError as exc: - raise ImportError( - "Couldn't import Django. Are you sure it's installed and " - "available on your PYTHONPATH environment variable? Did you " - "forget to activate a virtual environment?" - ) from exc - execute_from_command_line(sys.argv) - - -if __name__ == "__main__": - main() diff --git a/trainvel-front/package-lock.json b/package-lock.json similarity index 100% rename from trainvel-front/package-lock.json rename to package-lock.json diff --git a/trainvel-front/package.json b/package.json similarity index 100% rename from trainvel-front/package.json rename to package.json diff --git a/trainvel-front/public/bus.svg b/public/bus.svg similarity index 100% rename from trainvel-front/public/bus.svg rename to public/bus.svg diff --git a/trainvel-front/public/eurostar.svg b/public/eurostar.svg similarity index 100% rename from trainvel-front/public/eurostar.svg rename to public/eurostar.svg diff --git a/trainvel-front/public/eurostar_mini.svg b/public/eurostar_mini.svg similarity index 100% rename from trainvel-front/public/eurostar_mini.svg rename to public/eurostar_mini.svg diff --git a/trainvel-front/public/favicon.ico b/public/favicon.ico similarity index 100% rename from trainvel-front/public/favicon.ico rename to public/favicon.ico diff --git a/trainvel-front/public/frecciarossa.svg b/public/frecciarossa.svg similarity index 100% rename from trainvel-front/public/frecciarossa.svg rename to public/frecciarossa.svg diff --git a/trainvel-front/public/ice.svg b/public/ice.svg similarity index 100% rename from trainvel-front/public/ice.svg rename to public/ice.svg diff --git a/trainvel-front/public/index.html b/public/index.html similarity index 100% rename from trainvel-front/public/index.html rename to public/index.html diff --git a/trainvel-front/public/logo192.png b/public/logo192.png similarity index 100% rename from trainvel-front/public/logo192.png rename to public/logo192.png diff --git a/trainvel-front/public/logo512.png b/public/logo512.png similarity index 100% rename from trainvel-front/public/logo512.png rename to public/logo512.png diff --git a/trainvel-front/public/lyria.svg b/public/lyria.svg similarity index 100% rename from trainvel-front/public/lyria.svg rename to public/lyria.svg diff --git a/trainvel-front/public/manifest.json b/public/manifest.json similarity index 100% rename from trainvel-front/public/manifest.json rename to public/manifest.json diff --git a/trainvel-front/public/nightjet.svg b/public/nightjet.svg similarity index 100% rename from trainvel-front/public/nightjet.svg rename to public/nightjet.svg diff --git a/trainvel-front/public/ouigo.svg b/public/ouigo.svg similarity index 100% rename from trainvel-front/public/ouigo.svg rename to public/ouigo.svg diff --git a/trainvel-front/public/renfe.svg b/public/renfe.svg similarity index 100% rename from trainvel-front/public/renfe.svg rename to public/renfe.svg diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..e9e57dc --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,3 @@ +# https://www.robotstxt.org/robotstxt.html +User-agent: * +Disallow: diff --git a/trainvel-front/public/ter.svg b/public/ter.svg similarity index 100% rename from trainvel-front/public/ter.svg rename to public/ter.svg diff --git a/trainvel-front/public/tgv_inoui.svg b/public/tgv_inoui.svg similarity index 100% rename from trainvel-front/public/tgv_inoui.svg rename to public/tgv_inoui.svg diff --git a/trainvel-front/public/trenitalia.svg b/public/trenitalia.svg similarity index 100% rename from trainvel-front/public/trenitalia.svg rename to public/trenitalia.svg diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 3931bce..0000000 --- a/requirements.txt +++ /dev/null @@ -1,8 +0,0 @@ -Django>=5.0.4,<6.0 -django-cors-headers~=4.3.1 -django-extensions~=3.2.3 -django-filter~=24.2 -djangorestframework~=3.14.0 -protobuf~=5.26.1 -requests~=2.31.0 -tqdm~=4.66.4 \ No newline at end of file diff --git a/trainvel-front/src/App.css b/src/App.css similarity index 100% rename from trainvel-front/src/App.css rename to src/App.css diff --git a/trainvel-front/src/App.js b/src/App.js similarity index 100% rename from trainvel-front/src/App.js rename to src/App.js diff --git a/trainvel-front/src/AutocompleteStation.jsx b/src/AutocompleteStation.jsx similarity index 100% rename from trainvel-front/src/AutocompleteStation.jsx rename to src/AutocompleteStation.jsx diff --git a/trainvel-front/src/Home.js b/src/Home.js similarity index 100% rename from trainvel-front/src/Home.js rename to src/Home.js diff --git a/trainvel-front/src/Station.js b/src/Station.js similarity index 100% rename from trainvel-front/src/Station.js rename to src/Station.js diff --git a/trainvel-front/src/Station.test.js b/src/Station.test.js similarity index 100% rename from trainvel-front/src/Station.test.js rename to src/Station.test.js diff --git a/trainvel-front/src/TrainsTable.js b/src/TrainsTable.js similarity index 100% rename from trainvel-front/src/TrainsTable.js rename to src/TrainsTable.js diff --git a/trainvel-front/src/TripsFilter.js b/src/TripsFilter.js similarity index 100% rename from trainvel-front/src/TripsFilter.js rename to src/TripsFilter.js diff --git a/trainvel-front/src/index.css b/src/index.css similarity index 100% rename from trainvel-front/src/index.css rename to src/index.css diff --git a/trainvel-front/src/index.js b/src/index.js similarity index 100% rename from trainvel-front/src/index.js rename to src/index.js diff --git a/trainvel-front/src/logo.svg b/src/logo.svg similarity index 100% rename from trainvel-front/src/logo.svg rename to src/logo.svg diff --git a/trainvel-front/src/reportWebVitals.js b/src/reportWebVitals.js similarity index 100% rename from trainvel-front/src/reportWebVitals.js rename to src/reportWebVitals.js diff --git a/trainvel-front/src/setupTests.js b/src/setupTests.js similarity index 100% rename from trainvel-front/src/setupTests.js rename to src/setupTests.js diff --git a/trainvel-front/.gitignore b/trainvel-front/.gitignore deleted file mode 100644 index 4d29575..0000000 --- a/trainvel-front/.gitignore +++ /dev/null @@ -1,23 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage - -# production -/build - -# misc -.DS_Store -.env.local -.env.development.local -.env.test.local -.env.production.local - -npm-debug.log* -yarn-debug.log* -yarn-error.log* diff --git a/trainvel/__init__.py b/trainvel/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/trainvel/api/__init__.py b/trainvel/api/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/trainvel/api/apps.py b/trainvel/api/apps.py deleted file mode 100644 index 64bbd05..0000000 --- a/trainvel/api/apps.py +++ /dev/null @@ -1,6 +0,0 @@ -from django.apps import AppConfig - - -class ApiConfig(AppConfig): - default_auto_field = "django.db.models.BigAutoField" - name = "trainvel.api" diff --git a/trainvel/api/serializers.py b/trainvel/api/serializers.py deleted file mode 100644 index 8ab0330..0000000 --- a/trainvel/api/serializers.py +++ /dev/null @@ -1,91 +0,0 @@ -from rest_framework import serializers - -from trainvel.core.models import Station -from trainvel.gtfs.models import Agency, Calendar, CalendarDate, FeedInfo, GTFSFeed, Route, \ - Stop, StopTime, StopTimeUpdate, Transfer, Trip, TripUpdate - - -class StationSerializer(serializers.ModelSerializer): - class Meta: - model = Station - lookup_field = 'slug' - fields = ('id', 'slug', 'name', 'uic', 'uic8_sncf', 'latitude', 'longitude', 'country', - 'country_hint', 'main_station_hint',) - - -class GTFSFeedSerializer(serializers.ModelSerializer): - class Meta: - model = GTFSFeed - fields = '__all__' - - -class AgencySerializer(serializers.ModelSerializer): - class Meta: - model = Agency - fields = '__all__' - - -class StopSerializer(serializers.ModelSerializer): - class Meta: - model = Stop - fields = '__all__' - - -class RouteSerializer(serializers.ModelSerializer): - class Meta: - model = Route - fields = '__all__' - - -class TripSerializer(serializers.ModelSerializer): - class Meta: - model = Trip - fields = '__all__' - - -class StopTimeSerializer(serializers.ModelSerializer): - arrival_date = serializers.DateField(required=False) - departure_date = serializers.DateField(required=False) - arrival_time_24h = serializers.DurationField(required=False) - departure_time_24h = serializers.DurationField(required=False) - departure_time_real = serializers.CharField(required=False) - - class Meta: - model = StopTime - fields = '__all__' - - -class CalendarSerializer(serializers.ModelSerializer): - class Meta: - model = Calendar - fields = '__all__' - - -class CalendarDateSerializer(serializers.ModelSerializer): - class Meta: - model = CalendarDate - fields = '__all__' - - -class TransferSerializer(serializers.ModelSerializer): - class Meta: - model = Transfer - fields = '__all__' - - -class FeedInfoSerializer(serializers.ModelSerializer): - class Meta: - model = FeedInfo - fields = '__all__' - - -class TripUpdateSerializer(serializers.ModelSerializer): - class Meta: - model = TripUpdate - fields = '__all__' - - -class StopTimeUpdateSerializer(serializers.ModelSerializer): - class Meta: - model = StopTimeUpdate - fields = '__all__' diff --git a/trainvel/api/tests.py b/trainvel/api/tests.py deleted file mode 100644 index 7ce503c..0000000 --- a/trainvel/api/tests.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.test import TestCase - -# Create your tests here. diff --git a/trainvel/api/views.py b/trainvel/api/views.py deleted file mode 100644 index 887b296..0000000 --- a/trainvel/api/views.py +++ /dev/null @@ -1,357 +0,0 @@ -from datetime import datetime, timedelta, date - -from django.db.models import Exists, Case, F, Min, OuterRef, Q, Value, When -from django.utils.decorators import method_decorator -from django.views.decorators.cache import cache_control -from django.views.decorators.http import last_modified -from django_filters.rest_framework import DjangoFilterBackend -from rest_framework import viewsets -from rest_framework.filters import OrderingFilter, SearchFilter - -from trainvel.api.serializers import AgencySerializer, CalendarDateSerializer, CalendarSerializer, \ - FeedInfoSerializer, GTFSFeedSerializer, RouteSerializer, StationSerializer, StopSerializer, StopTimeSerializer, \ - StopTimeUpdateSerializer, TransferSerializer, TripSerializer, TripUpdateSerializer -from trainvel.core.models import Station -from trainvel.gtfs.models import Agency, Calendar, CalendarDate, FeedInfo, GTFSFeed, Route, Stop, StopTime, \ - StopTimeUpdate, Transfer, Trip, TripUpdate, PickupType - -CACHE_CONTROL = cache_control(max_age=30) -LAST_MODIFIED = last_modified(lambda *args, **kwargs: GTFSFeed.objects.order_by('-last_modified').first().last_modified) -LOOKUP_VALUE_REGEX = r"[\w.: |+-]+" - - -class StationViewSet(viewsets.ReadOnlyModelViewSet): - queryset = Station.objects.filter(is_suggestable=True) - serializer_class = StationSerializer - filter_backends = [DjangoFilterBackend, SearchFilter] - filterset_fields = '__all__' - search_fields = ['name', 'slug', - 'info_de', 'info_en', 'info_es', 'info_fr', 'info_it', 'info_nb', 'info_nl', 'info_cs', - 'info_da', 'info_hu', 'info_ja', 'info_ko', 'info_pl', 'info_pt', 'info_ru', 'info_sv', - 'info_tr', 'info_zh', ] - lookup_field = 'slug' - lookup_value_regex = LOOKUP_VALUE_REGEX - - -@method_decorator(name='list', decorator=[CACHE_CONTROL, LAST_MODIFIED]) -@method_decorator(name='retrieve', decorator=[CACHE_CONTROL, LAST_MODIFIED]) -class GTFSFeedViewSet(viewsets.ReadOnlyModelViewSet): - queryset = GTFSFeed.objects.all() - serializer_class = GTFSFeedSerializer - filter_backends = [DjangoFilterBackend] - filterset_fields = '__all__' - lookup_value_regex = LOOKUP_VALUE_REGEX - - -@method_decorator(name='list', decorator=[CACHE_CONTROL, LAST_MODIFIED]) -@method_decorator(name='retrieve', decorator=[CACHE_CONTROL, LAST_MODIFIED]) -class AgencyViewSet(viewsets.ReadOnlyModelViewSet): - queryset = Agency.objects.all() - serializer_class = AgencySerializer - filter_backends = [DjangoFilterBackend] - filterset_fields = '__all__' - lookup_value_regex = LOOKUP_VALUE_REGEX - - -@method_decorator(name='list', decorator=[CACHE_CONTROL, LAST_MODIFIED]) -@method_decorator(name='retrieve', decorator=[CACHE_CONTROL, LAST_MODIFIED]) -class StopViewSet(viewsets.ReadOnlyModelViewSet): - queryset = Stop.objects.all() - serializer_class = StopSerializer - filter_backends = [DjangoFilterBackend, SearchFilter] - filterset_fields = '__all__' - search_fields = ['name',] - lookup_value_regex = LOOKUP_VALUE_REGEX - - -@method_decorator(name='list', decorator=[CACHE_CONTROL, LAST_MODIFIED]) -@method_decorator(name='retrieve', decorator=[CACHE_CONTROL, LAST_MODIFIED]) -class RouteViewSet(viewsets.ReadOnlyModelViewSet): - queryset = Route.objects.all() - serializer_class = RouteSerializer - filter_backends = [DjangoFilterBackend] - filterset_fields = '__all__' - lookup_value_regex = LOOKUP_VALUE_REGEX - - -@method_decorator(name='list', decorator=[CACHE_CONTROL, LAST_MODIFIED]) -@method_decorator(name='retrieve', decorator=[CACHE_CONTROL, LAST_MODIFIED]) -class TripViewSet(viewsets.ReadOnlyModelViewSet): - queryset = Trip.objects.all() - serializer_class = TripSerializer - filter_backends = [DjangoFilterBackend] - filterset_fields = '__all__' - lookup_value_regex = LOOKUP_VALUE_REGEX - - -@method_decorator(name='list', decorator=[CACHE_CONTROL, LAST_MODIFIED]) -@method_decorator(name='retrieve', decorator=[CACHE_CONTROL, LAST_MODIFIED]) -class StopTimeViewSet(viewsets.ReadOnlyModelViewSet): - queryset = StopTime.objects.order_by('id').all() - serializer_class = StopTimeSerializer - filter_backends = [DjangoFilterBackend, OrderingFilter] - filterset_fields = '__all__' - ordering_fields = ['arrival_time', 'departure_time', 'stop_sequence', ] - ordering = ['stop_sequence', ] - lookup_value_regex = LOOKUP_VALUE_REGEX - - -@method_decorator(name='list', decorator=[CACHE_CONTROL, LAST_MODIFIED]) -@method_decorator(name='retrieve', decorator=[CACHE_CONTROL, LAST_MODIFIED]) -class CalendarViewSet(viewsets.ReadOnlyModelViewSet): - queryset = Calendar.objects.all() - serializer_class = CalendarSerializer - filter_backends = [DjangoFilterBackend] - filterset_fields = '__all__' - lookup_value_regex = LOOKUP_VALUE_REGEX - - -@method_decorator(name='list', decorator=[CACHE_CONTROL, LAST_MODIFIED]) -@method_decorator(name='retrieve', decorator=[CACHE_CONTROL, LAST_MODIFIED]) -class CalendarDateViewSet(viewsets.ReadOnlyModelViewSet): - queryset = CalendarDate.objects.all() - serializer_class = CalendarDateSerializer - filter_backends = [DjangoFilterBackend] - filterset_fields = '__all__' - lookup_value_regex = LOOKUP_VALUE_REGEX - - -@method_decorator(name='list', decorator=[CACHE_CONTROL, LAST_MODIFIED]) -@method_decorator(name='retrieve', decorator=[CACHE_CONTROL, LAST_MODIFIED]) -class TransferViewSet(viewsets.ReadOnlyModelViewSet): - queryset = Transfer.objects.all() - serializer_class = TransferSerializer - filter_backends = [DjangoFilterBackend] - lookup_value_regex = LOOKUP_VALUE_REGEX - - -@method_decorator(name='list', decorator=[CACHE_CONTROL, LAST_MODIFIED]) -@method_decorator(name='retrieve', decorator=[CACHE_CONTROL, LAST_MODIFIED]) -class FeedInfoViewSet(viewsets.ReadOnlyModelViewSet): - queryset = FeedInfo.objects.all() - serializer_class = FeedInfoSerializer - filter_backends = [DjangoFilterBackend] - filterset_fields = '__all__' - lookup_value_regex = LOOKUP_VALUE_REGEX - - -class TripUpdateViewSet(viewsets.ReadOnlyModelViewSet): - queryset = TripUpdate.objects.all() - serializer_class = TripUpdateSerializer - filter_backends = [DjangoFilterBackend] - filterset_fields = '__all__' - lookup_value_regex = LOOKUP_VALUE_REGEX - - -class StopTimeUpdateViewSet(viewsets.ReadOnlyModelViewSet): - queryset = StopTimeUpdate.objects.all() - serializer_class = StopTimeUpdateSerializer - filter_backends = [DjangoFilterBackend] - filterset_fields = '__all__' - lookup_value_regex = LOOKUP_VALUE_REGEX - - -class NextDeparturesViewSet(viewsets.ReadOnlyModelViewSet): - queryset = StopTime.objects.none() - serializer_class = StopTimeSerializer - - def get_queryset(self): - now = datetime.now() - - station_slug = self.request.query_params.get('station_slug', None) - query_date = date.fromisoformat(self.request.query_params.get('date', now.date().isoformat())) - query_time = self.request.query_params.get('time', now.time().isoformat(timespec='seconds')) - query_time = timedelta(seconds=int(query_time[:2]) * 3600 - + int(query_time[3:5]) * 60 - + (int(query_time[6:]) if len(query_time) > 6 else 0)) - - yesterday = query_date - timedelta(days=1) - time_yesterday = query_time + timedelta(days=1) - tomorrow = query_date + timedelta(days=1) - - stop_filter = Q(stop__location_type=0) - if station_slug: - station = Station.objects.get(is_suggestable=True, slug=station_slug) - near_stops = station.get_near_stops() - stop_filter = Q(stop_id__in=near_stops.values_list('id', flat=True)) - - excluded_agencies = ~Q(trip__route__gtfs_feed__excluded_agencies=F('trip__route__agency_id')) - - not_last_stop = ~Q(stop_sequence=StopTime.objects.filter(trip_id=OuterRef('trip_id')) - .filter(pickup_type=PickupType.REGULAR) - .order_by('-stop_sequence')[:1].values_list('stop_sequence')) - - trip_filter = Q() - if self.request.query_params.get('route_name', None): - trip_filter &= Q(trip__route_name__in=self.request.query_params.get('route_name').split(',')) - if self.request.query_params.get('transport_type', None): - trip_filter &= Q(trip__route__type__in=self.request.query_params.get('transport_type').split(',')) - if self.request.query_params.get('long_distance', None) is not None: - long_distance = str(self.request.query_params.get('long_distance')) == 'true' - trip_filter &= Q(trip__long_distance=long_distance) - - def calendar_filter(d: date): - return Q(trip__service_id__in=CalendarDate.objects.filter(date=d, exception_type=1) - .values_list('service_id')) \ - | Q(trip__service_id__in=Calendar.objects.filter( - start_date__lte=d, - end_date__gte=d, - **{f"{d:%A}".lower(): True}) - .filter(~Q(id__in=CalendarDate.objects.filter(date=d, exception_type=2) - .values_list('service_id', flat=True))) - .values_list('id')) - - def stop_time_update_qs(d: date): - return StopTimeUpdate.objects.filter(trip_update__start_date=d) \ - .exclude(departure_time=datetime.fromtimestamp(0)).filter(stop_time_id=OuterRef('pk')) - - def departure_time_real(d: date): - return Case( - When( - condition=Exists(stop_time_update_qs(d)), - then=F('departure_time') + stop_time_update_qs(d).values('departure_delay'), - ), - default=F('departure_time'), - ) - - def canceled_filter(d: date): - return Exists(stop_time_update_qs(d).filter(Q(schedule_relationship=1) | Q(schedule_relationship=3))) - - qs_today = StopTime.objects.filter(stop_filter) \ - .filter(excluded_agencies) \ - .filter(not_last_stop) \ - .filter(trip_filter) \ - .annotate(departure_time_real=departure_time_real(query_date)) \ - .filter(departure_time_real__gte=query_time) \ - .filter(Q(pickup_type=PickupType.REGULAR) | canceled_filter(query_date)) \ - .filter(calendar_filter(query_date)) \ - .annotate(departure_date=Value(query_date)) \ - .annotate(departure_time_24h=F('departure_time')) - - qs_yesterday = StopTime.objects.filter(stop_filter) \ - .filter(excluded_agencies) \ - .filter(not_last_stop) \ - .filter(trip_filter) \ - .annotate(departure_time_real=departure_time_real(query_date)) \ - .filter(departure_time_real__gte=time_yesterday) \ - .filter(Q(pickup_type=PickupType.REGULAR) | canceled_filter(yesterday)) \ - .filter(calendar_filter(yesterday)) \ - .annotate(departure_date=Value(yesterday)) \ - .annotate(departure_time_24h=F('departure_time') - timedelta(days=1)) - - qs_tomorrow = StopTime.objects.filter(stop_filter) \ - .filter(excluded_agencies) \ - .filter(not_last_stop) \ - .filter(trip_filter) \ - .annotate(departure_time_real=departure_time_real(query_date)) \ - .filter(departure_time_real__gte=timedelta(0)) \ - .filter(Q(pickup_type=PickupType.REGULAR) | canceled_filter(tomorrow)) \ - .filter(calendar_filter(tomorrow)) \ - .annotate(departure_date=Value(tomorrow)) \ - .annotate(departure_time_24h=F('departure_time') + timedelta(days=1)) - - return qs_today.union(qs_yesterday).union(qs_tomorrow).order_by("departure_time_24h").all() - - -class NextArrivalsViewSet(viewsets.ReadOnlyModelViewSet): - queryset = StopTime.objects.none() - serializer_class = StopTimeSerializer - filter_backends = [DjangoFilterBackend] - - def get_queryset(self): - now = datetime.now() - - station_slug = self.request.query_params.get('station_slug', None) - query_date = date.fromisoformat(self.request.query_params.get('date', now.date().isoformat())) - query_time = self.request.query_params.get('time', now.time().isoformat(timespec='seconds')) - query_time = timedelta(seconds=int(query_time[:2]) * 3600 - + int(query_time[3:5]) * 60 - + (int(query_time[6:]) if len(query_time) > 6 else 0)) - query_time -= timedelta(minutes=5) # Keep the last trains of the 5 previous minutes - - yesterday = query_date - timedelta(days=1) - time_yesterday = query_time + timedelta(days=1) - tomorrow = query_date + timedelta(days=1) - - stop_filter = Q(stop__location_type=0) - if station_slug: - station = Station.objects.get(is_suggestable=True, slug=station_slug) - near_stops = station.get_near_stops() - stop_filter = Q(stop_id__in=near_stops.values_list('id', flat=True)) - - excluded_agencies = ~Q(trip__route__gtfs_feed__excluded_agencies=F('trip__route__agency_id')) - - not_first_stop = ~Q(stop_sequence=StopTime.objects.filter(trip_id=OuterRef('trip_id')) - .filter(drop_off_type=PickupType.REGULAR) - .order_by('stop_sequence')[:1].values_list('stop_sequence')) - - trip_filter = Q() - if self.request.query_params.get('route_name', None): - trip_filter &= Q(trip__route_name__in=self.request.query_params.get('route_name').split(',')) - if self.request.query_params.get('transport_type', None): - trip_filter &= Q(trip__route__type__in=self.request.query_params.get('transport_type').split(',')) - if self.request.query_params.get('long_distance', None) is not None: - long_distance = str(self.request.query_params.get('long_distance')) == 'true' - trip_filter &= Q(trip__long_distance=long_distance) - - def calendar_filter(d: date): - return Q(trip__service_id__in=CalendarDate.objects.filter(date=d, exception_type=1) - .values_list('service_id')) \ - | Q(trip__service_id__in=Calendar.objects.filter( - start_date__lte=d, - end_date__gte=d, - **{f"{d:%A}".lower(): True}) - .filter(~Q(id__in=CalendarDate.objects.filter(date=d, exception_type=2) - .values_list('service_id', flat=True))) - .values_list('id')) - - def stop_time_update_qs(d: date): - return StopTimeUpdate.objects.filter(trip_update__start_date=d) \ - .exclude(arrival_time=datetime.fromtimestamp(0)).filter(stop_time_id=OuterRef('pk')) - - def arrival_time_real(d: date): - return Case( - When( - condition=Exists(stop_time_update_qs(d)), - then=F('arrival_time') + stop_time_update_qs(d).values('arrival_delay'), - ), - default=F('arrival_time'), - ) - - def canceled_filter(d: date): - return Exists(stop_time_update_qs(d).filter(Q(schedule_relationship=1) | Q(schedule_relationship=3))) - - qs_today = StopTime.objects.filter(stop_filter) \ - .filter(excluded_agencies) \ - .filter(not_first_stop) \ - .filter(trip_filter) \ - .annotate(arrival_time_real=arrival_time_real(query_date)) \ - .filter(arrival_time_real__gte=query_time) \ - .filter(Q(drop_off_type=PickupType.REGULAR) | canceled_filter(query_date)) \ - .filter(calendar_filter(query_date)) \ - .annotate(arrival_date=Value(query_date)) \ - .annotate(arrival_time_24h=F('arrival_time')) - - qs_yesterday = StopTime.objects.filter(stop_filter) \ - .filter(excluded_agencies) \ - .filter(not_first_stop) \ - .filter(trip_filter) \ - .annotate(arrival_time_real=arrival_time_real(yesterday)) \ - .filter(arrival_time_real__gte=time_yesterday) \ - .filter(Q(drop_off_type=PickupType.REGULAR) | canceled_filter(yesterday)) \ - .filter(calendar_filter(yesterday)) \ - .annotate(arrival_date=Value(yesterday)) \ - .annotate(arrival_time_24h=F('arrival_time') - timedelta(days=1)) - - qs_tomorrow = StopTime.objects.filter(stop_filter) \ - .filter(excluded_agencies) \ - .filter(not_first_stop) \ - .filter(trip_filter) \ - .annotate(arrival_time_real=arrival_time_real(tomorrow)) \ - .filter(arrival_time_real__gte=timedelta(0)) \ - .filter(Q(drop_off_type=PickupType.REGULAR) | canceled_filter(tomorrow)) \ - .filter(calendar_filter(tomorrow)) \ - .annotate(arrival_date=Value(tomorrow)) \ - .annotate(arrival_time_24h=F('arrival_time') + timedelta(days=1)) - - return qs_today.union(qs_yesterday).union(qs_tomorrow).order_by("arrival_time_24h").all() diff --git a/trainvel/asgi.py b/trainvel/asgi.py deleted file mode 100644 index 8d94156..0000000 --- a/trainvel/asgi.py +++ /dev/null @@ -1,16 +0,0 @@ -""" -ASGI config for trainvel project. - -It exposes the ASGI callable as a module-level variable named ``application``. - -For more information on this file, see -https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/ -""" - -import os - -from django.core.asgi import get_asgi_application - -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "trainvel.settings") - -application = get_asgi_application() diff --git a/trainvel/core/__init__.py b/trainvel/core/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/trainvel/core/admin.py b/trainvel/core/admin.py deleted file mode 100644 index cc217fc..0000000 --- a/trainvel/core/admin.py +++ /dev/null @@ -1,23 +0,0 @@ -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] diff --git a/trainvel/core/apps.py b/trainvel/core/apps.py deleted file mode 100644 index 4279511..0000000 --- a/trainvel/core/apps.py +++ /dev/null @@ -1,8 +0,0 @@ -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") diff --git a/trainvel/core/locale/fr/LC_MESSAGES/django.po b/trainvel/core/locale/fr/LC_MESSAGES/django.po deleted file mode 100644 index b645971..0000000 --- a/trainvel/core/locale/fr/LC_MESSAGES/django.po +++ /dev/null @@ -1,325 +0,0 @@ -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 \n" -"Language-Team: LANGUAGE \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" diff --git a/trainvel/core/management/__init__.py b/trainvel/core/management/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/trainvel/core/management/commands/__init__.py b/trainvel/core/management/commands/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/trainvel/core/management/commands/update_trainline_stations.py b/trainvel/core/management/commands/update_trainline_stations.py deleted file mode 100644 index e91111e..0000000 --- a/trainvel/core/management/commands/update_trainline_stations.py +++ /dev/null @@ -1,37 +0,0 @@ -import csv -from time import time - -import requests -from django.core.management import BaseCommand -from django.db import connection, transaction -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_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()} - stations.append(values) - - Station.objects.all().delete() - print("Deleted all stations.") - with connection.cursor() as cursor: - cursor.execute("BEGIN;") - keys = ", ".join(stations[0].keys()) - cursor.executemany( - f"INSERT INTO core_station ({keys}) VALUES ({', '.join(['%s'] * len(values))});", - [list(station.values()) for station in stations], - ) - cursor.execute("COMMIT;") diff --git a/trainvel/core/migrations/0001_initial.py b/trainvel/core/migrations/0001_initial.py deleted file mode 100644 index 37cfd42..0000000 --- a/trainvel/core/migrations/0001_initial.py +++ /dev/null @@ -1,603 +0,0 @@ -# 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=16, - 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", - }, - ), - ] diff --git a/trainvel/core/migrations/0002_alter_station_parent_station_alter_station_same_as.py b/trainvel/core/migrations/0002_alter_station_parent_station_alter_station_same_as.py deleted file mode 100644 index 4685a7b..0000000 --- a/trainvel/core/migrations/0002_alter_station_parent_station_alter_station_same_as.py +++ /dev/null @@ -1,40 +0,0 @@ -# Generated by Django 5.0.6 on 2024-05-12 11:09 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("core", "0001_initial"), - ] - - operations = [ - migrations.AlterField( - model_name="station", - name="parent_station", - field=models.ForeignKey( - blank=True, - default=None, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - related_name="children", - to="core.station", - verbose_name="parent station", - ), - ), - migrations.AlterField( - model_name="station", - name="same_as", - field=models.ForeignKey( - blank=True, - default=None, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - related_name="same_as_other", - to="core.station", - verbose_name="same as", - ), - ), - ] diff --git a/trainvel/core/migrations/__init__.py b/trainvel/core/migrations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/trainvel/core/models.py b/trainvel/core/models.py deleted file mode 100644 index bec865f..0000000 --- a/trainvel/core/models.py +++ /dev/null @@ -1,519 +0,0 @@ -from django.conf import settings -from django.db import models -from django.db.models import F, QuerySet -from django.db.models.functions import ACos, Sin, Radians, Cos -from django.utils.translation import gettext_lazy as _ - -from trainvel.gtfs.models import Country, Stop - - -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.SET_NULL, - 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=16, - 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.SET_NULL, - 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 get_near_stops(self, radius: float = settings.STATION_RADIUS) -> QuerySet[Stop]: - """ - Returns a queryset of all stops that are in a radius of radius meters around the station. - It calculates a distance from each stop to the station using spatial coordinates. - """ - return Stop.objects.annotate(distance=6371000 * ACos( - Sin(Radians(self.latitude)) * Sin(Radians(F('lat'))) - + Cos(Radians(self.latitude)) * Cos(Radians(F('lat'))) * Cos(Radians(F('lon')) - Radians(self.longitude))))\ - .filter(distance__lte=radius) - - def __str__(self): - return self.name - - class Meta: - verbose_name = _("station") - verbose_name_plural = _("stations") diff --git a/trainvel/core/tests.py b/trainvel/core/tests.py deleted file mode 100644 index 7ce503c..0000000 --- a/trainvel/core/tests.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.test import TestCase - -# Create your tests here. diff --git a/trainvel/core/views.py b/trainvel/core/views.py deleted file mode 100644 index 91ea44a..0000000 --- a/trainvel/core/views.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.shortcuts import render - -# Create your views here. diff --git a/trainvel/gtfs/__init__.py b/trainvel/gtfs/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/trainvel/gtfs/admin.py b/trainvel/gtfs/admin.py deleted file mode 100644 index 12475d3..0000000 --- a/trainvel/gtfs/admin.py +++ /dev/null @@ -1,166 +0,0 @@ -from django.contrib import admin -from django.forms import BaseInlineFormSet - -from trainvel.gtfs.models import Agency, Calendar, CalendarDate, FeedInfo, GTFSFeed, \ - Route, Stop, StopTime, StopTimeUpdate, Transfer, Trip, TripUpdate - - -class LimitModelFormset(BaseInlineFormSet): - """ Base Inline formset to limit inline Model query results. """ - def get_queryset(self): - return super(LimitModelFormset, self).get_queryset()[:50] - - -class CalendarDateInline(admin.TabularInline): - model = CalendarDate - extra = 0 - formset = LimitModelFormset - - -class TripInline(admin.TabularInline): - model = Trip - extra = 0 - formset = LimitModelFormset - autocomplete_fields = ('route', 'service',) - show_change_link = True - ordering = ('service',) - readonly_fields = ('gtfs_feed',) - - -class StopTimeInline(admin.TabularInline): - model = StopTime - extra = 0 - formset = LimitModelFormset - autocomplete_fields = ('stop',) - readonly_fields = ('id',) - show_change_link = True - ordering = ('stop_sequence',) - - -class TripUpdateInline(admin.StackedInline): - model = TripUpdate - extra = 0 - formset = LimitModelFormset - autocomplete_fields = ('trip',) - - -class StopTimeUpdateInline(admin.StackedInline): - model = StopTimeUpdate - extra = 0 - formset = LimitModelFormset - autocomplete_fields = ('trip_update', 'stop_time',) - - -@admin.register(GTFSFeed) -class GTFSFeedAdmin(admin.ModelAdmin): - list_display = ('name', 'code', 'country', 'last_modified',) - list_filter = ('country', 'last_modified',) - search_fields = ('name', 'code',) - readonly_fields = ('code',) - autocomplete_fields = ('excluded_agencies',) - - -@admin.register(Agency) -class AgencyAdmin(admin.ModelAdmin): - list_display = ('name', 'id', 'url', 'timezone', 'gtfs_feed',) - list_filter = ('gtfs_feed', 'timezone',) - search_fields = ('name',) - autocomplete_fields = ('gtfs_feed',) - - -@admin.register(Stop) -class StopAdmin(admin.ModelAdmin): - list_display = ('name', 'id', 'lat', 'lon', 'location_type',) - list_filter = ('location_type', 'gtfs_feed',) - search_fields = ('name', 'id',) - ordering = ('name',) - autocomplete_fields = ('parent_station', 'gtfs_feed',) - - -@admin.register(Route) -class RouteAdmin(admin.ModelAdmin): - list_display = ('__str__', 'id', 'type', 'gtfs_feed',) - list_filter = ('gtfs_feed', 'type', 'agency',) - search_fields = ('long_name', 'short_name', 'id',) - ordering = ('long_name',) - autocomplete_fields = ('agency', 'gtfs_feed',) - inlines = (TripInline,) - - -@admin.register(Trip) -class TripAdmin(admin.ModelAdmin): - list_display = ('id', 'origin_destination', 'route', 'service', 'headsign', 'direction_id',) - list_filter = ('direction_id', 'route__gtfs_feed',) - search_fields = ('id', 'route__id', 'route__long_name', 'service__id', 'headsign',) - ordering = ('route', 'service',) - autocomplete_fields = ('route', 'service', 'gtfs_feed',) - inlines = (StopTimeInline, TripUpdateInline,) - - -@admin.register(StopTime) -class StopTimeAdmin(admin.ModelAdmin): - list_display = ('trip', 'stop', 'arrival_time', 'departure_time', - 'stop_sequence', 'pickup_type', 'drop_off_type',) - list_filter = ('pickup_type', 'drop_off_type', 'trip__route__gtfs_feed',) - search_fields = ('trip__id', 'stop__name', 'arrival_time', 'departure_time',) - ordering = ('trip', 'stop_sequence',) - autocomplete_fields = ('trip', 'stop',) - readonly_fields = ('id',) - inlines = (StopTimeUpdateInline,) - - -@admin.register(Calendar) -class CalendarAdmin(admin.ModelAdmin): - list_display = ('id', 'gtfs_feed', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', - 'saturday', 'sunday', 'start_date', 'end_date',) - list_filter = ('gtfs_feed', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday', - 'start_date', 'end_date',) - search_fields = ('id', 'start_date', 'end_date',) - autocomplete_fields = ('gtfs_feed',) - ordering = ('gtfs_feed', 'id',) - inlines = (CalendarDateInline, TripInline,) - - -@admin.register(CalendarDate) -class CalendarDateAdmin(admin.ModelAdmin): - list_display = ('id', 'service_id', 'date', 'exception_type',) - list_filter = ('exception_type', 'date', 'service__gtfs_feed',) - search_fields = ('id', 'date',) - ordering = ('date', 'service_id',) - - -@admin.register(Transfer) -class TransferAdmin(admin.ModelAdmin): - list_display = ('from_stop', 'to_stop', 'transfer_type', 'min_transfer_time',) - list_filter = ('transfer_type',) - search_fields = ('from_stop__name', 'to_stop__name',) - autocomplete_fields = ('from_stop', 'to_stop',) - - -@admin.register(FeedInfo) -class FeedInfoAdmin(admin.ModelAdmin): - list_display = ('publisher_name', 'publisher_url', 'lang', 'start_date', - 'end_date', 'version',) - search_fields = ('publisher_name', 'publisher_url', 'lang', 'start_date', - 'end_date', 'version',) - autocomplete_fields = ('gtfs_feed',) - ordering = ('publisher_name',) - - -@admin.register(StopTimeUpdate) -class StopTimeUpdateAdmin(admin.ModelAdmin): - list_display = ('trip_update', 'stop_time', 'arrival_delay', 'arrival_time', - 'departure_delay', 'departure_time', 'schedule_relationship',) - list_filter = ('schedule_relationship', 'trip_update__trip__gtfs_feed',) - search_fields = ('trip_update__trip__id', 'stop_time__stop__name', 'arrival_time', 'departure_time',) - ordering = ('trip_update', 'stop_time',) - autocomplete_fields = ('trip_update', 'stop_time',) - - -@admin.register(TripUpdate) -class TripUpdateAdmin(admin.ModelAdmin): - list_display = ('trip_id', 'start_date', 'start_time',) - list_filter = ('start_date', 'schedule_relationship',) - search_fields = ('trip__id', 'start_date', 'start_time',) - ordering = ('trip_id', 'start_date', 'start_time',) - autocomplete_fields = ('trip',) diff --git a/trainvel/gtfs/apps.py b/trainvel/gtfs/apps.py deleted file mode 100644 index 0dc8df4..0000000 --- a/trainvel/gtfs/apps.py +++ /dev/null @@ -1,14 +0,0 @@ -from django.apps import AppConfig -from django.db.models.signals import pre_save -from django.utils.translation import gettext_lazy as _ - - -class TrainvelGTFSConfig(AppConfig): - default_auto_field = "django.db.models.BigAutoField" - name = "trainvel.gtfs" - verbose_name = _("Trainvel - GTFS") - - def ready(self): - from trainvel.gtfs import signals - - pre_save.connect(signals.keep_gtfs_feed_modification_date, sender="gtfs.GTFSFeed") diff --git a/trainvel/gtfs/fixtures/gtfs_feeds.json b/trainvel/gtfs/fixtures/gtfs_feeds.json deleted file mode 100644 index 5cd894e..0000000 --- a/trainvel/gtfs/fixtures/gtfs_feeds.json +++ /dev/null @@ -1,180 +0,0 @@ -[ - { - "model": "gtfs.gtfsfeed", - "pk": "FR-SNCF-TGV", - "fields": { - "name": "SNCF - TGV", - "country": "FR", - "feed_url": "https://eu.ftp.opendatasoft.com/sncf/gtfs/export_gtfs_voyages.zip", - "rt_feed_url": "https://proxy.transport.data.gouv.fr/resource/sncf-tgv-gtfs-rt-trip-updates", - "categorize_routes": false, - "route_name_regex": "route_short_name:([\\w\\s]+)", - "route_type_regex": "SNCF-&stop:FR-SNCF-TGV-StopPoint:OCE([\\w\\s]+)-\\d+", - "trip_number_regex": "trip_headsign:(\\d+)", - "long_distance_regex": "", - "excluded_agencies": [] - } - }, - { - "model": "gtfs.gtfsfeed", - "pk": "FR-SNCF-IC", - "fields": { - "name": "SNCF - Intercités", - "country": "FR", - "feed_url": "https://eu.ftp.opendatasoft.com/sncf/gtfs/export-intercites-gtfs-last.zip", - "rt_feed_url": "https://proxy.transport.data.gouv.fr/resource/sncf-ic-gtfs-rt-trip-updates", - "categorize_routes": false, - "route_name_regex": "route_short_name:([\\w\\s]+)", - "route_type_regex": "SNCF-&stop:FR-SNCF-IC-StopPoint:OCE([\\w\\s]+)-\\d+", - "trip_number_regex": "trip_headsign:(\\d+)", - "long_distance_regex": "", - "excluded_agencies": [] - } - }, - { - "model": "gtfs.gtfsfeed", - "pk": "FR-SNCF-TER", - "fields": { - "name": "SNCF - TER", - "country": "FR", - "feed_url": "https://eu.ftp.opendatasoft.com/sncf/gtfs/export-ter-gtfs-last.zip", - "rt_feed_url": "https://proxy.transport.data.gouv.fr/resource/sncf-ter-gtfs-rt-trip-updates", - "categorize_routes": false, - "route_name_regex": "route_short_name:([\\w\\s]+)", - "route_type_regex": "SNCF-&stop:FR-SNCF-TER-StopPoint:OCE([\\w\\s]+)-\\d+", - "trip_number_regex": "trip_headsign:(\\d+)", - "long_distance_regex": "^$", - "excluded_agencies": [] - } - }, - { - "model": "gtfs.gtfsfeed", - "pk": "FR-IDF-IDFM", - "fields": { - "name": "Île-de-France Mobilités", - "country": "FR", - "feed_url": "https://eu.ftp.opendatasoft.com/stif/GTFS/IDFM-gtfs.zip", - "rt_feed_url": "", - "categorize_routes": true, - "route_name_regex": "route_short_name:([\\w]+)", - "route_type_regex": "IDFM", - "trip_number_regex": "trip_short_name:([\\d\\w-]*)§", - "long_distance_regex": "^$", - "excluded_agencies": [] - } - }, - { - "model": "gtfs.gtfsfeed", - "pk": "FR-GES-CTS", - "fields": { - "name": "Compagnie des Transports Strasbourgeois (CTS)", - "country": "FR", - "feed_url": "https://opendata.cts-strasbourg.eu/google_transit.zip", - "rt_feed_url": "", - "categorize_routes": true, - "route_name_regex": "route_short_name:([\\w\\d]+)", - "route_type_regex": "CTS", - "trip_number_regex": "", - "long_distance_regex": "^$", - "excluded_agencies": [] - } - }, - { - "model": "gtfs.gtfsfeed", - "pk": "FR-EUROSTAR", - "fields": { - "name": "Eurostar", - "country": "FR", - "feed_url": "https://www.data.gouv.fr/fr/datasets/r/9089b550-696e-4ae0-87b5-40ea55a14292", - "rt_feed_url": "", - "categorize_routes": false, - "route_name_regex": "route_short_name:([\\w\\s]+)", - "route_type_regex": "Eurostar", - "trip_number_regex": "trip_short_name:(\\d+)", - "long_distance_regex": "", - "excluded_agencies": [] - } - }, - { - "model": "gtfs.gtfsfeed", - "pk": "IT-FRA-TI", - "fields": { - "name": "Trenitalia France", - "country": "FR", - "feed_url": "https://thello.axelor.com/public/gtfs/gtfs.zip", - "rt_feed_url": "https://thello.axelor.com/public/gtfs/GTFS-RT.bin", - "categorize_routes": false, - "route_name_regex": "route_short_name:([\\w\\s/-]+)", - "route_type_regex": "Trenitalia France", - "trip_number_regex": "trip_id:IT-FRA-TI-(\\d+)", - "long_distance_regex": "", - "excluded_agencies": [] - } - }, - { - "model": "gtfs.gtfsfeed", - "pk": "ES-RENFE", - "fields": { - "name": "Renfe", - "country": "ES", - "feed_url": "https://ssl.renfe.com/gtransit/Fichero_AV_LD/google_transit.zip", - "rt_feed_url": "", - "categorize_routes": true, - "route_name_regex": "route_short_name:([\\w\\s]+)", - "route_type_regex": "RENFE-&route_short_name:([\\w\\s]+)", - "trip_number_regex": "trip_short_name:(\\d+)", - "long_distance_regex": "", - "excluded_agencies": [] - } - }, - { - "model": "gtfs.gtfsfeed", - "pk": "AT-ÖBB", - "fields": { - "name": "ÖBB", - "country": "AT", - "feed_url": "https://static.oebb.at/open-data/soll-fahrplan-gtfs/GTFS_OP_2024_obb.zip", - "rt_feed_url": "", - "categorize_routes": true, - "route_name_regex": "route_short_name:([\\w\\s]+)", - "route_type_regex": "ÖBB-&trip_short_name:(\\w+)\\s", - "trip_number_regex": "trip_short_name:\\w+\\s(\\d+)", - "long_distance_regex": "", - "excluded_agencies": [] - } - }, - { - "model": "gtfs.gtfsfeed", - "pk": "CH-ALL", - "fields": { - "name": "Transports suisses", - "country": "CH", - "feed_url": "https://opentransportdata.swiss/fr/dataset/timetable-2024-gtfs2020/permalink", - "rt_feed_url": "https://api.opentransportdata.swiss/gtfsrt2020", - "categorize_routes": true, - "route_name_regex": "route_short_name:([\\w\\s]*)", - "route_type_regex": "CH-&route_desc:([\\w\\s]*)", - "trip_number_regex": "trip_short_name:(\\d+)", - "long_distance_regex": "", - "excluded_agencies": [ - "CH-ALL-87_LEX" - ] - } - }, - { - "model": "gtfs.gtfsfeed", - "pk": "LU-ALL", - "fields": { - "name": "CFL", - "country": "LU", - "feed_url": "https://data.public.lu/fr/datasets/r/aab2922d-27ff-4e53-a789-d990cf1ceb1e", - "rt_feed_url": "", - "categorize_routes": true, - "route_name_regex": "route_short_name:([\\w\\s]+)", - "route_type_regex": "CFL-&route_short_name:([\\w\\s]+)", - "trip_number_regex": "trip_short_name:(\\d+)", - "long_distance_regex": "route_type:3", - "excluded_agencies": [] - } - } -] diff --git a/trainvel/gtfs/gtfs-realtime.proto b/trainvel/gtfs/gtfs-realtime.proto deleted file mode 100644 index bcd7d88..0000000 --- a/trainvel/gtfs/gtfs-realtime.proto +++ /dev/null @@ -1,1035 +0,0 @@ -// Copyright 2015 The GTFS Specifications Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Protocol definition file for GTFS Realtime. -// -// GTFS Realtime lets transit agencies provide consumers with realtime -// information about disruptions to their service (stations closed, lines not -// operating, important delays etc), location of their vehicles and expected -// arrival times. -// -// This protocol is published at: -// https://github.com/google/transit/tree/master/gtfs-realtime - -syntax = "proto2"; -option java_package = "com.google.transit.realtime"; -package transit_realtime; - -// The contents of a feed message. -// A feed is a continuous stream of feed messages. Each message in the stream is -// obtained as a response to an appropriate HTTP GET request. -// A realtime feed is always defined with relation to an existing GTFS feed. -// All the entity ids are resolved with respect to the GTFS feed. -// Note that "required" and "optional" as stated in this file refer to Protocol -// Buffer cardinality, not semantic cardinality. See reference.md at -// https://github.com/google/transit/tree/master/gtfs-realtime for field -// semantic cardinality. -message FeedMessage { - // Metadata about this feed and feed message. - required FeedHeader header = 1; - - // Contents of the feed. - repeated FeedEntity entity = 2; - - // The extensions namespace allows 3rd-party developers to extend the - // GTFS Realtime specification in order to add and evaluate new features and - // modifications to the spec. - extensions 1000 to 1999; - - // The following extension IDs are reserved for private use by any organization. - extensions 9000 to 9999; -} - -// Metadata about a feed, included in feed messages. -message FeedHeader { - // Version of the feed specification. - // The current version is 2.0. Valid versions are "2.0", "1.0". - required string gtfs_realtime_version = 1; - - // Determines whether the current fetch is incremental. Currently, - // DIFFERENTIAL mode is unsupported and behavior is unspecified for feeds - // that use this mode. There are discussions on the GTFS Realtime mailing - // list around fully specifying the behavior of DIFFERENTIAL mode and the - // documentation will be updated when those discussions are finalized. - enum Incrementality { - FULL_DATASET = 0; - DIFFERENTIAL = 1; - } - optional Incrementality incrementality = 2 [default = FULL_DATASET]; - - // This timestamp identifies the moment when the content of this feed has been - // created (in server time). In POSIX time (i.e., number of seconds since - // January 1st 1970 00:00:00 UTC). - optional uint64 timestamp = 3; - - // The extensions namespace allows 3rd-party developers to extend the - // GTFS Realtime specification in order to add and evaluate new features and - // modifications to the spec. - extensions 1000 to 1999; - - // The following extension IDs are reserved for private use by any organization. - extensions 9000 to 9999; -} - -// A definition (or update) of an entity in the transit feed. -message FeedEntity { - // The ids are used only to provide incrementality support. The id should be - // unique within a FeedMessage. Consequent FeedMessages may contain - // FeedEntities with the same id. In case of a DIFFERENTIAL update the new - // FeedEntity with some id will replace the old FeedEntity with the same id - // (or delete it - see is_deleted below). - // The actual GTFS entities (e.g. stations, routes, trips) referenced by the - // feed must be specified by explicit selectors (see EntitySelector below for - // more info). - required string id = 1; - - // Whether this entity is to be deleted. Relevant only for incremental - // fetches. - optional bool is_deleted = 2 [default = false]; - - // Data about the entity itself. Exactly one of the following fields must be - // present (unless the entity is being deleted). - optional TripUpdate trip_update = 3; - optional VehiclePosition vehicle = 4; - optional Alert alert = 5; - - // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future. - optional Shape shape = 6; - - // The extensions namespace allows 3rd-party developers to extend the - // GTFS Realtime Specification in order to add and evaluate new features and - // modifications to the spec. - extensions 1000 to 1999; - - // The following extension IDs are reserved for private use by any organization. - extensions 9000 to 9999; -} - -// -// Entities used in the feed. -// - -// Realtime update of the progress of a vehicle along a trip. -// Depending on the value of ScheduleRelationship, a TripUpdate can specify: -// - A trip that proceeds along the schedule. -// - A trip that proceeds along a route but has no fixed schedule. -// - A trip that have been added or removed with regard to schedule. -// -// The updates can be for future, predicted arrival/departure events, or for -// past events that already occurred. -// Normally, updates should get more precise and more certain (see -// uncertainty below) as the events gets closer to current time. -// Even if that is not possible, the information for past events should be -// precise and certain. In particular, if an update points to time in the past -// but its update's uncertainty is not 0, the client should conclude that the -// update is a (wrong) prediction and that the trip has not completed yet. -// -// Note that the update can describe a trip that is already completed. -// To this end, it is enough to provide an update for the last stop of the trip. -// If the time of that is in the past, the client will conclude from that that -// the whole trip is in the past (it is possible, although inconsequential, to -// also provide updates for preceding stops). -// This option is most relevant for a trip that has completed ahead of schedule, -// but according to the schedule, the trip is still proceeding at the current -// time. Removing the updates for this trip could make the client assume -// that the trip is still proceeding. -// Note that the feed provider is allowed, but not required, to purge past -// updates - this is one case where this would be practically useful. -message TripUpdate { - // The Trip that this message applies to. There can be at most one - // TripUpdate entity for each actual trip instance. - // If there is none, that means there is no prediction information available. - // It does *not* mean that the trip is progressing according to schedule. - required TripDescriptor trip = 1; - - // Additional information on the vehicle that is serving this trip. - optional VehicleDescriptor vehicle = 3; - - // Timing information for a single predicted event (either arrival or - // departure). - // Timing consists of delay and/or estimated time, and uncertainty. - // - delay should be used when the prediction is given relative to some - // existing schedule in GTFS. - // - time should be given whether there is a predicted schedule or not. If - // both time and delay are specified, time will take precedence - // (although normally, time, if given for a scheduled trip, should be - // equal to scheduled time in GTFS + delay). - // - // Uncertainty applies equally to both time and delay. - // The uncertainty roughly specifies the expected error in true delay (but - // note, we don't yet define its precise statistical meaning). It's possible - // for the uncertainty to be 0, for example for trains that are driven under - // computer timing control. - message StopTimeEvent { - // Delay (in seconds) can be positive (meaning that the vehicle is late) or - // negative (meaning that the vehicle is ahead of schedule). Delay of 0 - // means that the vehicle is exactly on time. - optional int32 delay = 1; - - // Event as absolute time. - // In Unix time (i.e., number of seconds since January 1st 1970 00:00:00 - // UTC). - optional int64 time = 2; - - // If uncertainty is omitted, it is interpreted as unknown. - // If the prediction is unknown or too uncertain, the delay (or time) field - // should be empty. In such case, the uncertainty field is ignored. - // To specify a completely certain prediction, set its uncertainty to 0. - optional int32 uncertainty = 3; - - // The extensions namespace allows 3rd-party developers to extend the - // GTFS Realtime Specification in order to add and evaluate new features - // and modifications to the spec. - extensions 1000 to 1999; - - // The following extension IDs are reserved for private use by any organization. - extensions 9000 to 9999; - } - - // Realtime update for arrival and/or departure events for a given stop on a - // trip. Updates can be supplied for both past and future events. - // The producer is allowed, although not required, to drop past events. - message StopTimeUpdate { - // The update is linked to a specific stop either through stop_sequence or - // stop_id, so one of the fields below must necessarily be set. - // See the documentation in TripDescriptor for more information. - - // Must be the same as in stop_times.txt in the corresponding GTFS feed. - optional uint32 stop_sequence = 1; - // Must be the same as in stops.txt in the corresponding GTFS feed. - optional string stop_id = 4; - - optional StopTimeEvent arrival = 2; - optional StopTimeEvent departure = 3; - - // Expected occupancy after departure from the given stop. - // Should be provided only for future stops. - // In order to provide departure_occupancy_status without either arrival or - // departure StopTimeEvents, ScheduleRelationship should be set to NO_DATA. - optional VehiclePosition.OccupancyStatus departure_occupancy_status = 7; - - // The relation between the StopTimeEvents and the static schedule. - enum ScheduleRelationship { - // The vehicle is proceeding in accordance with its static schedule of - // stops, although not necessarily according to the times of the schedule. - // At least one of arrival and departure must be provided. If the schedule - // for this stop contains both arrival and departure times then so must - // this update. Frequency-based trips (GTFS frequencies.txt with exact_times = 0) - // should not have a SCHEDULED value and should use UNSCHEDULED instead. - SCHEDULED = 0; - - // The stop is skipped, i.e., the vehicle will not stop at this stop. - // Arrival and departure are optional. - SKIPPED = 1; - - // No StopTimeEvents are given for this stop. - // The main intention for this value is to give time predictions only for - // part of a trip, i.e., if the last update for a trip has a NO_DATA - // specifier, then StopTimeEvents for the rest of the stops in the trip - // are considered to be unspecified as well. - // Neither arrival nor departure should be supplied. - NO_DATA = 2; - - // The vehicle is operating a trip defined in GTFS frequencies.txt with exact_times = 0. - // This value should not be used for trips that are not defined in GTFS frequencies.txt, - // or trips in GTFS frequencies.txt with exact_times = 1. Trips containing StopTimeUpdates - // with ScheduleRelationship=UNSCHEDULED must also set TripDescriptor.ScheduleRelationship=UNSCHEDULED. - // NOTE: This field is still experimental, and subject to change. It may be - // formally adopted in the future. - UNSCHEDULED = 3; - } - optional ScheduleRelationship schedule_relationship = 5 - [default = SCHEDULED]; - - // Provides the updated values for the stop time. - // NOTE: This message is still experimental, and subject to change. It may be formally adopted in the future. - message StopTimeProperties { - // Supports real-time stop assignments. Refers to a stop_id defined in the GTFS stops.txt. - // The new assigned_stop_id should not result in a significantly different trip experience for the end user than - // the stop_id defined in GTFS stop_times.txt. In other words, the end user should not view this new stop_id as an - // "unusual change" if the new stop was presented within an app without any additional context. - // For example, this field is intended to be used for platform assignments by using a stop_id that belongs to the - // same station as the stop originally defined in GTFS stop_times.txt. - // To assign a stop without providing any real-time arrival or departure predictions, populate this field and set - // StopTimeUpdate.schedule_relationship = NO_DATA. - // If this field is populated, it is preferred to omit `StopTimeUpdate.stop_id` and use only `StopTimeUpdate.stop_sequence`. If - // `StopTimeProperties.assigned_stop_id` and `StopTimeUpdate.stop_id` are populated, `StopTimeUpdate.stop_id` must match `assigned_stop_id`. - // Platform assignments should be reflected in other GTFS-realtime fields as well - // (e.g., `VehiclePosition.stop_id`). - // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future. - optional string assigned_stop_id = 1; - - // The extensions namespace allows 3rd-party developers to extend the - // GTFS Realtime Specification in order to add and evaluate new features - // and modifications to the spec. - extensions 1000 to 1999; - - // The following extension IDs are reserved for private use by any organization. - extensions 9000 to 9999; - } - - // Realtime updates for certain properties defined within GTFS stop_times.txt - // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future. - optional StopTimeProperties stop_time_properties = 6; - - // The extensions namespace allows 3rd-party developers to extend the - // GTFS Realtime Specification in order to add and evaluate new features - // and modifications to the spec. - extensions 1000 to 1999; - - // The following extension IDs are reserved for private use by any organization. - extensions 9000 to 9999; - } - - // Updates to StopTimes for the trip (both future, i.e., predictions, and in - // some cases, past ones, i.e., those that already happened). - // The updates must be sorted by stop_sequence, and apply for all the - // following stops of the trip up to the next specified one. - // - // Example 1: - // For a trip with 20 stops, a StopTimeUpdate with arrival delay and departure - // delay of 0 for stop_sequence of the current stop means that the trip is - // exactly on time. - // - // Example 2: - // For the same trip instance, 3 StopTimeUpdates are provided: - // - delay of 5 min for stop_sequence 3 - // - delay of 1 min for stop_sequence 8 - // - delay of unspecified duration for stop_sequence 10 - // This will be interpreted as: - // - stop_sequences 3,4,5,6,7 have delay of 5 min. - // - stop_sequences 8,9 have delay of 1 min. - // - stop_sequences 10,... have unknown delay. - repeated StopTimeUpdate stop_time_update = 2; - - // The most recent moment at which the vehicle's real-time progress was measured - // to estimate StopTimes in the future. When StopTimes in the past are provided, - // arrival/departure times may be earlier than this value. In POSIX - // time (i.e., the number of seconds since January 1st 1970 00:00:00 UTC). - optional uint64 timestamp = 4; - - // The current schedule deviation for the trip. Delay should only be - // specified when the prediction is given relative to some existing schedule - // in GTFS. - // - // Delay (in seconds) can be positive (meaning that the vehicle is late) or - // negative (meaning that the vehicle is ahead of schedule). Delay of 0 - // means that the vehicle is exactly on time. - // - // Delay information in StopTimeUpdates take precedent of trip-level delay - // information, such that trip-level delay is only propagated until the next - // stop along the trip with a StopTimeUpdate delay value specified. - // - // Feed providers are strongly encouraged to provide a TripUpdate.timestamp - // value indicating when the delay value was last updated, in order to - // evaluate the freshness of the data. - // - // NOTE: This field is still experimental, and subject to change. It may be - // formally adopted in the future. - optional int32 delay = 5; - - // Defines updated properties of the trip, such as a new shape_id when there is a detour. Or defines the - // trip_id, start_date, and start_time of a DUPLICATED trip. - // NOTE: This message is still experimental, and subject to change. It may be formally adopted in the future. - message TripProperties { - // Defines the identifier of a new trip that is a duplicate of an existing trip defined in (CSV) GTFS trips.txt - // but will start at a different service date and/or time (defined using the TripProperties.start_date and - // TripProperties.start_time fields). See definition of trips.trip_id in (CSV) GTFS. Its value must be different - // than the ones used in the (CSV) GTFS. Required if schedule_relationship=DUPLICATED, otherwise this field must not - // be populated and will be ignored by consumers. - // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future. - optional string trip_id = 1; - // Service date on which the DUPLICATED trip will be run, in YYYYMMDD format. Required if - // schedule_relationship=DUPLICATED, otherwise this field must not be populated and will be ignored by consumers. - // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future. - optional string start_date = 2; - // Defines the departure start time of the trip when it’s duplicated. See definition of stop_times.departure_time - // in (CSV) GTFS. Scheduled arrival and departure times for the duplicated trip are calculated based on the offset - // between the original trip departure_time and this field. For example, if a GTFS trip has stop A with a - // departure_time of 10:00:00 and stop B with departure_time of 10:01:00, and this field is populated with the value - // of 10:30:00, stop B on the duplicated trip will have a scheduled departure_time of 10:31:00. Real-time prediction - // delay values are applied to this calculated schedule time to determine the predicted time. For example, if a - // departure delay of 30 is provided for stop B, then the predicted departure time is 10:31:30. Real-time - // prediction time values do not have any offset applied to them and indicate the predicted time as provided. - // For example, if a departure time representing 10:31:30 is provided for stop B, then the predicted departure time - // is 10:31:30. This field is required if schedule_relationship is DUPLICATED, otherwise this field must not be - // populated and will be ignored by consumers. - // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future. - optional string start_time = 3; - // Specifies the shape of the vehicle travel path when the trip shape differs from the shape specified in - // (CSV) GTFS or to specify it in real-time when it's not provided by (CSV) GTFS, such as a vehicle that takes differing - // paths based on rider demand. See definition of trips.shape_id in (CSV) GTFS. If a shape is neither defined in (CSV) GTFS - // nor in real-time, the shape is considered unknown. This field can refer to a shape defined in the (CSV) GTFS in shapes.txt - // or a Shape in the (protobuf) real-time feed. The order of stops (stop sequences) for this trip must remain the same as - // (CSV) GTFS. Stops that are a part of the original trip but will no longer be made, such as when a detour occurs, should - // be marked as schedule_relationship=SKIPPED. - // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future. - optional string shape_id = 4; - - // The extensions namespace allows 3rd-party developers to extend the - // GTFS Realtime Specification in order to add and evaluate new features - // and modifications to the spec. - extensions 1000 to 1999; - - // The following extension IDs are reserved for private use by any organization. - extensions 9000 to 9999; - } - optional TripProperties trip_properties = 6; - - // The extensions namespace allows 3rd-party developers to extend the - // GTFS Realtime Specification in order to add and evaluate new features and - // modifications to the spec. - extensions 1000 to 1999; - - // The following extension IDs are reserved for private use by any organization. - extensions 9000 to 9999; -} - -// Realtime positioning information for a given vehicle. -message VehiclePosition { - // The Trip that this vehicle is serving. - // Can be empty or partial if the vehicle can not be identified with a given - // trip instance. - optional TripDescriptor trip = 1; - - // Additional information on the vehicle that is serving this trip. - optional VehicleDescriptor vehicle = 8; - - // Current position of this vehicle. - optional Position position = 2; - - // The stop sequence index of the current stop. The meaning of - // current_stop_sequence (i.e., the stop that it refers to) is determined by - // current_status. - // If current_status is missing IN_TRANSIT_TO is assumed. - optional uint32 current_stop_sequence = 3; - // Identifies the current stop. The value must be the same as in stops.txt in - // the corresponding GTFS feed. - optional string stop_id = 7; - - enum VehicleStopStatus { - // The vehicle is just about to arrive at the stop (on a stop - // display, the vehicle symbol typically flashes). - INCOMING_AT = 0; - - // The vehicle is standing at the stop. - STOPPED_AT = 1; - - // The vehicle has departed and is in transit to the next stop. - IN_TRANSIT_TO = 2; - } - // The exact status of the vehicle with respect to the current stop. - // Ignored if current_stop_sequence is missing. - optional VehicleStopStatus current_status = 4 [default = IN_TRANSIT_TO]; - - // Moment at which the vehicle's position was measured. In POSIX time - // (i.e., number of seconds since January 1st 1970 00:00:00 UTC). - optional uint64 timestamp = 5; - - // Congestion level that is affecting this vehicle. - enum CongestionLevel { - UNKNOWN_CONGESTION_LEVEL = 0; - RUNNING_SMOOTHLY = 1; - STOP_AND_GO = 2; - CONGESTION = 3; - SEVERE_CONGESTION = 4; // People leaving their cars. - } - optional CongestionLevel congestion_level = 6; - - // The state of passenger occupancy for the vehicle or carriage. - // Individual producers may not publish all OccupancyStatus values. Therefore, consumers - // must not assume that the OccupancyStatus values follow a linear scale. - // Consumers should represent OccupancyStatus values as the state indicated - // and intended by the producer. Likewise, producers must use OccupancyStatus values that - // correspond to actual vehicle occupancy states. - // For describing passenger occupancy levels on a linear scale, see `occupancy_percentage`. - // This field is still experimental, and subject to change. It may be formally adopted in the future. - enum OccupancyStatus { - // The vehicle or carriage is considered empty by most measures, and has few or no - // passengers onboard, but is still accepting passengers. - EMPTY = 0; - - // The vehicle or carriage has a large number of seats available. - // The amount of free seats out of the total seats available to be - // considered large enough to fall into this category is determined at the - // discretion of the producer. - MANY_SEATS_AVAILABLE = 1; - - // The vehicle or carriage has a relatively small number of seats available. - // The amount of free seats out of the total seats available to be - // considered small enough to fall into this category is determined at the - // discretion of the feed producer. - FEW_SEATS_AVAILABLE = 2; - - // The vehicle or carriage can currently accommodate only standing passengers. - STANDING_ROOM_ONLY = 3; - - // The vehicle or carriage can currently accommodate only standing passengers - // and has limited space for them. - CRUSHED_STANDING_ROOM_ONLY = 4; - - // The vehicle or carriage is considered full by most measures, but may still be - // allowing passengers to board. - FULL = 5; - - // The vehicle or carriage is not accepting passengers, but usually accepts passengers for boarding. - NOT_ACCEPTING_PASSENGERS = 6; - - // The vehicle or carriage doesn't have any occupancy data available at that time. - NO_DATA_AVAILABLE = 7; - - // The vehicle or carriage is not boardable and never accepts passengers. - // Useful for special vehicles or carriages (engine, maintenance carriage, etc…). - NOT_BOARDABLE = 8; - - } - // If multi_carriage_status is populated with per-carriage OccupancyStatus, - // then this field should describe the entire vehicle with all carriages accepting passengers considered. - optional OccupancyStatus occupancy_status = 9; - - // A percentage value indicating the degree of passenger occupancy in the vehicle. - // The values are represented as an integer without decimals. 0 means 0% and 100 means 100%. - // The value 100 should represent the total maximum occupancy the vehicle was designed for, - // including both seated and standing capacity, and current operating regulations allow. - // The value may exceed 100 if there are more passengers than the maximum designed capacity. - // The precision of occupancy_percentage should be low enough that individual passengers cannot be tracked boarding or alighting the vehicle. - // If multi_carriage_status is populated with per-carriage occupancy_percentage, - // then this field should describe the entire vehicle with all carriages accepting passengers considered. - // This field is still experimental, and subject to change. It may be formally adopted in the future. - optional uint32 occupancy_percentage = 10; - - // Carriage specific details, used for vehicles composed of several carriages - // This message/field is still experimental, and subject to change. It may be formally adopted in the future. - message CarriageDetails { - - // Identification of the carriage. Should be unique per vehicle. - optional string id = 1; - - // User visible label that may be shown to the passenger to help identify - // the carriage. Example: "7712", "Car ABC-32", etc... - // This message/field is still experimental, and subject to change. It may be formally adopted in the future. - optional string label = 2; - - // Occupancy status for this given carriage, in this vehicle - // This message/field is still experimental, and subject to change. It may be formally adopted in the future. - optional OccupancyStatus occupancy_status = 3 [default = NO_DATA_AVAILABLE]; - - // Occupancy percentage for this given carriage, in this vehicle. - // Follows the same rules as "VehiclePosition.occupancy_percentage" - // -1 in case data is not available for this given carriage (as protobuf defaults to 0 otherwise) - // This message/field is still experimental, and subject to change. It may be formally adopted in the future. - optional int32 occupancy_percentage = 4 [default = -1]; - - // Identifies the order of this carriage with respect to the other - // carriages in the vehicle's list of CarriageDetails. - // The first carriage in the direction of travel must have a value of 1. - // The second value corresponds to the second carriage in the direction - // of travel and must have a value of 2, and so forth. - // For example, the first carriage in the direction of travel has a value of 1. - // If the second carriage in the direction of travel has a value of 3, - // consumers will discard data for all carriages (i.e., the multi_carriage_details field). - // Carriages without data must be represented with a valid carriage_sequence number and the fields - // without data should be omitted (alternately, those fields could also be included and set to the "no data" values). - // This message/field is still experimental, and subject to change. It may be formally adopted in the future. - optional uint32 carriage_sequence = 5; - - // The extensions namespace allows 3rd-party developers to extend the - // GTFS Realtime Specification in order to add and evaluate new features and - // modifications to the spec. - extensions 1000 to 1999; - - // The following extension IDs are reserved for private use by any organization. - extensions 9000 to 9999; - } - - // Details of the multiple carriages of this given vehicle. - // The first occurrence represents the first carriage of the vehicle, - // given the current direction of travel. - // The number of occurrences of the multi_carriage_details - // field represents the number of carriages of the vehicle. - // It also includes non boardable carriages, - // like engines, maintenance carriages, etc… as they provide valuable - // information to passengers about where to stand on a platform. - // This message/field is still experimental, and subject to change. It may be formally adopted in the future. - repeated CarriageDetails multi_carriage_details = 11; - - // The extensions namespace allows 3rd-party developers to extend the - // GTFS Realtime Specification in order to add and evaluate new features and - // modifications to the spec. - extensions 1000 to 1999; - - // The following extension IDs are reserved for private use by any organization. - extensions 9000 to 9999; -} - -// An alert, indicating some sort of incident in the public transit network. -message Alert { - // Time when the alert should be shown to the user. If missing, the - // alert will be shown as long as it appears in the feed. - // If multiple ranges are given, the alert will be shown during all of them. - repeated TimeRange active_period = 1; - - // Entities whose users we should notify of this alert. - repeated EntitySelector informed_entity = 5; - - // Cause of this alert. If cause_detail is included, then Cause must also be included. - enum Cause { - UNKNOWN_CAUSE = 1; - OTHER_CAUSE = 2; // Not machine-representable. - TECHNICAL_PROBLEM = 3; - STRIKE = 4; // Public transit agency employees stopped working. - DEMONSTRATION = 5; // People are blocking the streets. - ACCIDENT = 6; - HOLIDAY = 7; - WEATHER = 8; - MAINTENANCE = 9; - CONSTRUCTION = 10; - POLICE_ACTIVITY = 11; - MEDICAL_EMERGENCY = 12; - } - optional Cause cause = 6 [default = UNKNOWN_CAUSE]; - - // What is the effect of this problem on the affected entity. If effect_detail is included, then Effect must also be included. - enum Effect { - NO_SERVICE = 1; - REDUCED_SERVICE = 2; - - // We don't care about INsignificant delays: they are hard to detect, have - // little impact on the user, and would clutter the results as they are too - // frequent. - SIGNIFICANT_DELAYS = 3; - - DETOUR = 4; - ADDITIONAL_SERVICE = 5; - MODIFIED_SERVICE = 6; - OTHER_EFFECT = 7; - UNKNOWN_EFFECT = 8; - STOP_MOVED = 9; - NO_EFFECT = 10; - ACCESSIBILITY_ISSUE = 11; - } - optional Effect effect = 7 [default = UNKNOWN_EFFECT]; - - // The URL which provides additional information about the alert. - optional TranslatedString url = 8; - - // Alert header. Contains a short summary of the alert text as plain-text. - optional TranslatedString header_text = 10; - - // Full description for the alert as plain-text. The information in the - // description should add to the information of the header. - optional TranslatedString description_text = 11; - - // Text for alert header to be used in text-to-speech implementations. This field is the text-to-speech version of header_text. - optional TranslatedString tts_header_text = 12; - - // Text for full description for the alert to be used in text-to-speech implementations. This field is the text-to-speech version of description_text. - optional TranslatedString tts_description_text = 13; - - // Severity of this alert. - enum SeverityLevel { - UNKNOWN_SEVERITY = 1; - INFO = 2; - WARNING = 3; - SEVERE = 4; - } - - optional SeverityLevel severity_level = 14 [default = UNKNOWN_SEVERITY]; - - // TranslatedImage to be displayed along the alert text. Used to explain visually the alert effect of a detour, station closure, etc. The image must enhance the understanding of the alert. Any essential information communicated within the image must also be contained in the alert text. - // The following types of images are discouraged : image containing mainly text, marketing or branded images that add no additional information. - // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future. - optional TranslatedImage image = 15; - - // Text describing the appearance of the linked image in the `image` field (e.g., in case the image can't be displayed - // or the user can't see the image for accessibility reasons). See the HTML spec for alt image text - https://html.spec.whatwg.org/#alt. - // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future. - optional TranslatedString image_alternative_text = 16; - - - // Description of the cause of the alert that allows for agency-specific language; more specific than the Cause. If cause_detail is included, then Cause must also be included. - // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future. - optional TranslatedString cause_detail = 17; - - // Description of the effect of the alert that allows for agency-specific language; more specific than the Effect. If effect_detail is included, then Effect must also be included. - // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future. - optional TranslatedString effect_detail = 18; - - // The extensions namespace allows 3rd-party developers to extend the - // GTFS Realtime Specification in order to add and evaluate new features - // and modifications to the spec. - extensions 1000 to 1999; - - // The following extension IDs are reserved for private use by any organization. - extensions 9000 to 9999; -} - -// -// Low level data structures used above. -// - -// A time interval. The interval is considered active at time 't' if 't' is -// greater than or equal to the start time and less than the end time. -message TimeRange { - // Start time, in POSIX time (i.e., number of seconds since January 1st 1970 - // 00:00:00 UTC). - // If missing, the interval starts at minus infinity. - optional uint64 start = 1; - - // End time, in POSIX time (i.e., number of seconds since January 1st 1970 - // 00:00:00 UTC). - // If missing, the interval ends at plus infinity. - optional uint64 end = 2; - - // The extensions namespace allows 3rd-party developers to extend the - // GTFS Realtime Specification in order to add and evaluate new features and - // modifications to the spec. - extensions 1000 to 1999; - - // The following extension IDs are reserved for private use by any organization. - extensions 9000 to 9999; -} - -// A position. -message Position { - // Degrees North, in the WGS-84 coordinate system. - required float latitude = 1; - - // Degrees East, in the WGS-84 coordinate system. - required float longitude = 2; - - // Bearing, in degrees, clockwise from North, i.e., 0 is North and 90 is East. - // This can be the compass bearing, or the direction towards the next stop - // or intermediate location. - // This should not be direction deduced from the sequence of previous - // positions, which can be computed from previous data. - optional float bearing = 3; - - // Odometer value, in meters. - optional double odometer = 4; - // Momentary speed measured by the vehicle, in meters per second. - optional float speed = 5; - - // The extensions namespace allows 3rd-party developers to extend the - // GTFS Realtime Specification in order to add and evaluate new features and - // modifications to the spec. - extensions 1000 to 1999; - - // The following extension IDs are reserved for private use by any organization. - extensions 9000 to 9999; -} - -// A descriptor that identifies an instance of a GTFS trip, or all instances of -// a trip along a route. -// - To specify a single trip instance, the trip_id (and if necessary, -// start_time) is set. If route_id is also set, then it should be same as one -// that the given trip corresponds to. -// - To specify all the trips along a given route, only the route_id should be -// set. Note that if the trip_id is not known, then stop sequence ids in -// TripUpdate are not sufficient, and stop_ids must be provided as well. In -// addition, absolute arrival/departure times must be provided. -message TripDescriptor { - // The trip_id from the GTFS feed that this selector refers to. - // For non frequency-based trips, this field is enough to uniquely identify - // the trip. For frequency-based trip, start_time and start_date might also be - // necessary. When schedule_relationship is DUPLICATED within a TripUpdate, the trip_id identifies the trip from - // static GTFS to be duplicated. When schedule_relationship is DUPLICATED within a VehiclePosition, the trip_id - // identifies the new duplicate trip and must contain the value for the corresponding TripUpdate.TripProperties.trip_id. - optional string trip_id = 1; - - // The route_id from the GTFS that this selector refers to. - optional string route_id = 5; - - // The direction_id from the GTFS feed trips.txt file, indicating the - // direction of travel for trips this selector refers to. - optional uint32 direction_id = 6; - - // The initially scheduled start time of this trip instance. - // When the trip_id corresponds to a non-frequency-based trip, this field - // should either be omitted or be equal to the value in the GTFS feed. When - // the trip_id correponds to a frequency-based trip, the start_time must be - // specified for trip updates and vehicle positions. If the trip corresponds - // to exact_times=1 GTFS record, then start_time must be some multiple - // (including zero) of headway_secs later than frequencies.txt start_time for - // the corresponding time period. If the trip corresponds to exact_times=0, - // then its start_time may be arbitrary, and is initially expected to be the - // first departure of the trip. Once established, the start_time of this - // frequency-based trip should be considered immutable, even if the first - // departure time changes -- that time change may instead be reflected in a - // StopTimeUpdate. - // Format and semantics of the field is same as that of - // GTFS/frequencies.txt/start_time, e.g., 11:15:35 or 25:15:35. - optional string start_time = 2; - // The scheduled start date of this trip instance. - // Must be provided to disambiguate trips that are so late as to collide with - // a scheduled trip on a next day. For example, for a train that departs 8:00 - // and 20:00 every day, and is 12 hours late, there would be two distinct - // trips on the same time. - // This field can be provided but is not mandatory for schedules in which such - // collisions are impossible - for example, a service running on hourly - // schedule where a vehicle that is one hour late is not considered to be - // related to schedule anymore. - // In YYYYMMDD format. - optional string start_date = 3; - - // The relation between this trip and the static schedule. If a trip is done - // in accordance with temporary schedule, not reflected in GTFS, then it - // shouldn't be marked as SCHEDULED, but likely as ADDED. - enum ScheduleRelationship { - // Trip that is running in accordance with its GTFS schedule, or is close - // enough to the scheduled trip to be associated with it. - SCHEDULED = 0; - - // An extra trip that was added in addition to a running schedule, for - // example, to replace a broken vehicle or to respond to sudden passenger - // load. - // NOTE: Currently, behavior is unspecified for feeds that use this mode. There are discussions on the GTFS GitHub - // [(1)](https://github.com/google/transit/issues/106) [(2)](https://github.com/google/transit/pull/221) - // [(3)](https://github.com/google/transit/pull/219) around fully specifying or deprecating ADDED trips and the - // documentation will be updated when those discussions are finalized. - ADDED = 1; - - // A trip that is running with no schedule associated to it (GTFS frequencies.txt exact_times=0). - // Trips with ScheduleRelationship=UNSCHEDULED must also set all StopTimeUpdates.ScheduleRelationship=UNSCHEDULED. - UNSCHEDULED = 2; - - // A trip that existed in the schedule but was removed. - CANCELED = 3; - - // Should not be used - for backwards-compatibility only. - REPLACEMENT = 5 [deprecated=true]; - - // An extra trip that was added in addition to a running schedule, for example, to replace a broken vehicle or to - // respond to sudden passenger load. Used with TripUpdate.TripProperties.trip_id, TripUpdate.TripProperties.start_date, - // and TripUpdate.TripProperties.start_time to copy an existing trip from static GTFS but start at a different service - // date and/or time. Duplicating a trip is allowed if the service related to the original trip in (CSV) GTFS - // (in calendar.txt or calendar_dates.txt) is operating within the next 30 days. The trip to be duplicated is - // identified via TripUpdate.TripDescriptor.trip_id. This enumeration does not modify the existing trip referenced by - // TripUpdate.TripDescriptor.trip_id - if a producer wants to cancel the original trip, it must publish a separate - // TripUpdate with the value of CANCELED or DELETED. Trips defined in GTFS frequencies.txt with exact_times that is - // empty or equal to 0 cannot be duplicated. The VehiclePosition.TripDescriptor.trip_id for the new trip must contain - // the matching value from TripUpdate.TripProperties.trip_id and VehiclePosition.TripDescriptor.ScheduleRelationship - // must also be set to DUPLICATED. - // Existing producers and consumers that were using the ADDED enumeration to represent duplicated trips must follow - // the migration guide (https://github.com/google/transit/tree/master/gtfs-realtime/spec/en/examples/migration-duplicated.md) - // to transition to the DUPLICATED enumeration. - // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future. - DUPLICATED = 6; - - - // A trip that existed in the schedule but was removed and must not be shown to users. - // DELETED should be used instead of CANCELED to indicate that a transit provider would like to entirely remove - // information about the corresponding trip from consuming applications, so the trip is not shown as cancelled to - // riders, e.g. a trip that is entirely being replaced by another trip. - // This designation becomes particularly important if several trips are cancelled and replaced with substitute service. - // If consumers were to show explicit information about the cancellations it would distract from the more important - // real-time predictions. - // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future. - DELETED = 7; - } - optional ScheduleRelationship schedule_relationship = 4; - - // The extensions namespace allows 3rd-party developers to extend the - // GTFS Realtime Specification in order to add and evaluate new features and - // modifications to the spec. - extensions 1000 to 1999; - - // The following extension IDs are reserved for private use by any organization. - extensions 9000 to 9999; -} - -// Identification information for the vehicle performing the trip. -message VehicleDescriptor { - // Internal system identification of the vehicle. Should be unique per - // vehicle, and can be used for tracking the vehicle as it proceeds through - // the system. - optional string id = 1; - - // User visible label, i.e., something that must be shown to the passenger to - // help identify the correct vehicle. - optional string label = 2; - - // The license plate of the vehicle. - optional string license_plate = 3; - - enum WheelchairAccessible { - // The trip doesn't have information about wheelchair accessibility. - // This is the **default** behavior. If the static GTFS contains a - // _wheelchair_accessible_ value, it won't be overwritten. - NO_VALUE = 0; - - // The trip has no accessibility value present. - // This value will overwrite the value from the GTFS. - UNKNOWN = 1; - - // The trip is wheelchair accessible. - // This value will overwrite the value from the GTFS. - WHEELCHAIR_ACCESSIBLE = 2; - - // The trip is **not** wheelchair accessible. - // This value will overwrite the value from the GTFS. - WHEELCHAIR_INACCESSIBLE = 3; - } - optional WheelchairAccessible wheelchair_accessible = 4 [default = NO_VALUE]; - - // The extensions namespace allows 3rd-party developers to extend the - // GTFS Realtime Specification in order to add and evaluate new features and - // modifications to the spec. - extensions 1000 to 1999; - - // The following extension IDs are reserved for private use by any organization. - extensions 9000 to 9999; -} - -// A selector for an entity in a GTFS feed. -message EntitySelector { - // The values of the fields should correspond to the appropriate fields in the - // GTFS feed. - // At least one specifier must be given. If several are given, then the - // matching has to apply to all the given specifiers. - optional string agency_id = 1; - optional string route_id = 2; - // corresponds to route_type in GTFS. - optional int32 route_type = 3; - optional TripDescriptor trip = 4; - optional string stop_id = 5; - // Corresponds to trip direction_id in GTFS trips.txt. If provided the - // route_id must also be provided. - optional uint32 direction_id = 6; - - // The extensions namespace allows 3rd-party developers to extend the - // GTFS Realtime Specification in order to add and evaluate new features and - // modifications to the spec. - extensions 1000 to 1999; - - // The following extension IDs are reserved for private use by any organization. - extensions 9000 to 9999; -} - -// An internationalized message containing per-language versions of a snippet of -// text or a URL. -// One of the strings from a message will be picked up. The resolution proceeds -// as follows: -// 1. If the UI language matches the language code of a translation, -// the first matching translation is picked. -// 2. If a default UI language (e.g., English) matches the language code of a -// translation, the first matching translation is picked. -// 3. If some translation has an unspecified language code, that translation is -// picked. -message TranslatedString { - message Translation { - // A UTF-8 string containing the message. - required string text = 1; - // BCP-47 language code. Can be omitted if the language is unknown or if - // no i18n is done at all for the feed. At most one translation is - // allowed to have an unspecified language tag. - optional string language = 2; - - // The extensions namespace allows 3rd-party developers to extend the - // GTFS Realtime Specification in order to add and evaluate new features and - // modifications to the spec. - extensions 1000 to 1999; - - // The following extension IDs are reserved for private use by any organization. - extensions 9000 to 9999; - } - // At least one translation must be provided. - repeated Translation translation = 1; - - // The extensions namespace allows 3rd-party developers to extend the - // GTFS Realtime Specification in order to add and evaluate new features and - // modifications to the spec. - extensions 1000 to 1999; - - // The following extension IDs are reserved for private use by any organization. - extensions 9000 to 9999; -} - -// An internationalized image containing per-language versions of a URL linking to an image -// along with meta information -// Only one of the images from a message will be retained by consumers. The resolution proceeds -// as follows: -// 1. If the UI language matches the language code of a translation, -// the first matching translation is picked. -// 2. If a default UI language (e.g., English) matches the language code of a -// translation, the first matching translation is picked. -// 3. If some translation has an unspecified language code, that translation is -// picked. -// NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future. -message TranslatedImage { - message LocalizedImage { - // String containing an URL linking to an image - // The image linked must be less than 2MB. - // If an image changes in a significant enough way that an update is required on the consumer side, the producer must update the URL to a new one. - // The URL should be a fully qualified URL that includes http:// or https://, and any special characters in the URL must be correctly escaped. See the following http://www.w3.org/Addressing/URL/4_URI_Recommentations.html for a description of how to create fully qualified URL values. - required string url = 1; - - // IANA media type as to specify the type of image to be displayed. - // The type must start with "image/" - required string media_type = 2; - - // BCP-47 language code. Can be omitted if the language is unknown or if - // no i18n is done at all for the feed. At most one translation is - // allowed to have an unspecified language tag. - optional string language = 3; - - - // The extensions namespace allows 3rd-party developers to extend the - // GTFS Realtime Specification in order to add and evaluate new features and - // modifications to the spec. - extensions 1000 to 1999; - - // The following extension IDs are reserved for private use by any organization. - extensions 9000 to 9999; - } - // At least one localized image must be provided. - repeated LocalizedImage localized_image = 1; - - // The extensions namespace allows 3rd-party developers to extend the - // GTFS Realtime Specification in order to add and evaluate new features and - // modifications to the spec. - extensions 1000 to 1999; - - // The following extension IDs are reserved for private use by any organization. - extensions 9000 to 9999; -} - -// Describes the physical path that a vehicle takes when it's not part of the (CSV) GTFS, -// such as for a detour. Shapes belong to Trips, and consist of a sequence of shape points. -// Tracing the points in order provides the path of the vehicle. Shapes do not need to intercept -// the location of Stops exactly, but all Stops on a trip should lie within a small distance of -// the shape for that trip, i.e. close to straight line segments connecting the shape points -// NOTE: This message is still experimental, and subject to change. It may be formally adopted in the future. -message Shape { - // Identifier of the shape. Must be different than any shape_id defined in the (CSV) GTFS. - // This field is required as per reference.md, but needs to be specified here optional because "Required is Forever" - // See https://developers.google.com/protocol-buffers/docs/proto#specifying_field_rules - // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future. - optional string shape_id = 1; - - // Encoded polyline representation of the shape. This polyline must contain at least two points. - // For more information about encoded polylines, see https://developers.google.com/maps/documentation/utilities/polylinealgorithm - // This field is required as per reference.md, but needs to be specified here optional because "Required is Forever" - // See https://developers.google.com/protocol-buffers/docs/proto#specifying_field_rules - // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future. - optional string encoded_polyline = 2; - - // The extensions namespace allows 3rd-party developers to extend the - // GTFS Realtime Specification in order to add and evaluate new features and - // modifications to the spec. - extensions 1000 to 1999; - - // The following extension IDs are reserved for private use by any organization. - extensions 9000 to 9999; -} diff --git a/trainvel/gtfs/gtfs_realtime_pb2.py b/trainvel/gtfs/gtfs_realtime_pb2.py deleted file mode 100644 index 0f56af7..0000000 --- a/trainvel/gtfs/gtfs_realtime_pb2.py +++ /dev/null @@ -1,89 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: gtfs-realtime.proto -# Protobuf Python Version: 4.25.2 -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x13gtfs-realtime.proto\x12\x10transit_realtime\"y\n\x0b\x46\x65\x65\x64Message\x12,\n\x06header\x18\x01 \x02(\x0b\x32\x1c.transit_realtime.FeedHeader\x12,\n\x06\x65ntity\x18\x02 \x03(\x0b\x32\x1c.transit_realtime.FeedEntity*\x06\x08\xe8\x07\x10\xd0\x0f*\x06\x08\xa8\x46\x10\x90N\"\xd7\x01\n\nFeedHeader\x12\x1d\n\x15gtfs_realtime_version\x18\x01 \x02(\t\x12Q\n\x0eincrementality\x18\x02 \x01(\x0e\x32+.transit_realtime.FeedHeader.Incrementality:\x0c\x46ULL_DATASET\x12\x11\n\ttimestamp\x18\x03 \x01(\x04\"4\n\x0eIncrementality\x12\x10\n\x0c\x46ULL_DATASET\x10\x00\x12\x10\n\x0c\x44IFFERENTIAL\x10\x01*\x06\x08\xe8\x07\x10\xd0\x0f*\x06\x08\xa8\x46\x10\x90N\"\xfa\x01\n\nFeedEntity\x12\n\n\x02id\x18\x01 \x02(\t\x12\x19\n\nis_deleted\x18\x02 \x01(\x08:\x05\x66\x61lse\x12\x31\n\x0btrip_update\x18\x03 \x01(\x0b\x32\x1c.transit_realtime.TripUpdate\x12\x32\n\x07vehicle\x18\x04 \x01(\x0b\x32!.transit_realtime.VehiclePosition\x12&\n\x05\x61lert\x18\x05 \x01(\x0b\x32\x17.transit_realtime.Alert\x12&\n\x05shape\x18\x06 \x01(\x0b\x32\x17.transit_realtime.Shape*\x06\x08\xe8\x07\x10\xd0\x0f*\x06\x08\xa8\x46\x10\x90N\"\xeb\x08\n\nTripUpdate\x12.\n\x04trip\x18\x01 \x02(\x0b\x32 .transit_realtime.TripDescriptor\x12\x34\n\x07vehicle\x18\x03 \x01(\x0b\x32#.transit_realtime.VehicleDescriptor\x12\x45\n\x10stop_time_update\x18\x02 \x03(\x0b\x32+.transit_realtime.TripUpdate.StopTimeUpdate\x12\x11\n\ttimestamp\x18\x04 \x01(\x04\x12\r\n\x05\x64\x65lay\x18\x05 \x01(\x05\x12\x44\n\x0ftrip_properties\x18\x06 \x01(\x0b\x32+.transit_realtime.TripUpdate.TripProperties\x1aQ\n\rStopTimeEvent\x12\r\n\x05\x64\x65lay\x18\x01 \x01(\x05\x12\x0c\n\x04time\x18\x02 \x01(\x03\x12\x13\n\x0buncertainty\x18\x03 \x01(\x05*\x06\x08\xe8\x07\x10\xd0\x0f*\x06\x08\xa8\x46\x10\x90N\x1a\xf7\x04\n\x0eStopTimeUpdate\x12\x15\n\rstop_sequence\x18\x01 \x01(\r\x12\x0f\n\x07stop_id\x18\x04 \x01(\t\x12;\n\x07\x61rrival\x18\x02 \x01(\x0b\x32*.transit_realtime.TripUpdate.StopTimeEvent\x12=\n\tdeparture\x18\x03 \x01(\x0b\x32*.transit_realtime.TripUpdate.StopTimeEvent\x12U\n\x1a\x64\x65parture_occupancy_status\x18\x07 \x01(\x0e\x32\x31.transit_realtime.VehiclePosition.OccupancyStatus\x12j\n\x15schedule_relationship\x18\x05 \x01(\x0e\x32@.transit_realtime.TripUpdate.StopTimeUpdate.ScheduleRelationship:\tSCHEDULED\x12\\\n\x14stop_time_properties\x18\x06 \x01(\x0b\x32>.transit_realtime.TripUpdate.StopTimeUpdate.StopTimeProperties\x1a>\n\x12StopTimeProperties\x12\x18\n\x10\x61ssigned_stop_id\x18\x01 \x01(\t*\x06\x08\xe8\x07\x10\xd0\x0f*\x06\x08\xa8\x46\x10\x90N\"P\n\x14ScheduleRelationship\x12\r\n\tSCHEDULED\x10\x00\x12\x0b\n\x07SKIPPED\x10\x01\x12\x0b\n\x07NO_DATA\x10\x02\x12\x0f\n\x0bUNSCHEDULED\x10\x03*\x06\x08\xe8\x07\x10\xd0\x0f*\x06\x08\xa8\x46\x10\x90N\x1ak\n\x0eTripProperties\x12\x0f\n\x07trip_id\x18\x01 \x01(\t\x12\x12\n\nstart_date\x18\x02 \x01(\t\x12\x12\n\nstart_time\x18\x03 \x01(\t\x12\x10\n\x08shape_id\x18\x04 \x01(\t*\x06\x08\xe8\x07\x10\xd0\x0f*\x06\x08\xa8\x46\x10\x90N*\x06\x08\xe8\x07\x10\xd0\x0f*\x06\x08\xa8\x46\x10\x90N\"\xdf\t\n\x0fVehiclePosition\x12.\n\x04trip\x18\x01 \x01(\x0b\x32 .transit_realtime.TripDescriptor\x12\x34\n\x07vehicle\x18\x08 \x01(\x0b\x32#.transit_realtime.VehicleDescriptor\x12,\n\x08position\x18\x02 \x01(\x0b\x32\x1a.transit_realtime.Position\x12\x1d\n\x15\x63urrent_stop_sequence\x18\x03 \x01(\r\x12\x0f\n\x07stop_id\x18\x07 \x01(\t\x12Z\n\x0e\x63urrent_status\x18\x04 \x01(\x0e\x32\x33.transit_realtime.VehiclePosition.VehicleStopStatus:\rIN_TRANSIT_TO\x12\x11\n\ttimestamp\x18\x05 \x01(\x04\x12K\n\x10\x63ongestion_level\x18\x06 \x01(\x0e\x32\x31.transit_realtime.VehiclePosition.CongestionLevel\x12K\n\x10occupancy_status\x18\t \x01(\x0e\x32\x31.transit_realtime.VehiclePosition.OccupancyStatus\x12\x1c\n\x14occupancy_percentage\x18\n \x01(\r\x12Q\n\x16multi_carriage_details\x18\x0b \x03(\x0b\x32\x31.transit_realtime.VehiclePosition.CarriageDetails\x1a\xd9\x01\n\x0f\x43\x61rriageDetails\x12\n\n\x02id\x18\x01 \x01(\t\x12\r\n\x05label\x18\x02 \x01(\t\x12^\n\x10occupancy_status\x18\x03 \x01(\x0e\x32\x31.transit_realtime.VehiclePosition.OccupancyStatus:\x11NO_DATA_AVAILABLE\x12 \n\x14occupancy_percentage\x18\x04 \x01(\x05:\x02-1\x12\x19\n\x11\x63\x61rriage_sequence\x18\x05 \x01(\r*\x06\x08\xe8\x07\x10\xd0\x0f*\x06\x08\xa8\x46\x10\x90N\"G\n\x11VehicleStopStatus\x12\x0f\n\x0bINCOMING_AT\x10\x00\x12\x0e\n\nSTOPPED_AT\x10\x01\x12\x11\n\rIN_TRANSIT_TO\x10\x02\"}\n\x0f\x43ongestionLevel\x12\x1c\n\x18UNKNOWN_CONGESTION_LEVEL\x10\x00\x12\x14\n\x10RUNNING_SMOOTHLY\x10\x01\x12\x0f\n\x0bSTOP_AND_GO\x10\x02\x12\x0e\n\nCONGESTION\x10\x03\x12\x15\n\x11SEVERE_CONGESTION\x10\x04\"\xd9\x01\n\x0fOccupancyStatus\x12\t\n\x05\x45MPTY\x10\x00\x12\x18\n\x14MANY_SEATS_AVAILABLE\x10\x01\x12\x17\n\x13\x46\x45W_SEATS_AVAILABLE\x10\x02\x12\x16\n\x12STANDING_ROOM_ONLY\x10\x03\x12\x1e\n\x1a\x43RUSHED_STANDING_ROOM_ONLY\x10\x04\x12\x08\n\x04\x46ULL\x10\x05\x12\x1c\n\x18NOT_ACCEPTING_PASSENGERS\x10\x06\x12\x15\n\x11NO_DATA_AVAILABLE\x10\x07\x12\x11\n\rNOT_BOARDABLE\x10\x08*\x06\x08\xe8\x07\x10\xd0\x0f*\x06\x08\xa8\x46\x10\x90N\"\xeb\n\n\x05\x41lert\x12\x32\n\ractive_period\x18\x01 \x03(\x0b\x32\x1b.transit_realtime.TimeRange\x12\x39\n\x0finformed_entity\x18\x05 \x03(\x0b\x32 .transit_realtime.EntitySelector\x12;\n\x05\x63\x61use\x18\x06 \x01(\x0e\x32\x1d.transit_realtime.Alert.Cause:\rUNKNOWN_CAUSE\x12>\n\x06\x65\x66\x66\x65\x63t\x18\x07 \x01(\x0e\x32\x1e.transit_realtime.Alert.Effect:\x0eUNKNOWN_EFFECT\x12/\n\x03url\x18\x08 \x01(\x0b\x32\".transit_realtime.TranslatedString\x12\x37\n\x0bheader_text\x18\n \x01(\x0b\x32\".transit_realtime.TranslatedString\x12<\n\x10\x64\x65scription_text\x18\x0b \x01(\x0b\x32\".transit_realtime.TranslatedString\x12;\n\x0ftts_header_text\x18\x0c \x01(\x0b\x32\".transit_realtime.TranslatedString\x12@\n\x14tts_description_text\x18\r \x01(\x0b\x32\".transit_realtime.TranslatedString\x12O\n\x0eseverity_level\x18\x0e \x01(\x0e\x32%.transit_realtime.Alert.SeverityLevel:\x10UNKNOWN_SEVERITY\x12\x30\n\x05image\x18\x0f \x01(\x0b\x32!.transit_realtime.TranslatedImage\x12\x42\n\x16image_alternative_text\x18\x10 \x01(\x0b\x32\".transit_realtime.TranslatedString\x12\x38\n\x0c\x63\x61use_detail\x18\x11 \x01(\x0b\x32\".transit_realtime.TranslatedString\x12\x39\n\reffect_detail\x18\x12 \x01(\x0b\x32\".transit_realtime.TranslatedString\"\xd8\x01\n\x05\x43\x61use\x12\x11\n\rUNKNOWN_CAUSE\x10\x01\x12\x0f\n\x0bOTHER_CAUSE\x10\x02\x12\x15\n\x11TECHNICAL_PROBLEM\x10\x03\x12\n\n\x06STRIKE\x10\x04\x12\x11\n\rDEMONSTRATION\x10\x05\x12\x0c\n\x08\x41\x43\x43IDENT\x10\x06\x12\x0b\n\x07HOLIDAY\x10\x07\x12\x0b\n\x07WEATHER\x10\x08\x12\x0f\n\x0bMAINTENANCE\x10\t\x12\x10\n\x0c\x43ONSTRUCTION\x10\n\x12\x13\n\x0fPOLICE_ACTIVITY\x10\x0b\x12\x15\n\x11MEDICAL_EMERGENCY\x10\x0c\"\xdd\x01\n\x06\x45\x66\x66\x65\x63t\x12\x0e\n\nNO_SERVICE\x10\x01\x12\x13\n\x0fREDUCED_SERVICE\x10\x02\x12\x16\n\x12SIGNIFICANT_DELAYS\x10\x03\x12\n\n\x06\x44\x45TOUR\x10\x04\x12\x16\n\x12\x41\x44\x44ITIONAL_SERVICE\x10\x05\x12\x14\n\x10MODIFIED_SERVICE\x10\x06\x12\x10\n\x0cOTHER_EFFECT\x10\x07\x12\x12\n\x0eUNKNOWN_EFFECT\x10\x08\x12\x0e\n\nSTOP_MOVED\x10\t\x12\r\n\tNO_EFFECT\x10\n\x12\x17\n\x13\x41\x43\x43\x45SSIBILITY_ISSUE\x10\x0b\"H\n\rSeverityLevel\x12\x14\n\x10UNKNOWN_SEVERITY\x10\x01\x12\x08\n\x04INFO\x10\x02\x12\x0b\n\x07WARNING\x10\x03\x12\n\n\x06SEVERE\x10\x04*\x06\x08\xe8\x07\x10\xd0\x0f*\x06\x08\xa8\x46\x10\x90N\"7\n\tTimeRange\x12\r\n\x05start\x18\x01 \x01(\x04\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x04*\x06\x08\xe8\x07\x10\xd0\x0f*\x06\x08\xa8\x46\x10\x90N\"q\n\x08Position\x12\x10\n\x08latitude\x18\x01 \x02(\x02\x12\x11\n\tlongitude\x18\x02 \x02(\x02\x12\x0f\n\x07\x62\x65\x61ring\x18\x03 \x01(\x02\x12\x10\n\x08odometer\x18\x04 \x01(\x01\x12\r\n\x05speed\x18\x05 \x01(\x02*\x06\x08\xe8\x07\x10\xd0\x0f*\x06\x08\xa8\x46\x10\x90N\"\xdb\x02\n\x0eTripDescriptor\x12\x0f\n\x07trip_id\x18\x01 \x01(\t\x12\x10\n\x08route_id\x18\x05 \x01(\t\x12\x14\n\x0c\x64irection_id\x18\x06 \x01(\r\x12\x12\n\nstart_time\x18\x02 \x01(\t\x12\x12\n\nstart_date\x18\x03 \x01(\t\x12T\n\x15schedule_relationship\x18\x04 \x01(\x0e\x32\x35.transit_realtime.TripDescriptor.ScheduleRelationship\"\x81\x01\n\x14ScheduleRelationship\x12\r\n\tSCHEDULED\x10\x00\x12\t\n\x05\x41\x44\x44\x45\x44\x10\x01\x12\x0f\n\x0bUNSCHEDULED\x10\x02\x12\x0c\n\x08\x43\x41NCELED\x10\x03\x12\x13\n\x0bREPLACEMENT\x10\x05\x1a\x02\x08\x01\x12\x0e\n\nDUPLICATED\x10\x06\x12\x0b\n\x07\x44\x45LETED\x10\x07*\x06\x08\xe8\x07\x10\xd0\x0f*\x06\x08\xa8\x46\x10\x90N\"\xa3\x02\n\x11VehicleDescriptor\x12\n\n\x02id\x18\x01 \x01(\t\x12\r\n\x05label\x18\x02 \x01(\t\x12\x15\n\rlicense_plate\x18\x03 \x01(\t\x12\x61\n\x15wheelchair_accessible\x18\x04 \x01(\x0e\x32\x38.transit_realtime.VehicleDescriptor.WheelchairAccessible:\x08NO_VALUE\"i\n\x14WheelchairAccessible\x12\x0c\n\x08NO_VALUE\x10\x00\x12\x0b\n\x07UNKNOWN\x10\x01\x12\x19\n\x15WHEELCHAIR_ACCESSIBLE\x10\x02\x12\x1b\n\x17WHEELCHAIR_INACCESSIBLE\x10\x03*\x06\x08\xe8\x07\x10\xd0\x0f*\x06\x08\xa8\x46\x10\x90N\"\xb0\x01\n\x0e\x45ntitySelector\x12\x11\n\tagency_id\x18\x01 \x01(\t\x12\x10\n\x08route_id\x18\x02 \x01(\t\x12\x12\n\nroute_type\x18\x03 \x01(\x05\x12.\n\x04trip\x18\x04 \x01(\x0b\x32 .transit_realtime.TripDescriptor\x12\x0f\n\x07stop_id\x18\x05 \x01(\t\x12\x14\n\x0c\x64irection_id\x18\x06 \x01(\r*\x06\x08\xe8\x07\x10\xd0\x0f*\x06\x08\xa8\x46\x10\x90N\"\xa6\x01\n\x10TranslatedString\x12\x43\n\x0btranslation\x18\x01 \x03(\x0b\x32..transit_realtime.TranslatedString.Translation\x1a=\n\x0bTranslation\x12\x0c\n\x04text\x18\x01 \x02(\t\x12\x10\n\x08language\x18\x02 \x01(\t*\x06\x08\xe8\x07\x10\xd0\x0f*\x06\x08\xa8\x46\x10\x90N*\x06\x08\xe8\x07\x10\xd0\x0f*\x06\x08\xa8\x46\x10\x90N\"\xc1\x01\n\x0fTranslatedImage\x12I\n\x0flocalized_image\x18\x01 \x03(\x0b\x32\x30.transit_realtime.TranslatedImage.LocalizedImage\x1aS\n\x0eLocalizedImage\x12\x0b\n\x03url\x18\x01 \x02(\t\x12\x12\n\nmedia_type\x18\x02 \x02(\t\x12\x10\n\x08language\x18\x03 \x01(\t*\x06\x08\xe8\x07\x10\xd0\x0f*\x06\x08\xa8\x46\x10\x90N*\x06\x08\xe8\x07\x10\xd0\x0f*\x06\x08\xa8\x46\x10\x90N\"C\n\x05Shape\x12\x10\n\x08shape_id\x18\x01 \x01(\t\x12\x18\n\x10\x65ncoded_polyline\x18\x02 \x01(\t*\x06\x08\xe8\x07\x10\xd0\x0f*\x06\x08\xa8\x46\x10\x90NB\x1d\n\x1b\x63om.google.transit.realtime') - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'gtfs_realtime_pb2', _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - _globals['DESCRIPTOR']._options = None - _globals['DESCRIPTOR']._serialized_options = b'\n\033com.google.transit.realtime' - _globals['_TRIPDESCRIPTOR_SCHEDULERELATIONSHIP'].values_by_name["REPLACEMENT"]._options = None - _globals['_TRIPDESCRIPTOR_SCHEDULERELATIONSHIP'].values_by_name["REPLACEMENT"]._serialized_options = b'\010\001' - _globals['_FEEDMESSAGE']._serialized_start=41 - _globals['_FEEDMESSAGE']._serialized_end=162 - _globals['_FEEDHEADER']._serialized_start=165 - _globals['_FEEDHEADER']._serialized_end=380 - _globals['_FEEDHEADER_INCREMENTALITY']._serialized_start=312 - _globals['_FEEDHEADER_INCREMENTALITY']._serialized_end=364 - _globals['_FEEDENTITY']._serialized_start=383 - _globals['_FEEDENTITY']._serialized_end=633 - _globals['_TRIPUPDATE']._serialized_start=636 - _globals['_TRIPUPDATE']._serialized_end=1767 - _globals['_TRIPUPDATE_STOPTIMEEVENT']._serialized_start=927 - _globals['_TRIPUPDATE_STOPTIMEEVENT']._serialized_end=1008 - _globals['_TRIPUPDATE_STOPTIMEUPDATE']._serialized_start=1011 - _globals['_TRIPUPDATE_STOPTIMEUPDATE']._serialized_end=1642 - _globals['_TRIPUPDATE_STOPTIMEUPDATE_STOPTIMEPROPERTIES']._serialized_start=1482 - _globals['_TRIPUPDATE_STOPTIMEUPDATE_STOPTIMEPROPERTIES']._serialized_end=1544 - _globals['_TRIPUPDATE_STOPTIMEUPDATE_SCHEDULERELATIONSHIP']._serialized_start=1546 - _globals['_TRIPUPDATE_STOPTIMEUPDATE_SCHEDULERELATIONSHIP']._serialized_end=1626 - _globals['_TRIPUPDATE_TRIPPROPERTIES']._serialized_start=1644 - _globals['_TRIPUPDATE_TRIPPROPERTIES']._serialized_end=1751 - _globals['_VEHICLEPOSITION']._serialized_start=1770 - _globals['_VEHICLEPOSITION']._serialized_end=3017 - _globals['_VEHICLEPOSITION_CARRIAGEDETAILS']._serialized_start=2364 - _globals['_VEHICLEPOSITION_CARRIAGEDETAILS']._serialized_end=2581 - _globals['_VEHICLEPOSITION_VEHICLESTOPSTATUS']._serialized_start=2583 - _globals['_VEHICLEPOSITION_VEHICLESTOPSTATUS']._serialized_end=2654 - _globals['_VEHICLEPOSITION_CONGESTIONLEVEL']._serialized_start=2656 - _globals['_VEHICLEPOSITION_CONGESTIONLEVEL']._serialized_end=2781 - _globals['_VEHICLEPOSITION_OCCUPANCYSTATUS']._serialized_start=2784 - _globals['_VEHICLEPOSITION_OCCUPANCYSTATUS']._serialized_end=3001 - _globals['_ALERT']._serialized_start=3020 - _globals['_ALERT']._serialized_end=4407 - _globals['_ALERT_CAUSE']._serialized_start=3877 - _globals['_ALERT_CAUSE']._serialized_end=4093 - _globals['_ALERT_EFFECT']._serialized_start=4096 - _globals['_ALERT_EFFECT']._serialized_end=4317 - _globals['_ALERT_SEVERITYLEVEL']._serialized_start=4319 - _globals['_ALERT_SEVERITYLEVEL']._serialized_end=4391 - _globals['_TIMERANGE']._serialized_start=4409 - _globals['_TIMERANGE']._serialized_end=4464 - _globals['_POSITION']._serialized_start=4466 - _globals['_POSITION']._serialized_end=4579 - _globals['_TRIPDESCRIPTOR']._serialized_start=4582 - _globals['_TRIPDESCRIPTOR']._serialized_end=4929 - _globals['_TRIPDESCRIPTOR_SCHEDULERELATIONSHIP']._serialized_start=4784 - _globals['_TRIPDESCRIPTOR_SCHEDULERELATIONSHIP']._serialized_end=4913 - _globals['_VEHICLEDESCRIPTOR']._serialized_start=4932 - _globals['_VEHICLEDESCRIPTOR']._serialized_end=5223 - _globals['_VEHICLEDESCRIPTOR_WHEELCHAIRACCESSIBLE']._serialized_start=5102 - _globals['_VEHICLEDESCRIPTOR_WHEELCHAIRACCESSIBLE']._serialized_end=5207 - _globals['_ENTITYSELECTOR']._serialized_start=5226 - _globals['_ENTITYSELECTOR']._serialized_end=5402 - _globals['_TRANSLATEDSTRING']._serialized_start=5405 - _globals['_TRANSLATEDSTRING']._serialized_end=5571 - _globals['_TRANSLATEDSTRING_TRANSLATION']._serialized_start=5494 - _globals['_TRANSLATEDSTRING_TRANSLATION']._serialized_end=5555 - _globals['_TRANSLATEDIMAGE']._serialized_start=5574 - _globals['_TRANSLATEDIMAGE']._serialized_end=5767 - _globals['_TRANSLATEDIMAGE_LOCALIZEDIMAGE']._serialized_start=5668 - _globals['_TRANSLATEDIMAGE_LOCALIZEDIMAGE']._serialized_end=5751 - _globals['_SHAPE']._serialized_start=5769 - _globals['_SHAPE']._serialized_end=5836 -# @@protoc_insertion_point(module_scope) diff --git a/trainvel/gtfs/gtfs_realtime_pb2.pyi b/trainvel/gtfs/gtfs_realtime_pb2.pyi deleted file mode 100644 index 3cfa4d3..0000000 --- a/trainvel/gtfs/gtfs_realtime_pb2.pyi +++ /dev/null @@ -1,436 +0,0 @@ -from google.protobuf.internal import containers as _containers -from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper -from google.protobuf.internal import python_message as _python_message -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union - -DESCRIPTOR: _descriptor.FileDescriptor - -class FeedMessage(_message.Message): - __slots__ = ("header", "entity") - Extensions: _python_message._ExtensionDict - HEADER_FIELD_NUMBER: _ClassVar[int] - ENTITY_FIELD_NUMBER: _ClassVar[int] - header: FeedHeader - entity: _containers.RepeatedCompositeFieldContainer[FeedEntity] - def __init__(self, header: _Optional[_Union[FeedHeader, _Mapping]] = ..., entity: _Optional[_Iterable[_Union[FeedEntity, _Mapping]]] = ...) -> None: ... - -class FeedHeader(_message.Message): - __slots__ = ("gtfs_realtime_version", "incrementality", "timestamp") - Extensions: _python_message._ExtensionDict - class Incrementality(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - FULL_DATASET: _ClassVar[FeedHeader.Incrementality] - DIFFERENTIAL: _ClassVar[FeedHeader.Incrementality] - FULL_DATASET: FeedHeader.Incrementality - DIFFERENTIAL: FeedHeader.Incrementality - GTFS_REALTIME_VERSION_FIELD_NUMBER: _ClassVar[int] - INCREMENTALITY_FIELD_NUMBER: _ClassVar[int] - TIMESTAMP_FIELD_NUMBER: _ClassVar[int] - gtfs_realtime_version: str - incrementality: FeedHeader.Incrementality - timestamp: int - def __init__(self, gtfs_realtime_version: _Optional[str] = ..., incrementality: _Optional[_Union[FeedHeader.Incrementality, str]] = ..., timestamp: _Optional[int] = ...) -> None: ... - -class FeedEntity(_message.Message): - __slots__ = ("id", "is_deleted", "trip_update", "vehicle", "alert", "shape") - Extensions: _python_message._ExtensionDict - ID_FIELD_NUMBER: _ClassVar[int] - IS_DELETED_FIELD_NUMBER: _ClassVar[int] - TRIP_UPDATE_FIELD_NUMBER: _ClassVar[int] - VEHICLE_FIELD_NUMBER: _ClassVar[int] - ALERT_FIELD_NUMBER: _ClassVar[int] - SHAPE_FIELD_NUMBER: _ClassVar[int] - id: str - is_deleted: bool - trip_update: TripUpdate - vehicle: VehiclePosition - alert: Alert - shape: Shape - def __init__(self, id: _Optional[str] = ..., is_deleted: bool = ..., trip_update: _Optional[_Union[TripUpdate, _Mapping]] = ..., vehicle: _Optional[_Union[VehiclePosition, _Mapping]] = ..., alert: _Optional[_Union[Alert, _Mapping]] = ..., shape: _Optional[_Union[Shape, _Mapping]] = ...) -> None: ... - -class TripUpdate(_message.Message): - __slots__ = ("trip", "vehicle", "stop_time_update", "timestamp", "delay", "trip_properties") - Extensions: _python_message._ExtensionDict - class StopTimeEvent(_message.Message): - __slots__ = ("delay", "time", "uncertainty") - Extensions: _python_message._ExtensionDict - DELAY_FIELD_NUMBER: _ClassVar[int] - TIME_FIELD_NUMBER: _ClassVar[int] - UNCERTAINTY_FIELD_NUMBER: _ClassVar[int] - delay: int - time: int - uncertainty: int - def __init__(self, delay: _Optional[int] = ..., time: _Optional[int] = ..., uncertainty: _Optional[int] = ...) -> None: ... - class StopTimeUpdate(_message.Message): - __slots__ = ("stop_sequence", "stop_id", "arrival", "departure", "departure_occupancy_status", "schedule_relationship", "stop_time_properties") - Extensions: _python_message._ExtensionDict - class ScheduleRelationship(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - SCHEDULED: _ClassVar[TripUpdate.StopTimeUpdate.ScheduleRelationship] - SKIPPED: _ClassVar[TripUpdate.StopTimeUpdate.ScheduleRelationship] - NO_DATA: _ClassVar[TripUpdate.StopTimeUpdate.ScheduleRelationship] - UNSCHEDULED: _ClassVar[TripUpdate.StopTimeUpdate.ScheduleRelationship] - SCHEDULED: TripUpdate.StopTimeUpdate.ScheduleRelationship - SKIPPED: TripUpdate.StopTimeUpdate.ScheduleRelationship - NO_DATA: TripUpdate.StopTimeUpdate.ScheduleRelationship - UNSCHEDULED: TripUpdate.StopTimeUpdate.ScheduleRelationship - class StopTimeProperties(_message.Message): - __slots__ = ("assigned_stop_id",) - Extensions: _python_message._ExtensionDict - ASSIGNED_STOP_ID_FIELD_NUMBER: _ClassVar[int] - assigned_stop_id: str - def __init__(self, assigned_stop_id: _Optional[str] = ...) -> None: ... - STOP_SEQUENCE_FIELD_NUMBER: _ClassVar[int] - STOP_ID_FIELD_NUMBER: _ClassVar[int] - ARRIVAL_FIELD_NUMBER: _ClassVar[int] - DEPARTURE_FIELD_NUMBER: _ClassVar[int] - DEPARTURE_OCCUPANCY_STATUS_FIELD_NUMBER: _ClassVar[int] - SCHEDULE_RELATIONSHIP_FIELD_NUMBER: _ClassVar[int] - STOP_TIME_PROPERTIES_FIELD_NUMBER: _ClassVar[int] - stop_sequence: int - stop_id: str - arrival: TripUpdate.StopTimeEvent - departure: TripUpdate.StopTimeEvent - departure_occupancy_status: VehiclePosition.OccupancyStatus - schedule_relationship: TripUpdate.StopTimeUpdate.ScheduleRelationship - stop_time_properties: TripUpdate.StopTimeUpdate.StopTimeProperties - def __init__(self, stop_sequence: _Optional[int] = ..., stop_id: _Optional[str] = ..., arrival: _Optional[_Union[TripUpdate.StopTimeEvent, _Mapping]] = ..., departure: _Optional[_Union[TripUpdate.StopTimeEvent, _Mapping]] = ..., departure_occupancy_status: _Optional[_Union[VehiclePosition.OccupancyStatus, str]] = ..., schedule_relationship: _Optional[_Union[TripUpdate.StopTimeUpdate.ScheduleRelationship, str]] = ..., stop_time_properties: _Optional[_Union[TripUpdate.StopTimeUpdate.StopTimeProperties, _Mapping]] = ...) -> None: ... - class TripProperties(_message.Message): - __slots__ = ("trip_id", "start_date", "start_time", "shape_id") - Extensions: _python_message._ExtensionDict - TRIP_ID_FIELD_NUMBER: _ClassVar[int] - START_DATE_FIELD_NUMBER: _ClassVar[int] - START_TIME_FIELD_NUMBER: _ClassVar[int] - SHAPE_ID_FIELD_NUMBER: _ClassVar[int] - trip_id: str - start_date: str - start_time: str - shape_id: str - def __init__(self, trip_id: _Optional[str] = ..., start_date: _Optional[str] = ..., start_time: _Optional[str] = ..., shape_id: _Optional[str] = ...) -> None: ... - TRIP_FIELD_NUMBER: _ClassVar[int] - VEHICLE_FIELD_NUMBER: _ClassVar[int] - STOP_TIME_UPDATE_FIELD_NUMBER: _ClassVar[int] - TIMESTAMP_FIELD_NUMBER: _ClassVar[int] - DELAY_FIELD_NUMBER: _ClassVar[int] - TRIP_PROPERTIES_FIELD_NUMBER: _ClassVar[int] - trip: TripDescriptor - vehicle: VehicleDescriptor - stop_time_update: _containers.RepeatedCompositeFieldContainer[TripUpdate.StopTimeUpdate] - timestamp: int - delay: int - trip_properties: TripUpdate.TripProperties - def __init__(self, trip: _Optional[_Union[TripDescriptor, _Mapping]] = ..., vehicle: _Optional[_Union[VehicleDescriptor, _Mapping]] = ..., stop_time_update: _Optional[_Iterable[_Union[TripUpdate.StopTimeUpdate, _Mapping]]] = ..., timestamp: _Optional[int] = ..., delay: _Optional[int] = ..., trip_properties: _Optional[_Union[TripUpdate.TripProperties, _Mapping]] = ...) -> None: ... - -class VehiclePosition(_message.Message): - __slots__ = ("trip", "vehicle", "position", "current_stop_sequence", "stop_id", "current_status", "timestamp", "congestion_level", "occupancy_status", "occupancy_percentage", "multi_carriage_details") - Extensions: _python_message._ExtensionDict - class VehicleStopStatus(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - INCOMING_AT: _ClassVar[VehiclePosition.VehicleStopStatus] - STOPPED_AT: _ClassVar[VehiclePosition.VehicleStopStatus] - IN_TRANSIT_TO: _ClassVar[VehiclePosition.VehicleStopStatus] - INCOMING_AT: VehiclePosition.VehicleStopStatus - STOPPED_AT: VehiclePosition.VehicleStopStatus - IN_TRANSIT_TO: VehiclePosition.VehicleStopStatus - class CongestionLevel(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - UNKNOWN_CONGESTION_LEVEL: _ClassVar[VehiclePosition.CongestionLevel] - RUNNING_SMOOTHLY: _ClassVar[VehiclePosition.CongestionLevel] - STOP_AND_GO: _ClassVar[VehiclePosition.CongestionLevel] - CONGESTION: _ClassVar[VehiclePosition.CongestionLevel] - SEVERE_CONGESTION: _ClassVar[VehiclePosition.CongestionLevel] - UNKNOWN_CONGESTION_LEVEL: VehiclePosition.CongestionLevel - RUNNING_SMOOTHLY: VehiclePosition.CongestionLevel - STOP_AND_GO: VehiclePosition.CongestionLevel - CONGESTION: VehiclePosition.CongestionLevel - SEVERE_CONGESTION: VehiclePosition.CongestionLevel - class OccupancyStatus(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - EMPTY: _ClassVar[VehiclePosition.OccupancyStatus] - MANY_SEATS_AVAILABLE: _ClassVar[VehiclePosition.OccupancyStatus] - FEW_SEATS_AVAILABLE: _ClassVar[VehiclePosition.OccupancyStatus] - STANDING_ROOM_ONLY: _ClassVar[VehiclePosition.OccupancyStatus] - CRUSHED_STANDING_ROOM_ONLY: _ClassVar[VehiclePosition.OccupancyStatus] - FULL: _ClassVar[VehiclePosition.OccupancyStatus] - NOT_ACCEPTING_PASSENGERS: _ClassVar[VehiclePosition.OccupancyStatus] - NO_DATA_AVAILABLE: _ClassVar[VehiclePosition.OccupancyStatus] - NOT_BOARDABLE: _ClassVar[VehiclePosition.OccupancyStatus] - EMPTY: VehiclePosition.OccupancyStatus - MANY_SEATS_AVAILABLE: VehiclePosition.OccupancyStatus - FEW_SEATS_AVAILABLE: VehiclePosition.OccupancyStatus - STANDING_ROOM_ONLY: VehiclePosition.OccupancyStatus - CRUSHED_STANDING_ROOM_ONLY: VehiclePosition.OccupancyStatus - FULL: VehiclePosition.OccupancyStatus - NOT_ACCEPTING_PASSENGERS: VehiclePosition.OccupancyStatus - NO_DATA_AVAILABLE: VehiclePosition.OccupancyStatus - NOT_BOARDABLE: VehiclePosition.OccupancyStatus - class CarriageDetails(_message.Message): - __slots__ = ("id", "label", "occupancy_status", "occupancy_percentage", "carriage_sequence") - Extensions: _python_message._ExtensionDict - ID_FIELD_NUMBER: _ClassVar[int] - LABEL_FIELD_NUMBER: _ClassVar[int] - OCCUPANCY_STATUS_FIELD_NUMBER: _ClassVar[int] - OCCUPANCY_PERCENTAGE_FIELD_NUMBER: _ClassVar[int] - CARRIAGE_SEQUENCE_FIELD_NUMBER: _ClassVar[int] - id: str - label: str - occupancy_status: VehiclePosition.OccupancyStatus - occupancy_percentage: int - carriage_sequence: int - def __init__(self, id: _Optional[str] = ..., label: _Optional[str] = ..., occupancy_status: _Optional[_Union[VehiclePosition.OccupancyStatus, str]] = ..., occupancy_percentage: _Optional[int] = ..., carriage_sequence: _Optional[int] = ...) -> None: ... - TRIP_FIELD_NUMBER: _ClassVar[int] - VEHICLE_FIELD_NUMBER: _ClassVar[int] - POSITION_FIELD_NUMBER: _ClassVar[int] - CURRENT_STOP_SEQUENCE_FIELD_NUMBER: _ClassVar[int] - STOP_ID_FIELD_NUMBER: _ClassVar[int] - CURRENT_STATUS_FIELD_NUMBER: _ClassVar[int] - TIMESTAMP_FIELD_NUMBER: _ClassVar[int] - CONGESTION_LEVEL_FIELD_NUMBER: _ClassVar[int] - OCCUPANCY_STATUS_FIELD_NUMBER: _ClassVar[int] - OCCUPANCY_PERCENTAGE_FIELD_NUMBER: _ClassVar[int] - MULTI_CARRIAGE_DETAILS_FIELD_NUMBER: _ClassVar[int] - trip: TripDescriptor - vehicle: VehicleDescriptor - position: Position - current_stop_sequence: int - stop_id: str - current_status: VehiclePosition.VehicleStopStatus - timestamp: int - congestion_level: VehiclePosition.CongestionLevel - occupancy_status: VehiclePosition.OccupancyStatus - occupancy_percentage: int - multi_carriage_details: _containers.RepeatedCompositeFieldContainer[VehiclePosition.CarriageDetails] - def __init__(self, trip: _Optional[_Union[TripDescriptor, _Mapping]] = ..., vehicle: _Optional[_Union[VehicleDescriptor, _Mapping]] = ..., position: _Optional[_Union[Position, _Mapping]] = ..., current_stop_sequence: _Optional[int] = ..., stop_id: _Optional[str] = ..., current_status: _Optional[_Union[VehiclePosition.VehicleStopStatus, str]] = ..., timestamp: _Optional[int] = ..., congestion_level: _Optional[_Union[VehiclePosition.CongestionLevel, str]] = ..., occupancy_status: _Optional[_Union[VehiclePosition.OccupancyStatus, str]] = ..., occupancy_percentage: _Optional[int] = ..., multi_carriage_details: _Optional[_Iterable[_Union[VehiclePosition.CarriageDetails, _Mapping]]] = ...) -> None: ... - -class Alert(_message.Message): - __slots__ = ("active_period", "informed_entity", "cause", "effect", "url", "header_text", "description_text", "tts_header_text", "tts_description_text", "severity_level", "image", "image_alternative_text", "cause_detail", "effect_detail") - Extensions: _python_message._ExtensionDict - class Cause(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - UNKNOWN_CAUSE: _ClassVar[Alert.Cause] - OTHER_CAUSE: _ClassVar[Alert.Cause] - TECHNICAL_PROBLEM: _ClassVar[Alert.Cause] - STRIKE: _ClassVar[Alert.Cause] - DEMONSTRATION: _ClassVar[Alert.Cause] - ACCIDENT: _ClassVar[Alert.Cause] - HOLIDAY: _ClassVar[Alert.Cause] - WEATHER: _ClassVar[Alert.Cause] - MAINTENANCE: _ClassVar[Alert.Cause] - CONSTRUCTION: _ClassVar[Alert.Cause] - POLICE_ACTIVITY: _ClassVar[Alert.Cause] - MEDICAL_EMERGENCY: _ClassVar[Alert.Cause] - UNKNOWN_CAUSE: Alert.Cause - OTHER_CAUSE: Alert.Cause - TECHNICAL_PROBLEM: Alert.Cause - STRIKE: Alert.Cause - DEMONSTRATION: Alert.Cause - ACCIDENT: Alert.Cause - HOLIDAY: Alert.Cause - WEATHER: Alert.Cause - MAINTENANCE: Alert.Cause - CONSTRUCTION: Alert.Cause - POLICE_ACTIVITY: Alert.Cause - MEDICAL_EMERGENCY: Alert.Cause - class Effect(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - NO_SERVICE: _ClassVar[Alert.Effect] - REDUCED_SERVICE: _ClassVar[Alert.Effect] - SIGNIFICANT_DELAYS: _ClassVar[Alert.Effect] - DETOUR: _ClassVar[Alert.Effect] - ADDITIONAL_SERVICE: _ClassVar[Alert.Effect] - MODIFIED_SERVICE: _ClassVar[Alert.Effect] - OTHER_EFFECT: _ClassVar[Alert.Effect] - UNKNOWN_EFFECT: _ClassVar[Alert.Effect] - STOP_MOVED: _ClassVar[Alert.Effect] - NO_EFFECT: _ClassVar[Alert.Effect] - ACCESSIBILITY_ISSUE: _ClassVar[Alert.Effect] - NO_SERVICE: Alert.Effect - REDUCED_SERVICE: Alert.Effect - SIGNIFICANT_DELAYS: Alert.Effect - DETOUR: Alert.Effect - ADDITIONAL_SERVICE: Alert.Effect - MODIFIED_SERVICE: Alert.Effect - OTHER_EFFECT: Alert.Effect - UNKNOWN_EFFECT: Alert.Effect - STOP_MOVED: Alert.Effect - NO_EFFECT: Alert.Effect - ACCESSIBILITY_ISSUE: Alert.Effect - class SeverityLevel(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - UNKNOWN_SEVERITY: _ClassVar[Alert.SeverityLevel] - INFO: _ClassVar[Alert.SeverityLevel] - WARNING: _ClassVar[Alert.SeverityLevel] - SEVERE: _ClassVar[Alert.SeverityLevel] - UNKNOWN_SEVERITY: Alert.SeverityLevel - INFO: Alert.SeverityLevel - WARNING: Alert.SeverityLevel - SEVERE: Alert.SeverityLevel - ACTIVE_PERIOD_FIELD_NUMBER: _ClassVar[int] - INFORMED_ENTITY_FIELD_NUMBER: _ClassVar[int] - CAUSE_FIELD_NUMBER: _ClassVar[int] - EFFECT_FIELD_NUMBER: _ClassVar[int] - URL_FIELD_NUMBER: _ClassVar[int] - HEADER_TEXT_FIELD_NUMBER: _ClassVar[int] - DESCRIPTION_TEXT_FIELD_NUMBER: _ClassVar[int] - TTS_HEADER_TEXT_FIELD_NUMBER: _ClassVar[int] - TTS_DESCRIPTION_TEXT_FIELD_NUMBER: _ClassVar[int] - SEVERITY_LEVEL_FIELD_NUMBER: _ClassVar[int] - IMAGE_FIELD_NUMBER: _ClassVar[int] - IMAGE_ALTERNATIVE_TEXT_FIELD_NUMBER: _ClassVar[int] - CAUSE_DETAIL_FIELD_NUMBER: _ClassVar[int] - EFFECT_DETAIL_FIELD_NUMBER: _ClassVar[int] - active_period: _containers.RepeatedCompositeFieldContainer[TimeRange] - informed_entity: _containers.RepeatedCompositeFieldContainer[EntitySelector] - cause: Alert.Cause - effect: Alert.Effect - url: TranslatedString - header_text: TranslatedString - description_text: TranslatedString - tts_header_text: TranslatedString - tts_description_text: TranslatedString - severity_level: Alert.SeverityLevel - image: TranslatedImage - image_alternative_text: TranslatedString - cause_detail: TranslatedString - effect_detail: TranslatedString - def __init__(self, active_period: _Optional[_Iterable[_Union[TimeRange, _Mapping]]] = ..., informed_entity: _Optional[_Iterable[_Union[EntitySelector, _Mapping]]] = ..., cause: _Optional[_Union[Alert.Cause, str]] = ..., effect: _Optional[_Union[Alert.Effect, str]] = ..., url: _Optional[_Union[TranslatedString, _Mapping]] = ..., header_text: _Optional[_Union[TranslatedString, _Mapping]] = ..., description_text: _Optional[_Union[TranslatedString, _Mapping]] = ..., tts_header_text: _Optional[_Union[TranslatedString, _Mapping]] = ..., tts_description_text: _Optional[_Union[TranslatedString, _Mapping]] = ..., severity_level: _Optional[_Union[Alert.SeverityLevel, str]] = ..., image: _Optional[_Union[TranslatedImage, _Mapping]] = ..., image_alternative_text: _Optional[_Union[TranslatedString, _Mapping]] = ..., cause_detail: _Optional[_Union[TranslatedString, _Mapping]] = ..., effect_detail: _Optional[_Union[TranslatedString, _Mapping]] = ...) -> None: ... - -class TimeRange(_message.Message): - __slots__ = ("start", "end") - Extensions: _python_message._ExtensionDict - START_FIELD_NUMBER: _ClassVar[int] - END_FIELD_NUMBER: _ClassVar[int] - start: int - end: int - def __init__(self, start: _Optional[int] = ..., end: _Optional[int] = ...) -> None: ... - -class Position(_message.Message): - __slots__ = ("latitude", "longitude", "bearing", "odometer", "speed") - Extensions: _python_message._ExtensionDict - LATITUDE_FIELD_NUMBER: _ClassVar[int] - LONGITUDE_FIELD_NUMBER: _ClassVar[int] - BEARING_FIELD_NUMBER: _ClassVar[int] - ODOMETER_FIELD_NUMBER: _ClassVar[int] - SPEED_FIELD_NUMBER: _ClassVar[int] - latitude: float - longitude: float - bearing: float - odometer: float - speed: float - def __init__(self, latitude: _Optional[float] = ..., longitude: _Optional[float] = ..., bearing: _Optional[float] = ..., odometer: _Optional[float] = ..., speed: _Optional[float] = ...) -> None: ... - -class TripDescriptor(_message.Message): - __slots__ = ("trip_id", "route_id", "direction_id", "start_time", "start_date", "schedule_relationship") - Extensions: _python_message._ExtensionDict - class ScheduleRelationship(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - SCHEDULED: _ClassVar[TripDescriptor.ScheduleRelationship] - ADDED: _ClassVar[TripDescriptor.ScheduleRelationship] - UNSCHEDULED: _ClassVar[TripDescriptor.ScheduleRelationship] - CANCELED: _ClassVar[TripDescriptor.ScheduleRelationship] - REPLACEMENT: _ClassVar[TripDescriptor.ScheduleRelationship] - DUPLICATED: _ClassVar[TripDescriptor.ScheduleRelationship] - DELETED: _ClassVar[TripDescriptor.ScheduleRelationship] - SCHEDULED: TripDescriptor.ScheduleRelationship - ADDED: TripDescriptor.ScheduleRelationship - UNSCHEDULED: TripDescriptor.ScheduleRelationship - CANCELED: TripDescriptor.ScheduleRelationship - REPLACEMENT: TripDescriptor.ScheduleRelationship - DUPLICATED: TripDescriptor.ScheduleRelationship - DELETED: TripDescriptor.ScheduleRelationship - TRIP_ID_FIELD_NUMBER: _ClassVar[int] - ROUTE_ID_FIELD_NUMBER: _ClassVar[int] - DIRECTION_ID_FIELD_NUMBER: _ClassVar[int] - START_TIME_FIELD_NUMBER: _ClassVar[int] - START_DATE_FIELD_NUMBER: _ClassVar[int] - SCHEDULE_RELATIONSHIP_FIELD_NUMBER: _ClassVar[int] - trip_id: str - route_id: str - direction_id: int - start_time: str - start_date: str - schedule_relationship: TripDescriptor.ScheduleRelationship - def __init__(self, trip_id: _Optional[str] = ..., route_id: _Optional[str] = ..., direction_id: _Optional[int] = ..., start_time: _Optional[str] = ..., start_date: _Optional[str] = ..., schedule_relationship: _Optional[_Union[TripDescriptor.ScheduleRelationship, str]] = ...) -> None: ... - -class VehicleDescriptor(_message.Message): - __slots__ = ("id", "label", "license_plate", "wheelchair_accessible") - Extensions: _python_message._ExtensionDict - class WheelchairAccessible(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - NO_VALUE: _ClassVar[VehicleDescriptor.WheelchairAccessible] - UNKNOWN: _ClassVar[VehicleDescriptor.WheelchairAccessible] - WHEELCHAIR_ACCESSIBLE: _ClassVar[VehicleDescriptor.WheelchairAccessible] - WHEELCHAIR_INACCESSIBLE: _ClassVar[VehicleDescriptor.WheelchairAccessible] - NO_VALUE: VehicleDescriptor.WheelchairAccessible - UNKNOWN: VehicleDescriptor.WheelchairAccessible - WHEELCHAIR_ACCESSIBLE: VehicleDescriptor.WheelchairAccessible - WHEELCHAIR_INACCESSIBLE: VehicleDescriptor.WheelchairAccessible - ID_FIELD_NUMBER: _ClassVar[int] - LABEL_FIELD_NUMBER: _ClassVar[int] - LICENSE_PLATE_FIELD_NUMBER: _ClassVar[int] - WHEELCHAIR_ACCESSIBLE_FIELD_NUMBER: _ClassVar[int] - id: str - label: str - license_plate: str - wheelchair_accessible: VehicleDescriptor.WheelchairAccessible - def __init__(self, id: _Optional[str] = ..., label: _Optional[str] = ..., license_plate: _Optional[str] = ..., wheelchair_accessible: _Optional[_Union[VehicleDescriptor.WheelchairAccessible, str]] = ...) -> None: ... - -class EntitySelector(_message.Message): - __slots__ = ("agency_id", "route_id", "route_type", "trip", "stop_id", "direction_id") - Extensions: _python_message._ExtensionDict - AGENCY_ID_FIELD_NUMBER: _ClassVar[int] - ROUTE_ID_FIELD_NUMBER: _ClassVar[int] - ROUTE_TYPE_FIELD_NUMBER: _ClassVar[int] - TRIP_FIELD_NUMBER: _ClassVar[int] - STOP_ID_FIELD_NUMBER: _ClassVar[int] - DIRECTION_ID_FIELD_NUMBER: _ClassVar[int] - agency_id: str - route_id: str - route_type: int - trip: TripDescriptor - stop_id: str - direction_id: int - def __init__(self, agency_id: _Optional[str] = ..., route_id: _Optional[str] = ..., route_type: _Optional[int] = ..., trip: _Optional[_Union[TripDescriptor, _Mapping]] = ..., stop_id: _Optional[str] = ..., direction_id: _Optional[int] = ...) -> None: ... - -class TranslatedString(_message.Message): - __slots__ = ("translation",) - Extensions: _python_message._ExtensionDict - class Translation(_message.Message): - __slots__ = ("text", "language") - Extensions: _python_message._ExtensionDict - TEXT_FIELD_NUMBER: _ClassVar[int] - LANGUAGE_FIELD_NUMBER: _ClassVar[int] - text: str - language: str - def __init__(self, text: _Optional[str] = ..., language: _Optional[str] = ...) -> None: ... - TRANSLATION_FIELD_NUMBER: _ClassVar[int] - translation: _containers.RepeatedCompositeFieldContainer[TranslatedString.Translation] - def __init__(self, translation: _Optional[_Iterable[_Union[TranslatedString.Translation, _Mapping]]] = ...) -> None: ... - -class TranslatedImage(_message.Message): - __slots__ = ("localized_image",) - Extensions: _python_message._ExtensionDict - class LocalizedImage(_message.Message): - __slots__ = ("url", "media_type", "language") - Extensions: _python_message._ExtensionDict - URL_FIELD_NUMBER: _ClassVar[int] - MEDIA_TYPE_FIELD_NUMBER: _ClassVar[int] - LANGUAGE_FIELD_NUMBER: _ClassVar[int] - url: str - media_type: str - language: str - def __init__(self, url: _Optional[str] = ..., media_type: _Optional[str] = ..., language: _Optional[str] = ...) -> None: ... - LOCALIZED_IMAGE_FIELD_NUMBER: _ClassVar[int] - localized_image: _containers.RepeatedCompositeFieldContainer[TranslatedImage.LocalizedImage] - def __init__(self, localized_image: _Optional[_Iterable[_Union[TranslatedImage.LocalizedImage, _Mapping]]] = ...) -> None: ... - -class Shape(_message.Message): - __slots__ = ("shape_id", "encoded_polyline") - Extensions: _python_message._ExtensionDict - SHAPE_ID_FIELD_NUMBER: _ClassVar[int] - ENCODED_POLYLINE_FIELD_NUMBER: _ClassVar[int] - shape_id: str - encoded_polyline: str - def __init__(self, shape_id: _Optional[str] = ..., encoded_polyline: _Optional[str] = ...) -> None: ... diff --git a/trainvel/gtfs/locale/fr/LC_MESSAGES/django.po b/trainvel/gtfs/locale/fr/LC_MESSAGES/django.po deleted file mode 100644 index e1cf0a9..0000000 --- a/trainvel/gtfs/locale/fr/LC_MESSAGES/django.po +++ /dev/null @@ -1,825 +0,0 @@ -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 \n" -"Language-Team: LANGUAGE \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/gtfs/apps.py:8 -msgid "Trainvel - GTFS" -msgstr "Trainvel - GTFS" - -#: trainvel/gtfs/models.py:11 -msgid "Albania" -msgstr "Albanie" - -#: trainvel/gtfs/models.py:12 -msgid "Andorra" -msgstr "Andorre" - -#: trainvel/gtfs/models.py:13 -msgid "Armenia" -msgstr "Arménie" - -#: trainvel/gtfs/models.py:14 -msgid "Austria" -msgstr "Autriche" - -#: trainvel/gtfs/models.py:15 -msgid "Azerbaijan" -msgstr "Azerbaijan" - -#: trainvel/gtfs/models.py:16 -msgid "Belgium" -msgstr "Belgique" - -#: trainvel/gtfs/models.py:17 -msgid "Bosnia and Herzegovina" -msgstr " Bosnie-Herzégovine" - -#: trainvel/gtfs/models.py:18 -msgid "Bulgaria" -msgstr "Bulgarie" - -#: trainvel/gtfs/models.py:19 -msgid "Croatia" -msgstr "Croatie" - -#: trainvel/gtfs/models.py:20 -msgid "Cyprus" -msgstr "Chypre" - -#: trainvel/gtfs/models.py:21 -msgid "Czech Republic" -msgstr "République Tchèque" - -#: trainvel/gtfs/models.py:22 -msgid "Denmark" -msgstr "Danemark" - -#: trainvel/gtfs/models.py:23 -msgid "Estonia" -msgstr "Estonie" - -#: trainvel/gtfs/models.py:24 -msgid "Finland" -msgstr "Finlande" - -#: trainvel/gtfs/models.py:25 -msgid "France" -msgstr "France" - -#: trainvel/gtfs/models.py:26 -msgid "Georgia" -msgstr "Géorgie" - -#: trainvel/gtfs/models.py:27 -msgid "Germany" -msgstr "Allemagne" - -#: trainvel/gtfs/models.py:28 -msgid "Greece" -msgstr "Grèce" - -#: trainvel/gtfs/models.py:29 -msgid "Hungary" -msgstr "Hongrie" - -#: trainvel/gtfs/models.py:30 -msgid "Iceland" -msgstr "Islande" - -#: trainvel/gtfs/models.py:31 -msgid "Ireland" -msgstr "Irlande" - -#: trainvel/gtfs/models.py:32 -msgid "Italy" -msgstr "Italie" - -#: trainvel/gtfs/models.py:33 -msgid "Latvia" -msgstr "Lettonie" - -#: trainvel/gtfs/models.py:34 -msgid "Liechtenstein" -msgstr "Liechtenstein" - -#: trainvel/gtfs/models.py:35 -msgid "Lithuania" -msgstr "Lituanie" - -#: trainvel/gtfs/models.py:36 -msgid "Luxembourg" -msgstr "Luxembourg" - -#: trainvel/gtfs/models.py:37 -msgid "Malta" -msgstr "Malte" - -#: trainvel/gtfs/models.py:38 -msgid "Moldova" -msgstr "Moldavie" - -#: trainvel/gtfs/models.py:39 -msgid "Monaco" -msgstr "Monaco" - -#: trainvel/gtfs/models.py:40 -msgid "Montenegro" -msgstr "Monténégro" - -#: trainvel/gtfs/models.py:41 -msgid "Netherlands" -msgstr "Pays-Bas" - -#: trainvel/gtfs/models.py:42 -msgid "North Macedonia" -msgstr "Macédoine du Nord" - -#: trainvel/gtfs/models.py:43 -msgid "Norway" -msgstr "Norvège" - -#: trainvel/gtfs/models.py:44 -msgid "Poland" -msgstr "Pologne" - -#: trainvel/gtfs/models.py:45 -msgid "Portugal" -msgstr "Portugal" - -#: trainvel/gtfs/models.py:46 -msgid "Romania" -msgstr "Roumanie" - -#: trainvel/gtfs/models.py:47 -msgid "San Marino" -msgstr "Saint-Marin" - -#: trainvel/gtfs/models.py:48 -msgid "Serbia" -msgstr "Serbie" - -#: trainvel/gtfs/models.py:49 -msgid "Slovakia" -msgstr "Slovaquie" - -#: trainvel/gtfs/models.py:50 -msgid "Slovenia" -msgstr "Slovénie" - -#: trainvel/gtfs/models.py:51 -msgid "Spain" -msgstr "Espagne" - -#: trainvel/gtfs/models.py:52 -msgid "Sweden" -msgstr "Suède" - -#: trainvel/gtfs/models.py:53 -msgid "Switzerland" -msgstr "Suisse" - -#: trainvel/gtfs/models.py:54 -msgid "Turkey" -msgstr "Turquie" - -#: trainvel/gtfs/models.py:55 -msgid "United Kingdom" -msgstr "Royaume-Uni" - -#: trainvel/gtfs/models.py:56 -msgid "Ukraine" -msgstr "Ukraine" - -#: trainvel/gtfs/models.py:60 -msgid "Stop/platform" -msgstr "Arrêt / quai" - -#: trainvel/gtfs/models.py:61 -msgid "Station" -msgstr "Gare" - -#: trainvel/gtfs/models.py:62 -msgid "Entrance/exit" -msgstr "Entrée / sortie" - -#: trainvel/gtfs/models.py:63 -msgid "Generic node" -msgstr "Nœud générique" - -#: trainvel/gtfs/models.py:64 -msgid "Boarding area" -msgstr "Zone d'embarquement" - -#: trainvel/gtfs/models.py:68 -msgid "No information" -msgstr "Pas d'information" - -#: trainvel/gtfs/models.py:69 -msgid "Possible" -msgstr "Possible" - -#: trainvel/gtfs/models.py:70 trainvel/gtfs/models.py:100 -msgid "Not possible" -msgstr "Impossible" - -#: trainvel/gtfs/models.py:74 -msgid "Regular" -msgstr "Régulier" - -#: trainvel/gtfs/models.py:75 -msgid "None" -msgstr "Aucun" - -#: trainvel/gtfs/models.py:76 -msgid "Must phone agency" -msgstr "Doit téléphoner à l'agence" - -#: trainvel/gtfs/models.py:77 -msgid "Must coordinate with driver" -msgstr "Doit se coordonner avec læ conducteurice" - -#: trainvel/gtfs/models.py:81 -msgid "Tram" -msgstr "Tram" - -#: trainvel/gtfs/models.py:82 -msgid "Metro" -msgstr "Métro" - -#: trainvel/gtfs/models.py:83 -msgid "Rail" -msgstr "Rail" - -#: trainvel/gtfs/models.py:84 -msgid "Bus" -msgstr "Bus" - -#: trainvel/gtfs/models.py:85 -msgid "Ferry" -msgstr "Ferry" - -#: trainvel/gtfs/models.py:86 -msgid "Cable car" -msgstr "Câble" - -#: trainvel/gtfs/models.py:87 -msgid "Gondola" -msgstr "Gondole" - -#: trainvel/gtfs/models.py:88 -msgid "Funicular" -msgstr "Funiculaire" - -#: trainvel/gtfs/models.py:92 -msgid "Outbound" -msgstr "Vers l'extérieur" - -#: trainvel/gtfs/models.py:93 -msgid "Inbound" -msgstr "Vers l'intérieur" - -#: trainvel/gtfs/models.py:97 -msgid "Recommended" -msgstr "Recommandé" - -#: trainvel/gtfs/models.py:98 -msgid "Timed" -msgstr "Correspondance programmée" - -#: trainvel/gtfs/models.py:99 -msgid "Minimum time" -msgstr "Temps de correspondance minimum requis" - -#: trainvel/gtfs/models.py:104 trainvel/gtfs/models.py:110 -msgid "Added" -msgstr "Ajouté" - -#: trainvel/gtfs/models.py:105 -msgid "Removed" -msgstr "Supprimé" - -#: trainvel/gtfs/models.py:109 trainvel/gtfs/models.py:119 -msgid "Scheduled" -msgstr "Planifié" - -#: trainvel/gtfs/models.py:111 trainvel/gtfs/models.py:122 -msgid "Unscheduled" -msgstr "Non planifié" - -#: trainvel/gtfs/models.py:112 -msgid "Canceled" -msgstr "Annulé" - -#: trainvel/gtfs/models.py:113 -msgid "Replacement" -msgstr "Remplacé" - -#: trainvel/gtfs/models.py:114 -msgid "Duplicated" -msgstr "Dupliqué" - -#: trainvel/gtfs/models.py:115 -msgid "Deleted" -msgstr "Supprimé" - -#: trainvel/gtfs/models.py:120 -msgid "Skipped" -msgstr "Sauté" - -#: trainvel/gtfs/models.py:121 -msgid "No data" -msgstr "Pas de données" - -#: trainvel/gtfs/models.py:129 -msgid "code" -msgstr "code" - -#: trainvel/gtfs/models.py:130 -msgid "Unique code of the feed." -msgstr "Code unique du flux." - -#: trainvel/gtfs/models.py:135 -msgid "name" -msgstr "nom" - -#: trainvel/gtfs/models.py:137 -msgid "Full name that describes the feed." -msgstr "Nom complet qui décrit le flux." - -#: trainvel/gtfs/models.py:142 -msgid "country" -msgstr "pays" - -#: trainvel/gtfs/models.py:147 -msgid "feed URL" -msgstr "URL du flux" - -#: trainvel/gtfs/models.py:148 -msgid "" -"URL to download the GTFS feed. Must point to a ZIP archive. See https://gtfs." -"org/schedule/ for more information." -msgstr "" -"URL où télécharger le flux GTFS. Doit pointer vers une archive ZIP. Voir " -"https://gtfs.org/fr/schedule/ pour plus d'informations." - -#: trainvel/gtfs/models.py:153 -msgid "realtime feed URL" -msgstr "URL du flux temps réel" - -#: trainvel/gtfs/models.py:156 -msgid "" -"URL to download the GTFS-Realtime feed, in the GTFS-RT format. See https://" -"gtfs.org/realtime/ for more information." -msgstr "" -"URL où télécharger le flux GTFS-Temps réel, au format GTFS-RT. Voir https://" -"gtfs.org/fr/realtime/ pour plus d'informations." - -#: trainvel/gtfs/models.py:161 -msgid "last modified date" -msgstr "Date de dernière modification" - -#: trainvel/gtfs/models.py:168 -msgid "ETag" -msgstr "ETag" - -#: trainvel/gtfs/models.py:171 -msgid "" -"If applicable, corresponds to the tag of the last downloaded file. If it is " -"not modified, the file is the same." -msgstr "" -"Si applicable, correspond au tag du dernier fichier téléchargé. S'il n'est " -"pas modifié, le fichier est considéré comme identique." - -#: trainvel/gtfs/models.py:179 trainvel/gtfs/models.py:226 -#: trainvel/gtfs/models.py:326 trainvel/gtfs/models.py:405 -#: trainvel/gtfs/models.py:486 trainvel/gtfs/models.py:696 -#: trainvel/gtfs/models.py:811 -msgid "GTFS feed" -msgstr "flux GTFS" - -#: trainvel/gtfs/models.py:180 -msgid "GTFS feeds" -msgstr "flux GTFS" - -#: trainvel/gtfs/models.py:189 -msgid "Agency ID" -msgstr "ID de l'agence" - -#: trainvel/gtfs/models.py:194 -msgid "Agency name" -msgstr "Nom de l'agence" - -#: trainvel/gtfs/models.py:198 -msgid "Agency URL" -msgstr "URL de l'agence" - -#: trainvel/gtfs/models.py:203 -msgid "Agency timezone" -msgstr "Fuseau horaire de l'agence" - -#: trainvel/gtfs/models.py:208 -msgid "Agency language" -msgstr "Langue de l'agence" - -#: trainvel/gtfs/models.py:214 -msgid "Agency phone" -msgstr "Téléphone de l'agence" - -#: trainvel/gtfs/models.py:219 -msgid "Agency email" -msgstr "Adresse email de l'agence" - -#: trainvel/gtfs/models.py:233 trainvel/gtfs/models.py:356 -msgid "Agency" -msgstr "Agence" - -#: trainvel/gtfs/models.py:234 -msgid "Agencies" -msgstr "Agences" - -#: trainvel/gtfs/models.py:243 trainvel/gtfs/models.py:593 -msgid "Stop ID" -msgstr "ID de l'arrêt" - -#: trainvel/gtfs/models.py:248 -msgid "Stop code" -msgstr "Code de l'arrêt" - -#: trainvel/gtfs/models.py:254 -msgid "Stop name" -msgstr "Nom de l'arrêt" - -#: trainvel/gtfs/models.py:259 -msgid "Stop description" -msgstr "Description de l'arrêt" - -#: trainvel/gtfs/models.py:264 -msgid "Stop longitude" -msgstr "Longitude de l'arrêt" - -#: trainvel/gtfs/models.py:268 -msgid "Stop latitude" -msgstr "Latitude de l'arrêt" - -#: trainvel/gtfs/models.py:273 -msgid "Zone ID" -msgstr "ID de la zone" - -#: trainvel/gtfs/models.py:278 -msgid "Stop URL" -msgstr "URL de l'arrêt" - -#: trainvel/gtfs/models.py:283 -msgid "Location type" -msgstr "Type de localisation" - -#: trainvel/gtfs/models.py:292 -msgid "Parent station" -msgstr "Gare parente" - -#: trainvel/gtfs/models.py:300 -msgid "Stop timezone" -msgstr "Fuseau horaire de l'arrêt" - -#: trainvel/gtfs/models.py:306 -msgid "Level ID" -msgstr "ID du niveau" - -#: trainvel/gtfs/models.py:311 -msgid "Wheelchair boarding" -msgstr "Embarquement en fauteuil roulant" - -#: trainvel/gtfs/models.py:319 -msgid "Platform code" -msgstr "Code du quai" - -#: trainvel/gtfs/models.py:338 -msgid "Stop" -msgstr "Arrêt" - -#: trainvel/gtfs/models.py:339 -msgid "Stops" -msgstr "Arrêts" - -#: trainvel/gtfs/models.py:350 trainvel/gtfs/models.py:572 -#: trainvel/gtfs/models.py:713 trainvel/gtfs/models.py:746 -msgid "ID" -msgstr "Identifiant" - -#: trainvel/gtfs/models.py:365 -msgid "Route short name" -msgstr "Nom court de la ligne" - -#: trainvel/gtfs/models.py:370 -msgid "Route long name" -msgstr "Nom long de la ligne" - -#: trainvel/gtfs/models.py:376 -msgid "Route description" -msgstr "Description de la ligne" - -#: trainvel/gtfs/models.py:381 -msgid "Route type" -msgstr "Type de ligne" - -#: trainvel/gtfs/models.py:386 -msgid "Route URL" -msgstr "URL de la ligne" - -#: trainvel/gtfs/models.py:392 -msgid "Route color" -msgstr "Couleur de la ligne" - -#: trainvel/gtfs/models.py:398 -msgid "Route text color" -msgstr "Couleur du texte de la ligne" - -#: trainvel/gtfs/models.py:412 trainvel/gtfs/models.py:428 -msgid "Route" -msgstr "Ligne" - -#: trainvel/gtfs/models.py:413 -msgid "Routes" -msgstr "Lignes" - -#: trainvel/gtfs/models.py:422 -msgid "Trip ID" -msgstr "ID du trajet" - -#: trainvel/gtfs/models.py:435 trainvel/gtfs/models.py:719 -msgid "Service" -msgstr "Service" - -#: trainvel/gtfs/models.py:441 -msgid "Trip headsign" -msgstr "Destination du trajet" - -#: trainvel/gtfs/models.py:447 -msgid "Trip short name" -msgstr "Nom court du trajet" - -#: trainvel/gtfs/models.py:452 -msgid "Direction" -msgstr "Direction" - -#: trainvel/gtfs/models.py:459 -msgid "Block ID" -msgstr "ID du bloc" - -#: trainvel/gtfs/models.py:465 -msgid "Shape ID" -msgstr "ID de la forme" - -#: trainvel/gtfs/models.py:470 -msgid "Wheelchair accessible" -msgstr "Accessible en fauteuil roulant" - -#: trainvel/gtfs/models.py:477 -msgid "Bikes allowed" -msgstr "Vélos autorisés" - -#: trainvel/gtfs/models.py:500 trainvel/gtfs/models.py:509 -#: trainvel/gtfs/models.py:552 trainvel/gtfs/models.py:554 -msgid "Unknown" -msgstr "Inconnu" - -#: trainvel/gtfs/models.py:557 -msgid "Origin → Destination" -msgstr "Origine → Destination" - -#: trainvel/gtfs/models.py:563 trainvel/gtfs/models.py:578 -#: trainvel/gtfs/models.py:825 -msgid "Trip" -msgstr "Trajet" - -#: trainvel/gtfs/models.py:564 -msgid "Trips" -msgstr "Trajets" - -#: trainvel/gtfs/models.py:583 trainvel/gtfs/models.py:876 -msgid "Arrival time" -msgstr "Heure d'arrivée" - -#: trainvel/gtfs/models.py:587 trainvel/gtfs/models.py:884 -msgid "Departure time" -msgstr "Heure de départ" - -#: trainvel/gtfs/models.py:598 -msgid "Stop sequence" -msgstr "Séquence de l'arrêt" - -#: trainvel/gtfs/models.py:603 -msgid "Stop headsign" -msgstr "Destination de l'arrêt" - -#: trainvel/gtfs/models.py:608 -msgid "Pickup type" -msgstr "Type de prise en charge" - -#: trainvel/gtfs/models.py:615 -msgid "Drop off type" -msgstr "Type de dépose" - -#: trainvel/gtfs/models.py:622 -msgid "Timepoint" -msgstr "Ponctualité" - -#: trainvel/gtfs/models.py:645 trainvel/gtfs/models.py:866 -msgid "Stop time" -msgstr "Heure d'arrêt" - -#: trainvel/gtfs/models.py:646 -msgid "Stop times" -msgstr "Heures d'arrêt" - -#: trainvel/gtfs/models.py:654 -msgid "Service ID" -msgstr "ID du service" - -#: trainvel/gtfs/models.py:658 -msgid "Monday" -msgstr "Lundi" - -#: trainvel/gtfs/models.py:662 -msgid "Tuesday" -msgstr "Mardi" - -#: trainvel/gtfs/models.py:666 -msgid "Wednesday" -msgstr "Mercredi" - -#: trainvel/gtfs/models.py:670 -msgid "Thursday" -msgstr "Jeudi" - -#: trainvel/gtfs/models.py:674 -msgid "Friday" -msgstr "Vendredi" - -#: trainvel/gtfs/models.py:678 -msgid "Saturday" -msgstr "Samedi" - -#: trainvel/gtfs/models.py:682 -msgid "Sunday" -msgstr "Dimanche" - -#: trainvel/gtfs/models.py:686 trainvel/gtfs/models.py:831 -msgid "Start date" -msgstr "Date de début" - -#: trainvel/gtfs/models.py:690 -msgid "End date" -msgstr "Date de fin" - -#: trainvel/gtfs/models.py:703 -msgid "Calendar" -msgstr "Calendrier" - -#: trainvel/gtfs/models.py:704 -msgid "Calendars" -msgstr "Calendriers" - -#: trainvel/gtfs/models.py:724 -msgid "Date" -msgstr "Date" - -#: trainvel/gtfs/models.py:728 -msgid "Exception type" -msgstr "Type d'exception" - -#: trainvel/gtfs/models.py:736 -msgid "Calendar date" -msgstr "Date du calendrier" - -#: trainvel/gtfs/models.py:737 -msgid "Calendar dates" -msgstr "Dates du calendrier" - -#: trainvel/gtfs/models.py:752 -msgid "From stop" -msgstr "Depuis l'arrêt" - -#: trainvel/gtfs/models.py:759 -msgid "To stop" -msgstr "Jusqu'à l'arrêt" - -#: trainvel/gtfs/models.py:764 -msgid "Transfer type" -msgstr "Type de correspondance" - -#: trainvel/gtfs/models.py:770 -msgid "Minimum transfer time" -msgstr "Temps de correspondance minimum" - -#: trainvel/gtfs/models.py:775 -msgid "Transfer" -msgstr "Correspondance" - -#: trainvel/gtfs/models.py:776 -msgid "Transfers" -msgstr "Correspondances" - -#: trainvel/gtfs/models.py:783 -msgid "Feed publisher name" -msgstr "Nom de l'éditeur du flux" - -#: trainvel/gtfs/models.py:787 -msgid "Feed publisher URL" -msgstr "URL de l'éditeur du flux" - -#: trainvel/gtfs/models.py:792 -msgid "Feed language" -msgstr "Langue du flux" - -#: trainvel/gtfs/models.py:796 -msgid "Feed start date" -msgstr "Date de début du flux" - -#: trainvel/gtfs/models.py:800 -msgid "Feed end date" -msgstr "Date de fin du flux" - -#: trainvel/gtfs/models.py:805 -msgid "Feed version" -msgstr "Version du flux" - -#: trainvel/gtfs/models.py:815 -msgid "Feed info" -msgstr "Information du flux" - -#: trainvel/gtfs/models.py:816 -msgid "Feed infos" -msgstr "Informations du flux" - -#: trainvel/gtfs/models.py:835 -msgid "Start time" -msgstr "Heure de début" - -#: trainvel/gtfs/models.py:839 trainvel/gtfs/models.py:888 -msgid "Schedule relationship" -msgstr "Relation de la planification" - -#: trainvel/gtfs/models.py:848 trainvel/gtfs/models.py:859 -msgid "Trip update" -msgstr "Mise à jour du trajet" - -#: trainvel/gtfs/models.py:849 -msgid "Trip updates" -msgstr "Mises à jour des trajets" - -#: trainvel/gtfs/models.py:872 -msgid "Arrival delay" -msgstr "Retard à l'arrivée" - -#: trainvel/gtfs/models.py:880 -msgid "Departure delay" -msgstr "Retard au départ" - -#: trainvel/gtfs/models.py:897 -msgid "Stop time update" -msgstr "Mise à jour du temps d'arrêt" - -#: trainvel/gtfs/models.py:898 -msgid "Stop time updates" -msgstr "Mises à jour des temps d'arrêt" - -#~ msgid "TGV" -#~ msgstr "TGV" - -#~ msgid "TER" -#~ msgstr "TER" - -#~ msgid "Intercités" -#~ msgstr "Intercités" - -#~ msgid "Transilien" -#~ msgstr "Transilien" - -#~ msgid "Eurostar" -#~ msgstr "Eurostar" - -#~ msgid "Trenitalia" -#~ msgstr "Trenitalia" - -#~ msgid "Renfe" -#~ msgstr "Renfe" - -#~ msgid "ÖBB" -#~ msgstr "ÖBB" - -#~ msgid "Last update" -#~ msgstr "Dernière mise à jour" - -#~ msgid "Transport type" -#~ msgstr "Type de transport" diff --git a/trainvel/gtfs/management/__init__.py b/trainvel/gtfs/management/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/trainvel/gtfs/management/commands/__init__.py b/trainvel/gtfs/management/commands/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/trainvel/gtfs/management/commands/augment_data.py b/trainvel/gtfs/management/commands/augment_data.py deleted file mode 100644 index 0d920ef..0000000 --- a/trainvel/gtfs/management/commands/augment_data.py +++ /dev/null @@ -1,20 +0,0 @@ -from django.core.management import BaseCommand -from django.db import transaction - -from tqdm import tqdm -from trainvel.gtfs.models import Trip - - -class Command(BaseCommand): - def add_arguments(self, parser): - parser.add_argument('--feed', type=str, help='GTFS Feed code') - - def handle(self, *args, **options): - trips = Trip.objects.filter(route_name="").prefetch_related('gtfs_feed', 'route') - if options['feed']: - trips = trips.filter(gtfs_feed__code=options['feed']) - - with transaction.atomic(): - for trip in tqdm(trips.all()): - trip.augment_data() - trip.save() diff --git a/trainvel/gtfs/management/commands/update_trainvel_gtfs.py b/trainvel/gtfs/management/commands/update_trainvel_gtfs.py deleted file mode 100644 index f07873e..0000000 --- a/trainvel/gtfs/management/commands/update_trainvel_gtfs.py +++ /dev/null @@ -1,430 +0,0 @@ -import csv -import os.path -import tempfile -from datetime import datetime, timedelta -from time import time -from zipfile import ZipFile -from zoneinfo import ZoneInfo - -import requests -from django.core.management import BaseCommand -from django.db import transaction -from django.db.models import Q -from tqdm import tqdm - -from trainvel.gtfs.models import Agency, Calendar, CalendarDate, FeedInfo, GTFSFeed, Route, Stop, StopTime, \ - Transfer, Trip, PickupType, TripUpdate - - -class Command(BaseCommand): - help = "Update the Trainvel GTFS database." - - def add_arguments(self, parser): - parser.add_argument('--debug', '-d', action='store_true', help="Activate debug mode") - parser.add_argument('--bulk_size', '-b', type=int, default=2000, help="Number of objects to create in bulk.") - parser.add_argument('--dry-run', action='store_true', - help="Do not update the database, only print what would be done.") - parser.add_argument('--force', '-f', action='store_true', help="Force the update of the database.") - - def handle(self, debug: bool = False, bulk_size: int = 100, dry_run: bool = False, force: bool = False, - verbosity: int = 1, *args, **options): - if dry_run: - self.stdout.write(self.style.WARNING("Dry run mode activated.")) - - self.stdout.write("Updating database...") - - for gtfs_feed in GTFSFeed.objects.all(): - if not force: - # Check if the source file was updated - resp = requests.head(gtfs_feed.feed_url, allow_redirects=True) - if 'ETag' in resp.headers and gtfs_feed.etag: - if resp.headers['ETag'] == gtfs_feed.etag: - if verbosity >= 1: - self.stdout.write(self.style.WARNING(f"Database is already up-to-date for {gtfs_feed}.")) - continue - if 'Last-Modified' in resp.headers and gtfs_feed.last_modified: - last_modified = resp.headers['Last-Modified'] - last_modified = datetime.strptime(last_modified, "%a, %d %b %Y %H:%M:%S %Z") \ - .replace(tzinfo=ZoneInfo(last_modified.split(' ')[-1])) - if last_modified <= gtfs_feed.last_modified: - if verbosity >= 1: - self.stdout.write(self.style.WARNING(f"Database is already up-to-date for {gtfs_feed}.")) - continue - - self.stdout.write(f"Downloading GTFS feed for {gtfs_feed}...") - resp = requests.get(gtfs_feed.feed_url, allow_redirects=True, stream=True) - - with tempfile.TemporaryFile(suffix=".zip") as file: - for chunk in resp.iter_content(chunk_size=128): - file.write(chunk) - file.seek(0) - - with tempfile.TemporaryDirectory() as tmp_dir: - with ZipFile(file) as zipfile: - zipfile.extractall(tmp_dir) - - self.parse_gtfs(tmp_dir, gtfs_feed, bulk_size, dry_run, verbosity) - - if 'ETag' in resp.headers: - gtfs_feed.etag = resp.headers['ETag'] - gtfs_feed.save() - if 'Last-Modified' in resp.headers: - last_modified = resp.headers['Last-Modified'] - gtfs_feed.last_modified = datetime.strptime(last_modified, "%a, %d %b %Y %H:%M:%S %Z") \ - .replace(tzinfo=ZoneInfo(last_modified.split(' ')[-1])) - gtfs_feed.save() - - def parse_gtfs(self, zip_dir: str, gtfs_feed: GTFSFeed, bulk_size: int, dry_run: bool, verbosity: int): - gtfs_code = gtfs_feed.code - - def read_csv(filename): - with open(os.path.join(zip_dir, filename), 'r') as f: - reader = csv.DictReader(f) - reader.fieldnames = [field.replace('\ufeff', '').strip() - for field in reader.fieldnames] - iterator = tqdm(reader, desc=filename, unit=' rows') if verbosity >= 2 else reader - for row in iterator: - yield {k.strip(): v.strip() for k, v in row.items()} - - agencies = [] - for agency_dict in read_csv("agency.txt"): - agency_dict: dict - agency = Agency( - id=f"{gtfs_code}-{agency_dict['agency_id']}", - name=agency_dict['agency_name'], - url=agency_dict['agency_url'], - timezone=agency_dict['agency_timezone'], - lang=agency_dict.get('agency_lang', "fr"), - phone=agency_dict.get('agency_phone', ""), - email=agency_dict.get('agency_email', ""), - gtfs_feed_id=gtfs_code, - ) - agencies.append(agency) - if agencies and not dry_run: - Agency.objects.bulk_create(agencies, - update_conflicts=True, - update_fields=['name', 'url', 'timezone', 'lang', 'phone', 'email', - 'gtfs_feed'], - unique_fields=['id']) - agencies.clear() - - stops = [] - for stop_dict in read_csv("stops.txt"): - stop_dict: dict - stop_id = stop_dict['stop_id'] - stop_id = f"{gtfs_code}-{stop_id}" - - parent_station_id = stop_dict.get('parent_station', None) - parent_station_id = f"{gtfs_code}-{parent_station_id}" if parent_station_id else None - - stop = Stop( - id=stop_id, - name=stop_dict['stop_name'], - desc=stop_dict.get('stop_desc', ""), - lat=stop_dict['stop_lat'], - lon=stop_dict['stop_lon'], - zone_id=stop_dict.get('zone_id', ""), - url=stop_dict.get('stop_url', ""), - location_type=stop_dict.get('location_type', 0) or 0, - parent_station_id=parent_station_id, - timezone=stop_dict.get('stop_timezone', ""), - wheelchair_boarding=stop_dict.get('wheelchair_boarding', 0), - level_id=stop_dict.get('level_id', ""), - platform_code=stop_dict.get('platform_code', ""), - gtfs_feed_id=gtfs_code, - ) - stops.append(stop) - - if stops and not dry_run: - Stop.objects.bulk_create(stops, - batch_size=bulk_size, - update_conflicts=True, - update_fields=['name', 'desc', 'lat', 'lon', 'zone_id', 'url', - 'location_type', 'parent_station_id', 'timezone', - 'wheelchair_boarding', 'level_id', 'platform_code', - 'gtfs_feed'], - unique_fields=['id']) - stops.clear() - - routes = [] - for route_dict in read_csv("routes.txt"): - route_dict: dict - route_id = route_dict['route_id'] - route_id = f"{gtfs_code}-{route_id}" - # Agency is optional there is only one - agency_id = route_dict.get('agency_id', "") or Agency.objects.get(gtfs_feed_id=gtfs_code) - route = Route( - id=route_id, - agency_id=f"{gtfs_code}-{agency_id}", - short_name=route_dict['route_short_name'], - long_name=route_dict['route_long_name'], - desc=route_dict.get('route_desc', ""), - type=route_dict['route_type'], - url=route_dict.get('route_url', ""), - color=route_dict.get('route_color', ""), - text_color=route_dict.get('route_text_color', ""), - gtfs_feed_id=gtfs_code, - ) - routes.append(route) - - if len(routes) >= bulk_size and not dry_run: - Route.objects.bulk_create(routes, - update_conflicts=True, - update_fields=['agency_id', 'short_name', 'long_name', 'desc', - 'type', 'url', 'color', 'text_color', - 'gtfs_feed'], - unique_fields=['id']) - routes.clear() - if routes and not dry_run: - Route.objects.bulk_create(routes, - update_conflicts=True, - update_fields=['agency_id', 'short_name', 'long_name', 'desc', - 'type', 'url', 'color', 'text_color', - 'gtfs_feed'], - unique_fields=['id']) - routes.clear() - - start_time = 0 - if verbosity >= 1: - self.stdout.write("Deleting old calendars, trips and stop times…") - start_time = time() - - TripUpdate.objects.filter(trip__gtfs_feed_id=gtfs_code).delete() - StopTime.objects.filter(trip__gtfs_feed_id=gtfs_code)._raw_delete(StopTime.objects.db) - Trip.objects.filter(gtfs_feed_id=gtfs_code)._raw_delete(Trip.objects.db) - Calendar.objects.filter(gtfs_feed_id=gtfs_code).delete() - - if verbosity >= 1: - end = time() - self.stdout.write(f"Done in {end - start_time:.2f} s") - - calendars = {} - if os.path.exists(os.path.join(zip_dir, "calendar.txt")): - for calendar_dict in read_csv("calendar.txt"): - calendar_dict: dict - calendar = Calendar( - id=f"{gtfs_code}-{calendar_dict['service_id']}", - monday=calendar_dict['monday'], - tuesday=calendar_dict['tuesday'], - wednesday=calendar_dict['wednesday'], - thursday=calendar_dict['thursday'], - friday=calendar_dict['friday'], - saturday=calendar_dict['saturday'], - sunday=calendar_dict['sunday'], - start_date=calendar_dict['start_date'], - end_date=calendar_dict['end_date'], - gtfs_feed_id=gtfs_code, - ) - calendars[calendar.id] = calendar - - if len(calendars) >= bulk_size and not dry_run: - Calendar.objects.bulk_create(calendars.values(), batch_size=bulk_size) - calendars.clear() - - if calendars and not dry_run: - Calendar.objects.bulk_create(calendars.values(), batch_size=bulk_size) - calendars.clear() - - calendar_dates = [] - all_calendars = {calendar.id: calendar for calendar in Calendar.objects.filter(gtfs_feed_id=gtfs_code)} - new_calendars = {} - with transaction.atomic(): - for calendar_date_dict in read_csv("calendar_dates.txt"): - calendar_date_dict: dict - service_id = f"{gtfs_code}-{calendar_date_dict['service_id']}" - date = datetime.fromisoformat(calendar_date_dict['date']).date() - - calendar_date = CalendarDate( - id=f"{gtfs_code}-{calendar_date_dict['service_id']}-{calendar_date_dict['date']}", - service_id=service_id, - date=calendar_date_dict['date'], - exception_type=calendar_date_dict['exception_type'], - ) - calendar_dates.append(calendar_date) - - if service_id not in all_calendars: - calendar = Calendar( - id=service_id, - monday=False, - tuesday=False, - wednesday=False, - thursday=False, - friday=False, - saturday=False, - sunday=False, - start_date=date, - end_date=date, - gtfs_feed_id=gtfs_code, - ) - all_calendars[service_id] = calendar - new_calendars[service_id] = calendar - else: - calendar = all_calendars[service_id] - if calendar.start_date > date: - calendar.start_date = date - if calendar.end_date < date: - calendar.end_date = date - - if len(calendar_dates) >= bulk_size and not dry_run: - CalendarDate.objects.bulk_create(calendar_dates, batch_size=bulk_size) - calendar_dates.clear() - - if (calendar_dates or new_calendars) and not dry_run: - Calendar.objects.bulk_create(new_calendars.values(), batch_size=bulk_size) - CalendarDate.objects.bulk_create(calendar_dates, batch_size=bulk_size) - new_calendars.clear() - calendar_dates.clear() - - trips = [] - # start_time = time() - for trip_dict in read_csv("trips.txt"): - trip_dict: dict - trip_id = trip_dict['trip_id'] - route_id = trip_dict['route_id'] - trip_id = f"{gtfs_code}-{trip_id}" - route_id = f"{gtfs_code}-{route_id}" - trip = Trip( - id=trip_id, - route_id=route_id, - service_id=f"{gtfs_code}-{trip_dict['service_id']}", - headsign=trip_dict.get('trip_headsign', ""), - short_name=trip_dict.get('trip_short_name', ""), - direction_id=trip_dict.get('direction_id', None) or None, - block_id=trip_dict.get('block_id', ""), - shape_id=trip_dict.get('shape_id', ""), - wheelchair_accessible=trip_dict.get('wheelchair_accessible', None), - bikes_allowed=trip_dict.get('bikes_allowed', None), - gtfs_feed_id=gtfs_code, - ) - trips.append(trip) - - if len(trips) >= bulk_size and not dry_run: - # now = time() - # print(f"Elapsed time: {now - start_time:.3f}s, " - # f"{1000 * (now - start_time) / len(trips):.2f}ms per iteration") - # start_time = now - Trip.objects.bulk_create(trips) - # now = time() - # print(f"Elapsed time: {now - start_time:.3f}s to save") - # start_time = now - trips.clear() - if trips and not dry_run: - Trip.objects.bulk_create(trips) - trips.clear() - - stop_times = [] - # start_time = time() - for stop_time_dict in read_csv("stop_times.txt"): - stop_time_dict: dict - - stop_id = stop_time_dict['stop_id'] - stop_id = f"{gtfs_code}-{stop_id}" - - trip_id = stop_time_dict['trip_id'] - trip_id = f"{gtfs_code}-{trip_id}" - - arr_time = stop_time_dict['arrival_time'] - arr_h, arr_m, arr_s = map(int, arr_time.split(':')) - arr_time = arr_h * 3600 + arr_m * 60 + arr_s - dep_time = stop_time_dict['departure_time'] - dep_h, dep_m, dep_s = map(int, dep_time.split(':')) - dep_time = dep_h * 3600 + dep_m * 60 + dep_s - - pickup_type = stop_time_dict.get('pickup_type', PickupType.REGULAR) - drop_off_type = stop_time_dict.get('drop_off_type', PickupType.REGULAR) - # if stop_time_dict['stop_sequence'] == "1": - # # First stop - # drop_off_type = PickupType.NONE - # elif arr_time == dep_time: - # # Last stop - # pickup_type = PickupType.NONE - - st = StopTime( - id=f"{gtfs_code}-{stop_time_dict['trip_id']}-{stop_time_dict['stop_sequence']}", - trip_id=trip_id, - arrival_time=timedelta(seconds=arr_time), - departure_time=timedelta(seconds=dep_time), - stop_id=stop_id, - stop_sequence=stop_time_dict['stop_sequence'], - stop_headsign=stop_time_dict.get('stop_headsign', ""), - pickup_type=pickup_type, - drop_off_type=drop_off_type, - timepoint=stop_time_dict.get('timepoint', None), - ) - stop_times.append(st) - - if len(stop_times) >= bulk_size and not dry_run: - # now = time() - # print(f"Elapsed time: {now - start_time:.3f}s, " - # f"{1000 * (now - start_time) / len(stop_times):.2f}ms per iteration") - # start_time = now - StopTime.objects.bulk_create(stop_times) - # now = time() - # print(f"Elapsed time: {now - start_time:.3f}s to save") - # start_time = now - stop_times.clear() - - if stop_times and not dry_run: - StopTime.objects.bulk_create(stop_times) - stop_times.clear() - - if os.path.exists(os.path.join(zip_dir, "transfers.txt")): - Transfer.objects.filter(Q(from_stop__gtfs_feed_id=gtfs_code) | Q(to_stop__gtfs_feed_id=gtfs_code)).delete() - transfers = [] - for transfer_dict in read_csv("transfers.txt"): - transfer_dict: dict - from_stop_id = transfer_dict['from_stop_id'] - to_stop_id = transfer_dict['to_stop_id'] - from_stop_id = f"{gtfs_code}-{from_stop_id}" - to_stop_id = f"{gtfs_code}-{to_stop_id}" - from_route_id = transfer_dict.get('from_route_id', None) - from_route_id = f"{gtfs_code}-{from_route_id}" if from_route_id else None - to_route_id = transfer_dict.get('to_route_id', None) - to_route_id = f"{gtfs_code}-{to_route_id}" if to_route_id else None - from_trip_id = transfer_dict.get('from_trip_id', None) - from_trip_id = f"{gtfs_code}-{from_trip_id}" if from_trip_id else None - to_trip_id = transfer_dict.get('to_trip_id', None) - to_trip_id = f"{gtfs_code}-{to_trip_id}" if to_trip_id else None - - transfer_id = f"{gtfs_code}-{transfer_dict['from_stop_id']}-{transfer_dict['to_stop_id']}" - if from_route_id and to_route_id: - transfer_id += f"-{from_route_id}-{to_route_id}" - if from_trip_id and to_trip_id: - transfer_id += f"-{from_trip_id}-{to_trip_id}" - transfer_id += f"-{transfer_dict['transfer_type']}" - - transfer = Transfer( - id=transfer_id, - from_stop_id=from_stop_id, - to_stop_id=to_stop_id, - from_route_id=from_route_id, - to_route_id=to_route_id, - from_trip_id=from_trip_id, - to_trip_id=to_trip_id, - transfer_type=transfer_dict['transfer_type'], - min_transfer_time=transfer_dict.get('min_transfer_time', 0) or 0, - ) - transfers.append(transfer) - - if len(transfers) >= bulk_size and not dry_run: - Transfer.objects.bulk_create(transfers) - transfers.clear() - - if transfers and not dry_run: - Transfer.objects.bulk_create(transfers) - transfers.clear() - - if os.path.exists(os.path.join(zip_dir, "feed_info.txt")) and not dry_run: - for feed_info_dict in read_csv("feed_info.txt"): - feed_info_dict: dict - FeedInfo.objects.update_or_create( - publisher_name=feed_info_dict['feed_publisher_name'], - gtfs_feed_id=gtfs_code, - defaults=dict( - publisher_url=feed_info_dict['feed_publisher_url'], - lang=feed_info_dict['feed_lang'], - start_date=feed_info_dict.get('feed_start_date', datetime.now().date()), - end_date=feed_info_dict.get('feed_end_date', datetime.now().date()), - version=feed_info_dict.get('feed_version', 1), - ) - ) diff --git a/trainvel/gtfs/management/commands/update_trainvel_gtfs_rt.py b/trainvel/gtfs/management/commands/update_trainvel_gtfs_rt.py deleted file mode 100644 index 7a997fd..0000000 --- a/trainvel/gtfs/management/commands/update_trainvel_gtfs_rt.py +++ /dev/null @@ -1,204 +0,0 @@ -from datetime import timedelta, datetime, date, time -from zoneinfo import ZoneInfo - -import requests -from django.core.management import BaseCommand - -from trainvel import settings -from trainvel.gtfs.gtfs_realtime_pb2 import FeedMessage, TripUpdate as GTFSTripUpdate -from trainvel.gtfs.models import Calendar, CalendarDate, ExceptionType, GTFSFeed, PickupType, \ - Route, RouteType, StopScheduleRelationship, StopTime, StopTimeUpdate, \ - Trip, TripUpdate, TripScheduleRelationship - - -class Command(BaseCommand): - help = "Update the Trainvel GTFS Realtime database." - - def add_arguments(self, parser): - parser.add_argument('--debug', '-d', action='store_true', help="Activate debug mode") - - def handle(self, debug: bool = False, verbosity: int = 1, *args, **options): - for gtfs_feed in GTFSFeed.objects.all(): - if not gtfs_feed.rt_feed_url: - if verbosity >= 2: - self.stdout.write(self.style.WARNING(f"No GTFS-RT feed found for {gtfs_feed}.")) - continue - - self.stdout.write(f"Updating GTFS-RT feed for {gtfs_feed}…") - - gtfs_code = gtfs_feed.code - headers = {} - if gtfs_code == "CH-ALL": - headers["Authorization"] = settings.OPENTRANSPORTDATA_SWISS_TOKEN - resp = requests.get(gtfs_feed.rt_feed_url, allow_redirects=True, headers=headers) - feed_message = FeedMessage() - feed_message.ParseFromString(resp.content) - - stop_times_updates = [] - - if debug: - with open(f'feed_message-{gtfs_code}.txt', 'w') as f: - f.write(str(feed_message)) - - for entity in feed_message.entity: - try: - if entity.HasField("trip_update"): - trip_update = entity.trip_update - trip_id = trip_update.trip.trip_id - trip_id = f"{gtfs_code}-{trip_id}" - - start_date = date(year=int(trip_update.trip.start_date[:4]), - month=int(trip_update.trip.start_date[4:6]), - day=int(trip_update.trip.start_date[6:])) - start_dt = datetime.combine(start_date, time(0), tzinfo=ZoneInfo("Europe/Paris")) - - if trip_update.trip.schedule_relationship == TripScheduleRelationship.ADDED: - # C'est un trajet nouveau. On crée le trajet associé. - self.create_trip(trip_update, trip_id, start_dt, gtfs_feed) - - if not Trip.objects.filter(id=trip_id).exists(): - self.stdout.write(f"Trip {trip_id} does not exist in the GTFS feed.") - continue - - # Création du TripUpdate - tu, _created = TripUpdate.objects.update_or_create( - trip_id=trip_id, - start_date=trip_update.trip.start_date, - start_time=trip_update.trip.start_time, - defaults=dict( - schedule_relationship=trip_update.trip.schedule_relationship, - ) - ) - - for stop_sequence, stop_time_update in enumerate(trip_update.stop_time_update): - stop_id = stop_time_update.stop_id - stop_id = f"{gtfs_code}-{stop_id}" - if StopTime.objects.filter(trip_id=trip_id, stop=stop_id).exists(): - st = StopTime.objects.filter(trip_id=trip_id, stop=stop_id) - if st.count() > 1: - st = st.get(stop_sequence=stop_sequence) - else: - st = st.first() - else: - # Stop is added - st = StopTime.objects.create( - id=f"{trip_id}-{stop_time_update.stop_id}", - trip_id=trip_id, - stop_id=stop_id, - stop_sequence=stop_sequence, - arrival_time=datetime.fromtimestamp(stop_time_update.arrival.time, - tz=ZoneInfo("Europe/Paris")) - start_dt, - departure_time=datetime.fromtimestamp(stop_time_update.departure.time, - tz=ZoneInfo("Europe/Paris")) - start_dt, - pickup_type=(PickupType.REGULAR if stop_time_update.departure.time - else PickupType.NONE), - drop_off_type=(PickupType.REGULAR if stop_time_update.arrival.time - else PickupType.NONE), - ) - - if stop_time_update.schedule_relationship == StopScheduleRelationship.SKIPPED: - if st.pickup_type != PickupType.NONE or st.drop_off_type != PickupType.NONE: - st.pickup_type = PickupType.NONE - st.drop_off_type = PickupType.NONE - st.save() - - if st.stop_sequence != stop_sequence: - st.stop_sequence = stop_sequence - st.save() - - st_update = StopTimeUpdate( - trip_update=tu, - stop_time=st, - arrival_delay=timedelta(seconds=stop_time_update.arrival.delay), - arrival_time=datetime.fromtimestamp(stop_time_update.arrival.time, - tz=ZoneInfo("Europe/Paris")), - departure_delay=timedelta(seconds=stop_time_update.departure.delay), - departure_time=datetime.fromtimestamp(stop_time_update.departure.time, - tz=ZoneInfo("Europe/Paris")), - schedule_relationship=stop_time_update.schedule_relationship - or StopScheduleRelationship.SCHEDULED, - ) - stop_times_updates.append(st_update) - else: - self.stdout.write(str(entity)) - except Exception as e: - self.stderr.write(self.style.ERROR(f"Error while processing entity: {e}")) - - StopTimeUpdate.objects.bulk_create(stop_times_updates, - update_conflicts=True, - update_fields=['arrival_delay', 'arrival_time', - 'departure_delay', 'departure_time'], - unique_fields=['trip_update', 'stop_time']) - - def create_trip(self, trip_update: GTFSTripUpdate, trip_id: str, start_dt: datetime, gtfs_feed: GTFSFeed) -> None: - headsign = trip_id[5:-1] - gtfs_code = gtfs_feed.code - - route, _created = Route.objects.get_or_create( - id=f"{gtfs_code}-ADDED-{headsign}", - gtfs_feed=gtfs_feed, - type=RouteType.RAIL, - short_name="ADDED", - long_name="ADDED ROUTE", - ) - - Calendar.objects.update_or_create( - id=f"{gtfs_code}-ADDED-{headsign}", - defaults={ - "gtfs_feed": gtfs_feed, - "monday": False, - "tuesday": False, - "wednesday": False, - "thursday": False, - "friday": False, - "saturday": False, - "sunday": False, - "start_date": start_dt.date(), - "end_date": start_dt.date(), - } - ) - CalendarDate.objects.update_or_create( - id=f"{gtfs_code}-ADDED-{headsign}-{trip_update.trip.start_date}", - defaults={ - "service_id": f"{gtfs_code}-ADDED-{headsign}", - "date": trip_update.trip.start_date, - "exception_type": ExceptionType.ADDED, - } - ) - Trip.objects.update_or_create( - id=trip_id, - defaults={ - "route_id": route.id, - "service_id": f"{gtfs_code}-ADDED-{headsign}", - "headsign": headsign, - "direction_id": trip_update.trip.direction_id, - "gtfs_feed": gtfs_feed, - } - ) - - for stop_sequence, stop_time_update in enumerate(trip_update.stop_time_update): - stop_id = stop_time_update.stop_id - stop_id = f"{gtfs_code}-{stop_id}" - - arr_time = datetime.fromtimestamp(stop_time_update.arrival.time, - tz=ZoneInfo("Europe/Paris")) - start_dt - dep_time = datetime.fromtimestamp(stop_time_update.departure.time, - tz=ZoneInfo("Europe/Paris")) - start_dt - - pickup_type = PickupType.REGULAR if stop_time_update.departure.time and stop_sequence > 0 \ - else PickupType.NONE - drop_off_type = PickupType.REGULAR if stop_time_update.arrival.time \ - and stop_sequence < len(trip_update.stop_time_update) - 1 else PickupType.NONE - - StopTime.objects.update_or_create( - id=f"{gtfs_code}-{trip_id}-{stop_time_update.stop_sequence}", - trip_id=trip_id, - defaults={ - "stop_id": stop_id, - "stop_sequence": stop_sequence, - "arrival_time": arr_time, - "departure_time": dep_time, - "pickup_type": pickup_type, - "drop_off_type": drop_off_type, - } - ) diff --git a/trainvel/gtfs/migrations/0001_initial.py b/trainvel/gtfs/migrations/0001_initial.py deleted file mode 100644 index f46393d..0000000 --- a/trainvel/gtfs/migrations/0001_initial.py +++ /dev/null @@ -1,911 +0,0 @@ -# Generated by Django 5.0.1 on 2024-05-09 17:34 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [] - - operations = [ - migrations.CreateModel( - name="StopTime", - fields=[ - ( - "id", - models.CharField( - max_length=255, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("arrival_time", models.DurationField(verbose_name="Arrival time")), - ("departure_time", models.DurationField(verbose_name="Departure time")), - ("stop_sequence", models.IntegerField(verbose_name="Stop sequence")), - ( - "stop_headsign", - models.CharField( - blank=True, max_length=255, verbose_name="Stop headsign" - ), - ), - ( - "pickup_type", - models.IntegerField( - choices=[ - (0, "Regular"), - (1, "None"), - (2, "Must phone agency"), - (3, "Must coordinate with driver"), - ], - default=0, - null=True, - verbose_name="Pickup type", - ), - ), - ( - "drop_off_type", - models.IntegerField( - choices=[ - (0, "Regular"), - (1, "None"), - (2, "Must phone agency"), - (3, "Must coordinate with driver"), - ], - default=0, - null=True, - verbose_name="Drop off type", - ), - ), - ( - "timepoint", - models.BooleanField( - default=True, null=True, verbose_name="Timepoint" - ), - ), - ], - options={ - "verbose_name": "Stop time", - "verbose_name_plural": "Stop times", - }, - ), - migrations.CreateModel( - name="Trip", - fields=[ - ( - "id", - models.CharField( - max_length=255, - primary_key=True, - serialize=False, - verbose_name="Trip ID", - ), - ), - ( - "headsign", - models.CharField( - blank=True, max_length=255, verbose_name="Trip headsign" - ), - ), - ( - "short_name", - models.CharField( - blank=True, max_length=255, verbose_name="Trip short name" - ), - ), - ( - "direction_id", - models.IntegerField( - choices=[(0, "Outbound"), (1, "Inbound")], - null=True, - verbose_name="Direction", - ), - ), - ( - "block_id", - models.CharField( - blank=True, max_length=255, verbose_name="Block ID" - ), - ), - ( - "shape_id", - models.CharField( - blank=True, max_length=255, verbose_name="Shape ID" - ), - ), - ( - "wheelchair_accessible", - models.IntegerField( - choices=[ - (0, "No information"), - (1, "Possible"), - (2, "Not possible"), - ], - default=0, - null=True, - verbose_name="Wheelchair accessible", - ), - ), - ( - "bikes_allowed", - models.IntegerField( - choices=[ - (0, "No information"), - (1, "Possible"), - (2, "Not possible"), - ], - default=0, - null=True, - verbose_name="Bikes allowed", - ), - ), - ], - options={ - "verbose_name": "Trip", - "verbose_name_plural": "Trips", - }, - ), - migrations.CreateModel( - name="GTFSFeed", - fields=[ - ( - "code", - models.CharField( - help_text="Unique code of the feed.", - max_length=64, - primary_key=True, - serialize=False, - verbose_name="code", - ), - ), - ( - "name", - models.CharField( - help_text="Full name that describes the feed.", - max_length=255, - unique=True, - verbose_name="name", - ), - ), - ( - "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=2, - verbose_name="country", - ), - ), - ( - "feed_url", - models.URLField( - help_text="URL to download the GTFS feed. Must point to a ZIP archive. See https://gtfs.org/schedule/ for more information.", - verbose_name="feed URL", - ), - ), - ( - "rt_feed_url", - models.URLField( - blank=True, - default="", - help_text="URL to download the GTFS-Realtime feed, in the GTFS-RT format. See https://gtfs.org/realtime/ for more information.", - verbose_name="realtime feed URL", - ), - ), - ( - "last_modified", - models.DateTimeField( - default=None, null=True, verbose_name="last modified date" - ), - ), - ( - "etag", - models.CharField( - blank=True, - default="", - help_text="If applicable, corresponds to the tag of the last downloaded file. If it is not modified, the file is the same.", - max_length=255, - verbose_name="ETag", - ), - ), - ], - options={ - "verbose_name": "GTFS feed", - "verbose_name_plural": "GTFS feeds", - "ordering": ("country", "name"), - "indexes": [ - models.Index(fields=["name"], name="gtfs_gtfsfe_name_aabd02_idx") - ], - }, - ), - migrations.CreateModel( - name="Calendar", - fields=[ - ( - "id", - models.CharField( - max_length=255, - primary_key=True, - serialize=False, - verbose_name="Service ID", - ), - ), - ("monday", models.BooleanField(verbose_name="Monday")), - ("tuesday", models.BooleanField(verbose_name="Tuesday")), - ("wednesday", models.BooleanField(verbose_name="Wednesday")), - ("thursday", models.BooleanField(verbose_name="Thursday")), - ("friday", models.BooleanField(verbose_name="Friday")), - ("saturday", models.BooleanField(verbose_name="Saturday")), - ("sunday", models.BooleanField(verbose_name="Sunday")), - ("start_date", models.DateField(verbose_name="Start date")), - ("end_date", models.DateField(verbose_name="End date")), - ( - "gtfs_feed", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to="gtfs.gtfsfeed", - verbose_name="GTFS feed", - ), - ), - ], - options={ - "verbose_name": "Calendar", - "verbose_name_plural": "Calendars", - "ordering": ("id",), - }, - ), - migrations.CreateModel( - name="Agency", - fields=[ - ( - "id", - models.CharField( - max_length=255, - primary_key=True, - serialize=False, - verbose_name="Agency ID", - ), - ), - ("name", models.CharField(max_length=255, verbose_name="Agency name")), - ("url", models.URLField(verbose_name="Agency URL")), - ( - "timezone", - models.CharField(max_length=255, verbose_name="Agency timezone"), - ), - ( - "lang", - models.CharField( - blank=True, max_length=255, verbose_name="Agency language" - ), - ), - ( - "phone", - models.CharField( - blank=True, max_length=255, verbose_name="Agency phone" - ), - ), - ( - "email", - models.EmailField( - blank=True, max_length=254, verbose_name="Agency email" - ), - ), - ( - "gtfs_feed", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to="gtfs.gtfsfeed", - verbose_name="GTFS feed", - ), - ), - ], - options={ - "verbose_name": "Agency", - "verbose_name_plural": "Agencies", - "ordering": ("name",), - }, - ), - migrations.CreateModel( - name="Route", - fields=[ - ( - "id", - models.CharField( - max_length=255, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "short_name", - models.CharField(max_length=255, verbose_name="Route short name"), - ), - ( - "long_name", - models.CharField( - blank=True, max_length=255, verbose_name="Route long name" - ), - ), - ( - "desc", - models.CharField( - blank=True, max_length=255, verbose_name="Route description" - ), - ), - ( - "type", - models.IntegerField( - choices=[ - (0, "Tram"), - (1, "Metro"), - (2, "Rail"), - (3, "Bus"), - (4, "Ferry"), - (5, "Cable car"), - (6, "Gondola"), - (7, "Funicular"), - ], - verbose_name="Route type", - ), - ), - ("url", models.URLField(blank=True, verbose_name="Route URL")), - ( - "color", - models.CharField( - blank=True, max_length=255, verbose_name="Route color" - ), - ), - ( - "text_color", - models.CharField( - blank=True, max_length=255, verbose_name="Route text color" - ), - ), - ( - "agency", - models.ForeignKey( - blank=True, - default=None, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="routes", - to="gtfs.agency", - verbose_name="Agency", - ), - ), - ( - "gtfs_feed", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to="gtfs.gtfsfeed", - verbose_name="GTFS feed", - ), - ), - ], - options={ - "verbose_name": "Route", - "verbose_name_plural": "Routes", - "ordering": ("id",), - }, - ), - migrations.CreateModel( - name="Stop", - fields=[ - ( - "id", - models.CharField( - max_length=255, - primary_key=True, - serialize=False, - verbose_name="Stop ID", - ), - ), - ( - "code", - models.CharField( - blank=True, max_length=255, verbose_name="Stop code" - ), - ), - ("name", models.CharField(max_length=255, verbose_name="Stop name")), - ( - "desc", - models.CharField( - blank=True, max_length=255, verbose_name="Stop description" - ), - ), - ("lon", models.FloatField(verbose_name="Stop longitude")), - ("lat", models.FloatField(verbose_name="Stop latitude")), - ( - "zone_id", - models.CharField( - blank=True, max_length=255, verbose_name="Zone ID" - ), - ), - ("url", models.URLField(blank=True, verbose_name="Stop URL")), - ( - "location_type", - models.IntegerField( - blank=True, - choices=[ - (0, "Stop/platform"), - (1, "Station"), - (2, "Entrance/exit"), - (3, "Generic node"), - (4, "Boarding area"), - ], - default=0, - verbose_name="Location type", - ), - ), - ( - "timezone", - models.CharField( - blank=True, max_length=255, verbose_name="Stop timezone" - ), - ), - ( - "level_id", - models.CharField( - blank=True, max_length=255, verbose_name="Level ID" - ), - ), - ( - "wheelchair_boarding", - models.IntegerField( - blank=True, - choices=[ - (0, "No information"), - (1, "Possible"), - (2, "Not possible"), - ], - default=0, - verbose_name="Wheelchair boarding", - ), - ), - ( - "platform_code", - models.CharField( - blank=True, max_length=255, verbose_name="Platform code" - ), - ), - ( - "gtfs_feed", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to="gtfs.gtfsfeed", - verbose_name="GTFS feed", - ), - ), - ( - "parent_station", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.PROTECT, - related_name="children", - to="gtfs.stop", - verbose_name="Parent station", - ), - ), - ], - options={ - "verbose_name": "Stop", - "verbose_name_plural": "Stops", - "ordering": ("id",), - }, - ), - migrations.CreateModel( - name="StopTimeUpdate", - fields=[ - ( - "stop_time", - models.OneToOneField( - on_delete=django.db.models.deletion.CASCADE, - primary_key=True, - related_name="update", - serialize=False, - to="gtfs.stoptime", - verbose_name="Stop time", - ), - ), - ("arrival_delay", models.DurationField(verbose_name="Arrival delay")), - ("arrival_time", models.DateTimeField(verbose_name="Arrival time")), - ( - "departure_delay", - models.DurationField(verbose_name="Departure delay"), - ), - ("departure_time", models.DateTimeField(verbose_name="Departure time")), - ( - "schedule_relationship", - models.IntegerField( - choices=[ - (0, "Scheduled"), - (1, "Skipped"), - (2, "No data"), - (3, "Unscheduled"), - ], - default=0, - verbose_name="Schedule relationship", - ), - ), - ], - options={ - "verbose_name": "Stop time update", - "verbose_name_plural": "Stop time updates", - "ordering": ("trip_update", "stop_time"), - }, - ), - migrations.AddField( - model_name="stoptime", - name="stop", - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="stop_times", - to="gtfs.stop", - verbose_name="Stop ID", - ), - ), - migrations.CreateModel( - name="Transfer", - fields=[ - ( - "id", - models.CharField( - max_length=255, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "transfer_type", - models.IntegerField( - choices=[ - (0, "Recommended"), - (1, "Timed"), - (2, "Minimum time"), - (3, "Not possible"), - ], - default=0, - verbose_name="Transfer type", - ), - ), - ( - "min_transfer_time", - models.IntegerField( - blank=True, verbose_name="Minimum transfer time" - ), - ), - ( - "from_stop", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="transfers_from", - to="gtfs.stop", - verbose_name="From stop", - ), - ), - ( - "to_stop", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="transfers_to", - to="gtfs.stop", - verbose_name="To stop", - ), - ), - ], - options={ - "verbose_name": "Transfer", - "verbose_name_plural": "Transfers", - "ordering": ("id",), - }, - ), - migrations.CreateModel( - name="TripUpdate", - fields=[ - ( - "trip", - models.OneToOneField( - on_delete=django.db.models.deletion.CASCADE, - primary_key=True, - related_name="update", - serialize=False, - to="gtfs.trip", - verbose_name="Trip", - ), - ), - ("start_date", models.DateField(verbose_name="Start date")), - ("start_time", models.TimeField(verbose_name="Start time")), - ( - "schedule_relationship", - models.IntegerField( - choices=[ - (0, "Scheduled"), - (1, "Added"), - (2, "Unscheduled"), - (3, "Canceled"), - (5, "Replacement"), - (6, "Duplicated"), - (7, "Deleted"), - ], - default=0, - verbose_name="Schedule relationship", - ), - ), - ], - options={ - "verbose_name": "Trip update", - "verbose_name_plural": "Trip updates", - "ordering": ("start_date", "trip"), - }, - ), - migrations.AddField( - model_name="trip", - name="gtfs_feed", - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to="gtfs.gtfsfeed", - verbose_name="GTFS feed", - ), - ), - migrations.AddField( - model_name="trip", - name="route", - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="trips", - to="gtfs.route", - verbose_name="Route", - ), - ), - migrations.AddField( - model_name="trip", - name="service", - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="trips", - to="gtfs.calendar", - verbose_name="Service", - ), - ), - migrations.AddField( - model_name="stoptime", - name="trip", - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="stop_times", - to="gtfs.trip", - verbose_name="Trip", - ), - ), - migrations.CreateModel( - name="CalendarDate", - fields=[ - ( - "id", - models.CharField( - max_length=255, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("date", models.DateField(verbose_name="Date")), - ( - "exception_type", - models.IntegerField( - choices=[(1, "Added"), (2, "Removed")], - verbose_name="Exception type", - ), - ), - ( - "service", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="dates", - to="gtfs.calendar", - verbose_name="Service", - ), - ), - ], - options={ - "verbose_name": "Calendar date", - "verbose_name_plural": "Calendar dates", - "ordering": ("id",), - "indexes": [ - models.Index( - fields=["service"], name="gtfs_calend_service_211472_idx" - ), - models.Index(fields=["date"], name="gtfs_calend_date_e90040_idx"), - ], - }, - ), - migrations.CreateModel( - name="FeedInfo", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "publisher_name", - models.CharField( - max_length=255, verbose_name="Feed publisher name" - ), - ), - ("publisher_url", models.URLField(verbose_name="Feed publisher URL")), - ( - "lang", - models.CharField(max_length=255, verbose_name="Feed language"), - ), - ("start_date", models.DateField(verbose_name="Feed start date")), - ("end_date", models.DateField(verbose_name="Feed end date")), - ( - "version", - models.CharField(max_length=255, verbose_name="Feed version"), - ), - ( - "gtfs_feed", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to="gtfs.gtfsfeed", - verbose_name="GTFS feed", - ), - ), - ], - options={ - "verbose_name": "Feed info", - "verbose_name_plural": "Feed infos", - "ordering": ("publisher_name",), - "indexes": [ - models.Index( - fields=["gtfs_feed"], name="gtfs_feedin_gtfs_fe_73554b_idx" - ) - ], - }, - ), - migrations.AddIndex( - model_name="calendar", - index=models.Index( - fields=["gtfs_feed"], name="gtfs_calend_gtfs_fe_ff03d1_idx" - ), - ), - migrations.AddIndex( - model_name="agency", - index=models.Index(fields=["name"], name="gtfs_agency_name_a6dd2b_idx"), - ), - migrations.AddIndex( - model_name="agency", - index=models.Index( - fields=["gtfs_feed"], name="gtfs_agency_gtfs_fe_86414c_idx" - ), - ), - migrations.AddIndex( - model_name="route", - index=models.Index( - fields=["gtfs_feed"], name="gtfs_route_gtfs_fe_c6ac59_idx" - ), - ), - migrations.AddIndex( - model_name="stop", - index=models.Index(fields=["name"], name="gtfs_stop_name_1c87d7_idx"), - ), - migrations.AddIndex( - model_name="stop", - index=models.Index(fields=["code"], name="gtfs_stop_code_5f4ebc_idx"), - ), - migrations.AddIndex( - model_name="stop", - index=models.Index( - fields=["gtfs_feed"], name="gtfs_stop_gtfs_fe_0e17d6_idx" - ), - ), - migrations.AddIndex( - model_name="tripupdate", - index=models.Index(fields=["trip"], name="gtfs_tripup_trip_id_b3ee0e_idx"), - ), - migrations.AlterUniqueTogether( - name="tripupdate", - unique_together={("trip", "start_date", "start_time")}, - ), - migrations.AddField( - model_name="stoptimeupdate", - name="trip_update", - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="stop_time_updates", - to="gtfs.tripupdate", - verbose_name="Trip update", - ), - ), - migrations.AddIndex( - model_name="trip", - index=models.Index(fields=["route"], name="gtfs_trip_route_i_6d85d9_idx"), - ), - migrations.AddIndex( - model_name="trip", - index=models.Index( - fields=["gtfs_feed"], name="gtfs_trip_gtfs_fe_e63eac_idx" - ), - ), - migrations.AddIndex( - model_name="stoptime", - index=models.Index(fields=["stop"], name="gtfs_stopti_stop_id_64a4e3_idx"), - ), - migrations.AddIndex( - model_name="stoptime", - index=models.Index(fields=["trip"], name="gtfs_stopti_trip_id_bec7fe_idx"), - ), - migrations.AddIndex( - model_name="stoptimeupdate", - index=models.Index( - fields=["trip_update"], name="gtfs_stopti_trip_up_ffe901_idx" - ), - ), - migrations.AddIndex( - model_name="stoptimeupdate", - index=models.Index( - fields=["stop_time"], name="gtfs_stopti_stop_ti_4f2c63_idx" - ), - ), - migrations.AlterUniqueTogether( - name="stoptimeupdate", - unique_together={("trip_update", "stop_time")}, - ), - ] diff --git a/trainvel/gtfs/migrations/0002_alter_stop_parent_station.py b/trainvel/gtfs/migrations/0002_alter_stop_parent_station.py deleted file mode 100644 index 57d8156..0000000 --- a/trainvel/gtfs/migrations/0002_alter_stop_parent_station.py +++ /dev/null @@ -1,26 +0,0 @@ -# Generated by Django 5.0.6 on 2024-05-12 09:31 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("gtfs", "0001_initial"), - ] - - operations = [ - migrations.AlterField( - model_name="stop", - name="parent_station", - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - related_name="children", - to="gtfs.stop", - verbose_name="Parent station", - ), - ), - ] diff --git a/trainvel/gtfs/migrations/0003_gtfsfeed_categorize_routes_and_more.py b/trainvel/gtfs/migrations/0003_gtfsfeed_categorize_routes_and_more.py deleted file mode 100644 index 542dcca..0000000 --- a/trainvel/gtfs/migrations/0003_gtfsfeed_categorize_routes_and_more.py +++ /dev/null @@ -1,72 +0,0 @@ -# Generated by Django 5.0.6 on 2024-05-12 17:18 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("gtfs", "0002_alter_stop_parent_station"), - ] - - operations = [ - migrations.AddField( - model_name="gtfsfeed", - name="categorize_routes", - field=models.BooleanField( - default=False, - help_text="If checked, trips can be categorized by route type.", - verbose_name="categorize routes", - ), - ), - migrations.AddField( - model_name="gtfsfeed", - name="excluded_agencies", - field=models.ManyToManyField( - blank=True, - help_text="Agencies that are part of another feed and shouldn't be displayed with this feed.", - to="gtfs.agency", - verbose_name="excluded agencies", - ), - ), - migrations.AddField( - model_name="gtfsfeed", - name="long_distance_regex", - field=models.TextField( - blank=True, - default="", - help_text="Regular expression that filters long distance trips.", - verbose_name="long distance regex", - ), - ), - migrations.AddField( - model_name="gtfsfeed", - name="route_name_regex", - field=models.TextField( - blank=True, - default="route_short_name:([^§]+)", - help_text="Regular expression that catches the route name from a trip.", - verbose_name="route name regex", - ), - ), - migrations.AddField( - model_name="gtfsfeed", - name="route_type_regex", - field=models.TextField( - blank=True, - default="gtfs_feed:([^§]+)&-&route_type:([^§]+)", - help_text="Regular expression that catches the route type from a trip.", - verbose_name="route name regex", - ), - ), - migrations.AddField( - model_name="gtfsfeed", - name="trip_number_regex", - field=models.TextField( - blank=True, - default="trip_short_name:([^§]+)", - help_text="Regular expression that catches the trip number from a trip.", - verbose_name="route name regex", - ), - ), - ] diff --git a/trainvel/gtfs/migrations/0004_trip_long_distance_trip_route_name_trip_route_type_and_more.py b/trainvel/gtfs/migrations/0004_trip_long_distance_trip_route_name_trip_route_type_and_more.py deleted file mode 100644 index 7e7875b..0000000 --- a/trainvel/gtfs/migrations/0004_trip_long_distance_trip_route_name_trip_route_type_and_more.py +++ /dev/null @@ -1,39 +0,0 @@ -# Generated by Django 5.0.6 on 2024-05-12 18:33 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("gtfs", "0003_gtfsfeed_categorize_routes_and_more"), - ] - - operations = [ - migrations.AddField( - model_name="trip", - name="long_distance", - field=models.BooleanField(default=True, verbose_name="Long distance trip"), - ), - migrations.AddField( - model_name="trip", - name="route_name", - field=models.CharField( - blank=True, default="", max_length=255, verbose_name="Route name" - ), - ), - migrations.AddField( - model_name="trip", - name="route_type", - field=models.CharField( - blank=True, default="", max_length=255, verbose_name="Route type" - ), - ), - migrations.AddField( - model_name="trip", - name="trip_number", - field=models.CharField( - blank=True, default="", max_length=255, verbose_name="Trip number" - ), - ), - ] diff --git a/trainvel/gtfs/migrations/0005_transfer_from_route_transfer_from_trip_and_more.py b/trainvel/gtfs/migrations/0005_transfer_from_route_transfer_from_trip_and_more.py deleted file mode 100644 index cb29ba1..0000000 --- a/trainvel/gtfs/migrations/0005_transfer_from_route_transfer_from_trip_and_more.py +++ /dev/null @@ -1,73 +0,0 @@ -# Generated by Django 5.0.6 on 2024-08-12 18:33 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("gtfs", "0004_trip_long_distance_trip_route_name_trip_route_type_and_more"), - ] - - operations = [ - migrations.AddField( - model_name="transfer", - name="from_route", - field=models.ForeignKey( - blank=True, - default=None, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="transfers_from", - to="gtfs.route", - verbose_name="From route", - ), - ), - migrations.AddField( - model_name="transfer", - name="from_trip", - field=models.ForeignKey( - blank=True, - default=None, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="transfers_from", - to="gtfs.trip", - verbose_name="From trip", - ), - ), - migrations.AddField( - model_name="transfer", - name="to_route", - field=models.ForeignKey( - blank=True, - default=None, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="transfers_to", - to="gtfs.route", - verbose_name="To route", - ), - ), - migrations.AddField( - model_name="transfer", - name="to_trip", - field=models.ForeignKey( - blank=True, - default=None, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="transfers_to", - to="gtfs.trip", - verbose_name="To trip", - ), - ), - migrations.AlterField( - model_name="transfer", - name="min_transfer_time", - field=models.IntegerField( - blank=True, default=None, verbose_name="Minimum transfer time" - ), - ), - ] diff --git a/trainvel/gtfs/migrations/__init__.py b/trainvel/gtfs/migrations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/trainvel/gtfs/models.py b/trainvel/gtfs/models.py deleted file mode 100644 index 3e2254e..0000000 --- a/trainvel/gtfs/models.py +++ /dev/null @@ -1,1068 +0,0 @@ -import re - -from django.db import models -from django.utils.translation import gettext_lazy as _ - - -class Country(models.TextChoices): - """ - Country list by ISO 3166-1 alpha-2 code. - Only countries that are member of the Council of Europe - are listed for now. - """ - ALBANIA = "AL", _("Albania") - ANDORRA = "AD", _("Andorra") - ARMENIA = "AM", _("Armenia") - AUSTRIA = "AT", _("Austria") - AZERBAIJAN = "AZ", _("Azerbaijan") - BELGIUM = "BE", _("Belgium") - BOSNIA_AND_HERZEGOVINA = "BA", _("Bosnia and Herzegovina") - BULGARIA = "BG", _("Bulgaria") - CROATIA = "HR", _("Croatia") - CYPRUS = "CY", _("Cyprus") - CZECH_REPUBLIC = "CZ", _("Czech Republic") - DENMARK = "DK", _("Denmark") - ESTONIA = "EE", _("Estonia") - FINLAND = "FI", _("Finland") - FRANCE = "FR", _("France") - GEORGIA = "GE", _("Georgia") - GERMANY = "DE", _("Germany") - GREECE = "GR", _("Greece") - HUNGARY = "HU", _("Hungary") - ICELAND = "IS", _("Iceland") - IRELAND = "IE", _("Ireland") - ITALY = "IT", _("Italy") - LATVIA = "LV", _("Latvia") - LIECHTENSTEIN = "LI", _("Liechtenstein") - LITHUANIA = "LT", _("Lithuania") - LUXEMBOURG = "LU", _("Luxembourg") - MALTA = "MT", _("Malta") - MOLDOVA = "MD", _("Moldova") - MONACO = "MC", _("Monaco") - MONTENEGRO = "ME", _("Montenegro") - NETHERLANDS = "NL", _("Netherlands") - NORTH_MACEDONIA = "MK", _("North Macedonia") - NORWAY = "NO", _("Norway") - POLAND = "PL", _("Poland") - PORTUGAL = "PT", _("Portugal") - ROMANIA = "RO", _("Romania") - SAN_MARINO = "SM", _("San Marino") - SERBIA = "RS", _("Serbia") - SLOVAKIA = "SK", _("Slovakia") - SLOVENIA = "SI", _("Slovenia") - SPAIN = "ES", _("Spain") - SWEDEN = "SE", _("Sweden") - SWITZERLAND = "CH", _("Switzerland") - TURKEY = "TR", _("Turkey") - UNITED_KINGDOM = "GB", _("United Kingdom") - UKRAINE = "UA", _("Ukraine") - - -class CategorizeTrips(models.TextChoices): - """ - Make trips be categorized by route type. - """ - GTFS_FEED = "gtfs_feed", _("GTFS Feed (all trips of the dataset)") - ROUTE_SHORT_NAME = "route_short_name", _("By route short name (e.g. A, S9,…)") - TRIP_SHORT_NAME_SPLIT = "route_short_name_split", _("By first character of the route short name (e.g. RJ, NJ,…)") - - -class LocationType(models.IntegerChoices): - STOP_PLATFORM = 0, _("Stop/platform") - STATION = 1, _("Station") - ENTRANCE_EXIT = 2, _("Entrance/exit") - GENERIC_NODE = 3, _("Generic node") - BOARDING_AREA = 4, _("Boarding area") - - -class AccessInformation(models.IntegerChoices): - NO_INFORMATION = 0, _("No information") - POSSIBLE = 1, _("Possible") - NOT_POSSIBLE = 2, _("Not possible") - - -class PickupType(models.IntegerChoices): - REGULAR = 0, _("Regular") - NONE = 1, _("None") - MUST_PHONE_AGENCY = 2, _("Must phone agency") - MUST_COORDINATE_WITH_DRIVER = 3, _("Must coordinate with driver") - - -class RouteType(models.IntegerChoices): - TRAM = 0, _("Tram") - METRO = 1, _("Metro") - RAIL = 2, _("Rail") - BUS = 3, _("Bus") - FERRY = 4, _("Ferry") - CABLE_CAR = 5, _("Cable car") - GONDOLA = 6, _("Gondola") - FUNICULAR = 7, _("Funicular") - - -class Direction(models.IntegerChoices): - OUTBOUND = 0, _("Outbound") - INBOUND = 1, _("Inbound") - - -class TransferType(models.IntegerChoices): - RECOMMENDED = 0, _("Recommended") - TIMED = 1, _("Timed") - MINIMUM_TIME = 2, _("Minimum time") - NOT_POSSIBLE = 3, _("Not possible") - - -class ExceptionType(models.IntegerChoices): - ADDED = 1, _("Added") - REMOVED = 2, _("Removed") - - -class TripScheduleRelationship(models.IntegerChoices): - SCHEDULED = 0, _("Scheduled") - ADDED = 1, _("Added") - UNSCHEDULED = 2, _("Unscheduled") - CANCELED = 3, _("Canceled") - REPLACEMENT = 5, _("Replacement") - DUPLICATED = 6, _("Duplicated") - DELETED = 7, _("Deleted") - - -class StopScheduleRelationship(models.IntegerChoices): - SCHEDULED = 0, _("Scheduled") - SKIPPED = 1, _("Skipped") - NO_DATA = 2, _("No data") - UNSCHEDULED = 3, _("Unscheduled") - - -class GTFSFeed(models.Model): - code = models.CharField( - primary_key=True, - max_length=64, - verbose_name=_("code"), - help_text=_("Unique code of the feed.") - ) - - name = models.CharField( - max_length=255, - verbose_name=_("name"), - unique=True, - help_text=_("Full name that describes the feed."), - ) - - country = models.CharField( - max_length=2, - verbose_name=_("country"), - choices=Country, - ) - - feed_url = models.URLField( - verbose_name=_("feed URL"), - help_text=_("URL to download the GTFS feed. Must point to a ZIP archive. " - "See https://gtfs.org/schedule/ for more information."), - ) - - rt_feed_url = models.URLField( - verbose_name=_("realtime feed URL"), - blank=True, - default="", - help_text=_("URL to download the GTFS-Realtime feed, in the GTFS-RT format. " - "See https://gtfs.org/realtime/ for more information."), - ) - - last_modified = models.DateTimeField( - verbose_name=_("last modified date"), - null=True, - default=None, - ) - - etag = models.CharField( - max_length=255, - verbose_name=_("ETag"), - blank=True, - default="", - help_text=_("If applicable, corresponds to the tag of the last downloaded file. " - "If it is not modified, the file is the same."), - ) - - excluded_agencies = models.ManyToManyField( - to="Agency", - verbose_name=_("excluded agencies"), - blank=True, - help_text=_("Agencies that are part of another feed and shouldn't be displayed with this feed."), - ) - - categorize_routes = models.BooleanField( - verbose_name=_("categorize routes"), - default=False, - help_text=_("If checked, trips can be categorized by route type."), - ) - - route_name_regex = models.TextField( - verbose_name=_("route name regex"), - blank=True, - default=r"route_short_name:([^§]+)", - help_text=_("Regular expression that catches the route name from a trip."), - ) - - route_type_regex = models.TextField( - verbose_name=_("route name regex"), - blank=True, - default=r"gtfs_feed:([^§]+)&-&route_type:([^§]+)", - help_text=_("Regular expression that catches the route type from a trip."), - ) - - trip_number_regex = models.TextField( - verbose_name=_("route name regex"), - blank=True, - default=r"trip_short_name:([^§]+)", - help_text=_("Regular expression that catches the trip number from a trip."), - ) - - long_distance_regex = models.TextField( - verbose_name=_("long distance regex"), - blank=True, - default="", - help_text=_("Regular expression that filters long distance trips."), - ) - - def __str__(self): - return f"{self.name} ({self.code})" - - class Meta: - verbose_name = _("GTFS feed") - verbose_name_plural = _("GTFS feeds") - ordering = ('country', 'name',) - indexes = (models.Index(fields=['name']),) - - -class Agency(models.Model): - id = models.CharField( - max_length=255, - primary_key=True, - verbose_name=_("Agency ID"), - ) - - name = models.CharField( - max_length=255, - verbose_name=_("Agency name"), - ) - - url = models.URLField( - verbose_name=_("Agency URL"), - ) - - timezone = models.CharField( - max_length=255, - verbose_name=_("Agency timezone"), - ) - - lang = models.CharField( - max_length=255, - verbose_name=_("Agency language"), - blank=True, - ) - - phone = models.CharField( - max_length=255, - verbose_name=_("Agency phone"), - blank=True, - ) - - email = models.EmailField( - verbose_name=_("Agency email"), - blank=True, - ) - - gtfs_feed = models.ForeignKey( - GTFSFeed, - on_delete=models.CASCADE, - verbose_name=_("GTFS feed"), - ) - - def __str__(self): - return self.name - - class Meta: - verbose_name = _("Agency") - verbose_name_plural = _("Agencies") - ordering = ("name",) - indexes = (models.Index(fields=['name']), models.Index(fields=['gtfs_feed']),) - - -class Stop(models.Model): - id = models.CharField( - max_length=255, - primary_key=True, - verbose_name=_("Stop ID"), - ) - - code = models.CharField( - max_length=255, - verbose_name=_("Stop code"), - blank=True, - ) - - name = models.CharField( - max_length=255, - verbose_name=_("Stop name"), - ) - - desc = models.CharField( - max_length=255, - verbose_name=_("Stop description"), - blank=True, - ) - - lon = models.FloatField( - verbose_name=_("Stop longitude"), - ) - - lat = models.FloatField( - verbose_name=_("Stop latitude"), - ) - - zone_id = models.CharField( - max_length=255, - verbose_name=_("Zone ID"), - blank=True, - ) - - url = models.URLField( - verbose_name=_("Stop URL"), - blank=True, - ) - - location_type = models.IntegerField( - verbose_name=_("Location type"), - blank=True, - choices=LocationType, - default=LocationType.STOP_PLATFORM, - ) - - parent_station = models.ForeignKey( - to="Stop", - on_delete=models.SET_NULL, - verbose_name=_("Parent station"), - related_name="children", - blank=True, - null=True, - ) - - timezone = models.CharField( - max_length=255, - verbose_name=_("Stop timezone"), - blank=True, - ) - - level_id = models.CharField( - max_length=255, - verbose_name=_("Level ID"), - blank=True, - ) - - wheelchair_boarding = models.IntegerField( - verbose_name=_("Wheelchair boarding"), - blank=True, - choices=AccessInformation, - default=AccessInformation.NO_INFORMATION, - ) - - platform_code = models.CharField( - max_length=255, - verbose_name=_("Platform code"), - blank=True, - ) - - gtfs_feed = models.ForeignKey( - GTFSFeed, - on_delete=models.CASCADE, - verbose_name=_("GTFS feed"), - ) - - @property - def stop_type(self): - train_type = self.id.split('StopPoint:OCE')[-1].split('StopArea:OCE')[-1].split('-')[0] - return train_type - - def __str__(self): - return f"{self.name} ({self.id})" - - class Meta: - verbose_name = _("Stop") - verbose_name_plural = _("Stops") - ordering = ("id",) - indexes = (models.Index(fields=['name']), - models.Index(fields=['code']), - models.Index(fields=['gtfs_feed']),) - - -class Route(models.Model): - id = models.CharField( - max_length=255, - primary_key=True, - verbose_name=_("ID"), - ) - - agency = models.ForeignKey( - to="Agency", - on_delete=models.CASCADE, - verbose_name=_("Agency"), - related_name="routes", - null=True, - blank=True, - default=None, - ) - - short_name = models.CharField( - max_length=255, - verbose_name=_("Route short name"), - ) - - long_name = models.CharField( - max_length=255, - verbose_name=_("Route long name"), - blank=True, - ) - - desc = models.CharField( - max_length=255, - verbose_name=_("Route description"), - blank=True, - ) - - type = models.IntegerField( - verbose_name=_("Route type"), - choices=RouteType, - ) - - url = models.URLField( - verbose_name=_("Route URL"), - blank=True, - ) - - color = models.CharField( - max_length=255, - verbose_name=_("Route color"), - blank=True, - ) - - text_color = models.CharField( - max_length=255, - verbose_name=_("Route text color"), - blank=True, - ) - - gtfs_feed = models.ForeignKey( - GTFSFeed, - on_delete=models.CASCADE, - verbose_name=_("GTFS feed"), - ) - - def __str__(self): - return self.long_name or self.short_name - - class Meta: - verbose_name = _("Route") - verbose_name_plural = _("Routes") - ordering = ("id",) - indexes = (models.Index(fields=['gtfs_feed']),) - - -class Trip(models.Model): - id = models.CharField( - max_length=255, - primary_key=True, - verbose_name=_("Trip ID"), - ) - - route = models.ForeignKey( - to="Route", - on_delete=models.CASCADE, - verbose_name=_("Route"), - related_name="trips", - ) - - service = models.ForeignKey( - to="Calendar", - on_delete=models.CASCADE, - verbose_name=_("Service"), - related_name="trips", - ) - - headsign = models.CharField( - max_length=255, - verbose_name=_("Trip headsign"), - blank=True, - ) - - short_name = models.CharField( - max_length=255, - verbose_name=_("Trip short name"), - blank=True, - ) - - direction_id = models.IntegerField( - verbose_name=_("Direction"), - choices=Direction, - null=True, - ) - - block_id = models.CharField( - max_length=255, - verbose_name=_("Block ID"), - blank=True, - ) - - shape_id = models.CharField( - max_length=255, - verbose_name=_("Shape ID"), - blank=True, - ) - - wheelchair_accessible = models.IntegerField( - verbose_name=_("Wheelchair accessible"), - choices=AccessInformation, - default=AccessInformation.NO_INFORMATION, - null=True, - ) - - bikes_allowed = models.IntegerField( - verbose_name=_("Bikes allowed"), - choices=AccessInformation, - default=AccessInformation.NO_INFORMATION, - null=True, - ) - - gtfs_feed = models.ForeignKey( - GTFSFeed, - on_delete=models.CASCADE, - verbose_name=_("GTFS feed"), - ) - - """ - Augmented data - """ - - route_name = models.CharField( - max_length=255, - verbose_name=_("Route name"), - blank=True, - default="", - ) - - trip_number = models.CharField( - max_length=255, - verbose_name=_("Trip number"), - blank=True, - default="", - ) - - route_type = models.CharField( - max_length=255, - verbose_name=_("Route type"), - blank=True, - default="", - ) - - long_distance = models.BooleanField( - verbose_name=_("Long distance trip"), - default=True, - ) - - @property - def origin(self) -> Stop | None: - return self.stop_times.order_by('stop_sequence').first().stop if self.stop_times.exists() else None - - @property - def destination(self) -> Stop | None: - return self.stop_times.order_by('-stop_sequence').first().stop if self.stop_times.exists() else None - - @property - def departure_time(self): - if not self.stop_times.exists(): - return _("Unknown") - dep_time = self.stop_times.order_by('stop_sequence').first().departure_time - hours = int(dep_time.total_seconds() // 3600) - minutes = int((dep_time.total_seconds() % 3600) // 60) - return f"{hours:02}:{minutes:02}" - - @property - def arrival_time(self): - if not self.stop_times.exists(): - return _("Unknown") - arr_time = self.stop_times.order_by('-stop_sequence').first().arrival_time - hours = int(arr_time.total_seconds() // 3600) - minutes = int((arr_time.total_seconds() % 3600) // 60) - return f"{hours:02}:{minutes:02}" - - @property - def train_type(self): - if self.gtfs_feed.code == "FR-IDF-IDFM": - return self.route.short_name - else: - return self.origin.stop_type - - @property - def train_number(self): - if self.gtfs_feed.code == "FR-IDF-IDFM": - return self.short_name - else: - return self.headsign - - @property - def color(self): - if self.route.color: - return self.route.color - elif self.train_type == "OUIGO": - return "E60075" - return "FFFFFF" - - @property - def text_color(self): - if self.route.text_color: - return self.route.text_color - elif self.train_type == "OUIGO": - return "FFFFFF" - elif self.train_type == "TGV INOUI": - return "9B2743" - elif self.train_type == "INTER-CITÉS" or self.train_type == "INTER-CITÉS de nuit": - return "404042" - return "000000" - - @property - def origin_destination(self): - origin = self.origin - origin = origin.name if origin else _("Unknown") - destination = self.destination - destination = destination.name if destination else _("Unknown") - return f"{origin} {self.departure_time} → {destination} {self.arrival_time}" - - origin_destination.fget.short_description = _("Origin → Destination") - - def augment_data(self): - first_stop = self.stop_times.first() - if not first_stop: - return - desc_line = first_stop.description_line - - for key in ['route_name', 'route_type', 'trip_number']: - value = "" - full_pattern = getattr(self.gtfs_feed, f"{key}_regex") - for pattern in full_pattern.split('&'): - if '(' not in pattern: - value += pattern - continue - - groups = re.findall(pattern, desc_line) - if not any(group is not None for group in groups): - raise ValueError(f"Pattern {pattern} not found in {desc_line}") - value += "".join(group for group in groups if group) - setattr(self, key, value) - - self.long_distance = bool(re.match(self.gtfs_feed.long_distance_regex, desc_line)) - - def __str__(self): - return self.origin_destination - - class Meta: - verbose_name = _("Trip") - verbose_name_plural = _("Trips") - indexes = (models.Index(fields=['route']), models.Index(fields=['gtfs_feed']),) - - -class StopTime(models.Model): - id = models.CharField( - max_length=255, - primary_key=True, - verbose_name=_("ID"), - ) - - trip = models.ForeignKey( - to="Trip", - on_delete=models.CASCADE, - verbose_name=_("Trip"), - related_name="stop_times", - ) - - arrival_time = models.DurationField( - verbose_name=_("Arrival time"), - ) - - departure_time = models.DurationField( - verbose_name=_("Departure time"), - ) - - stop = models.ForeignKey( - to="Stop", - on_delete=models.CASCADE, - verbose_name=_("Stop ID"), - related_name="stop_times", - ) - - stop_sequence = models.IntegerField( - verbose_name=_("Stop sequence"), - ) - - stop_headsign = models.CharField( - max_length=255, - verbose_name=_("Stop headsign"), - blank=True, - ) - - pickup_type = models.IntegerField( - verbose_name=_("Pickup type"), - choices=PickupType, - default=PickupType.REGULAR, - null=True, - ) - - drop_off_type = models.IntegerField( - verbose_name=_("Drop off type"), - choices=PickupType, - default=PickupType.REGULAR, - null=True, - ) - - timepoint = models.BooleanField( - verbose_name=_("Timepoint"), - default=True, - null=True, - ) - - @property - def pretty_arrival_time(self): - seconds = self.arrival_time.total_seconds() - hours = int(seconds // 3600) % 24 - minutes = int((seconds % 3600) // 60) - return f"{hours:02}:{minutes:02}" - - @property - def pretty_departure_time(self): - seconds = self.departure_time.total_seconds() - hours = int(seconds // 3600) % 24 - minutes = int((seconds % 3600) // 60) - return f"{hours:02}:{minutes:02}" - - @property - def description_line(self) -> str: - return (f"gtfs_feed:{self.trip.gtfs_feed_id}" - f"§stop:{self.stop_id}" - f"§trip_id:{self.trip_id}" - f"§trip_short_name:{self.trip.short_name}" - f"§trip_headsign:{self.trip.headsign}" - f"§route_short_name:{self.trip.route.short_name}" - f"§route_desc:{self.trip.route.desc}" - f"§route_type:{self.trip.route.type}") - - @property - def description_line_expr(self): - return "gtfs_feed:" + models.F('trip__gtfs_feed_id') \ - + "§stop:" + models.F('stop_id') \ - + "§trip_id:" + models.F('trip_id') \ - + "§trip_short_name:" + models.F('trip__short_name') \ - + "§trip_headsign:" + models.F('trip__headsign') \ - + "§route_short_name:" + models.F('trip__route__short_name') \ - + "§route_desc:" + models.F('trip__route__desc') \ - + "§route_type:" + models.F('trip__route__type') - - def __str__(self): - return f"{self.stop.name} - {self.trip_id}" - - class Meta: - verbose_name = _("Stop time") - verbose_name_plural = _("Stop times") - indexes = (models.Index(fields=['stop']), models.Index(fields=['trip']),) - - -class Calendar(models.Model): - id = models.CharField( - max_length=255, - primary_key=True, - verbose_name=_("Service ID"), - ) - - monday = models.BooleanField( - verbose_name=_("Monday"), - ) - - tuesday = models.BooleanField( - verbose_name=_("Tuesday"), - ) - - wednesday = models.BooleanField( - verbose_name=_("Wednesday"), - ) - - thursday = models.BooleanField( - verbose_name=_("Thursday"), - ) - - friday = models.BooleanField( - verbose_name=_("Friday"), - ) - - saturday = models.BooleanField( - verbose_name=_("Saturday"), - ) - - sunday = models.BooleanField( - verbose_name=_("Sunday"), - ) - - start_date = models.DateField( - verbose_name=_("Start date"), - ) - - end_date = models.DateField( - verbose_name=_("End date"), - ) - - gtfs_feed = models.ForeignKey( - GTFSFeed, - on_delete=models.CASCADE, - verbose_name=_("GTFS feed"), - ) - - def __str__(self): - return self.id - - class Meta: - verbose_name = _("Calendar") - verbose_name_plural = _("Calendars") - ordering = ("id",) - indexes = (models.Index(fields=['gtfs_feed']),) - - -class CalendarDate(models.Model): - id = models.CharField( - max_length=255, - primary_key=True, - verbose_name=_("ID"), - ) - - service = models.ForeignKey( - to="Calendar", - on_delete=models.CASCADE, - verbose_name=_("Service"), - related_name="dates", - ) - - date = models.DateField( - verbose_name=_("Date"), - ) - - exception_type = models.IntegerField( - verbose_name=_("Exception type"), - choices=ExceptionType, - ) - - def __str__(self): - return f"{self.service.id} - {self.date} - {self.exception_type}" - - class Meta: - verbose_name = _("Calendar date") - verbose_name_plural = _("Calendar dates") - ordering = ("id",) - indexes = (models.Index(fields=['service']), models.Index(fields=['date']),) - - -class Transfer(models.Model): - id = models.CharField( - max_length=255, - primary_key=True, - verbose_name=_("ID"), - ) - - from_stop = models.ForeignKey( - to="Stop", - on_delete=models.CASCADE, - verbose_name=_("From stop"), - related_name="transfers_from", - ) - - to_stop = models.ForeignKey( - to="Stop", - on_delete=models.CASCADE, - verbose_name=_("To stop"), - related_name="transfers_to", - ) - - from_route = models.ForeignKey( - to="Route", - on_delete=models.CASCADE, - verbose_name=_("From route"), - related_name="transfers_from", - null=True, - blank=True, - default=None, - ) - - to_route = models.ForeignKey( - to="Route", - on_delete=models.CASCADE, - verbose_name=_("To route"), - related_name="transfers_to", - null=True, - blank=True, - default=None, - ) - - from_trip = models.ForeignKey( - to="Trip", - on_delete=models.CASCADE, - verbose_name=_("From trip"), - related_name="transfers_from", - null=True, - blank=True, - default=None, - ) - - to_trip = models.ForeignKey( - to="Trip", - on_delete=models.CASCADE, - verbose_name=_("To trip"), - related_name="transfers_to", - null=True, - blank=True, - default=None, - ) - - transfer_type = models.IntegerField( - verbose_name=_("Transfer type"), - choices=TransferType, - default=TransferType.RECOMMENDED, - ) - - min_transfer_time = models.IntegerField( - verbose_name=_("Minimum transfer time"), - blank=True, - default=None, - ) - - class Meta: - verbose_name = _("Transfer") - verbose_name_plural = _("Transfers") - ordering = ("id",) - - -class FeedInfo(models.Model): - publisher_name = models.CharField( - max_length=255, - verbose_name=_("Feed publisher name"), - ) - - publisher_url = models.URLField( - verbose_name=_("Feed publisher URL"), - ) - - lang = models.CharField( - max_length=255, - verbose_name=_("Feed language"), - ) - - start_date = models.DateField( - verbose_name=_("Feed start date"), - ) - - end_date = models.DateField( - verbose_name=_("Feed end date"), - ) - - version = models.CharField( - max_length=255, - verbose_name=_("Feed version"), - ) - - gtfs_feed = models.ForeignKey( - GTFSFeed, - on_delete=models.CASCADE, - verbose_name=_("GTFS feed"), - ) - - class Meta: - verbose_name = _("Feed info") - verbose_name_plural = _("Feed infos") - ordering = ("publisher_name",) - indexes = (models.Index(fields=['gtfs_feed']),) - - -class TripUpdate(models.Model): - trip = models.OneToOneField( - to="Trip", - on_delete=models.CASCADE, - verbose_name=_("Trip"), - related_name="update", - primary_key=True, - ) - - start_date = models.DateField( - verbose_name=_("Start date"), - ) - - start_time = models.TimeField( - verbose_name=_("Start time"), - ) - - schedule_relationship = models.IntegerField( - verbose_name=_("Schedule relationship"), - choices=TripScheduleRelationship, - default=TripScheduleRelationship.SCHEDULED, - ) - - def __str__(self): - return str(self.trip) - - class Meta: - verbose_name = _("Trip update") - verbose_name_plural = _("Trip updates") - ordering = ("start_date", "trip",) - unique_together = ("trip", "start_date", "start_time",) - indexes = (models.Index(fields=['trip']),) - - -class StopTimeUpdate(models.Model): - trip_update = models.ForeignKey( - to="TripUpdate", - on_delete=models.CASCADE, - verbose_name=_("Trip update"), - related_name="stop_time_updates", - ) - - stop_time = models.OneToOneField( - to="StopTime", - on_delete=models.CASCADE, - verbose_name=_("Stop time"), - related_name="update", - primary_key=True, - ) - - arrival_delay = models.DurationField( - verbose_name=_("Arrival delay"), - ) - - arrival_time = models.DateTimeField( - verbose_name=_("Arrival time"), - ) - - departure_delay = models.DurationField( - verbose_name=_("Departure delay"), - ) - - departure_time = models.DateTimeField( - verbose_name=_("Departure time"), - ) - - schedule_relationship = models.IntegerField( - verbose_name=_("Schedule relationship"), - choices=StopScheduleRelationship, - default=StopScheduleRelationship.SCHEDULED, - ) - - def __str__(self): - return str(self.trip_update) - - class Meta: - verbose_name = _("Stop time update") - verbose_name_plural = _("Stop time updates") - ordering = ("trip_update", "stop_time",) - unique_together = ("trip_update", "stop_time",) - indexes = (models.Index(fields=['trip_update']), models.Index(fields=['stop_time']),) diff --git a/trainvel/gtfs/signals.py b/trainvel/gtfs/signals.py deleted file mode 100644 index 3e339f0..0000000 --- a/trainvel/gtfs/signals.py +++ /dev/null @@ -1,14 +0,0 @@ -from trainvel.gtfs.models import GTFSFeed - - -def keep_gtfs_feed_modification_date(instance: GTFSFeed, raw: bool = True, **_kwargs): - """ - Keep the last_modified and etag fields from the existing GTFSFeed instance when saving a new one. - """ - if raw and GTFSFeed.objects.filter(pk=instance.pk).exists(): - # If a GTFSFeed instance is being saved from a raw query, - # we want to keep the last_modified and etag fields from the existing instance. - # This is useful when loading initial data from a fixture, for example. - old_instance = GTFSFeed.objects.get(pk=instance.pk) - instance.last_modified = old_instance.last_modified - instance.etag = old_instance.etag diff --git a/trainvel/gtfs/tests.py b/trainvel/gtfs/tests.py deleted file mode 100644 index 7ce503c..0000000 --- a/trainvel/gtfs/tests.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.test import TestCase - -# Create your tests here. diff --git a/trainvel/settings.py b/trainvel/settings.py deleted file mode 100644 index 400df71..0000000 --- a/trainvel/settings.py +++ /dev/null @@ -1,163 +0,0 @@ -""" -Django settings for trainvel project. - -Generated by 'django-admin startproject' using Django 5.0.1. - -For more information on this file, see -https://docs.djangoproject.com/en/5.0/topics/settings/ - -For the full list of settings and their values, see -https://docs.djangoproject.com/en/5.0/ref/settings/ -""" - -from pathlib import Path - -from corsheaders.defaults import default_headers - -# Build paths inside the project like this: BASE_DIR / 'subdir'. -BASE_DIR = Path(__file__).resolve().parent.parent - - -# Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/ - -# SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = "CHANGE ME" - -# SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True - -ALLOWED_HOSTS = [] - - -# Application definition - -INSTALLED_APPS = [ - "django.contrib.admin", - "django.contrib.auth", - "django.contrib.contenttypes", - "django.contrib.sessions", - "django.contrib.messages", - "django.contrib.staticfiles", - - "corsheaders", - "django_extensions", - "django_filters", - "rest_framework", - - "trainvel.api", - "trainvel.core", - "trainvel.gtfs", -] - -MIDDLEWARE = [ - "django.middleware.security.SecurityMiddleware", - "django.contrib.sessions.middleware.SessionMiddleware", - "corsheaders.middleware.CorsMiddleware", - "django.middleware.common.CommonMiddleware", - "django.middleware.csrf.CsrfViewMiddleware", - "django.contrib.auth.middleware.AuthenticationMiddleware", - "django.contrib.messages.middleware.MessageMiddleware", - "django.middleware.clickjacking.XFrameOptionsMiddleware", -] - -CORS_ALLOWED_ORIGINS = [ - "http://localhost:3000", -] - -CORS_ALLOW_HEADERS = ( - *default_headers, - "If-Modified-Since", - 'Cache-Control', -) - -ROOT_URLCONF = "trainvel.urls" - -TEMPLATES = [ - { - "BACKEND": "django.template.backends.django.DjangoTemplates", - "DIRS": [], - "APP_DIRS": True, - "OPTIONS": { - "context_processors": [ - "django.template.context_processors.debug", - "django.template.context_processors.request", - "django.contrib.auth.context_processors.auth", - "django.contrib.messages.context_processors.messages", - ], - }, - }, -] - -WSGI_APPLICATION = "trainvel.wsgi.application" - - -# Database -# https://docs.djangoproject.com/en/5.0/ref/settings/#databases - -DATABASES = { - "default": { - "ENGINE": "django.db.backends.sqlite3", - "NAME": BASE_DIR / "db.sqlite3", - } -} - - -# Password validation -# https://docs.djangoproject.com/en/5.0/ref/settings/#auth-password-validators - -AUTH_PASSWORD_VALIDATORS = [ - { - "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", - }, - { - "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", - }, - { - "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", - }, - { - "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", - }, -] - - -# Internationalization -# https://docs.djangoproject.com/en/5.0/topics/i18n/ - -LANGUAGE_CODE = "fr-fr" - -TIME_ZONE = "Europe/Paris" - -USE_I18N = True - -USE_TZ = True - - -# Static files (CSS, JavaScript, Images) -# https://docs.djangoproject.com/en/5.0/howto/static-files/ - -STATIC_URL = "api-static/" - -STATIC_ROOT = BASE_DIR / "static_files" - -# Default primary key field type -# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field - -DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" - -REST_FRAMEWORK = { - 'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'], - 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination', - 'PAGE_SIZE': 20, -} - -STATION_RADIUS = 300 - -OPENTRANSPORTDATA_SWISS_TOKEN = "CHANGE ME" - - -try: - from .settings_local import * -except ImportError: - pass diff --git a/trainvel/settings_local_example.py b/trainvel/settings_local_example.py deleted file mode 100644 index fd921ef..0000000 --- a/trainvel/settings_local_example.py +++ /dev/null @@ -1,22 +0,0 @@ -SECRET_KEY = "CHANGE ME" - -DEBUG = False - -ALLOWED_HOSTS = ['sncf.emy.lu'] - -CORS_ALLOWED_ORIGINS = [ - "https://sncf.emy.lu", -] - -DATABASES = { - "default": { - "ENGINE": "django.db.backends.postgresql", - "NAME": "trainvel", - "USER": "trainvel", - "PASSWORD": "CHANGE ME", - "HOST": "localhost", - "PORT": "5432", - } -} - -OPENTRANSPORTDATA_SWISS_TOKEN = "CHANGE ME" diff --git a/trainvel/urls.py b/trainvel/urls.py deleted file mode 100644 index 3ce17bd..0000000 --- a/trainvel/urls.py +++ /dev/null @@ -1,45 +0,0 @@ -""" -URL configuration for trainvel project. - -The `urlpatterns` list routes URLs to views. For more information please see: - https://docs.djangoproject.com/en/5.0/topics/http/urls/ -Examples: -Function views - 1. Add an import: from my_app import views - 2. Add a URL to urlpatterns: path('', views.home, name='home') -Class-based views - 1. Add an import: from other_app.views import Home - 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') -Including another URLconf - 1. Import the include() function: from django.urls import include, path - 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) -""" -from django.contrib import admin -from django.urls import path, include -from rest_framework import routers - -from trainvel.api.views import AgencyViewSet, StopViewSet, RouteViewSet, StationViewSet, TripViewSet, StopTimeViewSet, \ - CalendarViewSet, CalendarDateViewSet, TransferViewSet, FeedInfoViewSet, NextDeparturesViewSet, NextArrivalsViewSet, \ - TripUpdateViewSet, StopTimeUpdateViewSet - -router = routers.DefaultRouter() -router.register("core/station", StationViewSet) -router.register("gtfs/agency", AgencyViewSet) -router.register("gtfs/stop", StopViewSet) -router.register("gtfs/route", RouteViewSet) -router.register("gtfs/trip", TripViewSet) -router.register("gtfs/stop_time", StopTimeViewSet) -router.register("gtfs/calendar", CalendarViewSet) -router.register("gtfs/calendar_date", CalendarDateViewSet) -router.register("gtfs/transfer", TransferViewSet) -router.register("gtfs/feed_info", FeedInfoViewSet) -router.register("gtfs-rt/trip_update", TripUpdateViewSet) -router.register("gtfs-rt/stop_time_update", StopTimeUpdateViewSet) -router.register("station/next_departures", NextDeparturesViewSet, basename="next_departures") -router.register("station/next_arrivals", NextArrivalsViewSet, basename="next_arrivals") - -urlpatterns = [ - path("admin/", admin.site.urls, name="admin"), - path("api/", include(router.urls)), - path("api-auth/", include('rest_framework.urls', namespace='rest_framework')), -] diff --git a/trainvel/wsgi.py b/trainvel/wsgi.py deleted file mode 100644 index 58e21dc..0000000 --- a/trainvel/wsgi.py +++ /dev/null @@ -1,16 +0,0 @@ -""" -WSGI config for trainvel project. - -It exposes the WSGI callable as a module-level variable named ``application``. - -For more information on this file, see -https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/ -""" - -import os - -from django.core.wsgi import get_wsgi_application - -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "trainvel.settings") - -application = get_wsgi_application()