botón del modo claro y oscuro implementado

This commit is contained in:
DANYDHSV 2026-02-23 12:42:30 -06:00
parent 647bdfc6ae
commit aaec7ce0b4
250 changed files with 17324 additions and 451 deletions

0
.DS_Store vendored Normal file → Executable file
View File

0
.gitignore vendored Normal file → Executable file
View File

7
CHANGELOG.md Normal file → Executable file
View File

@ -7,10 +7,15 @@ y este proyecto adhiere a [Semantic Versioning](https://semver.org/lang/es/).
---
## [1.6.2] - 2025-12-09
### 🐛 Bug Fixes
- **Límite Inteligente (Smart Limit)**: Ahora la opción de límite (5, 10 IPs) busca activamente hasta encontrar esa cantidad de IPs *disponibles*. Antiguamente solo verificaba las primeras de la lista y si estaban ocupadas por ping devolvía 0 resultados.
## [1.6.1] - 2025-12-08
### 🚀 Mejoras de UX/UI
- Reorganización de elementos del formulario: Checkboxes agrupados y dropdown de límite al final.
- Reorganización de elementos del formulario: Checkboxes apilados verticalmente (Ping arriba, Ocultar Admin abajo) y dropdown de límite al final.
- **Mensajes de progreso persistentes**: Los mensajes de estado ("Validando por ping...", "Consultando...") ahora permanecen visibles durante todo el proceso.
- **Badge de IP**: Ahora muestra "No disponible" en rojo cuando una IP está en uso por ping o validación de sitios (antes mostraba "Cliente" en verde).
- **Estadísticas reales**: Los contadores de "IPs Disponibles" y "IPs en Uso" ahora reflejan exactamente lo que se muestra en la tabla después de la validación progresiva.

2
README.md Normal file → Executable file
View File

@ -1,6 +1,6 @@
# SIIP - Buscador de IP's Disponibles UISP
[![Version](https://img.shields.io/badge/version-1.6.1-blue.svg)](manifest.json)
[![Version](https://img.shields.io/badge/version-1.6.2-blue.svg)](manifest.json)
[![UCRM](https://img.shields.io/badge/UCRM-Compatible-green.svg)](https://uisp.com/)
[![UNMS](https://img.shields.io/badge/UNMS-Compatible-green.svg)](https://uisp.com/)

169
bin/pack-plugin-custom Executable file
View File

@ -0,0 +1,169 @@
#!/usr/bin/env php
<?php
if (! class_exists(ZipArchive::class)) {
echo 'This script requires zip PHP extension.' . PHP_EOL;
exit(1);
}
function checkRequiredFiles(string $pluginRootDir): void
{
if (! is_file(sprintf('%s/manifest.json', $pluginRootDir))) {
echo sprintf('Manifest file not found in "%s".', $pluginRootDir) . PHP_EOL;
exit(1);
}
if (! is_file(sprintf('%s/main.php', $pluginRootDir))) {
echo sprintf('WARNING: Plugin does not have required main.php file in "%s".', $pluginRootDir) . PHP_EOL;
}
}
function getPluginRootDir(?string $rootDir): string
{
if ($rootDir === null) {
$rootDir = realpath(__DIR__ . '/..'); // Assuming bin/pack-plugin-custom, so root is one level up
echo sprintf('Plugin root dir not given, trying to find automatically: "%s"', $rootDir) . PHP_EOL;
} else {
if (! is_dir($rootDir)) {
echo 'Given directory does not exist.' . PHP_EOL;
exit(1);
}
$rootDir = realpath($rootDir);
}
return $rootDir;
}
function getPluginInfo(string $pluginRootDir): array
{
$manifestContent = file_get_contents($pluginRootDir . '/manifest.json');
if ($manifestContent === false) {
echo 'Could not read manifest.json.' . PHP_EOL;
exit(1);
}
$manifest = json_decode($manifestContent, true, 512, JSON_BIGINT_AS_STRING);
$error = json_last_error();
if ($error !== JSON_ERROR_NONE) {
echo sprintf('Could not decode manifest: "%s"', $error) . PHP_EOL;
exit(1);
}
$name = $manifest['information']['name'] ?? null;
if ($name === null) {
echo 'Could not get plugin\'s name from manifest.' . PHP_EOL;
exit(1);
}
if (! preg_match('~^[a-z0-9_-]+$~', $name)) {
echo 'Plugin\'s name contains invalid characters. Valid characters are: a-z, 0-9, _ (underscore) and - (hyphen).' . PHP_EOL;
exit(1);
}
$version = $manifest['information']['version'] ?? '0.0.0';
return ['name' => $name, 'version' => $version];
}
$pluginRootDir = getPluginRootDir($argv[1] ?? null);
checkRequiredFiles($pluginRootDir);
$pluginInfo = getPluginInfo($pluginRootDir);
$pluginName = $pluginInfo['name'];
$pluginVersion = $pluginInfo['version'];
// Custom: Add version to zip name
$zipName = sprintf('%s-%s.zip', $pluginName, $pluginVersion);
// Create the zip in the plugin root directory logic
// If structure matches UBNT repo (src separate), put it one level up.
// But commonly specific plugins are just the root.
// The original script checks for README.md in parent and src dir to decide if it's in a mono-repo.
// We will simplify and default to current dir, but keep the check just in case.
if (file_exists(sprintf('%s/../README.md', $pluginRootDir)) && is_dir(sprintf('%s/../src', $pluginRootDir))) {
$zipPath = sprintf('%s/../%s', $pluginRootDir, $zipName);
} else {
$zipPath = sprintf('%s/%s', $pluginRootDir, $zipName);
}
// Delete old ZIP archive.
if (file_exists($zipPath)) {
unlink($zipPath);
}
// Install composer dependencies.
echo 'Installing composer dependencies...' . PHP_EOL;
shell_exec('composer install --classmap-authoritative --no-dev --no-interaction --quiet');
// Create the ZIP archive.
$zip = new ZipArchive();
if ($zip->open($zipPath, ZipArchive::CREATE) !== true) {
echo 'Can\'t open zip file.' . PHP_EOL;
exit(1);
}
$files = new CallbackFilterIterator(
new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($pluginRootDir, \RecursiveDirectoryIterator::SKIP_DOTS)
),
function (SplFileInfo $fileInfo) {
return $fileInfo->isFile();
}
);
$ignoredFiles = [
'ucrm.json',
'.ucrm-plugin-running',
'.ucrm-plugin-execution-requested',
$zipName,
'.DS_Store', // Added DS_Store
];
// Add wildcard support for ignored files if needed, but for now simple check
$ignoredDirectories = [
'.git/',
'.idea/',
'vendor/bin/', // Don't include binaries in the zip if not needed, or at least this script
'bin/', // Don't include this script itself if we don't want to distributed it (optional)
];
// We probably want to include vendor/bin/pack-plugin (original) if it was there,
// but we definitely want to exclude .git.
/** @var SplFileInfo $fileInfo */
foreach ($files as $fileInfo) {
// Get relative path
$filename = substr($fileInfo->getPathname(), strlen($pluginRootDir) + 1);
// Fix slashes for zip
$filename = str_replace('\\', '/', $filename);
if (in_array(basename($filename), $ignoredFiles, true)) {
// Simple check for filename
continue;
}
// Check ignored files by full relative path
if (in_array($filename, $ignoredFiles, true)) {
continue;
}
foreach ($ignoredDirectories as $ignoredDirectory) {
if (strpos($filename, $ignoredDirectory) === 0) {
continue 2;
}
}
// Exclude the script itself if it's inside the root
if (realpath($fileInfo->getPathname()) === realpath(__FILE__)) {
continue;
}
if (! $zip->addFile($fileInfo->getPathname(), $filename)) {
echo sprintf('Unable to add file "%s".', $filename) . PHP_EOL;
exit(1);
}
}
$zip->close();
echo sprintf('Created plugin ZIP archive: "%s"', realpath($zipPath)) . PHP_EOL;

0
composer.json Normal file → Executable file
View File

0
composer.lock generated Normal file → Executable file
View File

2
data/config.json Normal file → Executable file
View File

@ -1 +1 @@
{"ipserver":"sistema.siip.mx","apitoken":"72VoFACForJQzveorR1sTLrXXwrnnK/oy6Bp9luwFTGC/dRdeQWNmFZqJeHuUzqK","unmsApiToken":"393eb3d0-9b46-4a47-b9b4-473e4e24a89c","debugMode":true,"logging_level":true,"enablePingVerification":true,"adminRangeStart":"2","adminRangeEnd":"50","adminRangeFinalStart":"254","adminRangeFinalEnd":"255","useCustomAdminRanges":true,"customAdminRangesJson":"{\"segmentos\":[{\"segmento\":\"13\",\"administrativas_iniciales\":[{\"inicio\":2,\"hasta\":50}],\"administrativas_finales\":[{\"inicio\":253,\"hasta\":254}]},{\"segmento\":\"100\",\"administrativas_iniciales\":[{\"inicio\":2,\"hasta\":50}],\"administrativas_finales\":[{\"inicio\":254,\"hasta\":254}]}]}","adminPassword":"Siip.2963"}
{"ipserver":"sistema.siip.mx","apitoken":"72VoFACForJQzveorR1sTLrXXwrnnK/oy6Bp9luwFTGC/dRdeQWNmFZqJeHuUzqK","unmsApiToken":"393eb3d0-9b46-4a47-b9b4-473e4e24a89c","enablePingVerification":true,"adminRangeStart":"1","adminRangeEnd":"50","adminRangeFinalStart":"254","adminRangeFinalEnd":"255","useCustomAdminRanges":true,"customAdminRangesJson":"{\"segmentos\":[{\"segmento\":\"13\",\"administrativas_iniciales\":[{\"inicio\":2,\"hasta\":50}],\"administrativas_finales\":[{\"inicio\":253,\"hasta\":254}]},{\"segmento\":\"100\",\"administrativas_iniciales\":[{\"inicio\":2,\"hasta\":50}],\"administrativas_finales\":[{\"inicio\":254,\"hasta\":254}]}]}","adminPassword":"Siip.2963","debugMode":true,"logging_level":true}

0
data/devices_debug.json Normal file → Executable file
View File

15879
data/plugin.log Normal file → Executable file

File diff suppressed because it is too large Load Diff

0
main.php Normal file → Executable file
View File

2
manifest.json Normal file → Executable file
View File

@ -5,7 +5,7 @@
"displayName": "SIIP - Buscador de IP's Disponibles UISP",
"description": "Este plugin permite buscar IP's disponibles en UISP (UNMS) y asignarlas a los clientes en UCRM. Evitando así la asignación de IP's duplicadas y mejorando la gestión de direcciones IP en la red.",
"url": "https://siip.mx",
"version": "1.6.1",
"version": "1.6.2",
"ucrmVersionCompliancy": {
"min": "1.0.0",
"max": null

1706
public.php Normal file → Executable file

File diff suppressed because it is too large Load Diff

BIN
siip-available-ips.zip Normal file → Executable file

Binary file not shown.

0
src/AdminRangeHelper.php Normal file → Executable file
View File

0
src/ApiHandlers.php Normal file → Executable file
View File

0
src/CrmService.php Normal file → Executable file
View File

0
src/IpSearchService.php Normal file → Executable file
View File

0
src/IpValidator.php Normal file → Executable file
View File

0
src/PingService.php Normal file → Executable file
View File

0
test_debug.php Normal file → Executable file
View File

0
ucrm.json Normal file → Executable file
View File

0
unms-swagger.json Normal file → Executable file
View File

0
unms.yaml Normal file → Executable file
View File

0
unmscrm.apib Normal file → Executable file
View File

0
vendor/.DS_Store vendored Normal file → Executable file
View File

0
vendor/autoload.php vendored Normal file → Executable file
View File

0
vendor/composer/ClassLoader.php vendored Normal file → Executable file
View File

0
vendor/composer/InstalledVersions.php vendored Normal file → Executable file
View File

0
vendor/composer/LICENSE vendored Normal file → Executable file
View File

2
vendor/composer/autoload_classmap.php vendored Normal file → Executable file
View File

@ -111,7 +111,9 @@ return array(
'Psr\\Http\\Message\\UriFactoryInterface' => $vendorDir . '/psr/http-factory/src/UriFactoryInterface.php',
'Psr\\Http\\Message\\UriInterface' => $vendorDir . '/psr/http-message/src/UriInterface.php',
'SiipAvailableIps\\AdminRangeHelper' => $baseDir . '/src/AdminRangeHelper.php',
'SiipAvailableIps\\CrmService' => $baseDir . '/src/CrmService.php',
'SiipAvailableIps\\IpSearchService' => $baseDir . '/src/IpSearchService.php',
'SiipAvailableIps\\IpValidator' => $baseDir . '/src/IpValidator.php',
'SiipAvailableIps\\PingService' => $baseDir . '/src/PingService.php',
'Symfony\\Component\\Filesystem\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/filesystem/Exception/ExceptionInterface.php',
'Symfony\\Component\\Filesystem\\Exception\\FileNotFoundException' => $vendorDir . '/symfony/filesystem/Exception/FileNotFoundException.php',

0
vendor/composer/autoload_files.php vendored Normal file → Executable file
View File

0
vendor/composer/autoload_namespaces.php vendored Normal file → Executable file
View File

0
vendor/composer/autoload_psr4.php vendored Normal file → Executable file
View File

0
vendor/composer/autoload_real.php vendored Normal file → Executable file
View File

2
vendor/composer/autoload_static.php vendored Normal file → Executable file
View File

@ -189,7 +189,9 @@ class ComposerStaticInita8750288fc198a75aec345f4f4b7fd12
'Psr\\Http\\Message\\UriFactoryInterface' => __DIR__ . '/..' . '/psr/http-factory/src/UriFactoryInterface.php',
'Psr\\Http\\Message\\UriInterface' => __DIR__ . '/..' . '/psr/http-message/src/UriInterface.php',
'SiipAvailableIps\\AdminRangeHelper' => __DIR__ . '/../..' . '/src/AdminRangeHelper.php',
'SiipAvailableIps\\CrmService' => __DIR__ . '/../..' . '/src/CrmService.php',
'SiipAvailableIps\\IpSearchService' => __DIR__ . '/../..' . '/src/IpSearchService.php',
'SiipAvailableIps\\IpValidator' => __DIR__ . '/../..' . '/src/IpValidator.php',
'SiipAvailableIps\\PingService' => __DIR__ . '/../..' . '/src/PingService.php',
'Symfony\\Component\\Filesystem\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/filesystem/Exception/ExceptionInterface.php',
'Symfony\\Component\\Filesystem\\Exception\\FileNotFoundException' => __DIR__ . '/..' . '/symfony/filesystem/Exception/FileNotFoundException.php',

0
vendor/composer/installed.json vendored Normal file → Executable file
View File

4
vendor/composer/installed.php vendored Normal file → Executable file
View File

@ -5,7 +5,7 @@
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'reference' => 'ab8a60f55685ad4c70661113dab21b4e372aae0e',
'reference' => '647bdfc6ae27ce6b2e5a3dec02067293bfa5359e',
'name' => '__root__',
'dev' => false,
),
@ -16,7 +16,7 @@
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'reference' => 'ab8a60f55685ad4c70661113dab21b4e372aae0e',
'reference' => '647bdfc6ae27ce6b2e5a3dec02067293bfa5359e',
'dev_requirement' => false,
),
'guzzlehttp/guzzle' => array(

0
vendor/composer/platform_check.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/CHANGELOG.md vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/LICENSE vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/README.md vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/UPGRADING.md vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/composer.json vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/BodySummarizer.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/BodySummarizerInterface.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/Client.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/ClientInterface.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/ClientTrait.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/Cookie/CookieJar.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/Cookie/SetCookie.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/Exception/BadResponseException.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/Exception/ClientException.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/Exception/ConnectException.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/Exception/GuzzleException.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/Exception/InvalidArgumentException.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/Exception/RequestException.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/Exception/ServerException.php vendored Normal file → Executable file
View File

View File

0
vendor/guzzlehttp/guzzle/src/Exception/TransferException.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/Handler/CurlFactoryInterface.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/Handler/CurlHandler.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/Handler/EasyHandle.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/Handler/HeaderProcessor.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/Handler/MockHandler.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/Handler/Proxy.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/Handler/StreamHandler.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/HandlerStack.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/MessageFormatter.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/MessageFormatterInterface.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/Middleware.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/Pool.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/RequestOptions.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/RetryMiddleware.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/TransferStats.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/Utils.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/functions.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/guzzle/src/functions_include.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/promises/CHANGELOG.md vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/promises/LICENSE vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/promises/README.md vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/promises/composer.json vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/promises/src/AggregateException.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/promises/src/CancellationException.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/promises/src/Coroutine.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/promises/src/Create.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/promises/src/Each.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/promises/src/EachPromise.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/promises/src/FulfilledPromise.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/promises/src/Is.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/promises/src/Promise.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/promises/src/PromiseInterface.php vendored Normal file → Executable file
View File

0
vendor/guzzlehttp/promises/src/PromisorInterface.php vendored Normal file → Executable file
View File

Some files were not shown because too many files have changed in this diff Show More