Selaa lähdekoodia

Merge branch 'v2-develop' of https://github.com/causefx/Organizr into v2-develop

causefx@me.com 3 kuukautta sitten
vanhempi
commit
e83ea93408

+ 1 - 1
api/classes/ping.class.php

@@ -219,7 +219,7 @@ class Ping
 		exec($exec_string, $output, $return);
 		// Strip empty lines and reorder the indexes from 0 (to make results more
 		// uniform across OS versions).
-		$this->commandOutput = implode($output, '');
+		$this->commandOutput = implode('', $output);
 		$output = array_values(array_filter($output));
 		// If the result line in the output is not empty, parse it.
 		if (!empty($output[1])) {

+ 35 - 22
api/functions/UptimeKumaMetrics.php

@@ -21,7 +21,7 @@ class UptimeKumaMetrics
         $latencies = array_filter($processed, function (string $item) {
             return str_starts_with($item, 'monitor_response_time');
         });
-        
+
         $monitors = array_map(function (string $item) {
             return $this->parseMonitorStatus($item);
         }, $monitors);
@@ -37,23 +37,36 @@ class UptimeKumaMetrics
     }
 
     private function parseMonitorStatus(string $status): ?array
-    {  
+    {
         if (substr($status, -1) === '2') {
             return null;
-		}
-
-		$up = (substr($status, -1)) == '0' ? false : true;
-		$status = substr($status, 15);
-		$status = substr($status, 0, -4);
-		$status = explode(',', $status);
-		$data = [
-			'name' => $this->getStringBetweenQuotes($status[0]),
-			'url' => $this->getStringBetweenQuotes($status[2]),
-			'type' => $this->getStringBetweenQuotes($status[1]),
-			'status' => $up,
-		];
-
-		return $data;
+        }
+
+        if (preg_match('/{(.*?)}/', $status, $match) != 1) {
+            return null;
+        }
+
+        $matches = explode(',', $match[1]);
+
+        $data = [];
+        foreach ($matches as $match) {
+            switch (true) {
+                case str_starts_with($match, "monitor_name"):
+                    $data['name'] = $this->getStringBetweenQuotes($match);
+                    break;
+                case str_starts_with($match, "monitor_url"):
+                    $data['url'] = $this->getStringBetweenQuotes($match);
+                    break;
+                case str_starts_with($match, "monitor_type"):
+                    $data['type'] = $this->getStringBetweenQuotes($match);
+                    break;
+            }
+        }
+
+        $up = (substr($status, -1)) == '0' ? false : true;
+        $data['status'] = $up;
+
+        return $data;
     }
 
     private function addLatencyToMonitors(array &$monitors, array $latencies)
@@ -79,10 +92,10 @@ class UptimeKumaMetrics
     }
 
     private function getStringBetweenQuotes(string $input): string
-	{
-		if (preg_match('/"(.*?)"/', $input, $match) == 1) {
-			return $match[1];
-		}
-		return '';
-	} 
+    {
+        if (preg_match('/"(.*?)"/', $input, $match) == 1) {
+            return $match[1];
+        }
+        return '';
+    }
 }

+ 2 - 2
api/functions/sso-functions.php

@@ -169,7 +169,7 @@ trait SSOFunctions
 			$credentials = array('auth' => new Requests_Auth_Digest(array($email, $password)));
 			$url = $this->qualifyURL($this->config['komgaURL']);
 			$options = $this->requestOptions($url, $this->getSSOTimeout(), true, false, $credentials);
-			$response = Requests::get($url . '/api/v1/users/me', ['X-Auth-Token' => 'organizrSSO'], $options);
+			$response = Requests::get($url . '/api/v2/users/me', ['X-Auth-Token' => 'organizrSSO'], $options);
 			if ($response->success) {
 				if ($response->headers['x-auth-token']) {
 					$this->setLoggerChannel('Komga')->info('Grabbed token');
@@ -395,4 +395,4 @@ trait SSOFunctions
 			return false;
 		}
 	}
-}
+}

+ 1 - 0
api/homepage/pihole.php

@@ -204,6 +204,7 @@ trait PiHoleHomepageItem
 		} catch (Requests_Exception $e) {
 				$this->setResponse(500, $e->getMessage());
 				$this->setLoggerChannel('PiHole')->error($e);
+				throw $e;
 			};
 		return $processedResponse ?? [];
 	}

+ 0 - 139
debug_jellystat_metadata.php

