Compare commits
3 Commits
eb87518657
...
396060041f
| Author | SHA1 | Date | |
|---|---|---|---|
| 396060041f | |||
| 84db52c718 | |||
| bb7730e8dc |
2
.gitignore
vendored
2
.gitignore
vendored
@ -8,3 +8,5 @@ wheels/
|
|||||||
|
|
||||||
# Virtual environments
|
# Virtual environments
|
||||||
.venv
|
.venv
|
||||||
|
|
||||||
|
.nanocoder
|
||||||
|
|||||||
@ -23,6 +23,7 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
|
background: #1a1a1a;
|
||||||
}
|
}
|
||||||
.chevron {
|
.chevron {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|||||||
39
main.py
39
main.py
@ -6,16 +6,35 @@ import random
|
|||||||
import secrets
|
import secrets
|
||||||
import string
|
import string
|
||||||
import zipfile
|
import zipfile
|
||||||
|
from base64 import b64encode
|
||||||
from glob import glob
|
from glob import glob
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from fastapi import FastAPI, HTTPException
|
from fastapi import FastAPI, HTTPException, Depends
|
||||||
|
from fastapi.security import HTTPBasic, HTTPBasicCredentials
|
||||||
from fastapi.responses import FileResponse, HTMLResponse, RedirectResponse, StreamingResponse
|
from fastapi.responses import FileResponse, HTMLResponse, RedirectResponse, StreamingResponse
|
||||||
|
|
||||||
app = FastAPI()
|
|
||||||
file_mapping = {}
|
AUTH_SCHEME = HTTPBasic()
|
||||||
indexers = []
|
expected_password: str | None = None
|
||||||
|
|
||||||
|
|
||||||
|
async def get_current_username(credentials: HTTPBasicCredentials = Depends(AUTH_SCHEME)) -> str:
|
||||||
|
"""Verify Basic Authentication credentials"""
|
||||||
|
if expected_password is not None and credentials.password != expected_password:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=401,
|
||||||
|
detail="Incorrect password",
|
||||||
|
headers={"WWW-Authenticate": AUTH_SCHEME.getobfuscation_header()},
|
||||||
|
)
|
||||||
|
return credentials.username
|
||||||
|
|
||||||
|
|
||||||
|
def set_auth_password(password: str | None):
|
||||||
|
"""Set the expected password for authentication"""
|
||||||
|
global expected_password
|
||||||
|
expected_password = password
|
||||||
|
|
||||||
|
|
||||||
class FileIndexer:
|
class FileIndexer:
|
||||||
@ -128,7 +147,7 @@ async def health_check():
|
|||||||
|
|
||||||
|
|
||||||
@app.get("/api/{file_hash}/data")
|
@app.get("/api/{file_hash}/data")
|
||||||
async def get_file_data(file_hash: str):
|
async def get_file_data(file_hash: str, username: str = Depends(get_current_username)):
|
||||||
"""Serve a specific file by its hash"""
|
"""Serve a specific file by its hash"""
|
||||||
if file_hash not in file_mapping:
|
if file_hash not in file_mapping:
|
||||||
raise HTTPException(status_code=404, detail="File not found")
|
raise HTTPException(status_code=404, detail="File not found")
|
||||||
@ -152,14 +171,14 @@ async def get_file_data(file_hash: str):
|
|||||||
|
|
||||||
|
|
||||||
@app.get("/")
|
@app.get("/")
|
||||||
async def root():
|
async def root(username: str = Depends(get_current_username)):
|
||||||
"""Redirect to a random file hash"""
|
"""Redirect to a random file hash"""
|
||||||
random_hash = _get_random_hash()
|
random_hash = _get_random_hash()
|
||||||
return RedirectResponse(url="/{hash}".format(hash=random_hash))
|
return RedirectResponse(url="/{hash}".format(hash=random_hash))
|
||||||
|
|
||||||
|
|
||||||
@app.get("/{order}/{delay}")
|
@app.get("/{order}/{delay}")
|
||||||
async def order_delay(order: str, delay: int):
|
async def order_delay(order: str, delay: int, username: str = Depends(get_current_username)):
|
||||||
"""Redirect to random file with order and delay"""
|
"""Redirect to random file with order and delay"""
|
||||||
random_hash = _get_random_hash()
|
random_hash = _get_random_hash()
|
||||||
return RedirectResponse(
|
return RedirectResponse(
|
||||||
@ -209,7 +228,7 @@ def _render_page(
|
|||||||
|
|
||||||
|
|
||||||
@app.get("/{file_hash}")
|
@app.get("/{file_hash}")
|
||||||
async def hash_page(file_hash: str):
|
async def hash_page(file_hash: str, username: str = Depends(get_current_username)):
|
||||||
"""Serve a page for a specific file hash with navigation"""
|
"""Serve a page for a specific file hash with navigation"""
|
||||||
if file_hash not in file_mapping:
|
if file_hash not in file_mapping:
|
||||||
raise HTTPException(status_code=404, detail="File not found")
|
raise HTTPException(status_code=404, detail="File not found")
|
||||||
@ -222,7 +241,7 @@ async def hash_page(file_hash: str):
|
|||||||
|
|
||||||
|
|
||||||
@app.get("/{order}/{delay}/{file_hash}")
|
@app.get("/{order}/{delay}/{file_hash}")
|
||||||
async def hash_page_with_refresh(order: str, delay: int, file_hash: str):
|
async def hash_page_with_refresh(order: str, delay: int, file_hash: str, username: str = Depends(get_current_username)):
|
||||||
"""Serve a page for a specific file hash with auto-refresh navigation"""
|
"""Serve a page for a specific file hash with auto-refresh navigation"""
|
||||||
if file_hash not in file_mapping:
|
if file_hash not in file_mapping:
|
||||||
raise HTTPException(status_code=404, detail="File not found")
|
raise HTTPException(status_code=404, detail="File not found")
|
||||||
@ -278,9 +297,11 @@ if __name__ == "__main__":
|
|||||||
parser.add_argument("--host", type=str, default="0.0.0.0", help="Host to bind to")
|
parser.add_argument("--host", type=str, default="0.0.0.0", help="Host to bind to")
|
||||||
parser.add_argument("--port", type=int, default=8000, help="Port to bind to")
|
parser.add_argument("--port", type=int, default=8000, help="Port to bind to")
|
||||||
parser.add_argument("--salt", type=str, default=None, help="Salt for hashing file paths")
|
parser.add_argument("--salt", type=str, default=None, help="Salt for hashing file paths")
|
||||||
|
parser.add_argument("--password", type=str, default=None, help="Password for Basic Authentication")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
initialize_server(args)
|
initialize_server(args)
|
||||||
|
set_auth_password(args.password)
|
||||||
|
|
||||||
import uvicorn
|
import uvicorn
|
||||||
|
|
||||||
|
|||||||
@ -1,25 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://opencode.ai/config.json",
|
|
||||||
|
|
||||||
"provider": {
|
|
||||||
"ollama": {
|
|
||||||
"npm": "@ai-sdk/openai-compatible",
|
|
||||||
"name": "Local Llama-server",
|
|
||||||
"options": {
|
|
||||||
"baseURL": "http://llamaserver:8080/v1"
|
|
||||||
},
|
|
||||||
"models": {
|
|
||||||
"Qwen3.5-35B-A3B": {
|
|
||||||
"name": "Qwen3.5 35B-A3B"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"aws": {
|
|
||||||
"options": {
|
|
||||||
"accessKeyId": "{env:AWS_ACCESS_KEY_ID}",
|
|
||||||
"secretAccessKey": "{env:AWS_SECRET_ACCESS_KEY}",
|
|
||||||
"region": "us-east-1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user