Skip to content

Commit c9d2099

Browse files
committed
feat : API 2개 추가
1 parent 0dd1dc1 commit c9d2099

2 files changed

Lines changed: 67 additions & 21 deletions

File tree

app/diary/router.py

Lines changed: 65 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from app.user.auth import get_current_user
1212
from app.diary.models import Diary, RecommendedSong
1313
from app.diary.schemas import DiaryCreateRequest, DiaryUpdateRequest, DiaryResponse, DiaryCountResponse, SongResponse, \
14-
DiaryPreviewResponse, RecommendSongResponse
14+
DiaryPreviewResponse, RecommendSongResponse, EmotionTag
1515
from app.user.models import User
1616
from app.embedding.models import kobert, save_diary_embedding, split_sentences, get_user_preferred_genres, \
1717
get_songs_by_genre
@@ -30,6 +30,16 @@
3030
logging.basicConfig(level=logging.INFO)
3131
logger = logging.getLogger(__name__)
3232

33+
emotion_to_genres = {
34+
0: ["댄스", "록/메탈"],
35+
1: ["댄스", "포크/블루스"],
36+
2: ["포크/블루스", "R&B/Soul"],
37+
3: ["포크/블루스", "인디음악", "R&B/Soul"],
38+
4: ["포크/블루스", "인디음악", "R&B/Soul"],
39+
5: ["발라드", "포크/블루스"],
40+
6: ["발라드", "R&B/Soul", "포크/블루스"],
41+
7: ["랩/힙합", "록/메탈"]
42+
}
3343

