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
feat: add 2fa support, starred items, batch operations, and logging infrastructure
- Implement two-factor authentication with TOTP verification, recovery codes, and QR code setup in auth flow
- Add is_starred and last_accessed_at fields to File and Folder models for bookmarking and recency tracking
- Introduce batch operation endpoints for files and folders (delete, star, unstar, move, copy)
- Configure structured logging with timestamps and module names, replacing print statements
- Register admin and starred routers, add global HTTPException handler with JSON error responses
- Update authenticate_user and create_access_token to handle 2FA verification and token claims
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
feat: add 2fa support, starred items, batch operations, and logging infrastructure
- Implement two-factor authentication with TOTP verification, recovery codes, and QR code setup in auth flow
- Add is_starred and last_accessed_at fields to File and Folder models for bookmarking and recency tracking
- Introduce batch operation endpoints for files and folders (delete, star, unstar, move, copy)
- Configure structured logging with timestamps and module names, replacing print statements
- Register admin and starred routers, add global HTTPException handler with JSON error responses
- Update authenticate_user and create_access_token to handle 2FA verification and token claims
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
feat: add 2fa support, starred items, batch operations, and logging infrastructure
- Implement two-factor authentication with TOTP verification, recovery codes, and QR code setup in auth flow
- Add is_starred and last_accessed_at fields to File and Folder models for bookmarking and recency tracking
- Introduce batch operation endpoints for files and folders (delete, star, unstar, move, copy)
- Configure structured logging with timestamps and module names, replacing print statements
- Register admin and starred routers, add global HTTPException handler with JSON error responses
- Update authenticate_user and create_access_token to handle 2FA verification and token claims
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 (
chore: rebrand all user-facing strings from RBox to MyWebdav across docs, emails, and config
Replace every occurrence of "RBox" with "MyWebdav" in README.md, invoice templates, welcome emails, share notifications, FastAPI metadata, default database filename, domain name, S3 bucket name, TOTP issuer, and WebDAV realm header to reflect the commercial rebranding of the application.
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 ,
)
feat: add 2fa support, starred items, batch operations, and logging infrastructure
- Implement two-factor authentication with TOTP verification, recovery codes, and QR code setup in auth flow
- Add is_starred and last_accessed_at fields to File and Folder models for bookmarking and recency tracking
- Introduce batch operation endpoints for files and folders (delete, star, unstar, move, copy)
- Configure structured logging with timestamps and module names, replacing print statements
- Register admin and starred routers, add global HTTPException handler with JSON error responses
- Update authenticate_user and create_access_token to handle 2FA verification and token claims
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 ,
2025-11-13 23:05:26 +01:00
content = ErrorResponse ( code = exc . status_code , message = exc . detail ) . model_dump ( ) ,
feat: add 2fa support, starred items, batch operations, and logging infrastructure
- Implement two-factor authentication with TOTP verification, recovery codes, and QR code setup in auth flow
- Add is_starred and last_accessed_at fields to File and Folder models for bookmarking and recency tracking
- Introduce batch operation endpoints for files and folders (delete, star, unstar, move, copy)
- Configure structured logging with timestamps and module names, replacing print statements
- Register admin and starred routers, add global HTTPException handler with JSON error responses
- Update authenticate_user and create_access_token to handle 2FA verification and token claims
2025-11-10 01:58:41 +01:00
)
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 ( )