help@rskworld.in +91 93305 39277
RSK World
  • Home
  • Development
    • Web Development
    • Mobile Apps
    • Software
    • Games
    • Project
  • Technologies
    • Data Science
    • AI Development
    • Cloud Development
    • Blockchain
    • Cyber Security
    • Dev Tools
    • Testing Tools
  • Blog
  • About
  • Contact

Theme Settings

Color Scheme
Display Options
Font Size
100%
Back to Project
RSK World
news-summary-bot
/
__pycache__
RSK World
news-summary-bot
News Summary Bot - Python + Flask + OpenAI + NewsAPI + AI Summarization + Real-time News + News Aggregation
__pycache__
  • admin.cpython-313.pyc9.4 KB
  • analytics.cpython-313.pyc13.1 KB
  • app.cpython-313.pyc16.7 KB
  • auth.cpython-313.pyc17.9 KB
  • cache.cpython-313.pyc14.8 KB
  • news_bot.cpython-313.pyc6 KB
  • search.cpython-313.pyc18.3 KB
  • security.cpython-313.pyc17.6 KB
style.cssadmin.py
static/css/style.css
Raw Download
Find: Go to:
/*
News Summary Bot - Custom Styles
Developer: Molla Samser
Design & Testing: Rima Khatun
Company: RSK World
Year: 2026
Website: https://rskworld.in
*/

:root {
    --primary: #dc3545;
    /* text-danger */
    --primary-dark: #b02a37;
    --secondary: #0d6efd;
    --dark: #1a1a1a;
    --light: #f8f9fa;
    --gray: #6c757d;
    --glass: rgba(255, 255, 255, 0.1);
    --glass-border: rgba(255, 255, 255, 0.2);
    --shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
}

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: 'Outfit', sans-serif;
    background: #0f0f0f;
    color: var(--light);
    line-height: 1.6;
    overflow-x: hidden;
}

.glass-card {
    background: var(--glass);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    border: 1px solid var(--glass-border);
    border-radius: 15px;
    padding: 2rem;
    box-shadow: var(--shadow);
}

.btn-premium {
    background: linear-gradient(45deg, var(--primary), var(--secondary));
    border: none;
    color: white;
    padding: 0.8rem 2rem;
    border-radius: 50px;
    font-weight: 600;
    transition: transform 0.3s ease, box-shadow 0.3s ease;
    text-decoration: none;
    display: inline-block;
    cursor: pointer;
}

.btn-premium:hover {
    transform: translateY(-3px);
    box-shadow: 0 10px 20px rgba(220, 53, 69, 0.4);
    color: white;
}

/* Navbar */
nav {
    padding: 1.5rem 5%;
    display: flex;
    justify-content: space-between;
    align-items: center;
    position: fixed;
    width: 100%;
    top: 0;
    z-index: 1000;
    background: rgba(15, 15, 15, 0.8);
    backdrop-filter: blur(10px);
}

.logo {
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--primary);
    text-transform: uppercase;
    letter-spacing: 2px;
}

/* Hero Section */
.hero {
    height: 100vh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    text-align: center;
    padding: 0 10%;
    background: radial-gradient(circle at top right, rgba(220, 53, 69, 0.2), transparent),
        radial-gradient(circle at bottom left, rgba(13, 110, 253, 0.2), transparent);
}

.hero h1 {
    font-size: 4rem;
    margin-bottom: 1.5rem;
    background: linear-gradient(to right, #fff, #888);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}

.hero p {
    font-size: 1.2rem;
    max-width: 700px;
    margin-bottom: 2rem;
    color: var(--gray);
}

/* Dashboard Style */
.dashboard-container {
    margin-top: 100px;
    padding: 2rem 5%;
    display: grid;
    grid-template-columns: 250px 1fr;
    gap: 2rem;
    min-height: calc(100vh - 100px);
}

.sidebar {
    height: fit-content;
}

.category-list {
    list-style: none;
}

.category-item {
    padding: 1rem;
    margin-bottom: 0.5rem;
    border-radius: 10px;
    cursor: pointer;
    transition: background 0.3s;
    display: flex;
    align-items: center;
    gap: 10px;
}

.category-item:hover,
.category-item.active {
    background: var(--glass);
    color: var(--primary);
}

.news-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 2rem;
}

.news-card {
    transition: transform 0.3s ease;
}

.news-card:hover {
    transform: translateY(-10px);
}

.news-image {
    width: 100%;
    height: 180px;
    object-fit: cover;
    border-radius: 10px;
    margin-bottom: 1rem;
}

.summary-modal {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.8);
    z-index: 2000;
    justify-content: center;
    align-items: center;
}

