113 lines
3.8 KiB
Python
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
|