3444
def get_recently_recommended_lyrics(session, user_id: int, limit: int = 20) -> Set[str]:
3545
"""
@@ -553,16 +563,6 @@ async def create_diary_with_emotion_based_recommendation(
553563

554564
combined_embedding = kobert.get_embedding(best_sentence)
555565

556-
emotion_to_genres = {
557-
0: ["댄스", "록/메탈"], # 신남 → 에너지 + 감성 믹스
558-
1: ["인디음악", "댄스", "포크/블루스"], # 기대 → 발랄하거나 설레는 곡
559-
2: ["포크/블루스", "인디음악", "R&B/Soul"], # 편안 → 부드럽고 서정적인 계열
560-
3: ["포크/블루스", "인디음악", "R&B/Soul"], # 만족 → 감정 공감형 감성 음악
561-
4: ["포크/블루스", "인디음악", "R&B/Soul"], # 허무 → 무기력하거나 담담한 정서
562-
5: ["발라드", "포크/블루스"], # 우울 → 조용하거나 격한 감정 침잠
563-
6: ["발라드", "R&B/Soul", "포크/블루스"], # 슬픔 → 애절함 + 회상적 감정
564-
7: ["랩/힙합", "록/메탈"] # 분노 → 파워풀한 표현 위주
565-
}
566566
genre_names = emotion_to_genres.get(emotion_id_full)
567567
if not genre_names:
568568
raise HTTPException(status_code=400, detail="감정에 대응되는 장르가 없습니다.")
@@ -641,15 +641,15 @@ async def create_diary_with_emotion_based_recommendation(
641641
}
642642
))
643643

644-
top_3_raw = heapq.nlargest(7, heap, key=lambda x: (x[0], x[1]))
644+
top_6_raw = heapq.nlargest(10, heap, key=lambda x: (x[0], x[1]))
645645

646646
recent_lyrics = get_recently_recommended_lyrics(session, user_id=current_user.id)
647647

648648
seen_song_ids = set()
649649
seen_lyrics = set()
650-
top_3 = []
650+
top_6 = []
651651

652-
for sim, _, match in top_3_raw:
652+
for sim, _, match in top_6_raw:
653653
song_id = match["song_id"]
654654
lyric_chunk = " ".join(match["lyric_chunk"]).strip()
655655

@@ -659,14 +659,14 @@ async def create_diary_with_emotion_based_recommendation(
659659
logger.info(f"최근 추천된 동일 가사 블럭 제외됨: {lyric_chunk}")
660660
continue
661661

662-
top_3.append((sim, match))
662+
top_6.append((sim, match))
663663
seen_song_ids.add(song_id)
664664
seen_lyrics.add(lyric_chunk)
665665

666-
if len(top_3) >= 3:
666+
if len(top_6) >= 6:
667667
break
668668

669-
if not top_3:
669+
if not top_6:
670670
raise HTTPException(status_code=404, detail="적합한 노래를 찾을 수 없습니다.")
671671

672672
new_diary = Diary(
@@ -694,7 +694,7 @@ async def create_diary_with_emotion_based_recommendation(
694694
save_diary_embedding(session, new_diary.id, combined_embedding)
695695

696696
recommended_songs = []
697-
for sim, match in top_3:
697+
for sim, match in top_6:
698698
song_data = RecommendedSong(
699699
diary_id=new_diary.id,
700700
song_id=match["song_id"],
@@ -729,7 +729,7 @@ async def create_diary_with_emotion_based_recommendation(
729729
"best_sentence": new_diary.best_sentence,
730730
"created_at": new_diary.created_at,
731731
"updated_at": new_diary.updated_at,
732-
"recommended_songs": recommended_songs,
732+
"recommended_songs": recommended_songs[:3],
733733
"top_emotions": [
734734
{"emotion_id": eid, "score": round(score, 4)}
735735
for eid, score in sorted(emotion_vote_counter.items(), key=lambda x: -x[1])[:3]
@@ -881,6 +881,26 @@ def delete_diary(
881881

882882
return {"message": "일기가 삭제되었습니다!"}
883883

884+
@router.get("/{diary_id}/emotion-tags", response_model=List[EmotionTag],
885+
summary="감정 태그 조회", description="특정 일기의 감정 분석 결과(상위 3개)를 조회합니다.")
886+
def get_emotion_tags_by_diary(
887+
diary_id: int,
888+
current_user: User = Depends(get_current_user),
889+
db: Session = Depends(get_db)
890+
):
891+
diary = db.query(Diary).filter(
892+
Diary.id == diary_id,
893+
Diary.user_id == current_user.id
894+
).first()
895+
if not diary:
896+
raise HTTPException(status_code=404, detail="일기를 찾을 수 없습니다.")
897+
898+
tags = db.query(DiaryEmotionTag).filter(
899+
DiaryEmotionTag.diary_id == diary_id
900+
).order_by(DiaryEmotionTag.score.desc()).all()
901+
902+
return tags
903+
884904
@router.get("/{year}/{month}", response_model=List[DiaryResponse],
885905
summary="특정 연도/월의 일기 조회",
886906
description="입력한 연도와 월에 해당하는 일기를 모두 조회합니다.")
@@ -978,6 +998,32 @@ async def set_main_song(
978998
"youtube_url": song.youtube_url
979999
}
9801000

1001+
@router.get("/{diary_id}/recommended-songs/extra", response_model=List[RecommendSongResponse],
1002+
summary="일기 리롤 버튼",
1003+
description="일기 리롤 가능합니다. 1회.")
1004+
def get_additional_recommended_songs(
1005+
diary_id: int,
1006+
current_user: User = Depends(get_current_user),
1007+
db: Session = Depends(get_db)
1008+
):
1009+
diary = db.query(Diary).filter(
1010+
Diary.id == diary_id,
1011+
Diary.user_id == current_user.id
1012+
).first()
1013+
1014+
if not diary:
1015+
raise HTTPException(404, detail="일기를 찾을 수 없습니다.")
1016+
1017+
all_songs = db.query(RecommendedSong).filter(
1018+
RecommendedSong.diary_id == diary_id
1019+
).order_by(RecommendedSong.similarity_score.desc()).all()
1020+
1021+
if len(all_songs) <= 3:
1022+
raise HTTPException(404, detail="추가 추천곡이 없습니다.")
1023+
1024+
return all_songs[3:]
1025+
1026+
9811027
"""
9821028
안 씀
9831029
@router.get("/recommended-songs/{recommended_song_id}/youtube-link-direct")

app/user/auth.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
# 환경 변수 설정
1515
SECRET_KEY = os.getenv("SECRET_KEY")
1616
ALGORITHM = "HS256"
17-
ACCESS_TOKEN_EXPIRE_DAYS = int(os.getenv("ACCESS_TOKEN_EXPIRE_DAYS", 14)) # 1시간
17+
ACCESS_TOKEN_EXPIRE_MINUTES = int(os.getenv("ACCESS_TOKEN_EXPIRE_MINUTES", 60*24)) # 1일
1818
REFRESH_TOKEN_EXPIRE_DAYS = int(os.getenv("REFRESH_TOKEN_EXPIRE_DAYS", 14)) # 2주
1919

2020
# OAuth2 설정
@@ -31,7 +31,7 @@ def verify_password(plain_password: str, hashed_password: str) -> bool:
3131
# 액세스 토큰 생성
3232
def create_access_token(data: dict):
3333
to_encode = data.copy()
34-
expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_DAYS)
34+
expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
3535
to_encode.update({"exp": expire,
3636
"sub": data.get("sub")})
3737
return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)

0 commit comments

Comments
 (0)