mirror of
https://github.com/rekryt/iplist.git
synced 2025-10-13 08:59:34 +03:00
feat: portal groups
This commit is contained in:
@@ -2,12 +2,25 @@
|
|||||||
|
|
||||||
namespace OpenCCK\App\Controller;
|
namespace OpenCCK\App\Controller;
|
||||||
|
|
||||||
|
use OpenCCK\Domain\Entity\Site;
|
||||||
|
use OpenCCK\Domain\Factory\SiteFactory;
|
||||||
|
|
||||||
class MainController extends AbstractIPListController {
|
class MainController extends AbstractIPListController {
|
||||||
|
/**
|
||||||
|
* @var array<string, array<string, Site>>
|
||||||
|
*/
|
||||||
|
private array $groups = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getBody(): string {
|
public function getBody(): string {
|
||||||
$this->setHeaders(['content-type' => 'text/html; charset=utf-8']);
|
$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');
|
return $this->renderTemplate('index');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -10,6 +10,7 @@ use Exception;
|
|||||||
use Monolog\Logger;
|
use Monolog\Logger;
|
||||||
use Revolt\EventLoop;
|
use Revolt\EventLoop;
|
||||||
use function Amp\delay;
|
use function Amp\delay;
|
||||||
|
use function OpenCCK\dbg;
|
||||||
|
|
||||||
class IPListService {
|
class IPListService {
|
||||||
private static IPListService $_instance;
|
private static IPListService $_instance;
|
||||||
@@ -30,17 +31,27 @@ class IPListService {
|
|||||||
if (!is_dir($dir)) {
|
if (!is_dir($dir)) {
|
||||||
throw new Exception('config directory not found');
|
throw new Exception('config directory not found');
|
||||||
}
|
}
|
||||||
foreach (scandir($dir) as $file) {
|
|
||||||
if (str_ends_with($file, '.json')) {
|
foreach (scandir($dir) as $item) {
|
||||||
$name = substr($file, 0, -5);
|
if (in_array($item, ['.', '..'])) {
|
||||||
$this->loadConfig($name, json_decode(file_get_contents($dir . $file)));
|
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 () {
|
EventLoop::queue(function () {
|
||||||
foreach ($this->sites as $siteEntity) {
|
foreach ($this->sites as $siteEntity) {
|
||||||
$siteEntity->reload();
|
if ($siteEntity->timeout) {
|
||||||
delay(1);
|
$siteEntity->reload();
|
||||||
|
delay(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -55,15 +66,24 @@ class IPListService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $name
|
* @param string $path
|
||||||
* @param object $config
|
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
private function loadConfig(string $name, object $config): void {
|
private function loadConfig(string $path): void {
|
||||||
if (isset($this->sites[$name])) {
|
if (str_ends_with($path, '.json')) {
|
||||||
$this->logger->error(sprintf('Site "%s" already exists', $name));
|
$parts = explode('/', $path);
|
||||||
return;
|
$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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
use OpenCCK\App\Controller\TextController;
|
|
||||||
/** @var TextController $this */
|
use OpenCCK\App\Controller\MainController;
|
||||||
|
/** @var MainController $this */
|
||||||
?>
|
?>
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
@@ -600,7 +601,9 @@ use OpenCCK\App\Controller\TextController;
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
.main-formSelect {}
|
.main-formSelect {}
|
||||||
.main-formSelect_site {}
|
.main-formSelect_site {
|
||||||
|
min-height: 60vh;
|
||||||
|
}
|
||||||
.main-formItemCheckbox {
|
.main-formItemCheckbox {
|
||||||
margin: 0 6px 0 0;
|
margin: 0 6px 0 0;
|
||||||
}
|
}
|
||||||
@@ -644,8 +647,12 @@ use OpenCCK\App\Controller\TextController;
|
|||||||
<span>
|
<span>
|
||||||
Site:
|
Site:
|
||||||
<select name="site" class="main-formSelect main-formSelect_site" multiple>
|
<select name="site" class="main-formSelect main-formSelect_site" multiple>
|
||||||
<?php foreach ($this->service->sites as $site): ?>
|
<?php foreach ($this->groups as $group => $items): ?>
|
||||||
<option value="<?= $site->name ?>"><?= $site->name ?></option>
|
<optgroup label="<?= $group ?>">
|
||||||
|
<?php foreach ($items as $site): ?>
|
||||||
|
<option value="<?= $site->name ?>"><?= $site->name ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</optgroup>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</select>
|
</select>
|
||||||
</span>
|
</span>
|
||||||
|
@@ -18,6 +18,7 @@ final class Site {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $name Name of portal
|
* @param string $name Name of portal
|
||||||
|
* @param string $group Group of portal
|
||||||
* @param array $domains List of portal domains
|
* @param array $domains List of portal domains
|
||||||
* @param array $dns List of DNS servers for updating IP addresses
|
* @param array $dns List of DNS servers for updating IP addresses
|
||||||
* @param int $timeout Time interval between domain IP address updates (seconds)
|
* @param int $timeout Time interval between domain IP address updates (seconds)
|
||||||
@@ -30,6 +31,7 @@ final class Site {
|
|||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
public string $name,
|
public string $name,
|
||||||
|
public string $group,
|
||||||
public array $domains = [],
|
public array $domains = [],
|
||||||
public array $dns = [],
|
public array $dns = [],
|
||||||
public int $timeout = 1440 * 60,
|
public int $timeout = 1440 * 60,
|
||||||
@@ -149,7 +151,7 @@ final class Site {
|
|||||||
*/
|
*/
|
||||||
private function saveConfig(): void {
|
private function saveConfig(): void {
|
||||||
file_put_contents(
|
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)
|
json_encode($this->getConfig(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -21,11 +21,12 @@ class SiteFactory {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $name Name of portal
|
* @param string $name Name of portal
|
||||||
|
* @param string $group Group of portal
|
||||||
* @param object $config Configuration of portal
|
* @param object $config Configuration of portal
|
||||||
* @return Site
|
* @return Site
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static function create(string $name, object $config): Site {
|
static function create(string $name, string $group, object $config): Site {
|
||||||
$domains = $config->domains ?? [];
|
$domains = $config->domains ?? [];
|
||||||
$dns = $config->dns ?? [];
|
$dns = $config->dns ?? [];
|
||||||
$timeout = $config->timeout ?? 1440 * 60;
|
$timeout = $config->timeout ?? 1440 * 60;
|
||||||
@@ -75,10 +76,13 @@ class SiteFactory {
|
|||||||
$domains = self::normalize($domains);
|
$domains = self::normalize($domains);
|
||||||
$ip4 = self::normalize($ip4, true);
|
$ip4 = self::normalize($ip4, true);
|
||||||
$ip6 = self::normalize($ip6, 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user