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

add time, menbership in User and Videos

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

+ 45 - 0
backend/app/app/api/api_v1/endpoints/videos.py

@@ -0,0 +1,45 @@
+from typing import Any, List
+
+from fastapi import APIRouter, Depends, HTTPException
+from sqlalchemy.orm import Session
+
+import app.crud as crud
+import app.models as models
+import app.schemas as schemas 
+from app.api import deps
+
+router = APIRouter()
+
+@router.get("/", response_model=List[schemas.Video])
+def read_items(
+    db: Session = Depends(deps.get_db),
+    skip: int = 0,
+    limit: int = 100,
+    current_user: models.User = Depends(deps.get_current_active_user),
+) -> Any:
+    """
+    Retrieve items.
+    """
+    if crud.user.is_superuser(current_user):
+        items = crud.item.get_multi(db, skip=skip, limit=limit)
+    else:
+        items = crud.item.get_multi_by_owner(
+            db=db, owner_id=current_user.id, skip=skip, limit=limit
+        )
+    return items
+
+@router.post("/", response_model=schemas.Item)
+def create_item(
+    *,
+    db: Session = Depends(deps.get_db),
+    video_upload: schemas.VideoUpload,
+    current_user: models.User = Depends(deps.get_current_active_user),
+) -> Any:
+    """
+    Create new video.
+    """
+    video_create = schemas.VideoCreate
+    video_create.title = video_upload.title
+    video_create.progress = models.Progress.WAITING
+    video = crud.item.create_with_owner(db=db, obj_in=video_create, owner_id=current_user.id)
+    return video

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

@@ -1,5 +1,6 @@
 from .crud_item import item
 from .crud_user import user
+from .crud_video import video
 
 # For a new basic set of CRUD operations you could just do
 

+ 34 - 0
backend/app/app/crud/crud_video.py

@@ -0,0 +1,34 @@
+from typing import List
+
+from fastapi.encoders import jsonable_encoder
+from sqlalchemy.orm import Session
+
+from app.crud.base import CRUDBase
+from app.models.video import Video
+from app.schemas.video import VideoCreate, VideoUpdate
+
+
+class CRUDVideo(CRUDBase[Video, VideoCreate, VideoUpdate]):
+    def create_with_owner(
+        self, db: Session, *, obj_in: VideoCreate, owner_id: int
+    ) -> Video:
+        obj_in_data = jsonable_encoder(obj_in)
+        db_obj = self.model(**obj_in_data, owner_id=owner_id)
+        db.add(db_obj)
+        db.commit()
+        db.refresh(db_obj)
+        return db_obj
+
+    def get_multi_by_owner(
+        self, db: Session, *, owner_id: int, skip: int = 0, limit: int = 100
+    ) -> List[Video]:
+        return (
+            db.query(self.model)
+            .filter(Video.owner_id == owner_id)
+            .offset(skip)
+            .limit(limit)
+            .all()
+        )
+
+
+video = CRUDVideo(Video)

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

@@ -3,3 +3,4 @@
 from app.db.base_class import Base  # noqa
 from app.models.item import Item  # noqa
 from app.models.user import User  # noqa
+from app.models.video import Video

+ 3 - 0
backend/app/app/models/__init__.py

@@ -1,2 +1,5 @@
 from .item import Item
 from .user import User
+from .user import Membership
+from .video import Video
+from .video import Progress

+ 18 - 8
backend/app/app/models/user.py

@@ -1,19 +1,29 @@
 from typing import TYPE_CHECKING
 
-from sqlalchemy import Boolean, Column, Integer, String
+from sqlalchemy import Boolean, Column, Integer, String, Enum
 from sqlalchemy.orm import relationship
 
 from app.db.base_class import Base
 
+import enum
+
+
 if TYPE_CHECKING:
     from .item import Item  # noqa: F401
 
 
+class Membership(enum.Enum):
+  Chosen = enum.auto()
+  Normal = enum.auto()
+
 class User(Base):
-    id = Column(Integer, primary_key=True, index=True)
-    full_name = Column(String, index=True)
-    email = Column(String, unique=True, index=True, nullable=False)
-    hashed_password = Column(String, nullable=False)
-    is_active = Column(Boolean(), default=True)
-    is_superuser = Column(Boolean(), default=False)
-    items = relationship("Item", back_populates="owner")
+  id = Column(Integer, primary_key=True, index=True)
+  full_name = Column(String, index=True)
+  email = Column(String, unique=True, index=True, nullable=False)
+  hashed_password = Column(String, nullable=False)
+  membership = Column(Enum(Membership), nullable=False, default=Membership.Normal)
+  time = Column(Integer, default=0)
+  is_active = Column(Boolean(), default=True)
+  is_superuser = Column(Boolean(), default=False)
+  items = relationship("Item", back_populates="owner")
+  videos = relationship("Video", back_populates="owner")

