diff --git a/cruds/api.py b/cruds/api.py index bf290a1..646a1dd 100644 --- a/cruds/api.py +++ b/cruds/api.py @@ -1,27 +1,11 @@ from typing import List -from calendar import month -from datetime import datetime, timedelta +from datetime import datetime from dateutil.relativedelta import relativedelta from fastapi import HTTPException -from sqlalchemy.sql.functions import user +from sqlalchemy import func from db import models from sqlalchemy.orm.session import Session -from schemas.api import Book, Report, User as UserSchema - -months_name = [ - "January", - "February", - "March", - "April", - "May", - "June", - "July", - "August", - "September", - "October", - "November", - "December", -] +from schemas.api import RankingUser, Book, Report, User as UserSchema def get_books_order_by_query(db: Session, user_id: str, order_by: str) -> List[Book]: @@ -34,8 +18,6 @@ def get_books_order_by_query(db: Session, user_id: str, order_by: str) -> List[B ) user = UserSchema.from_orm_custom(user_orm) books = user.books - print(books) - print("-----------" + order_by + "------------") if(order_by == "title"): books = sorted(books, key=lambda x:x.title) @@ -55,6 +37,7 @@ def create_report(db: Session, user_id: str, type: str) -> Report: if not type in ['quantity', 'page']: raise HTTPException(status_code=400, detail='invalid query') now = datetime.now() + months_name = list(range(12)) labels = months_name[now.month:]+months_name[:now.month] print(labels) months = [] @@ -63,7 +46,7 @@ def create_report(db: Session, user_id: str, type: str) -> Report: previous = now - relativedelta(months=11-i) read_pages = db.query(models.ReadPage).filter(models.ReadPage.user_id == user_id, models.ReadPage.year == previous.year, models.ReadPage.month == previous.month).all() if len(read_pages) == 0 and len(months) == 0: - continue + continue data = 0 if type == 'page': for read_page in read_pages: @@ -72,9 +55,31 @@ def create_report(db: Session, user_id: str, type: str) -> Report: for read_page in read_pages: data += read_page.quantity data_list.append(data) - months.append(labels[i]) + months.append(labels[i]+1) report = Report( months=months, data=data_list ) return report + +def get_ranking(db: Session, type: str) -> List[RankingUser]: + if not type in ['quantity', 'page']: + raise HTTPException(status_code=400, detail='invalid query') + now = datetime.now() + + if type == 'quantity': + q = db.query(models.ReadPage.user_id, models.User.name, func.sum(models.ReadPage.quantity)) + if type == 'page': + q = db.query(models.ReadPage.user_id, models.User.name, func.sum(models.ReadPage.pages)) + + q = q.filter(models.ReadPage.year == now.year, models.ReadPage.month == now.month).group_by(models.ReadPage.user_id, models.User.name).limit(5) + + ranking = [] + for uid, name, val in q: + ranking.append(RankingUser( + user_id=uid, + name=name, + value=val + )) + + return ranking diff --git a/routers/api.py b/routers/api.py index e8fd9a8..f082b40 100644 --- a/routers/api.py +++ b/routers/api.py @@ -4,8 +4,8 @@ from fastapi import APIRouter from fastapi.params import Depends from db.main import get_db -from cruds.api import create_report, get_books_order_by_query -from schemas.api import Book, Report +from cruds.api import create_report, get_ranking, get_books_order_by_query +from schemas.api import Book, RankingUser, Report from fastapi_pagination import paginate from fastapi_pagination import Page, paginate @@ -15,6 +15,10 @@ class ModelName(str, Enum): published_date = "published_date" created_at = "created_at" +class Type(str, Enum): + quantity = "quantity" + page = "page" + router = APIRouter() @router.get('/api/books/{user_id}', response_model=Page[Book]) @@ -24,6 +28,11 @@ async def books(user_id: str, order_by: ModelName, db: Session = Depends(get_db) return paginate(books) @router.get('/api/reports/{user_id}', response_model=Report) -async def get_report(user_id: str, type: str = 'quantity', db: Session = Depends(get_db)): +async def get_report(user_id: str, type: Type, db: Session = Depends(get_db)): report = create_report(db, user_id, type) return report + +@router.get('/api/ranking', response_model=List[RankingUser]) +async def get_read_info_ranking(type: Type, db: Session = Depends(get_db)): + ranking = get_ranking(db, type) + return ranking diff --git a/schemas/api.py b/schemas/api.py index 96178ce..758c63b 100644 --- a/schemas/api.py +++ b/schemas/api.py @@ -40,11 +40,11 @@ def from_orm_custom(orm: models.User): class Config: orm_mode = True -class MockUser(BaseModel): +class RankingUser(BaseModel): user_id: str name: str - books: List[Book] + value: int class Report(BaseModel): - months: List[str] + months: List[int] data: List[int]