.modal-content {
    max-width: 600px;
    width: 90%;
}

.loader {
    width: 48px;
    height: 48px;
    border: 5px solid #FFF;
    border-bottom-color: var(--primary);
    border-radius: 50%;
    display: inline-block;
    box-sizing: border-box;
    animation: rotation 1s linear infinite;
}

@keyframes rotation {
    0% {
        transform: rotate(0deg);
    }

    100% {
        transform: rotate(360deg);
    }
}

/* Sentiment Badges */
.badge-sentiment {
    padding: 0.3rem 0.8rem;
    border-radius: 20px;
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    display: inline-block;
    margin-bottom: 0.5rem;
}

.bg-positive {
    background: rgba(40, 167, 69, 0.2);
    color: #28a745;
    border: 1px solid #28a745;
}

.bg-negative {
    background: rgba(220, 53, 69, 0.2);
    color: #dc3545;
    border: 1px solid #dc3545;
}

.bg-neutral {
    background: rgba(108, 117, 125, 0.2);
    color: #6c757d;
    border: 1px solid #6c757d;
}

/* Trending Topics */
.trend-tag {
    display: inline-block;
    padding: 0.4rem 0.8rem;
    background: var(--glass);
    border: 1px solid var(--glass-border);
    border-radius: 15px;
    margin: 0.3rem;
    font-size: 0.85rem;
    cursor: pointer;
    transition: all 0.3s ease;
}

.trend-tag:hover {
    border-color: var(--primary);
    color: var(--primary);
    transform: scale(1.05);
}

.live-dot {
    height: 8px;
    width: 8px;
    background-color: #dc3545;
    border-radius: 50%;
    display: inline-block;
    margin-right: 5px;
    animation: pulse 1.5s infinite;
}

@keyframes pulse {
    0% {
        transform: scale(0.95);
        box-shadow: 0 0 0 0 rgba(220, 53, 69, 0.7);
    }

    70% {
        transform: scale(1);
        box-shadow: 0 0 0 5px rgba(220, 53, 69, 0);
    }

    100% {
        transform: scale(0.95);
        box-shadow: 0 0 0 0 rgba(220, 53, 69, 0);
    }
}

/* Pro Features Styles */
.reliability-indicator {
    height: 4px;
    width: 100%;
    background: #444;
    border-radius: 2px;
    margin: 10px 0;
    overflow: hidden;
}

