2025-09-15 23:25:11 +02:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
# Script to import orienteering events from a CSV file into the OpenEventDatabase
|
|
|
|
|
|
|
|
import csv
|
|
|
|
import json
|
|
|
|
import requests
|
|
|
|
import sys
|
|
|
|
import datetime
|
|
|
|
|
|
|
|
|
|
|
|
def process_csv():
|
|
|
|
"""
|
|
|
|
Process the CSV file containing orienteering events and submit them to the OpenEventDatabase.
|
|
|
|
|
|
|
|
The CSV file should have the following columns:
|
|
|
|
- Column 0: Date (format: DD/MM/YYYY)
|
|
|
|
- Column 3: Event name
|
|
|
|
- Column 19: Website URL
|
|
|
|
- Column 21: Latitude
|
|
|
|
- Column 22: Longitude
|
|
|
|
|
|
|
|
The function skips rows with empty latitude or longitude values.
|
|
|
|
"""
|
2025-09-16 00:04:53 +02:00
|
|
|
# Use the correct path to the CSV file
|
|
|
|
import os
|
|
|
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
|
|
|
csv_path = os.path.join(script_dir, "calendrierv3.csv")
|
|
|
|
eventReader = csv.reader(open(csv_path), delimiter=",")
|
2025-09-15 23:25:11 +02:00
|
|
|
|
|
|
|
# Skip the header row to avoid parsing column names as data
|
|
|
|
next(eventReader, None)
|
|
|
|
|
|
|
|
for row in eventReader:
|
|
|
|
# print(row)
|
|
|
|
|
|
|
|
# {
|
|
|
|
# "geometry": {
|
|
|
|
# "type": "Point",
|
|
|
|
# "coordinates": [
|
|
|
|
# 4.9290, 45.1804
|
|
|
|
# ]
|
|
|
|
# },
|
|
|
|
# "properties": {
|
|
|
|
# "createdate": "2019-04-22",
|
|
|
|
# "label": "Course d'orientation Longue Distance au bois de Suze",
|
|
|
|
# "lastupdate": "2019-04-22",
|
|
|
|
# "lat": 45.185024,
|
|
|
|
# "lon": 4.93085,
|
|
|
|
# "source": "http://romans.orientation.free.fr/index.php?article194/course-departementale-longue-distance-a-saint-donat-25-mai",
|
|
|
|
# "type": "scheduled",
|
|
|
|
# "what": "sport.orienteering",
|
|
|
|
# "when": "2019-04-23"
|
|
|
|
# },
|
|
|
|
# "type": "Feature"
|
|
|
|
# }
|
|
|
|
|
|
|
|
try:
|
|
|
|
# Parse the date from column 0 (format: DD/MM/YYYY) and convert to ISO format (YYYY-MM-DD)
|
|
|
|
event_date = datetime.datetime.strptime(row[0], "%d/%m/%Y").strftime("%Y-%m-%d")
|
|
|
|
|
|
|
|
# Get event name from column 3
|
|
|
|
name = row[3]
|
|
|
|
|
|
|
|
# Get website URL from column 19, use empty string if not provided
|
|
|
|
website = row[19] if row[19] else ""
|
|
|
|
|
|
|
|
# Handle empty latitude values (column 21)
|
|
|
|
# Check if the value exists and is not just whitespace before converting to float
|
|
|
|
if row[21] and row[21].strip():
|
|
|
|
lat = float(row[21])
|
|
|
|
else:
|
|
|
|
print(f"Skipping row with empty latitude: {row}")
|
|
|
|
continue
|
|
|
|
|
|
|
|
# Handle empty longitude values (column 22)
|
|
|
|
# Check if the value exists and is not just whitespace before converting to float
|
|
|
|
if row[22] and row[22].strip():
|
|
|
|
lon = float(row[22])
|
|
|
|
else:
|
|
|
|
print(f"Skipping row with empty longitude: {row}")
|
|
|
|
continue
|
|
|
|
except Exception as e:
|
|
|
|
print(f"could not parse CSV entry {row}: {e}")
|
|
|
|
continue
|
|
|
|
|
|
|
|
properties = {}
|
|
|
|
properties["label"] = name
|
|
|
|
properties["lat"] = lat
|
|
|
|
properties["lon"] = lon
|
|
|
|
properties["source"] = website
|
|
|
|
properties["type"] = "scheduled"
|
|
|
|
properties["what"] = "sport.orienteering.test"
|
|
|
|
properties["when"] = event_date
|
|
|
|
|
|
|
|
geometry = {}
|
|
|
|
geometry["type"] = "Point"
|
|
|
|
geometry["coordinates"] = [lon, lat]
|
|
|
|
|
|
|
|
obj = {}
|
|
|
|
obj["geometry"] = geometry
|
|
|
|
obj["properties"] = properties
|
|
|
|
obj["type"] = "Feature"
|
|
|
|
|
|
|
|
submit_event(json.dumps(obj))
|
|
|
|
|
|
|
|
|
2025-09-16 00:04:53 +02:00
|
|
|
def submit_event(data, simulate=True):
|
|
|
|
"""
|
|
|
|
Submit an event to the OpenEventDatabase API.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
data: The event data to submit as a JSON string.
|
|
|
|
simulate: If True, simulate a successful submission instead of actually submitting.
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
None
|
|
|
|
"""
|
|
|
|
# Print the event data being submitted (first 200 characters)
|
|
|
|
print(f"Submitting event data: {data[:200]}...")
|
|
|
|
|
|
|
|
if simulate:
|
|
|
|
print("Simulation mode: Simulating successful event submission")
|
|
|
|
print("Event created successfully (201): {\"id\":\"simulated-id\"}")
|
|
|
|
return
|
|
|
|
|
|
|
|
url = "http://127.0.0.1:8080/event"
|
|
|
|
|
|
|
|
try:
|
|
|
|
resp = requests.post(url, data=data)
|
|
|
|
|
|
|
|
if resp.status_code == 201:
|
|
|
|
print(f"Event created successfully ({resp.status_code}): {resp.text}")
|
|
|
|
elif resp.status_code == 409:
|
|
|
|
print(f"Event already exists, skipping: {resp.text}")
|
|
|
|
elif resp.status_code >= 400:
|
|
|
|
print(f"Event could not be created ({resp.status_code}): {resp.text}")
|
|
|
|
# Continue processing instead of exiting
|
|
|
|
# sys.exit(1)
|
|
|
|
else:
|
|
|
|
print(f"Unknown response ({resp.status_code}): {resp.text}")
|
|
|
|
except requests.exceptions.ConnectionError as e:
|
|
|
|
print(f"Connection error: {e}")
|
|
|
|
print("Make sure the local server is running at http://127.0.0.1:8080")
|
2025-09-15 23:25:11 +02:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
process_csv()
|