Просмотр исходного кода

Merge branch 'backend-dev' of http://git.choozmo.com:3000/ai-anchor/video-maker

tomoya 2 лет назад
Родитель
Сommit
cf5ed9621e

+ 2 - 1
backend/app/app/api/api_v1/api.py

@@ -1,6 +1,6 @@
 from fastapi import APIRouter
 from fastapi import APIRouter
 
 
-from app.api.api_v1.endpoints import  login, users, utils, videos, images, reputations
+from app.api.api_v1.endpoints import  login, users, utils, videos, images, reputations, ser_no
 
 
 api_router = APIRouter()
 api_router = APIRouter()
 api_router.include_router(login.router, tags=["login"])
 api_router.include_router(login.router, tags=["login"])
@@ -9,3 +9,4 @@ api_router.include_router(utils.router, prefix="/utils", tags=["utils"])
 api_router.include_router(videos.router, prefix="/videos", tags=["videos"])
 api_router.include_router(videos.router, prefix="/videos", tags=["videos"])
 api_router.include_router(images.router, prefix="/images", tags=["iamges"])
 api_router.include_router(images.router, prefix="/images", tags=["iamges"])
 api_router.include_router(reputations.router, prefix="/reputations", tags=["reputations"])
 api_router.include_router(reputations.router, prefix="/reputations", tags=["reputations"])
+api_router.include_router(ser_no.router, prefix="/ser_nos", tags=["serial numbers"])

+ 24 - 4
backend/app/app/api/api_v1/endpoints/login.py

@@ -1,10 +1,10 @@
 from datetime import timedelta
 from datetime import timedelta
-from typing import Any
+from typing import Any, Optional
 
 
 from fastapi import APIRouter, Body, Depends, HTTPException
 from fastapi import APIRouter, Body, Depends, HTTPException
 from fastapi.security import OAuth2PasswordRequestForm
 from fastapi.security import OAuth2PasswordRequestForm
 from sqlalchemy.orm import Session
 from sqlalchemy.orm import Session
-
+from datetime import datetime
 from app import crud, models, schemas
 from app import crud, models, schemas
 from app.api import deps
 from app.api import deps
 from app.core import security
 from app.core import security
@@ -24,7 +24,7 @@ router = APIRouter()
 
 
 @router.post("/login/access-token", response_model=schemas.Token)
 @router.post("/login/access-token", response_model=schemas.Token)
 def login_access_token(
 def login_access_token(
-    db: Session = Depends(deps.get_db), form_data: OAuth2PasswordRequestForm = Depends()
+    db: Session = Depends(deps.get_db), form_data: OAuth2PasswordRequestForm = Depends(), add_time_code: Optional[str] = None
 ) -> Any:
 ) -> Any:
     """
     """
     OAuth2 compatible token login, get an access token for future requests
     OAuth2 compatible token login, get an access token for future requests
