Переработка под iptvc

This commit is contained in:
2025-05-12 00:07:43 +08:00
parent f43843bb07
commit 252af50239
29 changed files with 1662 additions and 1268 deletions

View File

@@ -1,36 +1,117 @@
<?php
/*
* Copyright (c) 2025, Антон Аксенов
* This file is part of iptv.axenov.dev web interface
* MIT License: https://git.axenov.dev/IPTV/web/src/branch/master/LICENSE
*/
declare(strict_types=1);
namespace App\Controllers;
use App\Errors\PlaylistNotFoundException;
use App\Playlists\ChannelLogo;
use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Random\RandomException;
use Twig\Error\LoaderError;
/**
*
* Контроллер методов API
*/
class ApiController extends BasicController
{
/**
* Возвращает информацию о каналов плейлиста
*
* @param ServerRequestInterface $request
* @param ResponseInterface $response
* @return ResponseInterface
* @throws RandomException
* @throws LoaderError
*/
public function json(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
public function makeQrCode(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
{
$code = $request->getAttribute('code');
$codes = array_keys(ini()->getPlaylists());
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 = base_url("$code");
$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 LoaderError
*/
public function getPlaylist(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
{
$code = $request->getAttributes()['code'];
$playlist = $this->getPlaylist($code, true);
$playlist->fetchContent();
$playlist->parse();
$json = json_encode($playlist->toArray(), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$response->getBody()->write($json);
try {
$playlist = ini()->getPlaylist($code);
return $this->responseJson($response, 200, $playlist);
} catch (PlaylistNotFoundException $e) {
return $this->responseJsonError($response, 404, $e);
}
}
return $response
->withHeader('Content-Type', 'application/json')
->withHeader('Content-Length', strlen($json));
/**
* Возвращает логотип канала
*
* @param ServerRequestInterface $request
* @param ResponseInterface $response
* @return ResponseInterface
* @throws LoaderError
* @throws PlaylistNotFoundException
* @todo логотипы каналов
*/
public function logo(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
{
$code = $request->getAttributes()['code'];
$playlist = ini()->getPlaylist($code);
$channelHash = $request->getAttributes()['hash'];
$channel = $playlist['channels'][$channelHash];
$url = $channel['attributes']['tvg-logo'] ?? '';
$logo = new ChannelLogo($url);
if (!$logo->readFile()) {
$logo->fetch();
if ($logo->size() === 0) {
$logo->setDefault();
} else {
$logo->store();
}
}
$body = $logo->raw();
$size = $logo->size();
$mime = $logo->mimeType();
$response->getBody()->write($body);
return $response->withHeader('Content-Type', $mime)
->withHeader('Content-Length', $size);
}
}