sqlite is supported and now default
This commit is contained in:
@@ -2,14 +2,14 @@ volumes:
|
|||||||
music_downloads: {}
|
music_downloads: {}
|
||||||
# These 2 are just for "nuxtjs-launcher"
|
# These 2 are just for "nuxtjs-launcher"
|
||||||
# If you use a normal nodejs build image, you don't need them
|
# If you use a normal nodejs build image, you don't need them
|
||||||
nuxt_internal: {}
|
#nuxt_internal: {}
|
||||||
nuxt_server: {}
|
#nuxt_server: {}
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
api_nuxt:
|
api_nuxt:
|
||||||
driver: "bridge"
|
driver: "bridge"
|
||||||
bridge:
|
#bridge:
|
||||||
external: true # Allow LAN access
|
# external: true # Allow LAN access
|
||||||
services:
|
services:
|
||||||
fastapi:
|
fastapi:
|
||||||
build:
|
build:
|
||||||
@@ -17,20 +17,17 @@ services:
|
|||||||
dockerfile: Dockerfile.fastapi
|
dockerfile: Dockerfile.fastapi
|
||||||
networks:
|
networks:
|
||||||
- api_nuxt
|
- api_nuxt
|
||||||
- bridge # allow external access
|
#- bridge # allow external access
|
||||||
volumes:
|
volumes:
|
||||||
- music_downloads:/tmp/downloads
|
- music_downloads:/tmp/downloads
|
||||||
environment:
|
environment:
|
||||||
- MYSQL_HOST=172.17.0.1
|
- DB_MODE=sqlite
|
||||||
- MYSQL_USER=yt2mp3_nuxt
|
|
||||||
- MYSQL_DB=yt2mp3_nuxt
|
|
||||||
- MYSQL_PASSWORD=JJ7ZEyDm!XAGFb_z
|
|
||||||
|
|
||||||
nuxt:
|
nuxt:
|
||||||
#build:
|
build:
|
||||||
# context: .
|
context: .
|
||||||
# dockerfile: Dockerfile.nuxt
|
dockerfile: Dockerfile.nuxt
|
||||||
image: nuxtjs-launcher
|
#image: nuxtjs-launcher
|
||||||
networks:
|
networks:
|
||||||
- api_nuxt
|
- api_nuxt
|
||||||
ports:
|
ports:
|
||||||
@@ -43,8 +40,8 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- music_downloads:/tmp/downloads
|
- music_downloads:/tmp/downloads
|
||||||
# These 3 are just for "nuxtjs-launcher"
|
# These 3 are just for "nuxtjs-launcher"
|
||||||
- ./:/app
|
# - ./:/app
|
||||||
- nuxt_server:/server
|
#- nuxt_server:/server
|
||||||
- nuxt_internal:/internal
|
#- nuxt_internal:/internal
|
||||||
|
|
||||||
|
|
||||||
BIN
server/py/fastapi_server/database.db
Normal file
BIN
server/py/fastapi_server/database.db
Normal file
Binary file not shown.
@@ -8,6 +8,7 @@ import aiomysql
|
|||||||
import os
|
import os
|
||||||
import bcrypt
|
import bcrypt
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import aiosqlite
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from yt_dlp import YoutubeDL
|
from yt_dlp import YoutubeDL
|
||||||
@@ -23,6 +24,14 @@ from yt_dlp.utils import DownloadError
|
|||||||
# So we can trust it
|
# So we can trust it
|
||||||
|
|
||||||
class db:
|
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
|
pool = None
|
||||||
|
|
||||||
host = os.environ.get("MYSQL_HOST","127.0.0.1")
|
host = os.environ.get("MYSQL_HOST","127.0.0.1")
|
||||||
@@ -33,21 +42,31 @@ class db:
|
|||||||
|
|
||||||
@asynccontextmanager
|
@asynccontextmanager
|
||||||
async def lifespan(app: FastAPI):
|
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)
|
if db.mode == "mysql":
|
||||||
try:
|
db.pool = await aiomysql.create_pool(host=db.host,user=db.user,password=db.pwd,db=db.db_name, minsize=1, maxsize=10)
|
||||||
yield
|
try:
|
||||||
finally:
|
yield
|
||||||
db.pool.close()
|
finally:
|
||||||
await db.pool.wait_closed()
|
db.pool.close()
|
||||||
|
await db.pool.wait_closed()
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
yield
|
||||||
|
finally: pass # no action required now
|
||||||
|
|
||||||
app = FastAPI(lifespan=lifespan)
|
app = FastAPI(lifespan=lifespan)
|
||||||
|
|
||||||
|
|
||||||
async def fetch_user_info(email: str):
|
async def fetch_user_info(arg: str, type: str):
|
||||||
async with db.pool.acquire() as conn:
|
if db.mode == "mysql":
|
||||||
async with conn.cursor(aiomysql.DictCursor) as cur:
|
async with db.pool.acquire() as conn:
|
||||||
await cur.execute("SELECT * FROM users WHERE email = %s", (email,))
|
async with conn.cursor(aiomysql.DictCursor) as cur:
|
||||||
return await cur.fetchone()
|
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:
|
def download_audio(video_url: str, output_folder: str) -> str:
|
||||||
ydl_opts = {
|
ydl_opts = {
|
||||||
@@ -132,13 +151,17 @@ async def create_user(req: Request):
|
|||||||
# Auto exceptions give more verbose to Nuxt.
|
# Auto exceptions give more verbose to Nuxt.
|
||||||
|
|
||||||
body["password"] = bcrypt.hashpw(body["password"].encode(), bcrypt.gensalt()).decode()
|
body["password"] = bcrypt.hashpw(body["password"].encode(), bcrypt.gensalt()).decode()
|
||||||
async with db.pool.acquire() as conn:
|
if db.mode == "mysql":
|
||||||
async with conn.cursor() as cur:
|
async with db.pool.acquire() as conn:
|
||||||
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))
|
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()
|
await conn.commit()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@app.post("/login")
|
@app.post("/login")
|
||||||
async def login_endpoint(req: Request):
|
async def login_endpoint(req: Request):
|
||||||
|
|
||||||
@@ -153,7 +176,7 @@ async def login_endpoint(req: Request):
|
|||||||
if (bcrypt.checkpw(body["password"].encode(), user_data.get("password").encode())):
|
if (bcrypt.checkpw(body["password"].encode(), user_data.get("password").encode())):
|
||||||
return user_data
|
return user_data
|
||||||
else:
|
else:
|
||||||
raise HTTPException(status_code=401)
|
raise HTTPException(status_code=401, detail="Wrong password")
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise HTTPException(status_code=400)
|
raise HTTPException(status_code=400)
|
||||||
#except ValidationError:
|
#except ValidationError:
|
||||||
@@ -168,9 +191,13 @@ async def me_get_endpoint(req: Request):
|
|||||||
Trusts Nuxt's backend to allow it or not.
|
Trusts Nuxt's backend to allow it or not.
|
||||||
"""
|
"""
|
||||||
args = dict(req.query_params)
|
args = dict(req.query_params)
|
||||||
#print(args)
|
me = None
|
||||||
try:
|
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):
|
if (me is None):
|
||||||
raise HTTPException(404, "User doesn't exist")
|
raise HTTPException(404, "User doesn't exist")
|
||||||
else: return me
|
else: return me
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
aiomysql==0.3.2
|
aiomysql==0.3.2
|
||||||
|
aiosqlite==0.22.1
|
||||||
annotated-doc==0.0.4
|
annotated-doc==0.0.4
|
||||||
annotated-types==0.7.0
|
annotated-types==0.7.0
|
||||||
anyio==4.12.1
|
anyio==4.12.1
|
||||||
|
|||||||
Reference in New Issue
Block a user