-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feature/332 like dislike backend (#355)
* Add my story to stories * add table for like and dislike * add table for like and dislike * fixed a bug * change like & dislike for my story * change like & dislike for my story
- Loading branch information
Showing
9 changed files
with
211 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
backend/alembic/versions/edace0efb31c_add_table_for_like_and_dislike.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
"""add table for like and dislike | ||
Revision ID: edace0efb31c | ||
Revises: 527194b9fb18 | ||
Create Date: 2020-10-14 02:51:38.265440 | ||
""" | ||
from alembic import op | ||
import sqlalchemy as sa | ||
|
||
|
||
# revision identifiers, used by Alembic. | ||
revision = "edace0efb31c" | ||
down_revision = "527194b9fb18" | ||
branch_labels = None | ||
depends_on = None | ||
|
||
|
||
def upgrade(): | ||
# ### commands auto generated by Alembic - please adjust! ### | ||
op.create_table( | ||
"likes", | ||
sa.Column("id", sa.Integer(), nullable=False), | ||
sa.Column("created_at", sa.DateTime(), nullable=True), | ||
sa.Column("updated_at", sa.DateTime(), nullable=True), | ||
sa.Column("like", sa.Boolean(), nullable=True), | ||
sa.Column("my_story_id", sa.Integer(), nullable=True), | ||
sa.Column("liker_story_id", sa.Integer(), nullable=True), | ||
sa.ForeignKeyConstraint(["liker_story_id"], ["stories.id"],), | ||
sa.ForeignKeyConstraint(["my_story_id"], ["my_stories.id"],), | ||
sa.PrimaryKeyConstraint("id"), | ||
) | ||
op.create_index(op.f("ix_likes_id"), "likes", ["id"], unique=False) | ||
# ### end Alembic commands ### | ||
|
||
|
||
def downgrade(): | ||
# ### commands auto generated by Alembic - please adjust! ### | ||
op.drop_index(op.f("ix_likes_id"), table_name="likes") | ||
op.drop_table("likes") | ||
# ### end Alembic commands ### |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
from sqlalchemy.orm import Session | ||
from . import models, schemas | ||
from sqlalchemy.sql.expression import and_ | ||
from stories.crud import update | ||
|
||
|
||
def get_like_by_story_and_user( | ||
db: Session, my_story_id: int, liker_story_id: int | ||
): | ||
return ( | ||
db.query(models.Like) | ||
.filter( | ||
and_( | ||
models.Like.my_story_id == my_story_id, | ||
models.Like.liker_story_id == liker_story_id, | ||
) | ||
) | ||
.first() | ||
) | ||
|
||
|
||
def update_like(db, like_id, like: schemas.LikeCreate): | ||
return update(like_id, like, models.Like, db) | ||
|
||
|
||
def create_like(db, like: schemas.LikeCreate, liker_story_id: int): | ||
d = like.dict() | ||
d["liker_story_id"] = liker_story_id | ||
db_like = models.Like(**d) | ||
db.add(db_like) | ||
db.commit() | ||
db.refresh(db_like) | ||
return db_like | ||
|
||
|
||
def get_like_count(db, my_story_id): | ||
return ( | ||
db.query(models.Like) | ||
.filter( | ||
and_(models.Like.my_story_id == my_story_id, models.Like.like == 1) | ||
) | ||
.count() | ||
) | ||
|
||
|
||
def get_dislike_count(db, my_story_id): | ||
return ( | ||
db.query(models.Like) | ||
.filter( | ||
and_(models.Like.my_story_id == my_story_id, models.Like.like == 0) | ||
) | ||
.count() | ||
) | ||
|
||
|
||
def is_like_by(db, my_story_id, liker_story_id): | ||
db_like = get_like_by_story_and_user(db, my_story_id, liker_story_id) | ||
if db_like: | ||
return db_like.like | ||
else: | ||
return None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
from database import Base | ||
from sqlalchemy import Column, ForeignKey, Integer, Boolean | ||
from sqlalchemy.orm import relationship | ||
|
||
|
||
class Like(Base): | ||
__tablename__ = "likes" | ||
|
||
like = Column(Boolean) | ||
my_story_id = Column(Integer, ForeignKey("my_stories.id")) | ||
liker_story_id = Column(Integer, ForeignKey("stories.id")) | ||
|
||
my_story = relationship("MyStory", lazy="select") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
from pydantic import BaseModel | ||
|
||
|
||
class LikeCreate(BaseModel): | ||
like: bool = None | ||
my_story_id: int | ||
|
||
|
||
class Like(LikeCreate): | ||
liker_story_id: int | ||
|
||
class Config: | ||
orm_mode = True |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
from fastapi import APIRouter, Depends, HTTPException, status | ||
from sqlalchemy.orm import Session | ||
from starlette.responses import JSONResponse | ||
|
||
from auth import main | ||
from database import get_db | ||
from likes import crud, schemas | ||
from stories.crud import get_my_story | ||
from stories import schemas as stories_schemas | ||
|
||
router = APIRouter() | ||
|
||
|
||
@router.post("/", response_model=schemas.Like) | ||
def create_like( | ||
like: schemas.LikeCreate, | ||
current_story: stories_schemas.Story = Depends(main.get_current_story), | ||
db: Session = Depends(get_db), | ||
): | ||
my_story = get_my_story(db, like.my_story_id) | ||
if not my_story: | ||
raise HTTPException( | ||
status_code=404, | ||
detail="Target my story cannot be found", | ||
headers={"WWW-Authenticate": "Bearer"}, | ||
) | ||
|
||
if not current_story: | ||
raise HTTPException( | ||
status_code=status.HTTP_401_UNAUTHORIZED, | ||
detail="User haven't shared their story", | ||
headers={"WWW-Authenticate": "Bearer"}, | ||
) | ||
|
||
like_to_update = crud.get_like_by_story_and_user( | ||
db, my_story_id=like.my_story_id, liker_story_id=current_story.id | ||
) | ||
|
||
if like_to_update: | ||
db_like = crud.update_like(db, like_to_update.id, like) | ||
else: | ||
if my_story.story_id == current_story.id: | ||
raise HTTPException( | ||
status_code=422, | ||
detail="User cannot like or dislike their own my stories", | ||
headers={"WWW-Authenticate": "Bearer"}, | ||
) | ||
|
||
db_like = crud.create_like(db, like, current_story.id) | ||
|
||
return db_like | ||
|
||
|
||
@router.get("/{my_story_id}") | ||
def get_like_count( | ||
my_story_id: int, | ||
current_story: stories_schemas.Story = Depends(main.get_current_story), | ||
db: Session = Depends(get_db), | ||
): | ||
like_count = crud.get_like_count(db, my_story_id) | ||
dislike_count = crud.get_dislike_count(db, my_story_id) | ||
is_like_by_me = crud.is_like_by(db, my_story_id, current_story.id) | ||
|
||
return JSONResponse( | ||
{ | ||
"like": like_count, | ||
"dislike": dislike_count, | ||
"like_by_me": is_like_by_me, | ||
}, | ||
status_code=200, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters