update
This commit is contained in:
@@ -8,36 +8,69 @@ subscription_bp = Blueprint('subscription', __name__)
|
||||
|
||||
@subscription_bp.route('/api/subscribe', methods=['POST'])
|
||||
def subscribe():
|
||||
"""Subscribe a user to the newsletter"""
|
||||
"""Subscribe a user to the newsletter with category preferences"""
|
||||
data = request.json
|
||||
email = data.get('email', '').strip().lower()
|
||||
# Get valid categories from RSS feeds
|
||||
from database import rss_feeds_collection
|
||||
valid_categories = rss_feeds_collection.distinct('category')
|
||||
|
||||
categories = data.get('categories', valid_categories) # Default: all categories
|
||||
|
||||
if not email or '@' not in email:
|
||||
return jsonify({'error': 'Invalid email address'}), 400
|
||||
|
||||
# Validate categories
|
||||
if not isinstance(categories, list) or not categories:
|
||||
categories = valid_categories # Default to all if invalid
|
||||
else:
|
||||
# Filter to only valid categories (categories that exist in RSS feeds)
|
||||
categories = [c for c in categories if c in valid_categories]
|
||||
if not categories:
|
||||
categories = valid_categories # Default to all if none valid
|
||||
|
||||
try:
|
||||
subscriber_doc = {
|
||||
'email': email,
|
||||
'subscribed_at': datetime.utcnow(),
|
||||
'status': 'active'
|
||||
'status': 'active',
|
||||
'categories': categories
|
||||
}
|
||||
|
||||
# Try to insert, if duplicate key error, subscriber already exists
|
||||
try:
|
||||
subscribers_collection.insert_one(subscriber_doc)
|
||||
return jsonify({'message': 'Successfully subscribed!'}), 201
|
||||
return jsonify({
|
||||
'message': 'Successfully subscribed!',
|
||||
'categories': categories
|
||||
}), 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
|
||||
# Update categories even if already subscribed
|
||||
subscribers_collection.update_one(
|
||||
{'email': email},
|
||||
{'$set': {'categories': categories}}
|
||||
)
|
||||
return jsonify({
|
||||
'message': 'Email already subscribed. Preferences updated!',
|
||||
'categories': categories
|
||||
}), 200
|
||||
else:
|
||||
# Reactivate if previously unsubscribed
|
||||
subscribers_collection.update_one(
|
||||
{'email': email},
|
||||
{'$set': {'status': 'active', 'subscribed_at': datetime.utcnow()}}
|
||||
{'$set': {
|
||||
'status': 'active',
|
||||
'subscribed_at': datetime.utcnow(),
|
||||
'categories': categories
|
||||
}}
|
||||
)
|
||||
return jsonify({'message': 'Successfully re-subscribed!'}), 200
|
||||
return jsonify({
|
||||
'message': 'Successfully re-subscribed!',
|
||||
'categories': categories
|
||||
}), 200
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({'error': str(e)}), 500
|
||||
@@ -95,6 +128,34 @@ def list_subscribers():
|
||||
return jsonify({'error': str(e)}), 500
|
||||
|
||||
|
||||
@subscription_bp.route('/api/subscribers/<email>', methods=['GET'])
|
||||
def get_subscriber(email):
|
||||
"""Get a single subscriber's information"""
|
||||
try:
|
||||
email = email.strip().lower()
|
||||
|
||||
subscriber = subscribers_collection.find_one(
|
||||
{'email': email},
|
||||
{'_id': 0, 'email': 1, 'categories': 1, 'status': 1, 'subscribed_at': 1}
|
||||
)
|
||||
|
||||
if subscriber:
|
||||
# Convert datetime to ISO format
|
||||
if 'subscribed_at' in subscriber:
|
||||
subscriber['subscribed_at'] = subscriber['subscribed_at'].isoformat()
|
||||
|
||||
# Ensure categories field exists
|
||||
if 'categories' not in subscriber:
|
||||
subscriber['categories'] = ['general', 'local', 'sports']
|
||||
|
||||
return jsonify(subscriber), 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/<email>', methods=['DELETE'])
|
||||
def remove_subscriber(email):
|
||||
"""Permanently remove a subscriber from the database"""
|
||||
@@ -110,3 +171,68 @@ def remove_subscriber(email):
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({'error': str(e)}), 500
|
||||
|
||||
|
||||
@subscription_bp.route('/api/admin/subscribers/delete-all', methods=['DELETE'])
|
||||
def delete_all_subscribers():
|
||||
"""Delete all subscribers (admin only)"""
|
||||
try:
|
||||
result = subscribers_collection.delete_many({})
|
||||
|
||||
return jsonify({
|
||||
'message': f'Successfully deleted {result.deleted_count} subscribers',
|
||||
'deleted_count': result.deleted_count
|
||||
}), 200
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({'error': str(e)}), 500
|
||||
|
||||
|
||||
@subscription_bp.route('/api/categories', methods=['GET'])
|
||||
def get_categories():
|
||||
"""Get available newsletter categories from RSS feeds"""
|
||||
from database import rss_feeds_collection
|
||||
|
||||
# Get unique categories from RSS feeds
|
||||
categories_from_db = rss_feeds_collection.distinct('category')
|
||||
|
||||
# Category metadata
|
||||
category_info = {
|
||||
'general': {
|
||||
'name': 'Top Trending',
|
||||
'description': 'Top trending news and updates',
|
||||
'icon': '🔥'
|
||||
},
|
||||
'local': {
|
||||
'name': 'Local Events',
|
||||
'description': 'Local events, culture, and community news',
|
||||
'icon': '🏛️'
|
||||
},
|
||||
'sports': {
|
||||
'name': 'Sports',
|
||||
'description': 'Sports news and updates',
|
||||
'icon': '⚽'
|
||||
},
|
||||
'science': {
|
||||
'name': 'Science & Tech',
|
||||
'description': 'Science and technology news',
|
||||
'icon': '🔬'
|
||||
}
|
||||
}
|
||||
|
||||
# Build category list
|
||||
categories = []
|
||||
for cat_id in sorted(categories_from_db):
|
||||
info = category_info.get(cat_id, {
|
||||
'name': cat_id.title(),
|
||||
'description': f'{cat_id.title()} news',
|
||||
'icon': '📄'
|
||||
})
|
||||
categories.append({
|
||||
'id': cat_id,
|
||||
'name': info['name'],
|
||||
'description': info['description'],
|
||||
'icon': info['icon']
|
||||
})
|
||||
|
||||
return jsonify({'categories': categories}), 200
|
||||
|
||||
Reference in New Issue
Block a user