.reliability-bar {
    height: 100%;
    background: linear-gradient(90deg, #dc3545, #ffc107, #28a745);
    transition: width 0.5s ease;
}

.bookmark-btn {
    position: absolute;
    top: 10px;
    right: 10px;
    background: var(--glass);
    border: 1px solid var(--glass-border);
    color: white;
    width: 35px;
    height: 35px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: all 0.3s;
    z-index: 5;
}

.bookmark-btn.active {
    background: var(--primary);
    border-color: var(--primary);
}

.voice-btn {
    background: var(--glass);
    border: 1px solid var(--glass-border);
    color: white;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    margin-right: 10px;
    cursor: pointer;
    transition: all 0.3s;
}

.voice-btn.listening {
    background: var(--primary);
    animation: pulse 1s infinite;
}

.trending-container {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
}

footer {
    padding: 3rem 5%;
    text-align: center;
    border-top: 1px solid var(--glass-border);
    margin-top: 4rem;
    background: #0a0a0a;
}

@media (max-width: 768px) {
    .dashboard-container {
        grid-template-columns: 1fr;
    }

    .hero h1 {
        font-size: 2.5rem;
    }
}
366 lines•7.2 KB
css
admin.py
Raw Download
Find: Go to:
"""
Admin Panel for News Summary Bot
Developer: Molla Samser
Design & Testing: Rima Khatun
Company: RSK World
Year: 2026
Website: https://rskworld.in
"""

from flask import Blueprint, render_template, request, jsonify, redirect, url_for, session, flash
from functools import wraps
import json
from datetime import datetime, timedelta
from analytics import NewsAnalytics, AdvancedNLP
import os

# Create admin blueprint
admin_bp = Blueprint('admin', __name__, url_prefix='/admin')

# Admin credentials (in production, use proper authentication)
ADMIN_USERNAME = os.getenv('ADMIN_USERNAME', 'admin')
ADMIN_PASSWORD = os.getenv('ADMIN_PASSWORD', 'admin123')

# Initialize analytics
analytics = NewsAnalytics()
nlp = AdvancedNLP()

def admin_required(f):
    """Decorator to require admin authentication."""
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if not session.get('admin_logged_in'):
            return redirect(url_for('admin.login'))
        return f(*args, **kwargs)
    return decorated_function

@admin_bp.route('/')
def index():
    """Redirect to dashboard if logged in, otherwise to login."""
    if session.get('admin_logged_in'):
        return redirect(url_for('admin.dashboard'))
    return redirect(url_for('admin.login'))

@admin_bp.route('/login', methods=['GET', 'POST'])
def login():
    """Admin login page."""
    if request.method == 'POST':
        username = request.form.get('username')
        password = request.form.get('password')
        
        if username == ADMIN_USERNAME and password == ADMIN_PASSWORD:
            session['admin_logged_in'] = True
            session['admin_username'] = username
            flash('Login successful!', 'success')
            return redirect(url_for('admin.dashboard'))
        else:
            flash('Invalid credentials!', 'error')
    
    return render_template('admin/login.html')

@admin_bp.route('/logout')
def logout():
    """Admin logout."""
    session.clear()
    flash('Logged out successfully!', 'info')
    return redirect(url_for('admin.login'))

@admin_bp.route('/dashboard')
@admin_required
def dashboard():
    """Main admin dashboard."""
    # Get key metrics
    total_articles = get_total_articles()
    total_users = get_total_users()
    avg_reliability = get_avg_reliability()
    trending_topics = analytics.analyze_trending_topics(days=7)
    
    # Get sentiment trends for the last 30 days
    sentiment_trends = analytics.get_sentiment_trends(days=30)
    
    # Get category analytics
    category_stats = analytics.get_category_analytics()
    
    return render_template('admin/dashboard.html',
                         total_articles=total_articles,
                         total_users=total_users,
                         avg_reliability=avg_reliability,
                         trending_topics=trending_topics[:5],
                         sentiment_trends=sentiment_trends,
                         category_stats=category_stats)

@admin_bp.route('/analytics')
@admin_required
def analytics_page():
    """Detailed analytics page."""
    # Get date range from request
    days = int(request.args.get('days', 30))
    
    # Get various analytics
    trending_topics = analytics.analyze_trending_topics(days=days)
    sentiment_trends = analytics.get_sentiment_trends(days=days)
    category_analytics = analytics.get_category_analytics()
    user_activity = analytics.get_user_activity_summary(days=days)
    
    return render_template('admin/analytics.html',
                         trending_topics=trending_topics,
                         sentiment_trends=sentiment_trends,
                         category_analytics=category_analytics,
                         user_activity=user_activity,
                         days=days)

@admin_bp.route('/users')
@admin_required
def users():
    """User management page."""
    # Get user statistics
    user_activity = analytics.get_user_activity_summary()
    
    # Mock user data (in production, this would come from a database)
    users = [
        {'id': 'user1', 'name': 'John Doe', 'email': 'john@example.com', 'last_active': '2024-01-10', 'actions': 45},
        {'id': 'user2', 'name': 'Jane Smith', 'email': 'jane@example.com', 'last_active': '2024-01-09', 'actions': 32},
        {'id': 'user3', 'name': 'Bob Johnson', 'email': 'bob@example.com', 'last_active': '2024-01-08', 'actions': 28}
    ]
    
    return render_template('admin/users.html', users=users, user_activity=user_activity)

@admin_bp.route('/content')
@admin_required
def content():
    """Content management page."""
    # Get recent articles and their analysis
    # This would typically fetch from database
    articles = []  # Mock data
    
    return render_template('admin/content.html', articles=articles)

@admin_bp.route('/settings')
@admin_required
def settings():
    """Settings page."""
    # Get current settings
    settings = {
        'news_api_key': os.getenv('NEWS_API_KEY', ''),
        'openai_api_key': os.getenv('OPENAI_API_KEY', ''),
        'max_articles_per_category': os.getenv('MAX_ARTICLES', '10'),
        'cache_duration': os.getenv('CACHE_DURATION', '300'),
        'enable_analytics': os.getenv('ENABLE_ANALYTICS', 'True')
    }
    
    return render_template('admin/settings.html', settings=settings)

@admin_bp.route('/api/analytics/data')
@admin_required
def analytics_data():
    """API endpoint for analytics data."""
    days = int(request.args.get('days', 30))
    data_type = request.args.get('type', 'overview')
    
    if data_type == 'overview':
        data = {
            'total_articles': get_total_articles(),
            'total_users': get_total_users(),
            'avg_reliability': get_avg_reliability(),
            'trending_topics': analytics.analyze_trending_topics(days=days)[:10]
        }
    elif data_type == 'sentiment':
        data = analytics.get_sentiment_trends(days=days)
    elif data_type == 'categories':
        data = analytics.get_category_analytics()
    elif data_type == 'activity':
        data = analytics.get_user_activity_summary(days=days)
    else:
        data = {'error': 'Invalid data type'}
    
    return jsonify(data)

@admin_bp.route('/api/settings/update', methods=['POST'])
@admin_required
def update_settings():
    """Update application settings."""
    try:
        settings = request.get_json()
        
        # Update environment variables (in production, this would update a config file)
        for key, value in settings.items():
            if key.upper() in ['NEWS_API_KEY', 'OPENAI_API_KEY', 'MAX_ARTICLES', 'CACHE_DURATION', 'ENABLE_ANALYTICS']:
                os.environ[key.upper()] = str(value)
        
        return jsonify({'success': True, 'message': 'Settings updated successfully'})
    except Exception as e:
        return jsonify({'success': False, 'error': str(e)})

# Helper functions
def get_total_articles():
    """Get total number of articles processed."""
    # This would typically query a database
    return 1250  # Mock data

def get_total_users():
    """Get total number of users."""
    # This would typically query a database
    return 342  # Mock data

def get_avg_reliability():
    """Get average reliability score."""
    # This would typically calculate from database
    return 78.5  # Mock data

# Error handlers
@admin_bp.errorhandler(404)
def not_found(error):
    return render_template('admin/404.html'), 404

@admin_bp.errorhandler(500)
def internal_error(error):
    return render_template('admin/500.html'), 500

# Developer Details
# Created by Molla Samser (RSK World)
# 2026
222 lines•7.6 KB
python

About RSK World

Founded by Molla Samser, with Designer & Tester Rima Khatun, RSK World is your one-stop destination for free programming resources, source code, and development tools.

Founder: Molla Samser
Designer & Tester: Rima Khatun

Development

  • Game Development
  • Web Development
  • Mobile Development
  • AI Development
  • Development Tools

Legal

  • Terms & Conditions
  • Privacy Policy
  • Disclaimer

Contact Info

Nutanhat, Mongolkote
Purba Burdwan, West Bengal
India, 713147

+91 93305 39277

hello@rskworld.in
support@rskworld.in

© 2026 RSK World. All rights reserved.

Content used for educational purposes only. View Disclaimer