diff --git a/.gitignore b/.gitignore index 3d5c8d7..6b57e4c 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ db/data .pytest_cache data/* app/ga-credential.json +.prettierrc +.vscode/ diff --git a/app/crud.py b/app/crud.py index 01d53be..c7af996 100644 --- a/app/crud.py +++ b/app/crud.py @@ -504,4 +504,41 @@ def create_events_from_df(db:Session, df: pd.DataFrame) -> None: db.commit() db.refresh(db_event) - return None \ No newline at end of file + return None + +def get_all_news(db:Session): + return db.query(models.News).all() + +def get_news(db:Session, news_id:str): + news = db.query(models.News).filter(models.News.id==news_id).first() + + if not news: + raise HTTPException(404, "指定されたidを持つnewsは存在しません。") + + return news + +def create_news(db:Session, news:schemas.NewsUpdate): + db_news = models.News(**news.dict()) + db_news.timestamp = datetime.now(timezone(timedelta(hours=9))).isoformat() #日本の時刻に修正。時間はstring型で保存 + db_news.id = ulid.new() + db.add(db_news) + db.commit() + db.refresh(db_news) + return db_news + +def delete_news(db:Session, news_id:str): + news = db.query(models.News).filter(models.News.id==news_id).first() + if not news: + raise HTTPException(404, "指定されたidを持つお知らせは存在しません。") + db.delete(news) + db.commit() + return news + +def update_news(db:Session, news_id:str, news:schemas.NewsUpdate): + db_news:models.News = db.query(models.News).filter(models.News.id == news_id).first() + if not db_news: + raise HTTPException(404, "指定されたidを持つnewsは存在しません。") + db_news.update_dict(news.dict()) + db.commit() + db.refresh(db_news) + return db_news \ No newline at end of file diff --git a/app/main.py b/app/main.py index b94ea9d..00948c3 100644 --- a/app/main.py +++ b/app/main.py @@ -690,6 +690,26 @@ def update_frontend(permission:schemas.JWTUser=Depends(auth.admin)): else: HTTPException(res.status_code,"Cloudflareへのデプロイに失敗しました") +@app.post( + "/support/events", + summary="公演の一括追加", + tags=["admin"], + description="csvファイルを元に公演を一斉に追加します。csvファイルについてはサンプルのエクセルと同じ書式で書いたものにしてください。正しく処理されません。" +) +async def create_all_events_from_csv(file: UploadFile = File(...), permission:schemas.JWTUser=Depends(auth.chief),db:Session = Depends(db.get_db)): + #pandasのDataFrameに読み込んだファイルを変換 + content = file.file.read() + string_data = str(content, 'utf-8') + data = StringIO(string_data) + df = pd.read_csv(data) + data.close() + file.file.close() + + converted_df = crud.convert_df(df) + crud.check_df(db,converted_df) + crud.create_events_from_df(db, converted_df) + + return {'message' :[converted_df.iloc[i,:].to_json() for i in range(len(converted_df))]} @app.get( "/hebe/nowplaying", @@ -723,7 +743,7 @@ def get_hebe_upnext(db:Session = Depends(db.get_db)): tags=["chief"], description="チーフのみ" ) -def get_hebe_nowplaying(hebe:schemas.HebeResponse,permission:schemas.JWTUser=Depends(auth.chief),db:Session = Depends(db.get_db)): +def set_hebe_nowplaying(hebe:schemas.HebeResponse,permission:schemas.JWTUser=Depends(auth.chief),db:Session = Depends(db.get_db)): return crud.set_hebe_nowplaying(db,hebe) @app.post( @@ -733,26 +753,51 @@ def get_hebe_nowplaying(hebe:schemas.HebeResponse,permission:schemas.JWTUser=Dep tags=["chief"], description="チーフのみ" ) -def get_hebe_nowplaying(hebe:schemas.HebeResponse,permission:schemas.JWTUser=Depends(auth.chief),db:Session = Depends(db.get_db)): +def set_hebe_upnext(hebe:schemas.HebeResponse,permission:schemas.JWTUser=Depends(auth.chief),db:Session = Depends(db.get_db)): return crud.set_hebe_upnext(db,hebe) +@app.get( + "/news", + response_model=List[schemas.NewsBase], + summary="全てのお知らせ情報を取得する", + tags=["news"] +) +def get_all_news(db:Session = Depends(db.get_db)): + return crud.get_all_news(db) + +@app.get( + "/news/{news_id}", + summary="指定されたidのnewsを取得", + response_model=schemas.NewsBase, + tags=["news"] +) +def get_news(news_id:str, db:Session = Depends(db.get_db)): + return crud.get_news(db, news_id) + @app.post( - "/support/events", - summary="公演の一括追加", - tags=["admin"], - description="csvファイルを元に公演を一斉に追加します。csvファイルについてはサンプルのエクセルと同じ書式で書いたものにしてください。正しく処理されません。" + "/news/create", + response_model=schemas.NewsUpdate, + summary="お知らせ情報の作成", + tags=["news","chief","admin"] ) -async def create_all_events_from_csv(file: UploadFile = File(...), permission:schemas.JWTUser=Depends(auth.chief),db:Session = Depends(db.get_db)): - #pandasのDataFrameに読み込んだファイルを変換 - content = file.file.read() - string_data = str(content, 'utf-8') - data = StringIO(string_data) - df = pd.read_csv(data) - data.close() - file.file.close() +def create_news(news:schemas.NewsUpdate,permission_chief:schemas.JWTUser=Depends(auth.chief),permission_admin:schemas.JWTUser=Depends(auth.admin), db:Session = Depends(db.get_db)): + return crud.create_news(db, news) - converted_df = crud.convert_df(df) - crud.check_df(db,converted_df) - crud.create_events_from_df(db, converted_df) +@app.delete( + "/news/{news_id}", + response_model=schemas.NewsBase, + summary="お知らせ情報の削除", + tags=["news","chief","admin"] +) +def delete_news(news_id:str, permission_chief:schemas.JWTUser=Depends(auth.chief),permission_admin:schemas.JWTUser=Depends(auth.admin), db:Session = Depends(db.get_db)): + return crud.delete_news(db, news_id) - return {'message' :[converted_df.iloc[i,:].to_json() for i in range(len(converted_df))]} \ No newline at end of file +@app.put( + "/news/{news_id}", + summary="お知らせ情報の更新", + response_model=schemas.NewsUpdate, + description="タイムスタンプとIDは変更されません。注意してください。", + tags=["news","chief","admin"] +) +def change_news(news_id:str, news:schemas.NewsUpdate, permission_chief:schemas.JWTUser=Depends(auth.chief),permission_admin:schemas.JWTUser=Depends(auth.admin), db:Session = Depends(db.get_db)): + return crud.update_news(db, news_id, news) \ No newline at end of file diff --git a/app/models.py b/app/models.py index 2eb6948..256b7fe 100644 --- a/app/models.py +++ b/app/models.py @@ -117,3 +117,16 @@ class HebeUpnext(Base): group_id = Column(VARCHAR(255),ForeignKey("groups.id"),primary_key=True,index=True) +class News(Base): + __tablename__ = "news" + + id = Column(VARCHAR(255), primary_key=True, unique=True) + title = Column(VARCHAR(255), nullable=False) + timestamp = Column(VARCHAR(255), nullable=False) + author = Column(VARCHAR(255), nullable=False) + detail = Column(VARCHAR(500), nullable=True) + + def update_dict(self,dict): + for name, value in dict.items(): + if name in self.__dict__ : + setattr(self, name, value) \ No newline at end of file diff --git a/app/schemas.py b/app/schemas.py index e916bae..f88a891 100644 --- a/app/schemas.py +++ b/app/schemas.py @@ -180,6 +180,19 @@ class GroupLink(GroupLinkBase): class Config: orm_mode=True +class NewsUpdate(BaseModel): + title:str = Query(default=None,max_length=200) + author:str = Query(default=None, max_length=50) + detail:Union[str, None] = Query(default=None) + + class Config: + orm_mode=True + +class NewsBase(NewsUpdate): + timestamp:datetime + id:str + + Event.update_forward_refs() Group.update_forward_refs() Tag.update_forward_refs() diff --git "a/migration/versions/b01b6794fa9c_\343\201\212\347\237\245\343\202\211\343\201\233\346\203\205\345\240\261\343\201\256\343\203\206\343\203\274\343\203\226\343\203\253\343\201\256\350\277\275\345\212\240.py" "b/migration/versions/b01b6794fa9c_\343\201\212\347\237\245\343\202\211\343\201\233\346\203\205\345\240\261\343\201\256\343\203\206\343\203\274\343\203\226\343\203\253\343\201\256\350\277\275\345\212\240.py" new file mode 100644 index 0000000..e6cb830 --- /dev/null +++ "b/migration/versions/b01b6794fa9c_\343\201\212\347\237\245\343\202\211\343\201\233\346\203\205\345\240\261\343\201\256\343\203\206\343\203\274\343\203\226\343\203\253\343\201\256\350\277\275\345\212\240.py" @@ -0,0 +1,36 @@ +"""お知らせ情報のテーブルの追加 + +Revision ID: b01b6794fa9c +Revises: b785ba3a2637 +Create Date: 2024-05-11 05:10:41.026198 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'b01b6794fa9c' +down_revision = 'b785ba3a2637' +branch_labels = None +depends_on = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('news', + sa.Column('id', sa.VARCHAR(length=255), nullable=False), + sa.Column('title', sa.VARCHAR(length=255), nullable=False), + sa.Column('timestamp', sa.VARCHAR(length=255), nullable=False), + sa.Column('author', sa.VARCHAR(length=255), nullable=False), + sa.Column('detail', sa.VARCHAR(length=255), nullable=True), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('id') + ) + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table('news') + # ### end Alembic commands ### diff --git "a/migration/versions/e525a328076b_news\343\201\256detail\343\201\256\346\226\207\345\255\227\346\225\260\343\202\222\351\225\267\343\201\217\343\201\227\343\201\237.py" "b/migration/versions/e525a328076b_news\343\201\256detail\343\201\256\346\226\207\345\255\227\346\225\260\343\202\222\351\225\267\343\201\217\343\201\227\343\201\237.py" new file mode 100644 index 0000000..3d9ec78 --- /dev/null +++ "b/migration/versions/e525a328076b_news\343\201\256detail\343\201\256\346\226\207\345\255\227\346\225\260\343\202\222\351\225\267\343\201\217\343\201\227\343\201\237.py" @@ -0,0 +1,28 @@ +"""Newsのdetailの文字数を長くした + +Revision ID: e525a328076b +Revises: b01b6794fa9c +Create Date: 2024-05-31 12:16:06.930988 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'e525a328076b' +down_revision = 'b01b6794fa9c' +branch_labels = None +depends_on = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + pass + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + pass + # ### end Alembic commands ###