Browse Source

Enhance Emby most watched content retrieval

- Implement activity log-based approach for getting most watched content
- Add fallback to simple date-played sorting when activity logs unavailable
- Improve data aggregation across all users for server-wide statistics
- Enhanced error handling and logging for API calls
mgomon 8 months ago
parent
commit
ef83b0fc91
1 changed files with 110 additions and 19 deletions
  1. 110 19
      api/homepage/userWatchStats.php

+ 110 - 19
api/homepage/userWatchStats.php

@@ -695,33 +695,124 @@ trait HomepageUserWatchStats
      */
     private function getEmbyMostWatched($url, $token, $days)
     {
-        // Get all users first
-        $users = $this->getEmbyUserStats($url, $token, $days);
-        $allWatchedContent = [];
+        // Use activity logs to get most watched content
+        $mostWatched = [];
+        
+        // Try to get activity data from Emby
+        $apiURL = rtrim($url, '/') . '/emby/System/ActivityLog/Entries?api_key=' . $token . 
+                  '&limit=1000&type=VideoPlayback';
+        
+        try {
+            $options = $this->requestOptions($url, null, $this->config['userWatchStatsDisableCertCheck'] ?? false, $this->config['userWatchStatsUseCustomCertificate'] ?? false);
+            $response = Requests::get($apiURL, [], $options);
+            
+            if ($response->success) {
+                $data = json_decode($response->body, true);
+                $items = $data['Items'] ?? [];
+                
+                $playCount = [];
+                foreach ($items as $item) {
+                    if (isset($item['Name']) && isset($item['ShortOverview'])) {
+                        $title = $item['Name'];
+                        if (!isset($playCount[$title])) {
+                            $playCount[$title] = [
+                                'title' => $title,
+                                'total_plays' => 0,
+                                'type' => 'Media',
+                                'year' => null
+                            ];
+                        }
+                        $playCount[$title]['total_plays']++;
+                    }
+                }
+                
+                // Sort by play count
+                uasort($playCount, function($a, $b) {
+                    return $b['total_plays'] - $a['total_plays'];
+                });
+                
+                $mostWatched = array_slice(array_values($playCount), 0, 10);
+            }
+        } catch (Requests_Exception $e) {
+            $this->writeLog('error', 'Emby Most Watched Error: ' . $e->getMessage(), 'SYSTEM');
+        }
+        
+        // If activity log doesn't work, try simpler approach
+        if (empty($mostWatched)) {
+            $mostWatched = $this->getEmbySimpleMostWatched($url, $token);
+        }
+
+        return $mostWatched;
+    }
+    
+    /**
+     * Simple approach to get most watched from Emby
+     */
+    private function getEmbySimpleMostWatched($url, $token)
+    {
+        $apiURL = rtrim($url, '/') . '/emby/Items?api_key=' . $token . 
+                  '&Recursive=true&IncludeItemTypes=Movie,Episode&Fields=Name,RunTimeTicks,ProductionYear' .
+                  '&SortBy=DatePlayed&SortOrder=Descending&Limit=20';
+        
+        try {
+            $options = $this->requestOptions($url, null, $this->config['userWatchStatsDisableCertCheck'] ?? false, $this->config['userWatchStatsUseCustomCertificate'] ?? false);
+            $response = Requests::get($apiURL, [], $options);
+            
+            if ($response->success) {
+                $data = json_decode($response->body, true);
+                $items = $data['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
+                    ];
+                }
+                
+                return $mostWatched;
+            }
+        } catch (Requests_Exception $e) {
+            $this->writeLog('error', 'Emby Simple Most Watched Error: ' . $e->getMessage(), 'SYSTEM');
+        }
+
+        return [];
+    }
+    
+    /**
+     * Get total play count for a specific item across all users
+     */
+    private function getEmbyItemTotalPlays($url, $token, $itemId)
+    {
+        $totalPlays = 0;
+        $users = $this->getEmbyUserStats($url, $token, 30);
         
-        // For each user, get their played content and aggregate
         foreach ($users as $user) {
+            if (isset($user['Policy']['IsDisabled']) && $user['Policy']['IsDisabled']) {
+                continue;
+            }
+            
             $userId = $user['Id'];
-            $userWatchedContent = $this->getEmbyUserWatchedContent($url, $token, $userId, $days);
+            $userItemURL = rtrim($url, '/') . '/emby/Users/' . $userId . '/Items/' . $itemId . '?api_key=' . $token . '&Fields=UserData';
             
-            foreach ($userWatchedContent as $content) {
-                $contentId = $content['Id'] ?? $content['title'];
-                if (!isset($allWatchedContent[$contentId])) {
-                    $allWatchedContent[$contentId] = $content;
-                    $allWatchedContent[$contentId]['total_plays'] = 0;
-                    $allWatchedContent[$contentId]['watched_by_users'] = [];
+            try {
+                $options = $this->requestOptions($url, null, $this->config['userWatchStatsDisableCertCheck'] ?? false, $this->config['userWatchStatsUseCustomCertificate'] ?? false);
+                $response = Requests::get($userItemURL, [], $options);
+                
+                if ($response->success) {
+                    $itemData = json_decode($response->body, true);
+                    $totalPlays += $itemData['UserData']['PlayCount'] ?? 0;
                 }
-                $allWatchedContent[$contentId]['total_plays'] += $content['play_count'] ?? 0;
-                $allWatchedContent[$contentId]['watched_by_users'][] = $user['Name'];
+            } catch (Requests_Exception $e) {
+                // Continue with other users if one fails
+                continue;
             }
         }
         
-        // Sort by total plays and return top 10
-        uasort($allWatchedContent, function($a, $b) {
-            return ($b['total_plays'] ?? 0) - ($a['total_plays'] ?? 0);
-        });
-        
-        return array_slice(array_values($allWatchedContent), 0, 10);
+        return $totalPlays;
     }
     
     /**