From 73b38ec96b4609254d81c4fa2528367f99081d2b Mon Sep 17 00:00:00 2001 From: Rekryt Date: Thu, 5 Sep 2024 00:54:41 +0300 Subject: [PATCH] feat: portal groups --- src/App/Controller/MainController.php | 13 ++++++++ src/App/Service/IPListService.php | 46 +++++++++++++++++++-------- src/App/Template/IndexTemplate.php | 17 +++++++--- src/Domain/Entity/Site.php | 4 ++- src/Domain/Factory/SiteFactory.php | 12 ++++--- 5 files changed, 69 insertions(+), 23 deletions(-) diff --git a/src/App/Controller/MainController.php b/src/App/Controller/MainController.php index 30a4154..22789db 100644 --- a/src/App/Controller/MainController.php +++ b/src/App/Controller/MainController.php @@ -2,12 +2,25 @@ namespace OpenCCK\App\Controller; +use OpenCCK\Domain\Entity\Site; +use OpenCCK\Domain\Factory\SiteFactory; + class MainController extends AbstractIPListController { + /** + * @var array> + */ + private array $groups = []; + /** * @return string */ public function getBody(): string { $this->setHeaders(['content-type' => 'text/html; charset=utf-8']); + + foreach ($this->service->sites as $siteEntity) { + $this->groups[$siteEntity->group][$siteEntity->name] = $siteEntity; + } + return $this->renderTemplate('index'); } diff --git a/src/App/Service/IPListService.php b/src/App/Service/IPListService.php index bc2cd45..b0591cd 100644 --- a/src/App/Service/IPListService.php +++ b/src/App/Service/IPListService.php @@ -10,6 +10,7 @@ use Exception; use Monolog\Logger; use Revolt\EventLoop; use function Amp\delay; +use function OpenCCK\dbg; class IPListService { private static IPListService $_instance; @@ -30,17 +31,27 @@ class IPListService { if (!is_dir($dir)) { throw new Exception('config directory not found'); } - foreach (scandir($dir) as $file) { - if (str_ends_with($file, '.json')) { - $name = substr($file, 0, -5); - $this->loadConfig($name, json_decode(file_get_contents($dir . $file))); + + foreach (scandir($dir) as $item) { + if (in_array($item, ['.', '..'])) { + continue; + } + $path = $dir . $item; + if (is_dir($path)) { + foreach (scandir($path) as $file) { + if (is_file($path . '/' . $file)) { + $this->loadConfig($path . '/' . $file); + } + } } } EventLoop::queue(function () { foreach ($this->sites as $siteEntity) { - $siteEntity->reload(); - delay(1); + if ($siteEntity->timeout) { + $siteEntity->reload(); + delay(1); + } } }); } @@ -55,15 +66,24 @@ class IPListService { } /** - * @param string $name - * @param object $config + * @param string $path * @return void */ - private function loadConfig(string $name, object $config): void { - if (isset($this->sites[$name])) { - $this->logger->error(sprintf('Site "%s" already exists', $name)); - return; + private function loadConfig(string $path): void { + if (str_ends_with($path, '.json')) { + $parts = explode('/', $path); + $filename = array_pop($parts); + $name = substr($filename, 0, -5); + $config = json_decode(file_get_contents($path)); + $group = array_pop($parts); + + if (isset($this->sites[$name])) { + $this->logger->error(sprintf('Site config "%s" already exists', $name)); + delay(5); + exit(); + } + + $this->sites[$name] = SiteFactory::create($name, $group, $config); } - $this->sites[$name] = SiteFactory::create($name, $config); } } diff --git a/src/App/Template/IndexTemplate.php b/src/App/Template/IndexTemplate.php index d42f3df..5ff901c 100644 --- a/src/App/Template/IndexTemplate.php +++ b/src/App/Template/IndexTemplate.php @@ -1,6 +1,7 @@ @@ -600,7 +601,9 @@ use OpenCCK\App\Controller\TextController; text-align: center; } .main-formSelect {} - .main-formSelect_site {} + .main-formSelect_site { + min-height: 60vh; + } .main-formItemCheckbox { margin: 0 6px 0 0; } @@ -644,8 +647,12 @@ use OpenCCK\App\Controller\TextController; Site: diff --git a/src/Domain/Entity/Site.php b/src/Domain/Entity/Site.php index 3cf4be8..be74e38 100644 --- a/src/Domain/Entity/Site.php +++ b/src/Domain/Entity/Site.php @@ -18,6 +18,7 @@ final class Site { /** * @param string $name Name of portal + * @param string $group Group of portal * @param array $domains List of portal domains * @param array $dns List of DNS servers for updating IP addresses * @param int $timeout Time interval between domain IP address updates (seconds) @@ -30,6 +31,7 @@ final class Site { */ public function __construct( public string $name, + public string $group, public array $domains = [], public array $dns = [], public int $timeout = 1440 * 60, @@ -149,7 +151,7 @@ final class Site { */ private function saveConfig(): void { file_put_contents( - PATH_ROOT . '/config/' . $this->name . '.json', + PATH_ROOT . '/config/' . $this->group . '/' . $this->name . '.json', json_encode($this->getConfig(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) ); } diff --git a/src/Domain/Factory/SiteFactory.php b/src/Domain/Factory/SiteFactory.php index 84d39c7..7ccf29d 100644 --- a/src/Domain/Factory/SiteFactory.php +++ b/src/Domain/Factory/SiteFactory.php @@ -21,11 +21,12 @@ class SiteFactory { /** * @param string $name Name of portal + * @param string $group Group of portal * @param object $config Configuration of portal * @return Site * */ - static function create(string $name, object $config): Site { + static function create(string $name, string $group, object $config): Site { $domains = $config->domains ?? []; $dns = $config->dns ?? []; $timeout = $config->timeout ?? 1440 * 60; @@ -75,10 +76,13 @@ class SiteFactory { $domains = self::normalize($domains); $ip4 = self::normalize($ip4, true); $ip6 = self::normalize($ip6, true); - $cidr4 = self::normalize(IP4Helper::processCIDR($ip4, self::normalize($cidr4)), true); - $cidr6 = self::normalize(IP6Helper::processCIDR($ip6, self::normalize($cidr6)), true); - return new Site($name, $domains, $dns, $timeout, $ip4, $ip6, $cidr4, $cidr6, $external); + if ($timeout) { + $cidr4 = self::normalize(IP4Helper::processCIDR($ip4, self::normalize($cidr4)), true); + $cidr6 = self::normalize(IP6Helper::processCIDR($ip6, self::normalize($cidr6)), true); + } + + return new Site($name, $group, $domains, $dns, $timeout, $ip4, $ip6, $cidr4, $cidr6, $external); } /**