from flask import Flask, send_from_directory, request, Response
import os
import mimetypes
import time

app = Flask(__name__)

MEDIA_DIR = '/home/redjifox/obs'

# Проверяем существование директории
if not os.path.exists(MEDIA_DIR):
    print(f"Ошибка: Директория {MEDIA_DIR} не существует!")
    print("Пожалуйста, проверьте путь к директории.")
    exit(1)

def get_file_range(file_path):
    """Получаем диапазон байтов для частичной загрузки"""
    range_header = request.headers.get('Range', None)
    if not range_header:
        return None
    
    size = os.path.getsize(file_path)
    
    try:
        # Парсим заголовок Range (пример: "bytes=0-499")
        ranges = range_header.replace('bytes=', '').split('-')
        byte1 = int(ranges[0])
        
        if ranges[1]:
            byte2 = int(ranges[1])
        else:
            byte2 = size - 1
        
        # Проверяем корректность диапазона
        if byte1 >= size or byte2 >= size:
            byte1 = 0
            byte2 = size - 1
        
        length = byte2 - byte1 + 1
        
        return byte1, byte2, length, size
    
    except (ValueError, IndexError):
        return None

@app.route('/media/<path:filename>')
def stream_media(filename):
    file_path = os.path.join(MEDIA_DIR, filename)
    
    if not os.path.exists(file_path):
        return f"Файл {filename} не найден", 404
    
    # Определяем MIME тип
    mime_type, _ = mimetypes.guess_type(file_path)
    if not mime_type:
        mime_type = 'application/octet-stream'
    
    # Получаем размер файла
    file_size = os.path.getsize(file_path)
    
    # Для медиа файлов используем частичную загрузку
    if mime_type.startswith('video/') or mime_type.startswith('audio/'):
        range_info = get_file_range(file_path)
        
        if range_info:
            byte1, byte2, length, size = range_info
            
            def generate():
                with open(file_path, 'rb') as f:
                    f.seek(byte1)
                    remaining = length
                    chunk_size = 1024 * 1024  # 1MB chunks
                    
                    while remaining > 0:
                        chunk = min(chunk_size, remaining)
                        data = f.read(chunk)
                        if not data:
                            break
                        yield data
                        remaining -= chunk
            
            response = Response(
                generate(), 
                status=206,  # Partial Content
                mimetype=mime_type,
                direct_passthrough=True
            )
            
            response.headers.add('Content-Range', f'bytes {byte1}-{byte2}/{size}')
            response.headers.add('Accept-Ranges', 'bytes')
            response.headers.add('Content-Length', str(length))
            response.headers.add('Cache-Control', 'public, max-age=3600')
            response.headers.add('Access-Control-Allow-Origin', '*')
            response.headers.add('Access-Control-Allow-Headers', 'Range')
            response.headers.add('Access-Control-Expose-Headers', 'Content-Range, Content-Length, Accept-Ranges')
            
            return response
        
        # Если Range заголовок отсутствует, отправляем весь файл
        response = Response(
            open(file_path, 'rb').read(),
            mimetype=mime_type
        )
        response.headers.add('Content-Length', str(file_size))
        response.headers.add('Accept-Ranges', 'bytes')
        response.headers.add('Cache-Control', 'public, max-age=3600')
        response.headers.add('Access-Control-Allow-Origin', '*')
        return response
    
    # Для обычных файлов
    response = send_from_directory(MEDIA_DIR, filename)
    response.headers.add('Cache-Control', 'public, max-age=3600')
    response.headers.add('Access-Control-Allow-Origin', '*')
    return response

@app.after_request
def after_request(response):
    """Добавляем CORS заголовки ко всем ответам"""
    response.headers.add('Access-Control-Allow-Origin', '*')
    response.headers.add('Access-Control-Allow-Headers', 'Range')
    response.headers.add('Access-Control-Expose-Headers', 'Content-Range, Content-Length, Accept-Ranges')
    return response

@app.route('/')
def home():
    # Создаем список доступных файлов
    files = []
    try:
        for file in os.listdir(MEDIA_DIR):
            if os.path.isfile(os.path.join(MEDIA_DIR, file)):
                files.append(file)
    except:
        files = ["Не удалось прочитать директорию"]
    
    file_list = "\n".join([f'<li><a href="/media/{file}">{file}</a></li>' for file in files[:20]])
    
    return f"""
    <!DOCTYPE html>
    <html>
    <head>
        <title>Медиа Сервер</title>
        <style>
            body {{ font-family: Arial, sans-serif; margin: 40px; }}
            .file-list {{ max-height: 400px; overflow-y: auto; border: 1px solid #ccc; padding: 10px; }}
        </style>
    </head>
    <body>
        <h1>Медиа Сервер</h1>
        <p>Используйте: /media/имя_файла</p>
        
        <h2>Доступные файлы:</h2>
        <div class="file-list">
            <ul>{file_list}</ul>
        </div>
        
        <p>Пример: http://ваш_ip:5000/media/видео.mp4</p>
    </body>
    </html>
    """

if __name__ == '__main__':
    print("=" * 50)
    print("Медиа сервер запускается...")
    print(f"Директория: {MEDIA_DIR}")
    print("Доступные файлы:")
    
    try:
        files = os.listdir(MEDIA_DIR)
        for file in files[:10]:
            if os.path.isfile(os.path.join(MEDIA_DIR, file)):
                print(f"  - {file}")
        if len(files) > 10:
            print(f"  ... и еще {len(files)-10} файлов")
    except Exception as e:
        print(f"Ошибка при чтении директории: {e}")
    
    print("=" * 50)
    print("Сервер запущен на http://0.0.0.0:5000")
    print("Для доступа с других устройств используйте ваш локальный IP")
    print("=" * 50)
    
    app.run(host='0.0.0.0', port=5000, debug=True, threaded=True)

