File size: 4,845 Bytes
fafd0bb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# ============================================
# apps/analytics/services.py - Search Tracking Service
# ============================================
from apps.analytics.models import SearchLog, PopularSearch
from django.db.models import F

class SearchTrackingService:
    """Service centralisé pour tracker les recherches"""
    
    @staticmethod
    def log_search(
        category: str,
        search_query: str,
        user=None,
        filters_applied: dict = None,
        results_count: int = 0,
        request=None
    ):
        """
        Enregistre une recherche dans les logs
        
        Args:
            category: Catégorie de recherche (QUESTIONS, MENTORS, etc.)
            search_query: Terme recherché
            user: Utilisateur qui effectue la recherche (None si anonyme)
            filters_applied: Dict des filtres appliqués
            results_count: Nombre de résultats retournés
            request: Objet request Django pour extraire métadonnées
        
        Returns:
            SearchLog instance
        """
        # Extraire métadonnées de la requête si disponible
        session_id = ''
        ip_address = None
        user_agent = ''
        page_url = ''
        
        if request:
            session_id = request.session.session_key or ''
            ip_address = request.META.get('REMOTE_ADDR')
            user_agent = request.META.get('HTTP_USER_AGENT', '')[:500]
            page_url = request.META.get('HTTP_REFERER', '')[:500]
        
        # Créer le log
        search_log = SearchLog.objects.create(
            user=user,
            category=category,
            search_query=search_query.strip()[:500],
            filters_applied=filters_applied or {},
            results_count=results_count,
            session_id=session_id,
            ip_address=ip_address,
            user_agent=user_agent,
            page_url=page_url
        )
        
        # Mettre à jour les recherches populaires
        SearchTrackingService._update_popular_search(category, search_query.strip())
        
        return search_log
    
    @staticmethod
    def _update_popular_search(category: str, search_query: str):
        """Mise à jour incrémentale des recherches populaires"""
        if not search_query or len(search_query) < 2:
            return
        
        popular, created = PopularSearch.objects.get_or_create(
            category=category,
            search_query=search_query[:500],
            defaults={'search_count': 1}
        )
        
        if not created:
            popular.search_count = F('search_count') + 1
            popular.save(update_fields=['search_count', 'last_searched'])
    
    @staticmethod
    def log_result_click(search_log_id: int, result_id: str, position: int):
        """
        Enregistre le clic sur un résultat de recherche
        
        Args:
            search_log_id: ID du SearchLog
            result_id: ID du résultat cliqué
            position: Position dans la liste (0-indexed)
        """
        try:
            search_log = SearchLog.objects.get(id=search_log_id)
            search_log.clicked_result_id = str(result_id)
            search_log.clicked_result_position = position
            search_log.save(update_fields=['clicked_result_id', 'clicked_result_position'])
        except SearchLog.DoesNotExist:
            pass
    
    @staticmethod
    def get_popular_searches(category: str = None, limit: int = 10):
        """
        Récupère les recherches les plus populaires
        
        Args:
            category: Filtrer par catégorie (None = toutes)
            limit: Nombre max de résultats
        
        Returns:
            QuerySet de PopularSearch
        """
        qs = PopularSearch.objects.all()
        
        if category:
            qs = qs.filter(category=category)
        
        return qs[:limit]
    
    @staticmethod
    def get_trending_searches(category: str = None, days: int = 7, limit: int = 10):
        """
        Récupère les recherches tendances (populaires récemment)
        
        Args:
            category: Filtrer par catégorie
            days: Nombre de jours à considérer
            limit: Nombre max de résultats
        
        Returns:
            Liste de dicts avec query et count
        """
        from django.utils import timezone
        from datetime import timedelta
        from django.db.models import Count
        
        since = timezone.now() - timedelta(days=days)
        
        qs = SearchLog.objects.filter(created_at__gte=since)
        
        if category:
            qs = qs.filter(category=category)
        
        trending = qs.values('search_query').annotate(
            count=Count('id')
        ).order_by('-count')[:limit]
        
        return list(trending)