@@ -1,139 +0,0 @@
-<?php
-/**
- * Debug script to test JellyStat metadata functionality
- * Run this to troubleshoot why metadata returns "Unknown Item"
- */
-
-require_once 'api/config/config.php';
-require_once 'api/classes/organizr.php';
-
-// Create Organizr instance (this will load config)
-$organizr = new Organizr();
-
-echo "=== JellyStat Metadata Debug Tool ===\n\n";
-
-// Check configuration
-$jellyStatURL = $organizr->config['jellyStatURL'] ?? '';
-$jellyStatInternalURL = $organizr->config['jellyStatInternalURL'] ?? '';
-$jellyStatApikey = $organizr->config['jellyStatApikey'] ?? '';
-$enabled = $organizr->config['homepageJellyStatEnabled'] ?? false;
-
-echo "Configuration:\n";
-echo "- JellyStat URL: " . ($jellyStatURL ?: 'NOT SET') . "\n";
-echo "- Internal URL: " . ($jellyStatInternalURL ?: 'NOT SET') . "\n";  
-echo "- API Key: " . ($jellyStatApikey ? 'SET (****)' : 'NOT SET') . "\n";
-echo "- Plugin Enabled: " . ($enabled ? 'YES' : 'NO') . "\n\n";
-
-if (!$enabled) {
-    echo "❌ JellyStat plugin is not enabled!\n";
-    echo "Enable it in Organizr settings first.\n";
-    exit(1);
-}
-
-if (!$jellyStatURL) {
-    echo "❌ JellyStat URL is not configured!\n";
-    echo "Set jellyStatURL in Organizr settings first.\n";
-    exit(1);
-}
-
-// Test basic connectivity
-$testUrl = !empty($jellyStatInternalURL) ? $jellyStatInternalURL : $jellyStatURL;
-$testUrl = rtrim($organizr->qualifyURL($testUrl), '/');
-
-echo "Testing connectivity to: {$testUrl}\n\n";
-
-// Test endpoints that the metadata function would try
-$testKey = 'test-item-id';
-$endpoints = [];
-
-if ($jellyStatApikey) {
-    $endpoints['JellyStat API (getItem)'] = $testUrl . '/api/getItem?apiKey=' . urlencode($jellyStatApikey) . '&id=' . urlencode($testKey);
-    $endpoints['JellyStat API (getItemById)'] = $testUrl . '/api/getItemById?apiKey=' . urlencode($jellyStatApikey) . '&id=' . urlencode($testKey);
-}
-
-$endpoints['Jellyfin Proxy (basic)'] = $testUrl . '/proxy/Items/' . rawurlencode($testKey);
-$endpoints['Jellyfin Proxy (with fields)'] = $testUrl . '/proxy/Items/' . rawurlencode($testKey) . '?Fields=Overview,People,Genres,CommunityRating,CriticRating,Studios,Taglines,ProductionYear,PremiereDate';
-
-// Also test a real item ID if provided via command line
-if (isset($argv[1])) {
-    $realKey = $argv[1];
-    echo "Testing with real item ID: {$realKey}\n\n";
-    
-    if ($jellyStatApikey) {
-        $endpoints['Real Item - JellyStat API'] = $testUrl . '/api/getItem?apiKey=' . urlencode($jellyStatApikey) . '&id=' . urlencode($realKey);
-    }
-    $endpoints['Real Item - Jellyfin Proxy'] = $testUrl . '/proxy/Items/' . rawurlencode($realKey) . '?Fields=Overview,People,Genres,CommunityRating,CriticRating,Studios,Taglines,ProductionYear,PremiereDate';
-}
-
-foreach ($endpoints as $name => $url) {
-    echo "Testing {$name}:\n";
-    echo "URL: {$url}\n";
-    
-    try {
-        $options = $organizr->requestOptions($url, null, 
-            $organizr->config['jellyStatDisableCertCheck'] ?? false,
-            $organizr->config['jellyStatUseCustomCertificate'] ?? false
-        );
-        
-        $response = Requests::get($url, [], $options);
-        
-        if ($response->success) {
-            $data = json_decode($response->body, true);
-            
-            if (json_last_error() === JSON_ERROR_NONE) {
-                echo "✅ SUCCESS - Status: {$response->status_code}\n";
-                
-                if (is_array($data)) {
-                    $keys = array_keys($data);
-                    echo "Response has keys: " . implode(', ', array_slice($keys, 0, 10)) . 
-                         (count($keys) > 10 ? '... (' . count($keys) . ' total)' : '') . "\n";
-                    
-                    // Look for typical media metadata fields
-                    $mediaFields = ['Name', 'Id', 'Type', 'Overview', 'Genres', 'People', 'RunTimeTicks', 'ProductionYear'];
-                    $foundFields = array_intersect($keys, $mediaFields);
-                    if (!empty($foundFields)) {
-                        echo "Media fields found: " . implode(', ', $foundFields) . "\n";
-                        
-                        // Show sample values
-                        foreach (['Name', 'Type', 'Overview'] as $field) {
-                            if (isset($data[$field])) {
-                                $value = $data[$field];
-                                if (is_string($value) && strlen($value) > 50) {
-                                    $value = substr($value, 0, 47) . '...';
-                                }
-                                echo "{$field}: {$value}\n";
-                            }
-                        }
-                    }
-                } else {
-                    echo "Response is not an array: " . gettype($data) . "\n";
-                }
-            } else {
-                echo "❌ Invalid JSON response\n";
-                echo "Raw response: " . substr($response->body, 0, 200) . "...\n";
-            }
-        } else {
-            echo "❌ HTTP Error: {$response->status_code}\n";
-            if (!empty($response->body)) {
-                echo "Error body: " . substr($response->body, 0, 200) . "...\n";
-            }
-        }
-        
-    } catch (Exception $e) {
-        echo "❌ Exception: " . $e->getMessage() . "\n";
-    }
-    
-    echo "\n" . str_repeat('-', 60) . "\n\n";
-}
-
-echo "=== Debug Complete ===\n\n";
-
-echo "Next steps if endpoints are failing:\n";
-echo "1. Verify JellyStat is running and accessible\n";  
-echo "2. Check if API key is correct and has permissions\n";
-echo "3. Test URLs directly in browser/curl\n";
-echo "4. Check JellyStat logs for errors\n";
-echo "5. Verify firewall/network connectivity\n\n";
-
-echo "If you have a working item ID from JellyStat, run:\n";
-echo "php debug_jellystat_metadata.php YOUR-ITEM-ID\n";