+ 23 - 0
backend/app/app/models/video.py

@@ -0,0 +1,23 @@
+from typing import TYPE_CHECKING
+
+from sqlalchemy import Column, ForeignKey, Integer, String, Enum
+from sqlalchemy.orm import relationship
+
+from app.db.base_class import Base
+
+import enum
+
+if TYPE_CHECKING:
+    from .user import User  # noqa: F401
+
+class Progress(enum.Enum):
+  WAITING = enum.auto()
+  PROCESSING = enum.auto()
+  COMPLETE = enum.auto()
+
+class Video(Base):
+  id = Column(Integer, primary_key=True, index=True)
+  title = Column(String, index=True)
+  progress = Column(Enum(Progress))
+  owner_id = Column(Integer, ForeignKey("user.id"))
+  owner = relationship("User", back_populates="videos")

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

@@ -2,3 +2,4 @@ from .item import Item, ItemCreate, ItemInDB, ItemUpdate
 from .msg import Msg
 from .token import Token, TokenPayload
 from .user import User, UserCreate, UserInDB, UserUpdate
+from .video import Video, VideoCreate, VideoInDB, VideoUpdate

+ 42 - 0
backend/app/app/schemas/video.py

@@ -0,0 +1,42 @@
+from typing import Optional
+
+from pydantic import BaseModel
+
+from fastapi import UploadFile, File
+
+# Shared properties
+class VideoBase(BaseModel):
+    title: Optional[str] = None
+
+# Properties to receive on item upload
+class VideoUpload(VideoBase):
+    title: str
+    zip_file: UploadFile=File()
+
+# Properties to receive on item creation
+class VideoCreate(VideoBase):
+    title: str
+
+# Properties to receive on item update
+class VideoUpdate(VideoBase):
+    pass
+
+# Properties shared by models stored in DB
+class VideoInDBBase(VideoBase):
+    id: int
+    title: str
+    progress: str
+    owner_id: int
+
+    class Config:
+        orm_mode = True
+
+
+# Properties to return to client
+class Video(VideoInDBBase):
+    pass
+
+
+# Properties properties stored in DB
+class VideoInDB(VideoInDBBase):
+    pass

+ 1 - 53
frontend/src/views/Login.vue

@@ -85,7 +85,7 @@ onMounted(() => {});
 
           <p class="text-center">
             還沒有帳號?
-            <router-link to="/signup">註冊</router-link><router-link
+            <router-link to="/signup">註冊</router-link> / <router-link
               to="/recover-password"
               >忘記密碼</router-link
             >
@@ -104,56 +104,4 @@ onMounted(() => {});
     </v-row>
   </v-container>
 
-  <!-- <v-container fluid class="d-flex fill-height">
-    <v-row align="center" justify="center">
-      <v-col :cols="width">
-        <v-card class="elevation-12">
-          <v-toolbar dark color="primary">
-            <v-toolbar-title>{{ appName }}</v-toolbar-title>
-            <v-spacer></v-spacer>
-            <v-btn to="/signup">SignUp</v-btn>
-          </v-toolbar>
-          <v-card-text>
-            <v-form @keyup.enter="submit">
-              <v-text-field
-                @keyup.enter="submit"
-                v-model="email"
-                prepend-icon="person"
-                name="email"
-                label="Email"
-                type="text"
-              ></v-text-field>
-              <v-text-field
-                @keyup.enter="submit"
-                v-model="password"
-                prepend-icon="key"
-                name="password"
-                label="Password"
-                id="password"
-                type="password"
-              ></v-text-field>
-            </v-form>
-            <div v-if="loginError">
-              <v-alert
-                :value="loginError"
-                transition="fade-transition"
-                type="error"
-              >
-                Incorrect email or password
-              </v-alert>
-            </div>
-            <div class="d-flex align-end flex-column">
-              <router-link to="/recover-password"
-                >Forgot your password?</router-link
-              >
-            </div>
-          </v-card-text>
-          <v-card-actions>
-            <v-spacer></v-spacer>
-            <v-btn @click.prevent="submit">Login</v-btn>
-          </v-card-actions>
-        </v-card>
-      </v-col>
-    </v-row>
-  </v-container> -->
 </template>