From a57643b0b8de9aef89c12dd44abf8164bd6eb11f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorsten=20Fr=C3=B6hlinghaus?= Date: Wed, 20 Aug 2025 16:00:39 +0200 Subject: [PATCH 1/6] add share_birrer_adjust_bicycle converter --- CHANGELOG.md | 3 ++ app/converters/gbfs_https_to_http.py | 1 + app/converters/gbfs_set_return_constraint.py | 1 + app/converters/gbfs_set_ttl.py | 1 + .../gbfs_share_birrer_adjust_bicycle.py | 33 +++++++++++++++++++ config_dist_dev.yaml | 1 + 6 files changed, 40 insertions(+) create mode 100644 app/converters/gbfs_share_birrer_adjust_bicycle.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 9cec140..7062339 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ The changelog lists relevant feature changes between each release. Search GitHub issues and pull requests for smaller issues. +## 2025-08-20 +- add converter for `share_birrer_ch` feed: adjust bicycle type + ## 2025-06-25: - add converter for bolt feeds: remove all bicycle entries - note: if future bolt feeds contain bicycles, the bicycle entries must be added again diff --git a/app/converters/gbfs_https_to_http.py b/app/converters/gbfs_https_to_http.py index db508d1..9b88686 100644 --- a/app/converters/gbfs_https_to_http.py +++ b/app/converters/gbfs_https_to_http.py @@ -22,6 +22,7 @@ class GbfsHttpsToHttpConverter(BaseConverter): 'gbfs.api.ridedott.com', 'zeus.city', 'yoio.rideatom.com', + 'www.share-birrer.ch', ] def convert(self, data: Union[dict, list], path: str) -> Union[dict, list]: diff --git a/app/converters/gbfs_set_return_constraint.py b/app/converters/gbfs_set_return_constraint.py index bf0cbd8..4303955 100644 --- a/app/converters/gbfs_set_return_constraint.py +++ b/app/converters/gbfs_set_return_constraint.py @@ -15,6 +15,7 @@ class GbfsSetReturnConstraintConverter(BaseConverter): 'gbfs.api.ridedott.com', 'zeus.city', 'yoio.rideatom.com', + 'www.share-birrer.ch', ] # ensure that return_constraint is always set diff --git a/app/converters/gbfs_set_ttl.py b/app/converters/gbfs_set_ttl.py index 1e2e806..d2bb586 100644 --- a/app/converters/gbfs_set_ttl.py +++ b/app/converters/gbfs_set_ttl.py @@ -14,6 +14,7 @@ class GbfsSetTtlConverter(BaseConverter): 'gbfs.prod.sharedmobility.ch', 'api.voiapp.io', 'gbfs.api.ridedott.com', + 'www.share-birrer.ch', ] def convert(self, data: Union[dict, list], path: str) -> Union[dict, list]: diff --git a/app/converters/gbfs_share_birrer_adjust_bicycle.py b/app/converters/gbfs_share_birrer_adjust_bicycle.py new file mode 100644 index 0000000..e581ca9 --- /dev/null +++ b/app/converters/gbfs_share_birrer_adjust_bicycle.py @@ -0,0 +1,33 @@ +from typing import Union + +from app.base_converter import BaseConverter + +BICYCLE_ELECTRIC_MAX_RANGE_METERS = 60000 + + +class GbfsShareBirrerAdjustBicycleConverter(BaseConverter): + """ + share_birrer_ch uses invalid form_factor 'bike' + """ + + hostnames = ['www.share-birrer.ch'] + + def convert(self, data: Union[dict, list], path: str) -> Union[dict, list]: + if not isinstance(data, dict): + return data + + if path.endswith('/vehicle_types'): + fields = data.get('data') + if not isinstance(fields, dict): + return data + vehicle_types = fields.get('vehicle_types') + if not isinstance(vehicle_types, list): + return data + for vehicle_type in vehicle_types: + if vehicle_type.get('form_factor') == 'bike': + vehicle_type['form_factor'] = 'bicycle' + vehicle_type['propulsion_type'] = 'electric' + vehicle_type['max_range_meters'] = BICYCLE_ELECTRIC_MAX_RANGE_METERS + return data + + return data diff --git a/config_dist_dev.yaml b/config_dist_dev.yaml index 1a08ca5..6c4fc34 100644 --- a/config_dist_dev.yaml +++ b/config_dist_dev.yaml @@ -11,3 +11,4 @@ HTTP_TO_HTTPS_HOSTS: - gbfs.api.ridedott.com - zeus.city - yoio.rideatom.com + - www.share-birrer.ch From 7d552c8561af9f2a2c0ea2cfee296620783854e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorsten=20Fr=C3=B6hlinghaus?= Date: Wed, 20 Aug 2025 16:20:15 +0200 Subject: [PATCH 2/6] add 2nd hostname --- app/converters/gbfs_https_to_http.py | 1 + app/converters/gbfs_set_return_constraint.py | 1 + app/converters/gbfs_set_ttl.py | 1 + app/converters/gbfs_share_birrer_adjust_bicycle.py | 2 +- config_dist_dev.yaml | 1 + 5 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/converters/gbfs_https_to_http.py b/app/converters/gbfs_https_to_http.py index 9b88686..4589ddd 100644 --- a/app/converters/gbfs_https_to_http.py +++ b/app/converters/gbfs_https_to_http.py @@ -23,6 +23,7 @@ class GbfsHttpsToHttpConverter(BaseConverter): 'zeus.city', 'yoio.rideatom.com', 'www.share-birrer.ch', + 'auto-birrer.ch', ] def convert(self, data: Union[dict, list], path: str) -> Union[dict, list]: diff --git a/app/converters/gbfs_set_return_constraint.py b/app/converters/gbfs_set_return_constraint.py index 4303955..9cf8399 100644 --- a/app/converters/gbfs_set_return_constraint.py +++ b/app/converters/gbfs_set_return_constraint.py @@ -16,6 +16,7 @@ class GbfsSetReturnConstraintConverter(BaseConverter): 'zeus.city', 'yoio.rideatom.com', 'www.share-birrer.ch', + 'auto-birrer.ch', ] # ensure that return_constraint is always set diff --git a/app/converters/gbfs_set_ttl.py b/app/converters/gbfs_set_ttl.py index d2bb586..dbb6935 100644 --- a/app/converters/gbfs_set_ttl.py +++ b/app/converters/gbfs_set_ttl.py @@ -15,6 +15,7 @@ class GbfsSetTtlConverter(BaseConverter): 'api.voiapp.io', 'gbfs.api.ridedott.com', 'www.share-birrer.ch', + 'auto-birrer.ch', ] def convert(self, data: Union[dict, list], path: str) -> Union[dict, list]: diff --git a/app/converters/gbfs_share_birrer_adjust_bicycle.py b/app/converters/gbfs_share_birrer_adjust_bicycle.py index e581ca9..675b4a8 100644 --- a/app/converters/gbfs_share_birrer_adjust_bicycle.py +++ b/app/converters/gbfs_share_birrer_adjust_bicycle.py @@ -10,7 +10,7 @@ class GbfsShareBirrerAdjustBicycleConverter(BaseConverter): share_birrer_ch uses invalid form_factor 'bike' """ - hostnames = ['www.share-birrer.ch'] + hostnames = ['www.share-birrer.ch', 'auto-birrer.ch'] def convert(self, data: Union[dict, list], path: str) -> Union[dict, list]: if not isinstance(data, dict): diff --git a/config_dist_dev.yaml b/config_dist_dev.yaml index 6c4fc34..a08b4d7 100644 --- a/config_dist_dev.yaml +++ b/config_dist_dev.yaml @@ -12,3 +12,4 @@ HTTP_TO_HTTPS_HOSTS: - zeus.city - yoio.rideatom.com - www.share-birrer.ch + - auto-birrer.ch From 31d678a773599603b16c49c7f5fb7431d0a1b8df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorsten=20Fr=C3=B6hlinghaus?= Date: Wed, 20 Aug 2025 17:03:05 +0200 Subject: [PATCH 3/6] replace propulsion_type hydrogen by electric --- CHANGELOG.md | 2 +- app/converters/gbfs_share_birrer_adjust_bicycle.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7062339..fe01248 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ The changelog lists relevant feature changes between each release. Search GitHub issues and pull requests for smaller issues. ## 2025-08-20 -- add converter for `share_birrer_ch` feed: adjust bicycle type +- add converter for `share_birrer_ch` feed: correct form_factor and propulsion_type ## 2025-06-25: - add converter for bolt feeds: remove all bicycle entries diff --git a/app/converters/gbfs_share_birrer_adjust_bicycle.py b/app/converters/gbfs_share_birrer_adjust_bicycle.py index 675b4a8..57c5657 100644 --- a/app/converters/gbfs_share_birrer_adjust_bicycle.py +++ b/app/converters/gbfs_share_birrer_adjust_bicycle.py @@ -28,6 +28,8 @@ def convert(self, data: Union[dict, list], path: str) -> Union[dict, list]: vehicle_type['form_factor'] = 'bicycle' vehicle_type['propulsion_type'] = 'electric' vehicle_type['max_range_meters'] = BICYCLE_ELECTRIC_MAX_RANGE_METERS + if vehicle_type.get('propulsion_type') == 'hydrogen': + vehicle_type['propulsion_type'] = 'electric' # hydrogen_fuel_cell is not available in 2.2 return data return data From f44fbcb7c44022c5a59fc38d5986550c7995bc87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorsten=20Fr=C3=B6hlinghaus?= Date: Wed, 20 Aug 2025 17:12:27 +0200 Subject: [PATCH 4/6] set bicycle return-constraint --- app/converters/gbfs_share_birrer_adjust_bicycle.py | 1 + 1 file changed, 1 insertion(+) diff --git a/app/converters/gbfs_share_birrer_adjust_bicycle.py b/app/converters/gbfs_share_birrer_adjust_bicycle.py index 57c5657..3d96504 100644 --- a/app/converters/gbfs_share_birrer_adjust_bicycle.py +++ b/app/converters/gbfs_share_birrer_adjust_bicycle.py @@ -28,6 +28,7 @@ def convert(self, data: Union[dict, list], path: str) -> Union[dict, list]: vehicle_type['form_factor'] = 'bicycle' vehicle_type['propulsion_type'] = 'electric' vehicle_type['max_range_meters'] = BICYCLE_ELECTRIC_MAX_RANGE_METERS + vehicle_type['return_constraint'] = 'roundtrip_station' # there is only one bicycle station if vehicle_type.get('propulsion_type') == 'hydrogen': vehicle_type['propulsion_type'] = 'electric' # hydrogen_fuel_cell is not available in 2.2 return data From bcfc3354efd4946402e08c705e3e8f156fb353c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorsten=20Fr=C3=B6hlinghaus?= Date: Wed, 20 Aug 2025 17:14:07 +0200 Subject: [PATCH 5/6] set bicycle return-constraint --- app/converters/gbfs_set_return_constraint.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/converters/gbfs_set_return_constraint.py b/app/converters/gbfs_set_return_constraint.py index 9cf8399..bf0cbd8 100644 --- a/app/converters/gbfs_set_return_constraint.py +++ b/app/converters/gbfs_set_return_constraint.py @@ -15,8 +15,6 @@ class GbfsSetReturnConstraintConverter(BaseConverter): 'gbfs.api.ridedott.com', 'zeus.city', 'yoio.rideatom.com', - 'www.share-birrer.ch', - 'auto-birrer.ch', ] # ensure that return_constraint is always set From 1289a2c943c2a801bf434ee08ba58a5394459899 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorsten=20Fr=C3=B6hlinghaus?= Date: Thu, 21 Aug 2025 07:09:53 +0200 Subject: [PATCH 6/6] return_constraint: any_station --- app/converters/gbfs_share_birrer_adjust_bicycle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/converters/gbfs_share_birrer_adjust_bicycle.py b/app/converters/gbfs_share_birrer_adjust_bicycle.py index 3d96504..9c1f2aa 100644 --- a/app/converters/gbfs_share_birrer_adjust_bicycle.py +++ b/app/converters/gbfs_share_birrer_adjust_bicycle.py @@ -28,7 +28,7 @@ def convert(self, data: Union[dict, list], path: str) -> Union[dict, list]: vehicle_type['form_factor'] = 'bicycle' vehicle_type['propulsion_type'] = 'electric' vehicle_type['max_range_meters'] = BICYCLE_ELECTRIC_MAX_RANGE_METERS - vehicle_type['return_constraint'] = 'roundtrip_station' # there is only one bicycle station + vehicle_type['return_constraint'] = 'any_station' # currently, there is only one station for bicycles if vehicle_type.get('propulsion_type') == 'hydrogen': vehicle_type['propulsion_type'] = 'electric' # hydrogen_fuel_cell is not available in 2.2 return data