Compare commits

...

4 Commits

8 changed files with 45 additions and 57 deletions

View File

@@ -21,6 +21,30 @@ use Psr\Http\Message\ServerRequestInterface;
*/
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);
}
}
/**
* Возвращает информацию о каналов плейлиста
*
@@ -56,24 +80,4 @@ class ApiController extends BasicController
return $response->withStatus(200)
->withHeader('Content-Type', $mime);
}
/**
* Возвращает информацию о плейлисте
*
* @param ServerRequestInterface $request
* @param ResponseInterface $response
* @return ResponseInterface
* @throws Exception
*/
public function json(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
{
$code = $request->getAttributes()['code'];
try {
$playlist = ini()->getPlaylist($code);
return $this->responseJson($response, 200, $playlist);
} catch (PlaylistNotFoundException $e) {
return $this->responseJsonError($response, 404, $e);
}
}
}

View File

@@ -34,7 +34,7 @@ class BasicController
*/
public function notFound(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
{
$code = $request->getAttributes()['code'];
$code = $request->getAttributes()['code'] ?? '';
$response->withStatus(404);
$this->view($request, $response, 'notfound.twig', ['code' => $code]);

View File

@@ -63,21 +63,6 @@ class WebController extends BasicController
]);
}
/**
* Возвращает страницу FAQ
*
* @param ServerRequestInterface $request
* @param ResponseInterface $response
* @return ResponseInterface
* @throws LoaderError
* @throws RuntimeError
* @throws SyntaxError
*/
public function faq(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
{
return $this->view($request, $response, 'faq.twig');
}
/**
* Переадресует запрос на прямую ссылку плейлиста
*

View File

@@ -41,7 +41,11 @@ class IniFile
// сохраняем порядок
foreach (array_keys($ini) as $code) {
$data = redis()->get($code);
try {
$data = @redis()->get($code);
} catch (Throwable) {
$data = false;
}
if ($data === false) {
$raw = $ini[$code];
$data = [

View File

@@ -6,6 +6,7 @@
*/
use App\Controllers\ApiController;
use App\Controllers\BasicController;
use App\Controllers\BotController;
use App\Controllers\WebController;
@@ -35,12 +36,6 @@ return [
'handler' => [WebController::class, 'home'],
'name' => 'home',
],
[
'method' => 'GET',
'path' => '/faq',
'handler' => [WebController::class, 'faq'],
'name' => 'faq',
],
[
'method' => 'GET',
'path' => '/{code:[0-9a-zA-Z]+}[.m3u[8]]',
@@ -62,13 +57,13 @@ return [
[
'method' => 'GET',
'path' => '/{code:[0-9a-zA-Z]+}/json',
'handler' => [ApiController::class, 'json'],
'name' => 'json',
'path' => '/api/playlists/{code:[0-9a-zA-Z]+}',
'handler' => [ApiController::class, 'getOne'],
'name' => 'api::getOne',
],
[
'method' => 'GET',
'path' => '/{code:[0-9a-zA-Z]+}/qrcode',
'path' => '/api/playlists/{code:[0-9a-zA-Z]+}/qrcode',
'handler' => [ApiController::class, 'makeQrCode'],
'name' => 'api::makeQrCode',
],

View File

@@ -175,7 +175,7 @@
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body text-center">
<img src="/{{ playlist.code }}/qrcode" alt="">
<img src="/api/playlists/{{ playlist.code }}/qrcode" alt="">
</div>
</div>
</div>

View File

@@ -70,26 +70,28 @@
<a href="/{{ code }}/details" class="text-decoration-none">
<h5 class="card-title text-light">{{ playlist.name }}</h5>
</a>
<p class="card-text small text-secondary">{{ playlist.description }}</p>
{% if playlist.description is not same as(null) %}
<p class="card-text small text-secondary d-none d-md-block">{{ playlist.description }}</p>
{% endif %}
<div class="d-flex flex-wrap gap-2 mb-1">
{% if playlist.isOnline is not same as(null) %}
<span class="badge border border-secondary">
<ion-icon name="videocam-outline" class="me-1"></ion-icon>&nbsp;{{ playlist.channels|length }}&nbsp;каналов
<ion-icon name="videocam-outline" class="me-1"></ion-icon>&nbsp;{{ playlist.channels|length }}<span class="d-none d-xl-inline-block">&nbsp;каналов</span>
</span>
{% endif %}
{% if playlist.groups|length > 0 %}
<span class="badge border border-secondary">
<ion-icon name="folder-open-outline" class="me-1"></ion-icon>&nbsp;{{ playlist.groups|length }}&nbsp;групп
<ion-icon name="folder-open-outline" class="me-1"></ion-icon>&nbsp;{{ playlist.groups|length }}<span class="d-none d-xl-inline-block">&nbsp;групп</span>
</span>
{% endif %}
{% if playlist.hasTvg %}
<span class="badge border border-secondary">
<ion-icon name="newspaper-outline" class="me-1"></ion-icon>&nbsp;ТВ-программа
<ion-icon name="newspaper-outline" class="me-1"></ion-icon><span class="d-none d-xl-inline-block">&nbsp;ТВ-программа</span>
</span>
{% endif %}
{% if playlist.hasCatchup %}
<span class="badge border border-secondary">
<ion-icon name="play-back-outline" class="me-1"></ion-icon>&nbsp;Архив
<ion-icon name="play-back-outline" class="me-1"></ion-icon><span class="d-none d-xl-inline-block">&nbsp;Архив</span>
</span>
{% endif %}
</div>

View File

@@ -12,13 +12,11 @@
<div class="card bg-dark border-secondary">
<div class="card-body">
<ion-icon name="warning-outline" class="display-1 text-warning mb-3"></ion-icon>
<h2 class="card-title">Плейлист не найден</h2>
<h2 class="card-title">Плейлист <code>{{ code }}</code> не найден</h2>
<p class="card-text">
Плейлист с кодом <code>{{ code }}</code> не найден в системе.
Возможно, его здесь никогда не было, либо он уже был удалён.
</p>
<p class="text-muted small">
Возможно, его здесь никогда не было, либо он уже был удалён.
<br />
Если хочешь, чтобы здесь был плейлист, предложи его к добавлению.
<br />
<a href="https://iptv.axenov.dev/docs/support.html#participate">Как это сделать?</a>