File size: 4,887 Bytes
8e4ba0a
5580f57
61c1719
836f75b
65e40ba
 
 
83371d8
836f75b
 
 
 
 
15d97c1
 
a46919c
 
 
 
 
15d97c1
 
e02fa6d
836f75b
f3aab4f
61c1719
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
836f75b
 
62cd5c9
65e40ba
fb99609
65e40ba
 
 
3d4bf49
65e40ba
8e4ba0a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61c1719
 
5ccc24c
61c1719
 
 
5ccc24c
 
 
65e40ba
 
 
83371d8
 
 
 
 
65e40ba
5ccc24c
65e40ba
83371d8
 
5ccc24c
 
83371d8
5ccc24c
65e40ba
 
5ccc24c
 
83371d8
 
5ccc24c
 
02a15c2
83371d8
02a15c2
 
 
 
 
8e4ba0a
 
 
 
 
02a15c2
 
8e4ba0a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
from fastapi import FastAPI, HTTPException, Request, Query
from fastapi.responses import JSONResponse
import logging
import os
from typing import List
from LoadBalancer import LoadBalancer
from utils import is_valid_url
from urllib.parse import unquote

CACHE_DIR = os.getenv("CACHE_DIR")
TOKEN = os.getenv("TOKEN")
REPO = os.getenv("REPO")

app = FastAPI()

@app.on_event("startup")
async def startup_event():
    global load_balancer
    load_balancer = LoadBalancer(cache_dir=CACHE_DIR, token=TOKEN, repo=REPO)

@app.get("/")
def greet_json():
    return {"Version": load_balancer.version}

@app.post("/api/post/register")
async def register_instance(request: Request):
    try:
        data = await request.json()
        if not data or "url" not in data:
            return JSONResponse(content={"error": "No URL provided"}, status_code=400)
        
        url = data["url"]
        if not is_valid_url(url):
            return JSONResponse(content={"error": "Invalid URL"}, status_code=400)

        # Register the instance
        load_balancer.register_instance(url)
        logging.info(f"Instance registered: {url}")

        return JSONResponse(content={"message": f"Instance {url} registered successfully"}, status_code=200)

    except Exception as e:
        logging.error(f"Error registering instance: {e}")
        return JSONResponse(content={"error": "Failed to register instance"}, status_code=500)

@app.get("/api/get/file_structure")
async def get_file_structure():
    return load_balancer.file_structure

@app.get("/api/get/music/store")
async def get_music_store():
    return load_balancer.MUSIC_STORE

@app.get("/api/get/music/all")
async def get_all_music_api(
    page: int = Query(None, ge=1),  # Default to None, but must be at least 1 if provided
    limit: int = Query(None, ge=1, le=100)  # Default to None, but must be between 1 and 100 if provided
):
    # Fetch all music files from the load balancer
    all_music = load_balancer.get_all_music()

    # If pagination parameters are not provided, return all music
    if page is None or limit is None:
        return {"total_files": len(all_music), "files": all_music}

    # Calculate the starting index and the end index for pagination
    start_index = (page - 1) * limit
    end_index = start_index + limit

    # Handle the case where the requested page exceeds available files
    if start_index >= len(all_music):
        raise HTTPException(status_code=404, detail="No more files available for the requested page.")

    # Get the paginated music files
    paginated_music = all_music[start_index:end_index]

    # Prepare the response
    return {
        "page": page,
        "limit": limit,
        "total_files": len(all_music),
        "files": paginated_music
    }


@app.get('/api/get/instances')
async def get_instances():
    return load_balancer.instances

@app.get('/api/get/instances/health')
async def get_instances_health():
    return load_balancer.instances_health

@app.get("/api/get/music/{file_name}")
async def get_music_api(file_name: str):
    """Endpoint to get the music file by title."""
    
    # Decode the file_name from URL encoding
    decoded_file_name = unquote(file_name)
    
    if not decoded_file_name:
        raise HTTPException(status_code=400, detail="file_name parameter is required")
    
    # Check if the music file is already cached
    if decoded_file_name in load_balancer.MUSIC_STORE:
        url = load_balancer.MUSIC_STORE[decoded_file_name]
        return JSONResponse(content={"url": url})

    music_path = load_balancer.find_music_path(decoded_file_name)
    
    if not music_path:
        raise HTTPException(status_code=404, detail="Music file not found")
    
    # Start the download in an instance
    response = load_balancer.download_music_to_best_instance(file_name=decoded_file_name)
    
    if response:
        return JSONResponse(content=response)


@app.get('/api/get/category/all')
async def get_categories():
    return load_balancer.get_all_categories()

@app.get("/api/get/category/{category}")
async def get_all_from_a_category(
    category: str, 
    page: int = Query(1, ge=1),  # Default to page 1, minimum value is 1
    limit: int = Query(10, ge=1, le=100)  # Default limit is 10, max limit is 100
):
    if not category:
        raise HTTPException(status_code=400, detail="category parameter is required")

    # Fetch all files from the category
    all_files = load_balancer.get_files_from_category(category)

    # Calculate the starting index and the end index for pagination
    start_index = (page - 1) * limit
    end_index = start_index + limit

    # Get the paginated files
    paginated_files = all_files[start_index:end_index]

    # Prepare the response
    return {
        "page": page,
        "limit": limit,
        "total_files": len(all_files),
        "files": paginated_files
    }