Skip to content

Commit f01e89e

Browse files
committed
add action to sync nextbike periodically
1 parent b5e3ba6 commit f01e89e

File tree

5 files changed

+116
-0
lines changed

5 files changed

+116
-0
lines changed

.github/workflows/sync.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: Sync networks
2+
on:
3+
workflow_dispatch:
4+
schedule:
5+
- cron: '0 10 * * *'
6+
jobs:
7+
sync-nextbike:
8+
runs-on: ubuntu-latest
9+
steps:
10+
- uses: actions/checkout@v4
11+
- name: Set up Python 3.12
12+
uses: actions/setup-python@v5
13+
with:
14+
python-version: 3.12
15+
- name: Install dependencies
16+
run: make install
17+
- name: Sync nextbike
18+
run: |
19+
python utils/sync_nextbike.py > nextbike.json
20+
mv nextbike.json pybikes/data/nextbike.json
21+
- name: Create Pull Request
22+
uses: peter-evans/create-pull-request@v7
23+
with:
24+
commit-message: update nextbike feeds
25+
title: update nextbike feeds
26+
branch: sync/nextbike

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ keys.py
88
.env
99

1010
.idea/
11+
12+
report/

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ test = [
6767
# pin pytest-metadata until https://github.com/numirias/pytest-json-report/issues/89
6868
"pytest-metadata==2.0.4",
6969
"pytest-json-report",
70+
"python-slugify",
7071
]
7172

7273
[tool.setuptools.packages.find]

requirements.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,6 @@ jinja2
1313
## pin pytest-metadata until https://github.com/numirias/pytest-json-report/issues/89
1414
pytest-metadata==2.0.4
1515
pytest-json-report
16+
17+
# sync script
18+
python-slugify

utils/sync_nextbike.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
""" Very dumb script that goes through the public list of nextbike feeds and
2+
syncs it with pybikes. Might work for 80% of the cases.
3+
"""
4+
5+
import json
6+
7+
import requests
8+
from slugify import slugify
9+
10+
import pybikes
11+
12+
NEXTBIKE_LIVE_FEED = 'https://api.nextbike.net/maps/nextbike-live.json'
13+
14+
# There are many tests systems. Put them here so they are ignored
15+
ignored_domains = [
16+
'wh', 'tb', 'bs', 'bw', 'lt',
17+
]
18+
19+
20+
def pybikes_net(country):
21+
# Try to detect when a system has a distinct name other than
22+
# nextbike-city. Or otherwise, detect when it is _not_ relevant
23+
# that is easier I guess
24+
city = ' - '.join([c['name'] for c in country['cities']])
25+
tag = slugify(country['name'])
26+
if 'nextbike' not in tag:
27+
tag = 'nextbike-%s' % tag
28+
29+
return {
30+
"domain": country["domain"],
31+
"tag": tag,
32+
"meta": {
33+
"name": country['name'],
34+
"city": city,
35+
"country": country["country"],
36+
"latitude": country["lat"],
37+
"longitude": country["lng"],
38+
},
39+
}
40+
41+
42+
data = requests.get(NEXTBIKE_LIVE_FEED).json()
43+
py_data = pybikes.get_data('nextbike')
44+
py_gbfs_data = pybikes.get_data('nextbike_gbfs')
45+
46+
domains = [c["domain"] for c in data["countries"]]
47+
py_domains = [i['domain'] for i in py_data['instances']]
48+
py_domains += [i['domain'] for i in py_gbfs_data['instances']]
49+
50+
instances = []
51+
52+
for i in py_data['instances']:
53+
if i['domain'] not in domains:
54+
# domain not present, check if it works
55+
instance = pybikes.get(i['tag'])
56+
try:
57+
instance.update()
58+
except:
59+
# its borked, remove it
60+
continue
61+
62+
# keep it
63+
instances.append(i)
64+
65+
# Now look for new ones
66+
for country in data['countries']:
67+
places = sum([len(c['places']) for c in country['cities']])
68+
# Ignore empty networks
69+
if places == 0:
70+
continue
71+
72+
# ignore already supported network
73+
if country["domain"] in py_domains:
74+
continue
75+
76+
if country["domain"] in ignored_domains:
77+
continue
78+
79+
instances.append(pybikes_net(country))
80+
81+
82+
py_data['instances'] = instances
83+
84+
print(json.dumps(py_data, indent=4))

0 commit comments

Comments
 (0)