diff --git a/docker-compose.yaml b/docker-compose.yaml index cda4758..a025b31 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -2,14 +2,14 @@ volumes: music_downloads: {} # These 2 are just for "nuxtjs-launcher" # If you use a normal nodejs build image, you don't need them - nuxt_internal: {} - nuxt_server: {} + #nuxt_internal: {} + #nuxt_server: {} networks: api_nuxt: driver: "bridge" - bridge: - external: true # Allow LAN access + #bridge: + # external: true # Allow LAN access services: fastapi: build: @@ -17,20 +17,17 @@ services: dockerfile: Dockerfile.fastapi networks: - api_nuxt - - bridge # allow external access + #- bridge # allow external access volumes: - music_downloads:/tmp/downloads environment: - - MYSQL_HOST=172.17.0.1 - - MYSQL_USER=yt2mp3_nuxt - - MYSQL_DB=yt2mp3_nuxt - - MYSQL_PASSWORD=JJ7ZEyDm!XAGFb_z + - DB_MODE=sqlite nuxt: - #build: - # context: . - # dockerfile: Dockerfile.nuxt - image: nuxtjs-launcher + build: + context: . + dockerfile: Dockerfile.nuxt + #image: nuxtjs-launcher networks: - api_nuxt ports: @@ -43,8 +40,8 @@ services: volumes: - music_downloads:/tmp/downloads # These 3 are just for "nuxtjs-launcher" - - ./:/app - - nuxt_server:/server - - nuxt_internal:/internal + # - ./:/app + #- nuxt_server:/server + #- nuxt_internal:/internal \ No newline at end of file diff --git a/server/py/fastapi_server/database.db b/server/py/fastapi_server/database.db new file mode 100644 index 0000000..514fc65 Binary files /dev/null and b/server/py/fastapi_server/database.db differ diff --git a/server/py/fastapi_server/main.py b/server/py/fastapi_server/main.py index 85dd609..3b9e358 100644 --- a/server/py/fastapi_server/main.py +++ b/server/py/fastapi_server/main.py @@ -8,6 +8,7 @@ import aiomysql import os import bcrypt import asyncio +import aiosqlite import subprocess from yt_dlp import YoutubeDL @@ -23,6 +24,14 @@ from yt_dlp.utils import DownloadError # So we can trust it class db: + + mode = os.environ.get("DB_MODE", "sqlite") + + # For SQLite usage + + file = os.environ.get("SQLITE_FILE","./database.db") + + # For MySQL usage pool = None host = os.environ.get("MYSQL_HOST","127.0.0.1") @@ -33,21 +42,31 @@ class db: @asynccontextmanager async def lifespan(app: FastAPI): - db.pool = await aiomysql.create_pool(host=db.host,user=db.user,password=db.pwd,db=db.db_name, minsize=1, maxsize=10) - try: - yield - finally: - db.pool.close() - await db.pool.wait_closed() + if db.mode == "mysql": + db.pool = await aiomysql.create_pool(host=db.host,user=db.user,password=db.pwd,db=db.db_name, minsize=1, maxsize=10) + try: + yield + finally: + db.pool.close() + await db.pool.wait_closed() + else: + try: + yield + finally: pass # no action required now app = FastAPI(lifespan=lifespan) -async def fetch_user_info(email: str): - async with db.pool.acquire() as conn: - async with conn.cursor(aiomysql.DictCursor) as cur: - await cur.execute("SELECT * FROM users WHERE email = %s", (email,)) - return await cur.fetchone() +async def fetch_user_info(arg: str, type: str): + if db.mode == "mysql": + async with db.pool.acquire() as conn: + async with conn.cursor(aiomysql.DictCursor) as cur: + await cur.execute("SELECT * FROM users WHERE %s = %s", (arg,type)) + return await cur.fetchone() + elif db.mode == "sqlite": + async with aiosqlite.connect(db.file) as conn: + async with conn.execute("SELECT * FROM users WHERE ? = ?", (arg,type)) as cursor: + return await cursor.fetchone() def download_audio(video_url: str, output_folder: str) -> str: ydl_opts = { @@ -132,11 +151,15 @@ async def create_user(req: Request): # Auto exceptions give more verbose to Nuxt. body["password"] = bcrypt.hashpw(body["password"].encode(), bcrypt.gensalt()).decode() - async with db.pool.acquire() as conn: - async with conn.cursor() as cur: - await cur.execute("INSERT INTO users (`first_name`,`last_name`,`email`,`password`) VALUES (%s,%s,%s,%s)", (body.first_name, body.last_name, body.email, body.password)) - await conn.commit() - + if db.mode == "mysql": + async with db.pool.acquire() as conn: + async with conn.cursor() as cur: + await cur.execute("INSERT INTO users (`first_name`,`last_name`,`email`,`password`) VALUES (%s,%s,%s,%s)", (body.first_name, body.last_name, body.email, body.password)) + await conn.commit() + elif db.mode == "sqlite": + async with aiosqlite.connect(db.file) as conn: + await conn.execute("INSERT INTO users (`first_name`,`last_name`,`email`,`password`) VALUES (?, ?, ?, ?)", (body.first_name, body.last_name, body.email, body.password)) + await conn.commit() @app.post("/login") @@ -153,7 +176,7 @@ async def login_endpoint(req: Request): if (bcrypt.checkpw(body["password"].encode(), user_data.get("password").encode())): return user_data else: - raise HTTPException(status_code=401) + raise HTTPException(status_code=401, detail="Wrong password") except KeyError: raise HTTPException(status_code=400) #except ValidationError: @@ -168,9 +191,13 @@ async def me_get_endpoint(req: Request): Trusts Nuxt's backend to allow it or not. """ args = dict(req.query_params) - #print(args) + me = None try: - me = await fetch_user_info(args["email"]) + # Prefer id over e-mail + if "id" in args.keys(): me = fetch_user_info(args["id"], "id") + elif "email" in args.keys(): me = fetch_user_info(args["email"], "email") + else: raise HTTPException(400, "Provide either email or user id") + #print(args) if (me is None): raise HTTPException(404, "User doesn't exist") else: return me diff --git a/server/py/fastapi_server/requirements_prod.txt b/server/py/fastapi_server/requirements_prod.txt index 12fe893..574f9ee 100644 --- a/server/py/fastapi_server/requirements_prod.txt +++ b/server/py/fastapi_server/requirements_prod.txt @@ -1,4 +1,5 @@ aiomysql==0.3.2 +aiosqlite==0.22.1 annotated-doc==0.0.4 annotated-types==0.7.0 anyio==4.12.1