videos.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. from typing import Any, List, Optional
  2. from fastapi import UploadFile, File, Form
  3. from fastapi.responses import FileResponse
  4. from fastapi import APIRouter, Depends, HTTPException
  5. from sqlalchemy.orm import Session
  6. import app.crud as crud
  7. import app.models as models
  8. import app.schemas as schemas
  9. from app.api import deps
  10. from app.core.celery_app import celery_app
  11. from app.core.config import settings
  12. from pathlib import Path
  13. from app.core.celery_app import celery_app
  14. ZIP_STORAGE = Path("/app").joinpath(settings.BACKEND_ZIP_STORAGE)
  15. VIDEO_STORAGE = Path("/app").joinpath(settings.BACKEND_VIDEO_STORAGE)
  16. router = APIRouter()
  17. @router.get("/", response_model=List[schemas.Video])
  18. def get_video_list(
  19. db: Session = Depends(deps.get_db),
  20. skip: int = 0,
  21. limit: int = 100,
  22. current_user: models.User = Depends(deps.get_current_active_user),
  23. ) -> Any:
  24. """
  25. Retrieve items.
  26. """
  27. if crud.user.is_superuser(current_user):
  28. videos = crud.video.get_multi(db, skip=skip, limit=limit)
  29. else:
  30. videos = crud.video.get_multi_by_owner(
  31. db=db, owner_id=current_user.id, skip=skip, limit=limit
  32. )
  33. return videos
  34. @router.post("/", response_model=schemas.Video)
  35. def upload_plot(
  36. *,
  37. db: Session = Depends(deps.get_db),
  38. title: str=Form(...),
  39. upload_file: UploadFile=File(),
  40. current_user: models.User = Depends(deps.get_current_active_user),
  41. ) -> Any:
  42. """
  43. Create new video.
  44. """
  45. print(title)
  46. print(upload_file.filename)
  47. file_name = crud.video.generate_file_name(db=db, n=20)
  48. video_create = schemas.VideoCreate(title=title, progress_state="waiting", stored_file_name=file_name)
  49. video = crud.video.create_with_owner(db=db, obj_in=video_create, owner_id=current_user.id)
  50. try:
  51. with open(str(Path(ZIP_STORAGE).joinpath(video.stored_file_name+".zip")), 'wb') as f:
  52. while contents := upload_file.file.read(1024 * 1024):
  53. f.write(contents)
  54. except Exception as e:
  55. print(e, type(e))
  56. return {"error": str(e)}
  57. finally:
  58. upload_file.file.close()
  59. celery_app.send_task("app.worker.make_video", args=[video.id, video.stored_file_name, current_user.id])
  60. return video
  61. @router.get("/{id}")
  62. def download_video(
  63. *,
  64. db: Session = Depends(deps.get_db),
  65. id: int,
  66. current_user: models.User = Depends(deps.get_current_active_user),
  67. ) -> Any:
  68. video = db.query(models.Video).filter(db=db, id=id).first()
  69. if not video:
  70. raise HTTPException(status_code=404, detail="Video not found")
  71. if not crud.user.is_superuser(current_user) and (video.owner_id != current_user.id):
  72. raise HTTPException(status_code=400, detail="Not enough permissions")
  73. if not video.progress == "completed":
  74. raise HTTPException(status_code=400, detail="Video not completed yet")
  75. result = celery_app.send_task("app.worker.upload_to_server", args=[video.id, video.stored_file_name])
  76. if result.get() == "completed" and (file_path:=Path(VIDEO_STORAGE).joinpath(video.stored_file_name+".mp4")).exit():
  77. return FileResponse(path=str(file_path), filename=video.title+".mp4")
  78. else:
  79. raise HTTPException(status_code=404, detail="Error occurs")
  80. @router.get("/worker/{id}")
  81. def download_plot(
  82. *,
  83. db: Session = Depends(deps.get_db),
  84. id: int
  85. ) -> Any:
  86. video = db.query(models.Video).filter(db=db, id=id).first()
  87. if not video:
  88. raise HTTPException(status_code=404, detail="Video not found")
  89. file_path = Path(ZIP_STORAGE).joinpath(video.stored_file_name+".zip")
  90. return FileResponse(path=str(file_path))
  91. @router.post("/worker/{id}")
  92. def upload_complete_video(
  93. *,
  94. db: Session = Depends(deps.get_db),
  95. id: int,
  96. upload_video: Optional[UploadFile]=None,
  97. result:int=Form(...)
  98. ) -> Any:
  99. video = db.query(models.Video).filter(db=db, id=id).first()
  100. if not video:
  101. raise HTTPException(status_code=404, detail="Video not found")
  102. try:
  103. with open(str(Path(VIDEO_STORAGE).joinpath(video.stored_file_name+".mp4")), 'wb') as f:
  104. while contents := upload_video.file.read(1024 * 1024):
  105. f.write(contents)
  106. except Exception as e:
  107. print(e, type(e))
  108. return {"error": str(e)}
  109. finally:
  110. upload_video.file.close()
  111. return video