diff --git a/app/Controllers/ApiController.php b/app/Controllers/ApiController.php index dfc274a..ab4dd7c 100644 --- a/app/Controllers/ApiController.php +++ b/app/Controllers/ApiController.php @@ -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); - } - } } diff --git a/app/Controllers/BasicController.php b/app/Controllers/BasicController.php index aab299f..4f422fe 100644 --- a/app/Controllers/BasicController.php +++ b/app/Controllers/BasicController.php @@ -34,8 +34,9 @@ class BasicController */ public function notFound(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface { + $code = $request->getAttributes()['code'] ?? ''; $response->withStatus(404); - $this->view($request, $response, 'notfound.twig'); + $this->view($request, $response, 'notfound.twig', ['code' => $code]); return $response; } diff --git a/app/Controllers/WebController.php b/app/Controllers/WebController.php index c2b6622..0d2a956 100644 --- a/app/Controllers/WebController.php +++ b/app/Controllers/WebController.php @@ -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'); - } - /** * Переадресует запрос на прямую ссылку плейлиста * diff --git a/app/Core/IniFile.php b/app/Core/IniFile.php index fa3bb27..0ac4cba 100644 --- a/app/Core/IniFile.php +++ b/app/Core/IniFile.php @@ -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 = [ diff --git a/config/routes.php b/config/routes.php index 1dc3031..f47be9b 100644 --- a/config/routes.php +++ b/config/routes.php @@ -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', ], diff --git a/views/details.twig b/views/details.twig index 2d79ead..db2f530 100644 --- a/views/details.twig +++ b/views/details.twig @@ -175,7 +175,7 @@ diff --git a/views/list.twig b/views/list.twig index 5574b4f..a5aae4f 100644 --- a/views/list.twig +++ b/views/list.twig @@ -10,119 +10,128 @@ {% block metakeywords %}самообновляемые,бесплатные,iptv-плейлисты,iptv,плейлисты{% endblock %} +{% block head %} + + +{% endblock %} + {% block header %} -
-
- Список изменён: {{ updatedAt }} МСК
- Плейлистов в списке: {{ count }} +
+
+

Список плейлистов ({{ count }})

+
Изменён {{ updatedAt }} МСК
-
- Состояние проверки:
- - online{{ onlineCount }} - - - offline{{ offlineCount }} - - - unknown{{ uncheckedCount }} - +
+ online: {{ onlineCount }} + offline: {{ offlineCount }} + unknown: {{ uncheckedCount }}
-
{% endblock %} {% block content %} -
- - - - - - - - - - +
{% for code, playlist in playlists %} -
- - - - - +
+ + {{ mirror_url(playlist.code) }} + + +
+ + + + + {% endfor %} - -
КодИнформация о плейлистеКаналовСсылка для ТВ
{{ code }} - {% if playlist.isOnline is same as(true) %} - online - {% elseif playlist.isOnline is same as(false) %} - offline - {% elseif playlist.isOnline is same as(null) %} - unknown - {% endif %} - {% if "adult" in playlist.tags %} - 18+ - {% endif %} - {{ playlist.name }} -
-

+ {% set statusClass = 'secondary' %} + {% if playlist.isOnline is same as(true) %} + {% set statusClass = 'success' %} + {% elseif playlist.isOnline is same as(false) %} + {% set statusClass = 'danger' %} + {% endif %} + +

+
+ +
+ {{ code }} + + {% if playlist.isOnline is same as(true) %}online + {% elseif playlist.isOnline is same as(false) %}offline + {% elseif playlist.isOnline is same as(null) %}unknown + {% endif %} + + {% if "adult" in playlist.tags %} + 18+ + {% endif %} +
+
+ +
+ +
{{ playlist.name }}
+
+ {% if playlist.description is not same as(null) %} +

{{ playlist.description }}

+ {% endif %} +
+ {% if playlist.isOnline is not same as(null) %} + +  {{ playlist.channels|length }} каналов + + {% endif %} {% if playlist.groups|length > 0 %} - + +  {{ playlist.groups|length }} групп + {% endif %} {% if playlist.hasTvg %} - + +  ТВ-программа + {% endif %} {% if playlist.hasCatchup %} - + +  Архив + {% endif %} - {{ playlist.description }} -

- {% if playlist.tags|length > 0 %} -

- - {% for tag in playlist.tags %} - #{{ tag }} - {% endfor %} -

- {% endif %} - Подробнее... +
-
- {% if (playlist.isOnline is not same as(null)) %} - {{ playlist.channels|length }} - {% else %} - ? - {% endif %} - - - {{ mirror_url(playlist.code) }} - -
- {% if pageCount > 1 %} -
-
    - {% for page in range(1, pageCount) %} - {% if page == pageCurrent %} -
  • - {{ page }} -
  • - {% else %} -
  • - {{ page }} -
  • - {% endif %} - {% endfor %} -
+ + {% if pageCount > 1 %} + {% endif %} -
{% endblock %} {% block footer %} diff --git a/views/notfound.twig b/views/notfound.twig index 6c5a71a..0140965 100644 --- a/views/notfound.twig +++ b/views/notfound.twig @@ -6,19 +6,26 @@ {% extends "template.twig" %} -{% block header %} -

Плейлист не найден

-{% endblock %} - {% block content %} -
-
-

- Плейлист {{ id }} не найден -

- - Перейти к списку - +
+
+
+
+ +

Плейлист {{ code }} не найден

+

+ Возможно, его здесь никогда не было, либо он уже был удалён. +

+

+ Если хочешь, чтобы здесь был плейлист, предложи его к добавлению. +
+ Как это сделать? +

+ + Перейти к списку плейлистов + +
+
{% endblock %} diff --git a/views/template.twig b/views/template.twig index 81bf47f..3acc477 100644 --- a/views/template.twig +++ b/views/template.twig @@ -5,7 +5,7 @@ ###########################################################################} - + {% block title %}{{ config('app.title') }}{% endblock %} @@ -30,67 +30,107 @@ {% block head %}{% endblock %} - - + - -
+ + {% block footer %}{% endblock %} {% include("custom.twig") ignore missing %}