b5d3b60356
- /api/version - /api/health - /api/stats
190 lines
6.9 KiB
PHP
190 lines
6.9 KiB
PHP
<?php
|
|
/*
|
|
* Copyright (c) 2025, Антон Аксенов
|
|
* This file is part of m3u.su project
|
|
* MIT License: https://git.axenov.dev/IPTV/web/src/branch/master/LICENSE
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Controllers;
|
|
|
|
use App\Core\Bot;
|
|
use App\Core\Kernel;
|
|
use App\Core\StatisticsService;
|
|
use App\Errors\PlaylistNotFoundException;
|
|
use chillerlan\QRCode\QRCode;
|
|
use chillerlan\QRCode\QROptions;
|
|
use Exception;
|
|
use Psr\Http\Message\ResponseInterface;
|
|
use Psr\Http\Message\ServerRequestInterface;
|
|
|
|
/**
|
|
* Контроллер методов API
|
|
*/
|
|
class ApiController extends BasicController
|
|
{
|
|
/**
|
|
* Возвращает информацию о плейлисте
|
|
*
|
|
* @param ServerRequestInterface $request
|
|
* @param ResponseInterface $response
|
|
* @return ResponseInterface
|
|
* @throws Exception
|
|
*/
|
|
public function getOne(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
|
|
{
|
|
try {
|
|
$code = $request->getAttributes()['code'] ?? null;
|
|
empty($code) && throw new PlaylistNotFoundException('');
|
|
|
|
$playlist = ini()->getPlaylist($code);
|
|
if ($playlist['isOnline'] === true) {
|
|
unset($playlist['content']);
|
|
}
|
|
return $this->responseJson($response, 200, $playlist);
|
|
} catch (PlaylistNotFoundException $e) {
|
|
return $this->responseJsonError($response, 404, $e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Возвращает информацию о каналов плейлиста
|
|
*
|
|
* @param ServerRequestInterface $request
|
|
* @param ResponseInterface $response
|
|
* @return ResponseInterface
|
|
* @throws Exception
|
|
*/
|
|
public function makeQrCode(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
|
|
{
|
|
$ini = ini()->load();
|
|
$code = $request->getAttribute('code');
|
|
$codes = array_keys($ini);
|
|
if (!in_array($code, $codes, true)) {
|
|
return $response->withStatus(404);
|
|
}
|
|
|
|
$filePath = cache_path("qr-codes/$code.jpg");
|
|
if (file_exists($filePath)) {
|
|
$raw = file_get_contents($filePath);
|
|
} else {
|
|
$options = new QROptions([
|
|
'version' => 5,
|
|
'outputType' => QRCode::OUTPUT_IMAGE_JPG,
|
|
'eccLevel' => QRCode::ECC_L,
|
|
]);
|
|
$data = config('app.mirror_url') ? mirror_url("$code.m3u") : base_url("$code.m3u");
|
|
$raw = new QRCode($options)->render($data, $filePath);
|
|
$raw = base64_decode(str_replace('data:image/jpg;base64,', '', $raw));
|
|
}
|
|
|
|
$mime = mime_content_type($filePath);
|
|
$response->getBody()->write($raw);
|
|
return $response->withStatus(200)
|
|
->withHeader('Content-Type', $mime);
|
|
}
|
|
|
|
/**
|
|
* Возвращает информацию о плейлисте
|
|
*
|
|
* @param ServerRequestInterface $request
|
|
* @param ResponseInterface $response
|
|
* @return ResponseInterface
|
|
* @throws Exception
|
|
*/
|
|
public function version(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
|
|
{
|
|
return $this->responseJson($response, 200, [
|
|
'web' => Kernel::VERSION,
|
|
'php' => PHP_VERSION,
|
|
'keydb' => redis()->info('server')['redis_version'],
|
|
'checker' => 'todo',
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Возвращает информацию о плейлисте
|
|
*
|
|
* @param ServerRequestInterface $request
|
|
* @param ResponseInterface $response
|
|
* @return ResponseInterface
|
|
* @throws Exception
|
|
*/
|
|
public function health(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
|
|
{
|
|
function getSize(string $directory): int
|
|
{
|
|
$size = 0;
|
|
foreach (glob($directory . '/*') as $path){
|
|
is_file($path) && $size += filesize($path);
|
|
is_dir($path) && $size += getSize($path);
|
|
}
|
|
return $size;
|
|
}
|
|
|
|
$tgBotInfo = config('bot.token') ? new Bot()->api->getMe() : null;
|
|
$redisInfoServer = redis()->info('server'); // General information about the Redis server
|
|
$redisInfoClients = redis()->info('clients'); // Client connections section
|
|
$redisInfoMemory = redis()->info('memory'); // Memory consumption related information
|
|
$redisInfoPers = redis()->info('persistence'); // RDB and AOF related information
|
|
$redisInfoStats = redis()->info('stats'); // General statistics
|
|
$redisInfoCpu = redis()->info('cpu'); // CPU consumption statistics
|
|
$redisInfoCmd = redis()->info('commandstats'); // Redis command statistics
|
|
$redisInfoKeysp = redis()->info('keyspace'); // Database related statistics
|
|
$redisInfoErr = redis()->info('errorstats'); // Redis error statistics
|
|
|
|
$health = [
|
|
'fileCache' => [
|
|
'tv-logos' => [
|
|
'sizeB' => $size = getSize(cache_path('tv-logos')),
|
|
'sizeMiB' => round($size / 1024 / 1024, 3),
|
|
'count' => count(glob(cache_path('tv-logos') . '/*')),
|
|
],
|
|
'qr-codes' => [
|
|
'sizeB' => $size = getSize(cache_path('qr-codes')),
|
|
'sizeMiB' => round($size / 1024 / 1024, 3),
|
|
'count' => count(glob(cache_path('qr-codes') . '/*')),
|
|
],
|
|
],
|
|
'telegram' => [
|
|
'id' => $tgBotInfo->getId(),
|
|
'first_name' => $tgBotInfo->getFirstName(),
|
|
'username' => $tgBotInfo->getUsername(),
|
|
],
|
|
'redis' => [
|
|
'isConnected' => redis()->isConnected(),
|
|
'info' => [
|
|
'server' => [
|
|
'uptime_in_seconds' => $redisInfoServer['uptime_in_seconds'],
|
|
'uptime_in_days' => $redisInfoServer['uptime_in_days'],
|
|
],
|
|
'clients' => ['connected_clients' => $redisInfoClients['connected_clients']],
|
|
'memory' => $redisInfoMemory,
|
|
'persistence' => $redisInfoPers,
|
|
'stats' => $redisInfoStats,
|
|
'cpu' => $redisInfoCpu,
|
|
'commandstats' => $redisInfoCmd,
|
|
'keyspace' => $redisInfoKeysp,
|
|
'errorstats' => $redisInfoErr,
|
|
],
|
|
],
|
|
];
|
|
|
|
return $this->responseJson($response, 200, $health);
|
|
}
|
|
|
|
/**
|
|
* Возвращает информацию о плейлисте
|
|
*
|
|
* @param ServerRequestInterface $request
|
|
* @param ResponseInterface $response
|
|
* @return ResponseInterface
|
|
* @throws Exception
|
|
*/
|
|
public function stats(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
|
|
{
|
|
return $this->responseJson($response, 200, new StatisticsService()->get());
|
|
}
|
|
}
|