Making public version
This commit is contained in:
@@ -8,4 +8,5 @@ passlib
|
||||
requests
|
||||
python-multipart
|
||||
Pillow
|
||||
joblib
|
||||
joblib
|
||||
celery
|
||||
@@ -1,7 +1,9 @@
|
||||
from typing import List
|
||||
|
||||
import numpy as np
|
||||
import requests
|
||||
from pydantic import BaseModel
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlmodel import Field, Relationship, SQLModel
|
||||
|
||||
from src.exceptions.base_exception import BaseException
|
||||
@@ -51,6 +53,26 @@ class Sign(SQLModelExtended, table=True):
|
||||
if self.video_url is None:
|
||||
raise BaseException(404, "Video url not found")
|
||||
|
||||
@classmethod
|
||||
async def get_random(self, session: AsyncSession):
|
||||
signs = await self.get_all(select_in_load=[Sign.sign_videos],session=session)
|
||||
|
||||
sign_videos = [len(s.sign_videos) for s in signs]
|
||||
|
||||
# get probability based on number of videos, lower must be more likely
|
||||
# the sum must be 1
|
||||
|
||||
random_prob = [1 / (x + 1) for x in sign_videos]
|
||||
random_prob = random_prob / np.sum(random_prob)
|
||||
|
||||
# get random sign
|
||||
sign = np.random.choice(signs, p=random_prob)
|
||||
|
||||
return sign
|
||||
|
||||
|
||||
|
||||
|
||||
class SignOut(BaseModel):
|
||||
id: int
|
||||
url: str
|
||||
@@ -59,3 +81,10 @@ class SignOut(BaseModel):
|
||||
video_url: str
|
||||
|
||||
sign_videos: List[SignVideo] = []
|
||||
|
||||
class SignOutSimple(BaseModel):
|
||||
id: int
|
||||
url: str
|
||||
name: str
|
||||
sign_id: str
|
||||
video_url: str
|
||||
@@ -13,7 +13,7 @@ import src.settings as settings
|
||||
from src.database.database import get_session
|
||||
from src.exceptions.login_exception import LoginException
|
||||
from src.models.auth import Login, User
|
||||
from src.models.sign import Sign, SignOut
|
||||
from src.models.sign import Sign, SignOut, SignOutSimple
|
||||
from src.models.signvideo import SignVideo
|
||||
from src.models.token import TokenExtended
|
||||
|
||||
@@ -22,6 +22,12 @@ router = APIRouter(prefix="/signs")
|
||||
class SignUrl(BaseModel):
|
||||
url: str
|
||||
|
||||
@router.get("/random", status_code=status.HTTP_200_OK, response_model=SignOutSimple)
|
||||
async def get_random_sign(session: AsyncSession = Depends(get_session)):
|
||||
# get a random sign where there is not much data from yet
|
||||
sign = await Sign.get_random(session=session)
|
||||
return sign
|
||||
|
||||
@router.post("/", status_code=status.HTTP_201_CREATED, response_model=SignOut)
|
||||
async def add_sign(url: SignUrl, Authorize: AuthJWT = Depends(), session: AsyncSession = Depends(get_session)):
|
||||
Authorize.jwt_required()
|
||||
@@ -127,6 +133,7 @@ async def download_all(background_tasks: BackgroundTasks, Authorize: AuthJWT = D
|
||||
|
||||
return response
|
||||
|
||||
|
||||
# define a function to delete the zip file
|
||||
async def delete_zip_file(zip_path):
|
||||
os.remove(zip_path)
|
||||
@@ -7,9 +7,11 @@ import random
|
||||
import string
|
||||
import subprocess
|
||||
|
||||
from celery import Celery
|
||||
from fastapi import (APIRouter, BackgroundTasks, Depends, File, UploadFile,
|
||||
status)
|
||||
from fastapi.responses import FileResponse
|
||||
from fastapi.concurrency import run_in_threadpool
|
||||
from fastapi.responses import FileResponse, JSONResponse
|
||||
from fastapi_jwt_auth import AuthJWT
|
||||
from joblib import Memory
|
||||
from pydantic import BaseModel
|
||||
@@ -26,6 +28,9 @@ from src.utils.cryptography import verify_password
|
||||
|
||||
# Create a Memory object that caches data to the specified directory
|
||||
cache_dir = settings.CACHE_PATH
|
||||
|
||||
celery_app = Celery('tasks', broker=settings.CELERY_REDIS)
|
||||
|
||||
async def extract_thumbnail(video_path):
|
||||
proc = await asyncio.create_subprocess_exec(
|
||||
"ffmpeg", "-i", video_path, "-ss", "00:00:02.000", "-vframes", "1", "-f", "image2pipe", "-"
|
||||
@@ -36,15 +41,18 @@ async def extract_thumbnail(video_path):
|
||||
|
||||
router = APIRouter(prefix="/signs/{sign_id}/video")
|
||||
|
||||
@celery_app.task
|
||||
def convert_video(video_filename):
|
||||
command = ['ffmpeg', '-y', '-i', settings.DATA_PATH + "/" + video_filename + ".test", '-c:v', 'libx264', '-c:a', 'aac', '-strict', '-2', '-b:a', '192k', '-c:a', 'aac', '-strict', '-2', '-b:a', '192k', settings.DATA_PATH + "/" + video_filename]
|
||||
|
||||
# run the command
|
||||
subprocess.run(command)
|
||||
|
||||
# delete the temporary file
|
||||
os.remove(settings.DATA_PATH + "/" + video_filename + ".test")
|
||||
|
||||
# create the thumbnail
|
||||
extract_thumbnail(settings.DATA_PATH + "/" + video_filename)
|
||||
# create thumbnail
|
||||
asyncio.run(extract_thumbnail(settings.DATA_PATH + "/" + video_filename))
|
||||
|
||||
|
||||
# endpoint to upload a file and save it in the data folder
|
||||
@@ -52,15 +60,14 @@ def convert_video(video_filename):
|
||||
async def sign_video(
|
||||
sign_id: int,
|
||||
video: UploadFile,
|
||||
background_tasks: BackgroundTasks,
|
||||
session: AsyncSession = Depends(get_session),
|
||||
Authorize: AuthJWT = Depends(),
|
||||
# Authorize: AuthJWT = Depends(),
|
||||
):
|
||||
Authorize.jwt_required()
|
||||
current_user_id: int = Authorize.get_jwt_subject()
|
||||
user = await User.get_by_id(current_user_id, session)
|
||||
if not user:
|
||||
raise LoginException("User not found")
|
||||
# Authorize.jwt_required()
|
||||
# current_user_id: int = Authorize.get_jwt_subject()
|
||||
# user = await User.get_by_id(current_user_id, session)
|
||||
# if not user:
|
||||
# raise LoginException("User not found")
|
||||
sign = await Sign.get_by_id(sign_id, session)
|
||||
if not sign:
|
||||
raise LoginException("Sign not found")
|
||||
@@ -79,12 +86,13 @@ async def sign_video(
|
||||
with open(settings.DATA_PATH + "/" + video.filename + ".test", 'wb') as f:
|
||||
f.write(video.file.read())
|
||||
|
||||
# convert the video in the background
|
||||
background_tasks.add_task(convert_video, video.filename)
|
||||
convert_video.delay(video.filename)
|
||||
|
||||
await sign_video.save(session)
|
||||
|
||||
return sign_video
|
||||
response = JSONResponse(content={"sign_video": sign_video.dict()})
|
||||
response.headers["Connection"] = "close"
|
||||
return response
|
||||
|
||||
@router.get("/{video_id}/thumbnail/", status_code=status.HTTP_200_OK)
|
||||
async def sign_video_thumbnail(
|
||||
|
||||
@@ -17,6 +17,8 @@ DB_PORT: str = os.getenv("DB_PORT", "5432")
|
||||
DB_USE_SQLITE: bool = os.getenv("DB_USE_SQLITE", False)
|
||||
DB_SQLITE_PATH: str = os.getenv("DB_SQLITE_PATH", "./sqlite.db")
|
||||
|
||||
CELERY_REDIS: str = os.getenv("CELERY_REDIS", "redis://localhost:6379/0")
|
||||
|
||||
"""Storage"""
|
||||
DATA_PATH: str = os.getenv("DATA_PATH", "data")
|
||||
CACHE_PATH: str = os.getenv("CACHE_PATH", "cache")
|
||||
@@ -31,4 +33,4 @@ REFRESH_EXPIRES: int = int(os.getenv("REFRESH_EXPIRES", 864000))
|
||||
"""Standard User"""
|
||||
DEFAULT_USER_ENABLED: bool = os.getenv("DEFAULT_USER_ENABLED", False)
|
||||
DEFAULT_USER_EMAIL: str = os.getenv("DEFAULT_USER_EMAIL", "test@test.com")
|
||||
DEFAULT_USER_PASSWORD: str = os.getenv("DEFAULT_USER_PASSWORD", "test")
|
||||
DEFAULT_USER_PASSWORD: str = os.getenv("DEFAULT_USER_PASSWORD", "test")
|
||||
Reference in New Issue
Block a user