Package Manager
+Please Note:
+ Installing additional packages can break your FPP installation requiring complete reinstallation of FPP. Continue at your own risk. ++
diff --git a/www/api/controllers/system.php b/www/api/controllers/system.php index 06116ebb8..11b788a5f 100644 --- a/www/api/controllers/system.php +++ b/www/api/controllers/system.php @@ -399,3 +399,79 @@ function finalizeStatusJson($obj) return $obj; } + +// GET /api/system/GetOSPackages +/** + * Get a list of all available packages on the system. + * + * @return array List of package names. + */ +function GetOSPackages() { + $packages = []; + $cmd = 'apt list --all-versions 2>&1'; // Fetch all package names and versions + $handle = popen($cmd, 'r'); // Open a process for reading the output + + if ($handle) { + while (($line = fgets($handle)) !== false) { + // Extract the package name before the slash + if (preg_match('/^([^\s\/]+)\//', $line, $matches)) { + $packages[] = $matches[1]; + } + } + pclose($handle); // Close the process + } else { + error_log("Error: Unable to fetch package list."); + } + + return json_encode($packages); +} +/** + * Get information about a specific package. + * + * This function retrieves the description, dependencies, and installation status for a given package. + * + * @param string $packageName The name of the package. + * @return array An associative array containing 'Description', 'Depends', and 'Installed'. + */ +function GetOSPackageInfo() { + $packageName = params('packageName'); + + // Fetch package information using apt-cache show + $output = shell_exec("apt-cache show " . escapeshellarg($packageName) . " 2>&1"); + + if (!$output) { + return ['error' => "Package '$packageName' not found or no information available."]; + } + + // Check installation status using dpkg-query + $installStatus = shell_exec("/usr/bin/dpkg-query -W -f='\${Status}\n' " . escapeshellarg($packageName) . " 2>&1"); + error_log("Raw dpkg-query output for $packageName: |" . $installStatus . "|"); + + // Trim and validate output + $trimmedStatus = trim($installStatus); + error_log("Trimmed dpkg-query output for $packageName: |" . $trimmedStatus . "|"); + + $isInstalled = ($trimmedStatus === 'install ok installed') ? 'Yes' : 'No'; + + // Parse apt-cache output + $lines = explode("\n", $output); + $description = ''; + $depends = ''; + + foreach ($lines as $line) { + if (strpos($line, 'Description:') === 0) { + $description = trim(substr($line, strlen('Description:'))); + } elseif (strpos($line, 'Depends:') === 0) { + $depends = trim(substr($line, strlen('Depends:'))); + } + } + + return json_encode([ + 'Description' => $description, + 'Depends' => $depends, + 'Installed' => $isInstalled + ]); +} + + + diff --git a/www/api/index.php b/www/api/index.php index ed3d98149..e34bdcb81 100644 --- a/www/api/index.php +++ b/www/api/index.php @@ -178,6 +178,8 @@ dispatch_post('/system/volume', 'SystemSetAudio'); dispatch_post('/system/proxies', 'PostProxies'); dispatch_get('/system/proxies', 'GetProxies'); +dispatch_get('/system/packages', 'GetOSpackages'); +dispatch_get('/system/packages/info/:packageName', 'GetOSpackageInfo'); dispatch_get('/testmode', 'testMode_Get'); dispatch_post('/testmode', 'testMode_Set'); diff --git a/www/menu.inc b/www/menu.inc index 2d119954b..33cee6cb9 100644 --- a/www/menu.inc +++ b/www/menu.inc @@ -351,6 +351,9 @@ function list_plugin_entries($menu) Browser Plugin Manager + if ($uiLevel >= 2) { ?> + Packages + } ?> @@ -445,4 +448,4 @@ function list_plugin_entries($menu) - \ No newline at end of file + diff --git a/www/packages.php b/www/packages.php new file mode 100644 index 000000000..809e229ce --- /dev/null +++ b/www/packages.php @@ -0,0 +1,290 @@ + &1", 'r'); + if (is_resource($process)) { + while (!feof($process)) { + echo fread($process, 1024); + flush(); + } + pclose($process); + } + + // Add package to user-installed packages if not already added + if (!in_array(trim($packageName, "'"), $userPackages)) { + $userPackages[] = trim($packageName, "'"); + file_put_contents($userPackagesFile, json_encode($userPackages, JSON_PRETTY_PRINT)); + } + + exit; + } + + if ($action === 'uninstall' && !empty($packageName)) { + $packageName = escapeshellarg($packageName); + header('Content-Type: text/plain'); + + $process = popen("sudo apt-get remove -y $packageName 2>&1", 'r'); + if (is_resource($process)) { + while (!feof($process)) { + echo fread($process, 1024); + flush(); + } + pclose($process); + } + + // Remove package from user-installed packages + $userPackages = array_filter($userPackages, function($pkg) use ($packageName) { + return $pkg !== trim($packageName, "'"); + }); + file_put_contents($userPackagesFile, json_encode($userPackages, JSON_PRETTY_PRINT)); + + exit; + } + } + include 'common/menuHead.inc'; + writeFPPVersionJavascriptFunctions(); + ?> + + +
+