108 lines
4.2 KiB
Python
Raw Normal View History

2025-11-09 23:29:07 +01:00
import argparse
import uvicorn
2025-11-10 15:46:40 +01:00
import logging
from contextlib import asynccontextmanager
2025-11-10 01:58:41 +01:00
from fastapi import FastAPI, Request, status, HTTPException
2025-11-09 23:29:07 +01:00
from fastapi.staticfiles import StaticFiles
2025-11-10 01:58:41 +01:00
from fastapi.responses import HTMLResponse, JSONResponse
2025-11-09 23:29:07 +01:00
from tortoise.contrib.fastapi import register_tortoise
from .settings import settings
2025-11-10 15:46:40 +01:00
from .routers import auth, users, folders, files, shares, search, admin, starred, billing, admin_billing
2025-11-09 23:29:07 +01:00
from . import webdav
2025-11-10 15:46:40 +01:00
from .schemas import ErrorResponse
2025-11-10 01:58:41 +01:00
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
2025-11-09 23:29:07 +01:00
2025-11-10 15:46:40 +01:00
@asynccontextmanager
async def lifespan(app: FastAPI):
logger.info("Starting up...")
logger.info("Database connected.")
from .billing.scheduler import start_scheduler
from .billing.models import PricingConfig
2025-11-11 12:47:26 +01:00
from .mail import email_service
2025-11-10 15:46:40 +01:00
start_scheduler()
logger.info("Billing scheduler started")
2025-11-11 12:47:26 +01:00
await email_service.start()
logger.info("Email service started")
2025-11-10 15:46:40 +01:00
pricing_count = await PricingConfig.all().count()
if pricing_count == 0:
from decimal import Decimal
await PricingConfig.create(config_key='storage_per_gb_month', config_value=Decimal('0.0045'), description='Storage cost per GB per month', unit='per_gb_month')
await PricingConfig.create(config_key='bandwidth_egress_per_gb', config_value=Decimal('0.009'), description='Bandwidth egress cost per GB', unit='per_gb')
await PricingConfig.create(config_key='bandwidth_ingress_per_gb', config_value=Decimal('0.0'), description='Bandwidth ingress cost per GB (free)', unit='per_gb')
await PricingConfig.create(config_key='free_tier_storage_gb', config_value=Decimal('15'), description='Free tier storage in GB', unit='gb')
await PricingConfig.create(config_key='free_tier_bandwidth_gb', config_value=Decimal('15'), description='Free tier bandwidth in GB per month', unit='gb')
await PricingConfig.create(config_key='tax_rate_default', config_value=Decimal('0.0'), description='Default tax rate (0 = no tax)', unit='percentage')
logger.info("Default pricing configuration initialized")
yield
from .billing.scheduler import stop_scheduler
stop_scheduler()
logger.info("Billing scheduler stopped")
2025-11-11 12:47:26 +01:00
await email_service.stop()
logger.info("Email service stopped")
2025-11-10 15:46:40 +01:00
print("Shutting down...")
2025-11-09 23:29:07 +01:00
app = FastAPI(
2025-11-13 12:05:05 +01:00
title="MyWebdav Cloud Storage",
description="A commercial cloud storage web application",
2025-11-09 23:29:07 +01:00
version="0.1.0",
2025-11-10 15:46:40 +01:00
lifespan=lifespan
2025-11-09 23:29:07 +01:00
)
app.include_router(auth.router)
app.include_router(users.router)
app.include_router(folders.router)
app.include_router(files.router)
app.include_router(shares.router)
app.include_router(search.router)
2025-11-10 15:46:40 +01:00
app.include_router(admin.router)
app.include_router(starred.router)
app.include_router(billing.router)
app.include_router(admin_billing.router)
2025-11-09 23:29:07 +01:00
app.include_router(webdav.router)
2025-11-10 15:46:40 +01:00
from .middleware.usage_tracking import UsageTrackingMiddleware
app.add_middleware(UsageTrackingMiddleware)
2025-11-09 23:29:07 +01:00
app.mount("/static", StaticFiles(directory="static"), name="static")
register_tortoise(
app,
db_url=settings.DATABASE_URL,
2025-11-10 15:46:40 +01:00
modules={
2025-11-13 20:42:43 +01:00
"models": ["mywebdav.models"],
"billing": ["mywebdav.billing.models"]
2025-11-10 15:46:40 +01:00
},
2025-11-09 23:29:07 +01:00
generate_schemas=True,
add_exception_handlers=True,
)
2025-11-10 01:58:41 +01:00
@app.exception_handler(HTTPException)
async def http_exception_handler(request: Request, exc: HTTPException):
logger.error(f"HTTPException: {exc.status_code} - {exc.detail} for URL: {request.url}")
return JSONResponse(
status_code=exc.status_code,
content=ErrorResponse(code=exc.status_code, message=exc.detail).dict(),
)
2025-11-09 23:29:07 +01:00
@app.get("/", response_class=HTMLResponse) # Change response_class to HTMLResponse
async def read_root():
with open("static/index.html", "r") as f:
return f.read()
def main():
2025-11-13 20:50:03 +01:00
parser = argparse.ArgumentParser(description="Run the MyWebdav application.")
2025-11-09 23:29:07 +01:00
parser.add_argument("--host", type=str, default="0.0.0.0", help="Host address to bind to")
parser.add_argument("--port", type=int, default=8000, help="Port to listen on")
args = parser.parse_args()
uvicorn.run(app, host=args.host, port=args.port)
if __name__ == "__main__":
main()