+ 8 - 8
js/functions.js

@@ -8026,18 +8026,18 @@ function buildPiholeItem(array){
                 value = e['domains_being_blocked'].map(function (x) {
                     return `<li>${x.toString()}</li>`;
                 }).join("");
+                card += `<ul class="multi-column" data-toggle="tooltip" title="` + key + `">` + value + `</ul>`;
             }
-            card += `<ul class="multi-column" data-toggle="tooltip" title="` + key + `">` + value + `</ul>`;
-	        }
-            card += `
-                        </div>
-                        <i class="fa fa-list inline-block" aria-hidden="true"></i>
+        }
+        card += `
                     </div>
+                    <i class="fa fa-list inline-block" aria-hidden="true"></i>
                 </div>
             </div>
-            `
-            return card;
-        }
+        </div>
+        `
+        return card;
+    }
 
     if(combine) {
         stats += '<div class="row">'

+ 1 - 1
scripts/linux-update.sh

@@ -6,7 +6,7 @@
 set -euo pipefail
 
 # Configuration
-GITHUB_REPO="${GITHUB_REPO:-metalcated/Organizr}"
+GITHUB_REPO="${GITHUB_REPO:-causefx/Organizr}"
 
 # Determine branch
 if [ -z "${1:-}" ]; then

+ 0 - 39
test_debug.php

@@ -1,39 +0,0 @@
-<?php
-error_reporting(E_ALL);
-ini_set('display_errors', 1);
-
-echo "Starting test...\n";
-
-// Include all necessary files
-$traitsPath = __DIR__ . '/api/functions/';
-$homepagePath = __DIR__ . '/api/homepage/';
-
-// Get all trait files
-$traitFiles = glob($traitsPath . '*.php');
-$homepageFiles = glob($homepagePath . '*.php');
-
-echo "Loading trait files...\n";
-foreach ($traitFiles as $file) {
-    echo "Including: " . basename($file) . "\n";
-    include_once $file;
-}
-
-echo "Loading homepage files...\n";
-foreach ($homepageFiles as $file) {
-    echo "Including: " . basename($file) . "\n";
-    include_once $file;
-}
-
-echo "Loading main class...\n";
-include_once __DIR__ . '/api/classes/organizr.class.php';
-
-echo "Creating instance...\n";
-try {
-    $organizr = new Organizr();
-    echo "SUCCESS: Class instantiated successfully!\n";
-} catch (Throwable $e) {
-    echo "ERROR: " . $e->getMessage() . "\n";
-    echo "File: " . $e->getFile() . "\n";
-    echo "Line: " . $e->getLine() . "\n";
-    echo "Trace:\n" . $e->getTraceAsString() . "\n";
-}

+ 0 - 37
test_jellystat_api.html

@@ -1,37 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-    <title>JellyStat API Test</title>
-</head>
-<body>
-    <h1>JellyStat Metadata API Test</h1>
-    <button onclick="testMetadata()">Test Metadata API</button>
-    <pre id="result"></pre>
-    
-    <script>
-    async function testMetadata() {
-        const token = '4wr9yn1z30k57hnsczpu';
-        const testKey = '123456'; // Replace with actual item ID
-        
-        try {
-            const response = await fetch('https://media.glassnetworks.net/api/v2/homepage/jellystat/metadata', {
-                method: 'POST',
-                headers: {
-                    'Content-Type': 'application/json',
-                    'Token': token
-                },
-                body: JSON.stringify({ key: testKey })
-            });
-            
-            const data = await response.json();
-            document.getElementById('result').textContent = JSON.stringify(data, null, 2);
-        } catch (error) {
-            document.getElementById('result').textContent = 'Error: ' + error.message;
-        }
-    }
-    
-    // Auto-run on load
-    window.onload = testMetadata;
-    </script>
-</body>
-</html>