2026-03-27 20:14:20 +01:00

219 lines
6.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from flask import Flask, request, jsonify
from flask_cors import CORS
import json
import os
from datetime import datetime
app = Flask(__name__)
CORS(app) # Enable CORS for all routes
# Data directory and file
DATA_DIR = 'data'
DATA_FILE = os.path.join(DATA_DIR, 'journeys.json')
os.makedirs(DATA_DIR, exist_ok=True)
# In-memory store (loaded from file on startup)
journeys = []
def load_journeys():
"""Load journeys from the JSON file."""
global journeys
try:
if os.path.exists(DATA_FILE):
with open(DATA_FILE, 'r') as f:
journeys = json.load(f)
else:
journeys = []
except Exception as e:
print(f"Error loading journeys: {e}")
journeys = []
def save_journeys():
"""Save journeys to the JSON file."""
try:
with open(DATA_FILE, 'w') as f:
json.dump(journeys, f, indent=2)
except Exception as e:
print(f"Error saving journeys: {e}")
# Load existing journeys on startup
load_journeys()
def get_next_id():
"""Return the next available ID (simple integer increment)."""
if not journeys:
return 1
return max(j['id'] for j in journeys) + 1
@app.route('/api/journeys', methods=['POST'])
def create_journey():
"""Create a new journey."""
data = request.get_json()
if not data:
return jsonify({'error': 'No data provided'}), 400
title = data.get('title')
if not title:
return jsonify({'error': 'Journey title is required'}), 400
new_journey = {
'id': get_next_id(),
'title': title,
'description': data.get('description', ''),
'markers': data.get('markers', []), # list of marker objects
'created_at': datetime.now().isoformat()
}
journeys.append(new_journey)
save_journeys()
return jsonify(new_journey), 201
@app.route('/api/journeys', methods=['GET'])
def get_journeys():
"""Return all journeys."""
return jsonify(journeys)
@app.route('/api/journeys/<int:journey_id>', methods=['GET'])
def get_journey(journey_id):
"""Return a specific journey by ID."""
journey = next((j for j in journeys if j['id'] == journey_id), None)
if journey is None:
return jsonify({'error': 'Journey not found'}), 404
return jsonify(journey)
@app.route('/api/journeys/<int:journey_id>', methods=['PUT'])
def update_journey(journey_id):
"""Update an existing journey."""
journey = next((j for j in journeys if j['id'] == journey_id), None)
if journey is None:
return jsonify({'error': 'Journey not found'}), 404
data = request.get_json()
if not data:
return jsonify({'error': 'No data provided'}), 400
# Update allowed fields
if 'title' in data:
journey['title'] = data['title']
if 'description' in data:
journey['description'] = data['description']
if 'markers' in data:
journey['markers'] = data['markers']
save_journeys()
return jsonify(journey)
@app.route('/api/journeys/<int:journey_id>', methods=['DELETE'])
def delete_journey(journey_id):
"""Delete a journey."""
global journeys
journey = next((j for j in journeys if j['id'] == journey_id), None)
if journey is None:
return jsonify({'error': 'Journey not found'}), 404
journeys = [j for j in journeys if j['id'] != journey_id]
save_journeys()
return jsonify({'message': 'Journey deleted successfully', 'journey': journey})
@app.route('/api/journeys/health', methods=['GET'])
def health_check():
"""Simple health check endpoint."""
return jsonify({'status': 'healthy', 'timestamp': datetime.now().isoformat()})
@app.route('/')
def index():
"""Root endpoint just a welcome message."""
return '''
<!DOCTYPE html>
<html>
<head><title>Journey Mapper Backend</title></head>
<body>
<h1>Journey Mapper API</h1>
<p>Backend is running. Use <code>/api/journeys</code> endpoints.</p>
</body>
</html>
'''
# Blog posts data file
BLOG_DATA_FILE = os.path.join(DATA_DIR, 'blog_posts.json')
def load_blog_posts():
try:
if os.path.exists(BLOG_DATA_FILE):
with open(BLOG_DATA_FILE, 'r') as f:
return json.load(f)
except:
pass
return []
def save_blog_posts(posts):
with open(BLOG_DATA_FILE, 'w') as f:
json.dump(posts, f, indent=2)
blog_posts = load_blog_posts()
def get_next_blog_id():
if not blog_posts:
return 1
return max(p['id'] for p in blog_posts) + 1
@app.route('/api/blog-posts', methods=['GET'])
def get_blog_posts():
return jsonify(blog_posts)
@app.route('/api/blog-posts/<int:post_id>', methods=['GET'])
def get_blog_post(post_id):
post = next((p for p in blog_posts if p['id'] == post_id), None)
if not post:
return jsonify({'error': 'Post not found'}), 404
return jsonify(post)
@app.route('/api/blog-posts', methods=['POST'])
def create_blog_post():
data = request.get_json()
title = data.get('title')
if not title:
return jsonify({'error': 'Title required'}), 400
new_post = {
'id': get_next_blog_id(),
'title': title,
'content': data.get('content', ''),
'journeyId': data.get('journeyId'),
'image': data.get('image'),
'created_at': datetime.now().isoformat()
}
blog_posts.append(new_post)
save_blog_posts(blog_posts)
return jsonify(new_post), 201
@app.route('/api/blog-posts/<int:post_id>', methods=['PUT'])
def update_blog_post(post_id):
post = next((p for p in blog_posts if p['id'] == post_id), None)
if not post:
return jsonify({'error': 'Post not found'}), 404
data = request.get_json()
if 'title' in data:
post['title'] = data['title']
if 'content' in data:
post['content'] = data['content']
if 'journeyId' in data:
post['journeyId'] = data['journeyId']
if 'image' in data:
post['image'] = data['image']
save_blog_posts(blog_posts)
return jsonify(post)
@app.route('/api/blog-posts/<int:post_id>', methods=['DELETE'])
def delete_blog_post(post_id):
global blog_posts
post = next((p for p in blog_posts if p['id'] == post_id), None)
if not post:
return jsonify({'error': 'Post not found'}), 404
blog_posts = [p for p in blog_posts if p['id'] != post_id]
save_blog_posts(blog_posts)
return jsonify({'message': 'Post deleted'})
if __name__ == '__main__':
app.run(debug=True, port=5000)