Files
Munich-news/backend/routes/subscription_routes.py
2025-11-12 13:35:59 +01:00

113 lines
3.8 KiB
Python

from flask import Blueprint, request, jsonify
from datetime import datetime
from pymongo.errors import DuplicateKeyError
from database import subscribers_collection
subscription_bp = Blueprint('subscription', __name__)
@subscription_bp.route('/api/subscribe', methods=['POST'])
def subscribe():
"""Subscribe a user to the newsletter"""
data = request.json
email = data.get('email', '').strip().lower()
if not email or '@' not in email:
return jsonify({'error': 'Invalid email address'}), 400
try:
subscriber_doc = {
'email': email,
'subscribed_at': datetime.utcnow(),
'status': 'active'
}
# Try to insert, if duplicate key error, subscriber already exists
try:
subscribers_collection.insert_one(subscriber_doc)
return jsonify({'message': 'Successfully subscribed!'}), 201
except DuplicateKeyError:
# Check if subscriber is active
existing = subscribers_collection.find_one({'email': email})
if existing and existing.get('status') == 'active':
return jsonify({'message': 'Email already subscribed'}), 200
else:
# Reactivate if previously unsubscribed
subscribers_collection.update_one(
{'email': email},
{'$set': {'status': 'active', 'subscribed_at': datetime.utcnow()}}
)
return jsonify({'message': 'Successfully re-subscribed!'}), 200
except Exception as e:
return jsonify({'error': str(e)}), 500
@subscription_bp.route('/api/unsubscribe', methods=['POST'])
def unsubscribe():
"""Unsubscribe a user from the newsletter"""
data = request.json
email = data.get('email', '').strip().lower()
try:
result = subscribers_collection.update_one(
{'email': email},
{'$set': {'status': 'inactive'}}
)
if result.matched_count > 0:
return jsonify({'message': 'Successfully unsubscribed'}), 200
else:
return jsonify({'error': 'Email not found in subscribers'}), 404
except Exception as e:
return jsonify({'error': str(e)}), 500
@subscription_bp.route('/api/subscribers', methods=['GET'])
def list_subscribers():
"""List all subscribers with optional status filter"""
try:
# Get status filter from query params (default: all)
status = request.args.get('status', None)
# Build query
query = {}
if status:
query['status'] = status
# Fetch subscribers
subscribers = list(subscribers_collection.find(
query,
{'_id': 0, 'email': 1, 'subscribed_at': 1, 'status': 1}
).sort('subscribed_at', -1))
# Convert datetime to ISO format
for sub in subscribers:
if 'subscribed_at' in sub:
sub['subscribed_at'] = sub['subscribed_at'].isoformat()
return jsonify({
'subscribers': subscribers,
'total': len(subscribers)
}), 200
except Exception as e:
return jsonify({'error': str(e)}), 500
@subscription_bp.route('/api/subscribers/<email>', methods=['DELETE'])
def remove_subscriber(email):
"""Permanently remove a subscriber from the database"""
try:
email = email.strip().lower()
result = subscribers_collection.delete_one({'email': email})
if result.deleted_count > 0:
return jsonify({'message': f'Subscriber {email} permanently removed'}), 200
else:
return jsonify({'error': 'Email not found in subscribers'}), 404
except Exception as e:
return jsonify({'error': str(e)}), 500