Просмотр исходного кода

JellyStat: implement real metadata fetch for popup; try JellyStat API/proxy, map fields to buildMetadata schema (title, year, genres, rating, duration, image) with graceful fallbacks

mgomon 11 месяцев назад
Родитель
Сommit
8766238a7b
1 измененных файлов с 86 добавлено и 12 удалено
  1. 86 12
      api/homepage/jellystat.php

+ 86 - 12
api/homepage/jellystat.php

@@ -221,33 +221,107 @@ trait JellyStatHomepageItem
                 return false;
             }
 
-            // Build minimal, safe metadata payload without external API calls
-            $title = 'JellyStat Item';
-            $year  = '';
+            // Prepare URLs and options
+            $url = $this->config['jellyStatURL'] ?? '';
+            $internalUrl = $this->config['jellyStatInternalURL'] ?? '';
+            $apiUrl = !empty($internalUrl) ? $internalUrl : $url;
+            $token = $this->config['jellyStatApikey'] ?? '';
+            $disableCert = $this->config['jellyStatDisableCertCheck'] ?? false;
+            $customCert = $this->config['jellyStatUseCustomCertificate'] ?? false;
+            $options = $this->requestOptions($apiUrl, null, $disableCert, $customCert);
+
+            $details = null;
+            // Try a JellyStat native item detail endpoint if available
+            $tryEndpoints = [];
+            if ($token !== '') {
+                $tryEndpoints[] = rtrim($this->qualifyURL($apiUrl), '/') . '/api/getItem?apiKey=' . urlencode($token) . '&id=' . urlencode($key);
+                $tryEndpoints[] = rtrim($this->qualifyURL($apiUrl), '/') . '/api/getItemById?apiKey=' . urlencode($token) . '&id=' . urlencode($key);
+            }
+            // Try proxying directly to Jellyfin/Emby items
+            $tryEndpoints[] = rtrim($this->qualifyURL($apiUrl), '/') . '/proxy/Items/' . rawurlencode($key);
+
+            foreach ($tryEndpoints as $ep) {
+                try {
+                    $resp = Requests::get($ep, [], $options);
+                    if ($resp->success) {
+                        $json = json_decode($resp->body, true);
+                        if (is_array($json) && !isset($json['error'])) {
+                            $details = $json;
+                            break;
+                        }
+                    }
+                } catch (\Throwable $e) {
+                    // ignore and try next
+                }
+            }
+
+            // Build response for buildMetadata()
+            $title = 'Item';
+            $type = 'jellystat';
+            $year = '';
+            $summary = '';
+            $tagline = 'JellyStat Analytics';
+            $genres = [];
+            $rating = '0';
+            $durationMs = '0';
+            $imageUrl = 'plugins/images/homepage/no-np.png';
+
+            if (is_array($details)) {
+                // Common fields from Jellyfin/Emby item shapes
+                $title = $details['Name'] ?? $details['OriginalTitle'] ?? $title;
+                $summary = $details['Overview'] ?? $summary;
+                $tagline = $details['Taglines'][0] ?? ($details['Tagline'] ?? $tagline);
+                $year = isset($details['ProductionYear']) ? (string)$details['ProductionYear'] : ($details['PremiereDate'] ?? '');
+                if ($year && preg_match('/^\d{4}/', $year, $m)) { $year = $m[0]; }
+                $genres = $details['Genres'] ?? [];
+                $ratingVal = $details['CommunityRating'] ?? ($details['CriticRating'] ?? null);
+                if ($ratingVal !== null) { $rating = (string)$ratingVal; }
+                // Duration: RunTimeTicks (100ns ticks)
+                if (isset($details['RunTimeTicks'])) {
+                    $durationMs = (string) floor(($details['RunTimeTicks'] / 10000000) * 1000);
+                }
+                // Type mapping
+                $jType = strtolower($details['Type'] ?? '');
+                if ($jType === 'movie') { $type = 'movie'; }
+                elseif ($jType === 'series') { $type = 'tv'; }
+                elseif ($jType === 'audio' || $jType === 'musicalbum' || $jType === 'musicvideo') { $type = 'music'; }
+
+                // Image selection
+                $primaryTag = $details['ImageTags']['Primary'] ?? null;
+                if ($primaryTag) {
+                    // Use proxy primary image
+                    $imageUrl = rtrim($this->qualifyURL($url), '/') . '/proxy/Items/' . rawurlencode($details['Id']) . '/Images/Primary?tag=' . urlencode($primaryTag);
+                } else {
+                    // Fallback: use earlier helper to derive from item id (frontend safe URL)
+                    $imageUrl = $this->getPosterUrl(null, $details['Id'] ?? $key, $details['ServerId'] ?? null) ?: $imageUrl;
+                }
+            } else {
+                // As a fallback, at least provide a generated poster via proxy if possible
+                $imageUrl = $this->getPosterUrl(null, $key, null) ?: $imageUrl;
+            }
 
             $item = [
                 'uid' => (string)$key,
                 'title' => $title,
-                'type' => 'jellystat',
-                'nowPlayingImageURL' => 'plugins/images/homepage/no-np.png',
+                'type' => $type,
+                'nowPlayingImageURL' => $imageUrl,
                 'address' => $this->qualifyURL($this->config['jellyStatURL'] ?? ''),
                 'tabName' => 'jellystat',
                 'openTab' => 'true',
                 'metadata' => [
                     'guid' => (string)$key,
-                    'summary' => 'Analytics item from JellyStat. Detailed metadata not available.',
-                    'rating' => '0',
-                    'duration' => '0',
+                    'summary' => $summary,
+                    'rating' => $rating,
+                    'duration' => $durationMs,
                     'originallyAvailableAt' => '',
                     'year' => $year,
-                    'tagline' => 'JellyStat Analytics',
-                    'genres' => [],
+                    'tagline' => $tagline,
+                    'genres' => $genres,
                     'actors' => []
                 ]
             ];
 
-            $api = [];
-            $api['content'][] = $item;
+            $api = ['content' => [$item]];
             $this->setAPIResponse('success', null, 200, $api);
             return $api;
         } catch (\Throwable $e) {