File size: 4,395 Bytes
91ae9ea
1ab78e2
bb45513
 
 
 
d74863e
bb45513
d74863e
bb45513
d74863e
9e1c846
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1ab78e2
9e1c846
8a0d292
91ae9ea
9e1c846
8a0d292
9e1c846
7fcef06
9e1c846
 
 
 
91ae9ea
 
 
7fcef06
 
9e1c846
7fcef06
9e1c846
 
7fcef06
 
 
 
9e1c846
 
 
 
 
 
7fcef06
0b64e1c
9e1c846
91ae9ea
 
 
 
9e1c846
91ae9ea
 
1ab78e2
 
9e1c846
7fcef06
9e1c846
91ae9ea
 
dfcca37
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
from fastapi import APIRouter, Depends, HTTPException, Query
from typing import Dict, Any
from src.auth.dependencies import get_current_user
from src.db.firebase import get_firebase_db
from src.recommendation.recommender import RecommendationService
from src.utils.logger import setup_logger

logger = setup_logger(__name__)
router = APIRouter(prefix="/recommendations", tags=["Recommendations"])
recommendation_service = RecommendationService()

GENERAL_VIDEOS = [
    {
        "videoId": "aircAruvnKk",
        "title": "But what is a neural network?",
        "channelTitle": "3Blue1Brown",
        "thumbnail": "https://img.youtube.com/vi/aircAruvnKk/hqdefault.jpg",
    },
    {
        "videoId": "rfscVS0vtbw",
        "title": "Learn Python in 4 hours",
        "channelTitle": "freeCodeCamp",
        "thumbnail": "https://img.youtube.com/vi/rfscVS0vtbw/hqdefault.jpg",
    },
    {
        "videoId": "8jLOx1hD3_o",
        "title": "Harvard CS50 2023",
        "channelTitle": "CS50",
        "thumbnail": "https://img.youtube.com/vi/8jLOx1hD3_o/hqdefault.jpg",
    },
    {
        "videoId": "kqtD5dpn9C8",
        "title": "Python for Beginners – Full Course",
        "channelTitle": "Programming with Mosh",
        "thumbnail": "https://img.youtube.com/vi/kqtD5dpn9C8/hqdefault.jpg",
    },
    {
        "videoId": "Ke90Tje7VS0",
        "title": "React JS Crash Course",
        "channelTitle": "Traversy Media",
        "thumbnail": "https://img.youtube.com/vi/Ke90Tje7VS0/hqdefault.jpg",
    },
    {
        "videoId": "bMknfKXIFA8",
        "title": "Machine Learning Course for Beginners",
        "channelTitle": "freeCodeCamp",
        "thumbnail": "https://img.youtube.com/vi/bMknfKXIFA8/hqdefault.jpg",
    },
    {
        "videoId": "ua-CiDNNj30",
        "title": "Fullstack Web Dev in 2024",
        "channelTitle": "Fireship",
        "thumbnail": "https://img.youtube.com/vi/ua-CiDNNj30/hqdefault.jpg",
    },
    {
        "videoId": "qiQR5rTSshw",
        "title": "C++ Tutorial for Beginners",
        "channelTitle": "freeCodeCamp",
        "thumbnail": "https://img.youtube.com/vi/qiQR5rTSshw/hqdefault.jpg",
    },
    {
        "videoId": "zOjov-2OZ0E",
        "title": "100+ Linux Things You Should Know",
        "channelTitle": "Fireship",
        "thumbnail": "https://img.youtube.com/vi/zOjov-2OZ0E/hqdefault.jpg",
    },
    {
        "videoId": "W6NZfCO5SIk",
        "title": "JavaScript Tutorial for Beginners",
        "channelTitle": "Programming with Mosh",
        "thumbnail": "https://img.youtube.com/vi/W6NZfCO5SIk/hqdefault.jpg",
    },
]

MIN_INTERACTIONS_FOR_PERSONALIZATION = 5


@router.get("")
async def get_recommendations(
    current_user=Depends(get_current_user),
    db=Depends(get_firebase_db),
    limit: int = Query(default=5, ge=1, le=20),
) -> Dict[str, Any]:

    user_id = current_user.id  # βœ… your model uses "id"

    if not user_id:
        raise HTTPException(status_code=401, detail="Invalid user")

    logger.info(f"🎯 Getting recommendations for user: {user_id}")

    try:
        # βœ… Use notesCount directly from user
        notes_count = getattr(current_user, "notesCount", 0) or 0

        is_personalized = notes_count >= MIN_INTERACTIONS_FOR_PERSONALIZATION

        if is_personalized:
            logger.info(f"βœ… Personalized mode for {user_id} ({notes_count} notes)")
            
            # ⚠️ for now you can still return general videos
            # until you build real recommender
            recommendations = await recommendation_service.get_recommendations_for_user(
                db=db,
                user_id=user_id,
                limit=limit,
            )
        else:
            logger.info(f"🌱 General mode for {user_id} ({notes_count}/{MIN_INTERACTIONS_FOR_PERSONALIZATION} notes)")
            recommendations = []

    except Exception as e:
        logger.error(f"❌ Failed to get recommendations for {user_id}: {e}")
        raise HTTPException(
            status_code=500,
            detail="Failed to fetch recommendations.",
        )

    return {
        "status": "success",
        "is_personalized": is_personalized,
        "interactions_count": notes_count,  # βœ… mapped correctly
        "interactions_needed": MIN_INTERACTIONS_FOR_PERSONALIZATION,
        "count": len(recommendations),
        "recommendations": recommendations,
    }