mgokg commited on
Commit
3ebcec9
·
verified ·
1 Parent(s): cc17660

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +0 -149
app.py CHANGED
@@ -3,154 +3,10 @@ import requests
3
  from datetime import datetime, timedelta
4
  import xml.etree.ElementTree as ET
5
  import json
6
- import os
7
 
8
  api_key=os.environ.get("api_key")
9
  client_id=os.environ.get("client_id")
10
 
11
- def get_station_info(pattern, client_id, api_key):
12
- """Ermittelt EVA-Nummer und offiziellen Namen."""
13
- url = f"https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/station/{pattern}"
14
- headers = {'DB-Client-Id': client_id, 'DB-Api-Key': api_key, 'accept': 'application/xml'}
15
- try:
16
- response = requests.get(url, headers=headers, timeout=10)
17
- response.raise_for_status()
18
- root = ET.fromstring(response.content)
19
- station = root.find('station')
20
- if station is not None:
21
- return {'name': station.get('name'), 'eva': station.get('eva')}
22
- except Exception:
23
- return None
24
- return None
25
-
26
- def fetch_timetable_hour(eva, date_str, hour_str, client_id, api_key):
27
- """Ruft den Fahrplan für eine bestimmte Stunde ab."""
28
- url = f"https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/plan/{eva}/{date_str}/{hour_str}"
29
- headers = {'DB-Client-Id': client_id, 'DB-Api-Key': api_key, 'accept': 'application/xml'}
30
- try:
31
- response = requests.get(url, headers=headers, timeout=10)
32
- if response.status_code == 200:
33
- return ET.fromstring(response.content)
34
- except Exception:
35
- pass
36
- return None
37
-
38
- def get_connections(departure, destination, client_id, api_key):
39
- """Sucht die nächsten 3 Verbindungen ab jetzt."""
40
-
41
- dep_info = get_station_info(departure, client_id, api_key)
42
- dest_info = get_station_info(destination, client_id, api_key)
43
-
44
- if not dep_info or not dest_info:
45
- return None, "❌ Bahnhof nicht gefunden. Bitte Namen prüfen."
46
-
47
- now = datetime.now()
48
- found_connections = []
49
-
50
- # Suche über 3 Stunden-Slots hinweg (aktuelle + nächste zwei)
51
- for hour_offset in range(3):
52
- search_time = now + timedelta(hours=hour_offset)
53
- datum = search_time.strftime("%y%m%d")
54
- stunde = search_time.strftime("%H")
55
-
56
- root = fetch_timetable_hour(dep_info['eva'], datum, stunde, client_id, api_key)
57
- if root is None: continue
58
-
59
- for train in root.findall('.//s'):
60
- dp = train.find('dp')
61
- if dp is None: continue
62
-
63
- path = dp.get('ppth', '')
64
- if dest_info['name'].lower() in path.lower() or destination.lower() in path.lower():
65
- pt = dp.get('pt', '')
66
- if not pt: continue
67
-
68
- dep_dt = datetime.strptime(pt, "%y%m%d%H%M")
69
-
70
- if dep_dt >= now:
71
- tl = train.find('tl')
72
- found_connections.append({
73
- "startort": dep_info['name'],
74
- "zielort": dest_info['name'],
75
- "abfahrtszeit": dep_dt.strftime("%H:%M"),
76
- "datum": dep_dt.strftime("%d.%m.%Y"),
77
- "gleis": dp.get('pp', '-'),
78
- "zug": f"{tl.get('c', '')} {tl.get('n', '')}",
79
- "_dt": dep_dt
80
- })
81
-
82
- found_connections.sort(key=lambda x: x['_dt'])
83
- return found_connections[:3], None
84
-
85
- def format_markdown(connections):
86
- """Erstellt eine Smartphone-optimierte Markdown-Ansicht."""
87
- if not connections:
88
- return "### ℹ️ Keine Verbindungen gefunden\nIn den nächsten 3 Stunden wurden keine Direktverbindungen gefunden."
89
-
90
- md = f"## 🚆 {connections[0]['startort']} → {connections[0]['zielort']}\n"
91
- md += f"*{datetime.now().strftime('%H:%M')} Uhr Stand*\n\n"
92
-
93
- for i, c in enumerate(connections, 1):
94
- md += f"### {i}. {c['abfahrtszeit']} Uhr\n"
95
- md += f"**{c['zug']}** \n"
96
- md += f"Gleis: **{c['gleis']}** | Datum: {c['datum']}\n"
97
- md += "---\n" # Trennlinie für bessere Lesbarkeit auf dem Handy
98
-
99
- return md
100
-
101
- def main_interface(dep, dest, cid, akey):
102
- conns, error = get_connections(dep, dest, cid, akey)
103
-
104
- if error:
105
- return error, json.dumps({"error": error}, indent=2)
106
-
107
- # JSON-Bereinigung (internes Sortierfeld entfernen)
108
- clean_json = []
109
- for c in conns:
110
- clean_json.append({k: v for k, v in c.items() if k != "_dt"})
111
-
112
- md_output = format_markdown(clean_json)
113
- json_output = json.dumps(clean_json, indent=4, ensure_ascii=False)
114
-
115
- return md_output, json_output
116
-
117
- # --- Gradio UI ---
118
- with gr.Blocks(title="DB Mobile Fahrplan", theme=gr.themes.Soft()) as demo:
119
- gr.Markdown("# 📱 DB Quick-Check")
120
-
121
- with gr.Accordion("⚙️ API-Konfiguration (Hier klicken)", open=False):
122
- cid_input = gr.Textbox(label="DB Client ID", type="password")
123
- akey_input = gr.Textbox(label="DB API Key", type="password")
124
-
125
- with gr.Row():
126
- dep_input = gr.Textbox(label="Von", placeholder="z.B. Berlin", scale=2)
127
- dest_input = gr.Textbox(label="Nach", placeholder="z.B. Hamburg", scale=2)
128
-
129
- btn = gr.Button("🔍 Verbindungen suchen", variant="primary")
130
-
131
- with gr.Tabs():
132
- with gr.TabItem("📱 Ansicht"):
133
- md_display = gr.Markdown("Geben Sie Start und Ziel ein und drücken Sie Suchen.")
134
- with gr.TabItem("💻 JSON"):
135
- json_display = gr.Code(label="API Response", language="json")
136
-
137
- btn.click(
138
- fn=main_interface,
139
- inputs=[dep_input, dest_input, cid_input, akey_input],
140
- outputs=[md_display, json_display]
141
- )
142
-
143
- if __name__ == "__main__":
144
- demo.launch()
145
-
146
-
147
- """
148
- import gradio as gr
149
- import requests
150
- from datetime import datetime, timedelta
151
- import xml.etree.ElementTree as ET
152
- import json
153
-
154
  def
155
  url = f"https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/station/{pattern}"
156
  headers = {
@@ -186,10 +42,6 @@ def fetch_timetable_hour(eva, date_str, hour_str, client_id, api_key):
186
  return None
187
 
188
  def search_next_3_connections(departure, destination, client_id, api_key):
189
-
190
-
191
- if not all([departure, destination, client_id, api_key]):
192
- return {"error": "Bitte alle Felder ausfüllen."}
193
 
194
  # 1. IBNRs ermitteln
195
  dep_info = get_station_info(departure, client_id, api_key)
@@ -401,4 +253,3 @@ with gr.Blocks(title="DB JSON Fahrplan", theme=gr.themes.Soft()) as demo:
401
  btn.click(fn=ui_wrapper, inputs=[dep_input, dest_input, cid_input, akey_input], outputs=output)
402
 
403
  if __name__ == "__main__":
404
- """
 
3
  from datetime import datetime, timedelta
4
  import xml.etree.ElementTree as ET
5
  import json
 
6
 
7
  api_key=os.environ.get("api_key")
8
  client_id=os.environ.get("client_id")
9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  def
11
  url = f"https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/station/{pattern}"
12
  headers = {
 
42
  return None
43
 
44
  def search_next_3_connections(departure, destination, client_id, api_key):
 
 
 
 
45
 
46
  # 1. IBNRs ermitteln
47
  dep_info = get_station_info(departure, client_id, api_key)
 
253
  btn.click(fn=ui_wrapper, inputs=[dep_input, dest_input, cid_input, akey_input], outputs=output)
254
 
255
  if __name__ == "__main__":