Răsfoiți Sursa

Implement proper most watched aggregation using real play counts from all Emby users

mgomon 8 luni în urmă
părinte
comite
49a2079bf7
1 a modificat fișierele cu 54 adăugiri și 53 ștergeri
  1. 54 53
      api/homepage/userWatchStats.php

+ 54 - 53
api/homepage/userWatchStats.php

@@ -700,69 +700,70 @@ trait HomepageUserWatchStats
     }
     
     /**
-     * Simple approach to get most watched from Emby
+     * Get most watched content by aggregating play counts across all users
      */
     private function getEmbySimpleMostWatched($url, $token)
     {
-        // Try multiple approaches to get content
-        $approaches = [
-            // Approach 1: Recently created items (most likely to have content)
-            rtrim($url, '/') . '/emby/Items?api_key=' . $token . 
-            '&Recursive=true&IncludeItemTypes=Movie,Episode&Fields=Name,RunTimeTicks,ProductionYear,DateCreated' .
-            '&SortBy=DateCreated&SortOrder=Descending&Limit=20',
+        // First get all users
+        $users = $this->getEmbyUserStats($url, $token, 30);
+        if (empty($users)) {
+            return [];
+        }
+        
+        $itemPlayCounts = [];
+        $itemDetails = [];
+        
+        // For each user, get their watched content
+        foreach ($users as $user) {
+            if (isset($user['Policy']['IsDisabled']) && $user['Policy']['IsDisabled']) {
+                continue;
+            }
             
-            // Approach 2: All items without date filter
-            rtrim($url, '/') . '/emby/Items?api_key=' . $token . 
-            '&Recursive=true&IncludeItemTypes=Movie,Episode&Fields=Name,RunTimeTicks,ProductionYear&Limit=20',
+            $userId = $user['Id'];
+            $userWatchedContent = $this->getEmbyUserWatchedContent($url, $token, $userId, 30);
             
-            // Approach 3: Recently played items (if available)
-            rtrim($url, '/') . '/emby/Items?api_key=' . $token . 
-            '&Recursive=true&IncludeItemTypes=Movie,Episode&Fields=Name,RunTimeTicks,ProductionYear' .
-            '&SortBy=DatePlayed&SortOrder=Descending&Limit=20'
-        ];
-        
-        foreach ($approaches as $index => $apiURL) {
-            try {
-                $options = $this->requestOptions($url, null, $this->config['userWatchStatsDisableCertCheck'] ?? false, $this->config['userWatchStatsUseCustomCertificate'] ?? false);
-                $response = Requests::get($apiURL, [], $options);
+            foreach ($userWatchedContent as $item) {
+                $itemId = $item['Id'] ?? $item['title'];
+                if (!$itemId) continue;
                 
-                if ($response->success) {
-                    $data = json_decode($response->body, true);
-                    $items = [];
-                    
-                    // Handle different response formats
-                    if ($index === 2) {
-                        // Latest items API returns array directly
-                        $items = is_array($data) ? $data : [];
-                    } else {
-                        // Other APIs return Items array
-                        $items = $data['Items'] ?? [];
-                    }
-                    
-                    if (!empty($items)) {
-                        $mostWatched = [];
-                        foreach ($items as $item) {
-                            $mostWatched[] = [
-                                'title' => $item['Name'] ?? 'Unknown Title',
-                                'total_plays' => 1, // We don't have actual play count, so assume 1
-                                'runtime' => isset($item['RunTimeTicks']) ? $this->formatDuration($item['RunTimeTicks'] / 10000000) : 'Unknown',
-                                'type' => $item['Type'] ?? 'Unknown',
-                                'year' => $item['ProductionYear'] ?? null
-                            ];
-                        }
-                        
-                        // Log which approach worked (approach " . ($index + 1) . " returned " . count($mostWatched) . " items)
-                        return $mostWatched;
-                    }
+                // Aggregate play counts across all users
+                if (!isset($itemPlayCounts[$itemId])) {
+                    $itemPlayCounts[$itemId] = 0;
+                    $itemDetails[$itemId] = [
+                        'title' => $item['title'],
+                        'type' => $item['type'],
+                        'runtime' => $item['runtime'],
+                        'year' => $item['year']
+                    ];
                 }
-            } catch (Requests_Exception $e) {
-                // Error in approach " . ($index + 1) . ": " . $e->getMessage();
-                continue;
+                $itemPlayCounts[$itemId] += $item['play_count'];
             }
         }
         
-        // All Emby Most Watched approaches failed
-        return [];
+        // Sort by play count descending
+        arsort($itemPlayCounts);
+        
+        // Build most watched list
+        $mostWatched = [];
+        $limit = 20;
+        $count = 0;
+        
+        foreach ($itemPlayCounts as $itemId => $totalPlays) {
+            if ($count >= $limit) break;
+            if ($totalPlays < 1) continue; // Skip items with no plays
+            
+            $details = $itemDetails[$itemId] ?? [];
+            $mostWatched[] = [
+                'title' => $details['title'] ?? 'Unknown Title',
+                'total_plays' => $totalPlays,
+                'runtime' => $details['runtime'] ?? 'Unknown',
+                'type' => $details['type'] ?? 'Unknown',
+                'year' => $details['year'] ?? null
+            ];
+            $count++;
+        }
+        
+        return $mostWatched;
     }
     
     /**