@@ -37,6 +37,16 @@ def login_access_token(
     elif not crud.user.is_active(user):
     elif not crud.user.is_active(user):
         raise HTTPException(status_code=400, detail="Inactive user")
         raise HTTPException(status_code=400, detail="Inactive user")
     access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
     access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
+
+    if add_time_code:
+        available_ser_no = crud.serial_number.available(db, ser_no=add_time_code)
+        
+        user_in = schemas.UserUpdate(available_time=user.available_time+available_ser_no.time)
+        crud.user.update(db, db_obj=user, obj_in=user_in)
+    
+        ser_no_in = schemas.SerialNumberUpdate(code=available_ser_no.code, is_used=True, used_datetime=str(datetime.now()), owner_id=user.id)
+        crud.serial_number.update(db, db_obj=available_ser_no, obj_in=ser_no_in)
+    
     return {
     return {
         "access_token": security.create_access_token(
         "access_token": security.create_access_token(
             user.id, expires_delta=access_token_expires
             user.id, expires_delta=access_token_expires
@@ -46,7 +56,7 @@ def login_access_token(
 
 
 @router.post("/login/google/access-token", response_model=schemas.Token)
 @router.post("/login/google/access-token", response_model=schemas.Token)
 def login_access_token(
 def login_access_token(
-    db: Session = Depends(deps.get_db), form_data: OAuth2PasswordRequestForm = Depends()
+    db: Session = Depends(deps.get_db), form_data: OAuth2PasswordRequestForm = Depends(), add_time_code: Optional[str] = None
 ) -> Any:
 ) -> Any:
     """
     """
     OAuth2 compatible token login, get an access token for future requests
     OAuth2 compatible token login, get an access token for future requests
@@ -60,6 +70,16 @@ def login_access_token(
     elif not crud.user.is_active(user):
     elif not crud.user.is_active(user):
         raise HTTPException(status_code=400, detail="Inactive user")
         raise HTTPException(status_code=400, detail="Inactive user")
     access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
     access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
+
+    if add_time_code:
+        available_ser_no = crud.serial_number.available(db, ser_no=add_time_code)
+        
+        user_in = schemas.UserUpdate(available_time=user.available_time+available_ser_no.time)
+        crud.user.update(db, db_obj=user, obj_in=user_in)
+    
+        ser_no_in = schemas.SerialNumberUpdate(code=available_ser_no.code, is_used=True, used_datetime=str(datetime.now()), owner_id=user.id)
+        crud.serial_number.update(db, db_obj=available_ser_no, obj_in=ser_no_in)
+    
     return {
     return {
         "access_token": security.create_access_token(
         "access_token": security.create_access_token(
             user.id, expires_delta=access_token_expires
             user.id, expires_delta=access_token_expires

+ 1 - 1
backend/app/app/api/api_v1/endpoints/reputations.py

@@ -36,6 +36,6 @@ async def post_reputation(
     """
     """
     
     
     #print(posted_article)
     #print(posted_article)
-    article = crud.artivle.create_with_owner(db=db, obj_in=posted_article, owner_id=current_user.id, posted_datetime=str(datetime.now()))
+    article = crud.article.create_with_owner(db=db, obj_in=posted_article, owner_id=current_user.id, posted_datetime=str(datetime.now()))
     if article:
     if article:
         return {"id":article.id}
         return {"id":article.id}

+ 41 - 0
backend/app/app/api/api_v1/endpoints/ser_no.py

@@ -0,0 +1,41 @@
+from typing import Any, List
+from fastapi.responses import RedirectResponse
+from fastapi import APIRouter, Body, Depends, HTTPException, Request
+from fastapi.encoders import jsonable_encoder
+from pydantic.networks import EmailStr
+from sqlalchemy.orm import Session
+
+from app import crud, models, schemas
+from app.api import deps
+from app.core.config import settings
+
+from datetime import datetime
+
+router = APIRouter()
+
+@router.get("/add-time")
+def add_time(
+    *,
+    db: Session = Depends(deps.get_db),
+    current_user: models.User = Depends(deps.get_current_active_user),
+    ser_no: models.SerialNumber = Depends(deps.get_avairable_serial_number)
+)-> Any:
+
+  
+    user_in = schemas.UserUpdate(available_time=current_user.available_time+ser_no.time)
+    crud.user.update(db, db_obj=current_user, obj_in=user_in)
+    
+    ser_no_in = schemas.SerialNumberUpdate(code=ser_no.code, is_used=True, used_datetime=str(datetime.now()), owner_id=current_user.id)
+    crud.serial_number.update(db, db_obj=ser_no, obj_in=ser_no_in)
+
+    return "ok"
+
+@router.get("/add-time-no-token")
+def add_time_no_token(
+    request: Request,
+    ser_no: models.SerialNumber = Depends(deps.get_avairable_serial_number)
+)-> Any:
+    print(f"{request.base_url}login?ser_no={ser_no.code}")
+    #return RedirectResponse(f"{request.base_url}login?ser_no={ser_no.code}")
+    return RedirectResponse(f"http://localhost:5173/login?add-time-code={ser_no.code}")
+

+ 12 - 0
backend/app/app/api/deps.py

@@ -59,3 +59,15 @@ def get_current_active_superuser(
             status_code=400, detail="The user doesn't have enough privileges"
             status_code=400, detail="The user doesn't have enough privileges"
         )
         )
     return current_user
     return current_user
+
+def get_valid_serial_number(code: str, db: Session = Depends(get_db)):
+    ser_no = db.query(models.SerialNumber).filter(models.SerialNumber.code==code).first()
+    if not ser_no:
+        raise HTTPException(status_code=400, detail="This serial number is invalid")
+    
+    return ser_no
+
+def get_avairable_serial_number(ser_no:models.SerialNumber = Depends(get_valid_serial_number)):
+    if ser_no.is_used:
+        raise HTTPException(status_code=400, detail="This serial number is already used")
+    return ser_no

+ 1 - 0
backend/app/app/core/celeryconf.py

@@ -0,0 +1 @@
+task_track_started = True

+ 2 - 1
backend/app/app/crud/__init__.py

@@ -1,6 +1,7 @@
 from .crud_user import user
 from .crud_user import user
 from .crud_video import video
 from .crud_video import video
-from .crud_article import artivle
+from .crud_article import article
+from .crud_ser_no import serial_number
 # For a new basic set of CRUD operations you could just do
 # For a new basic set of CRUD operations you could just do
 
 
 # from .base import CRUDBase
 # from .base import CRUDBase

+ 1 - 1
backend/app/app/crud/crud_article.py

@@ -20,4 +20,4 @@ class CRUDArticle(CRUDBase[Article, ArticleCreate, ArticleUpdate]):
         db.refresh(db_obj)
         db.refresh(db_obj)
         return db_obj
         return db_obj
     
     
-artivle = CRUDArticle(Article)
+article = CRUDArticle(Article)

+ 25 - 0
backend/app/app/crud/crud_ser_no.py

@@ -0,0 +1,25 @@
+from typing import List, Optional
+
+from fastapi.encoders import jsonable_encoder
+from sqlalchemy.orm import Session
+
+from app.crud.base import CRUDBase
+from app.models.serial_number import SerialNumber
+from app.schemas.serial_number import SerialNumberCreate, SerialNumberUpdate
+
+from app.utils import random_name
+
+class CRUDSerialNumber(CRUDBase[SerialNumber, SerialNumberCreate, SerialNumberUpdate]):
+    
+    def valid(self, db: Session, *, ser_no:str) -> Optional[SerialNumber]:
+        return db.query(SerialNumber).filter(SerialNumber.code==ser_no).first()
+
+    def available(self, db: Session, *, ser_no:str) -> Optional[SerialNumber]:
+        valid_ser_no = self.valid(db, ser_no=ser_no)
+        if valid_ser_no and not valid_ser_no.is_used:
+            return valid_ser_no
+        else:
+            return None
+        
+    
+serial_number = CRUDSerialNumber(SerialNumber)

+ 1 - 0
backend/app/app/db/base.py

@@ -6,3 +6,4 @@ from app.models.video import Video
 from app.models.enum import Progress, Membership
 from app.models.enum import Progress, Membership
 from app.models.character import Character
 from app.models.character import Character
 from app.models.article import Article
 from app.models.article import Article
+from app.models.serial_number import SerialNumber

+ 2 - 1
backend/app/app/models/__init__.py

@@ -1,4 +1,5 @@
 from .user import User
 from .user import User
 from .video import Video
 from .video import Video
 from .enum import Membership, Progress
 from .enum import Membership, Progress
-from .article import Article
+from .article import Article
+from .serial_number import SerialNumber

+ 14 - 0
backend/app/app/models/serial_number.py

@@ -0,0 +1,14 @@
+from typing import TYPE_CHECKING
+
+from sqlalchemy import Column, ForeignKey, Integer, String, DateTime, Boolean
+
+from app.db.base_class import Base
+
+class SerialNumber(Base):
+  __tablename__ = "serial_number"
+  code = Column(String(length=20), primary_key=True)
+  time = Column(Integer, nullable=False)
+  created_datetime = Column(DateTime)
+  is_used = Column(Boolean, nullable=False, default=False)
+  used_datetime = Column(DateTime)
+  owner_id = Column(Integer, ForeignKey("user.id"))

+ 1 - 0
backend/app/app/schemas/__init__.py

@@ -3,3 +3,4 @@ from .user import User, UserCreate, UserInDB, UserUpdate
 from .msg import Msg
 from .msg import Msg
 from .video import Video, VideoCreate, VideoInDB, VideoUpdate
 from .video import Video, VideoCreate, VideoInDB, VideoUpdate
 from .article import ArticleBase, ArticleCreate, ArticleUpdate
 from .article import ArticleBase, ArticleCreate, ArticleUpdate
+from .serial_number import SerialNumberBase, SerialNumberCreate, SerialNumberUpdate

+ 21 - 0
backend/app/app/schemas/serial_number.py

@@ -0,0 +1,21 @@
+from typing import Optional
+
+from pydantic import BaseModel
+
+
+
+class SerialNumberBase(BaseModel):
+    code: Optional[str] = None
+    time: Optional[int] = None
+    created_datetime: Optional[str] = None
+    is_used: Optional[bool] = False
+    used_datetime: Optional[str] = None
+
+# Properties to receive via API on creation
+class SerialNumberCreate(SerialNumberBase):
+    pass
+
+
+# Properties to receive via API on update
+class SerialNumberUpdate(SerialNumberBase):
+    owner_id: int

+ 1 - 0
backend/app/app/schemas/user.py

@@ -19,6 +19,7 @@ class UserCreate(UserBase):
 # Properties to receive via API on update
 # Properties to receive via API on update
 class UserUpdate(UserBase):
 class UserUpdate(UserBase):
     password: Optional[str] = None
     password: Optional[str] = None
+    available_time: Optional[int] = None
 
 
 
 
 class UserInDBBase(UserBase):
 class UserInDBBase(UserBase):