Compare commits
2 Commits
acf1f8083f
...
ed169220c2
Author | SHA1 | Date |
---|---|---|
Anthony Axenov | ed169220c2 | |
Anthony Axenov | 585392b295 |
|
@ -1,6 +1,7 @@
|
|||
/.idea
|
||||
/.vscode
|
||||
/downloaded
|
||||
/src/commit
|
||||
/src/cache/*
|
||||
/src/vendor
|
||||
/src/views/custom/*
|
||||
|
|
15
README.md
15
README.md
|
@ -188,19 +188,12 @@ GET https://iptv.axenov.dev/<ID>/json
|
|||
|
||||
## Развёртывание проекта
|
||||
|
||||
### Aвтоматически
|
||||
Локально достаточно выполнить `./iptv init && ./iptv open`.
|
||||
|
||||
Выполнить `./iptv init`
|
||||
На сервере опционально можно настроить реверс-прокси до контейнера, например, чтобы настроить доступ по доменному
|
||||
имени, изменить порт, подключить SSL-сертификаты или др.
|
||||
|
||||
### Вручную
|
||||
|
||||
1. Выполнить `cp ./src/.env.example ./src/.env`, установить необходимые параметры в файле `./src/.env`
|
||||
2. Выполнить `docker compose up -d --build` (или `./iptv up`)
|
||||
3. Открыть `http://<APP_URL>:8080` в браузере (или `./iptv open`)
|
||||
|
||||
Если на сервере, на котором запускаются контейнеры, стоит apache2, то его можно использовать как реверс прокси:
|
||||
|
||||
Для этого следует:
|
||||
Если на сервере, на котором запускаются контейнеры, стоит apache2, то, чтобы использовать его как реверс-прокси, нужно:
|
||||
|
||||
```
|
||||
$ sudo a2enmod proxy proxy_http proxy_balancer lbmethod_byrequests
|
||||
|
|
|
@ -32,7 +32,7 @@ services:
|
|||
- ./log/nginx:/var/log/nginx:rw
|
||||
- ./src:/var/www:ro
|
||||
ports:
|
||||
- 8080:80
|
||||
- '8080:80'
|
||||
links:
|
||||
- php
|
||||
depends_on:
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/bash
|
||||
# хук пробрасывает хэш свежего коммита в контейнер
|
||||
# для его отображения в подвале страницы
|
||||
git rev-parse HEAD > src/commit
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/bash
|
||||
# хук пробрасывает хэш свежего коммита в контейнер
|
||||
# для его отображения в подвале страницы и очищает
|
||||
# кеш шаблонов twig после слияния веток
|
||||
# главным образом необходимо при git pull
|
||||
git rev-parse HEAD > src/commit
|
||||
docker exec -ti iptv-php rm -rf cache/views
|
15
iptv
15
iptv
|
@ -15,15 +15,20 @@ open_browser() {
|
|||
}
|
||||
|
||||
case "$1" in
|
||||
'' | 'help' ) echo -e "Provide one of operations: \t init, start, stop, up, down, restart, rebuild, open";
|
||||
'' | 'help' ) echo -e "Provide one of operations: \t init, start, stop, up, down, restart, rebuild, open, hooks";
|
||||
echo "Otherwise all args will passed to 'docker exec -ti $CONTAINER ...'" ;;
|
||||
'init' ) cp src/.env.example src/.env && nano src/.env && ./iptv up && ./iptv composer i && ./iptv open && echo -e "\nYou're welcome!\n\t$APP_URL";;
|
||||
'init' ) cp src/.env.example src/.env && \
|
||||
./iptv hooks && \
|
||||
./iptv up && \
|
||||
./iptv composer i && \
|
||||
echo "Project started successfully! $APP_URL" ;;
|
||||
'up' ) $CMD up -d --build && ./iptv open ;; # build and start containers
|
||||
'down' ) $CMD down --remove-orphans ;; # stop and remove containers
|
||||
'start' ) $CMD start && ./iptv open ;; # start containers
|
||||
'start' ) $CMD start ;; # start containers
|
||||
'stop' ) $CMD stop ;; # stop containers
|
||||
'restart' ) $CMD stop && $CMD start ;; # restart containers
|
||||
'rebuild' ) $CMD down --remove-orphans && $CMD up -d --build ;; # rebuild containers
|
||||
'open' ) open_browser $APP_URL ;;
|
||||
* ) docker exec -ti $CONTAINER $@ # exec anything else in container
|
||||
'open' ) open_browser $APP_URL && echo -e "\nYou're welcome!\n\t$APP_URL" ;;
|
||||
'hooks' ) ./hooks/post-commit && cp hooks/* .git/hooks ;;
|
||||
* ) docker exec -ti $CONTAINER $* ;; # exec anything else in container
|
||||
esac
|
||||
|
|
|
@ -13,6 +13,7 @@ class TwigFunctions extends AbstractExtension
|
|||
{
|
||||
return [
|
||||
new TwigFunction('config', [$this, 'config']),
|
||||
new TwigFunction('commit', [$this, 'commit']),
|
||||
new TwigFunction('is_file', [$this, 'is_file']),
|
||||
new TwigFunction('base_url', [$this, 'base_url']),
|
||||
];
|
||||
|
@ -23,6 +24,11 @@ class TwigFunctions extends AbstractExtension
|
|||
return config($key, $default);
|
||||
}
|
||||
|
||||
public function commit(): string
|
||||
{
|
||||
return file_get_contents(root_path('commit'));
|
||||
}
|
||||
|
||||
public function base_url(string $path = ''): string
|
||||
{
|
||||
return base_url($path);
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
document.querySelectorAll('tr.pls').forEach((tr) => {
|
||||
const id = tr.attributes['data-playlist-id'].value
|
||||
const xhr = new XMLHttpRequest()
|
||||
xhr.responseType = 'json'
|
||||
xhr.timeout = 60000 // ms = 1 min
|
||||
let el_status = tr.querySelector('span.status')
|
||||
let el_count = tr.querySelector('td.count')
|
||||
xhr.onreadystatechange = () => {
|
||||
if (xhr.readyState === XMLHttpRequest.DONE) {
|
||||
console.log('[' + id + '] DONE', xhr.response)
|
||||
el_status.classList.remove('bg-secondary')
|
||||
el_status.innerText = xhr.response.status
|
||||
el_count.innerText = xhr.response.count ?? 0
|
||||
switch (xhr.response.status) {
|
||||
case 'online':
|
||||
el_status.classList.add('bg-success')
|
||||
break
|
||||
case 'timeout':
|
||||
el_status.classList.add('bg-warning')
|
||||
break
|
||||
default:
|
||||
el_status.classList.add('bg-danger')
|
||||
break
|
||||
}
|
||||
if (xhr.response.error) {
|
||||
el_status.title = '[' + xhr.response.error.code + '] ' + xhr.response.error.message
|
||||
}
|
||||
}
|
||||
}
|
||||
xhr.onerror = () => {
|
||||
console.log('[' + id + '] ERROR', xhr.response)
|
||||
el_status.classList.add('bg-danger')
|
||||
el_status.innerText = 'error'
|
||||
el_count.innerText = '-'
|
||||
}
|
||||
xhr.onabort = () => {
|
||||
console.log('[' + id + '] ABORTED', xhr.response)
|
||||
el_status.classList.add('bg-secondary')
|
||||
el_count.innerText = '-'
|
||||
}
|
||||
xhr.ontimeout = () => {
|
||||
console.log('[' + id + '] TIMEOUT', xhr.response)
|
||||
el_status.classList.add('bg-secondary')
|
||||
el_status.innerText = 'timeout'
|
||||
el_count.innerText = '-'
|
||||
}
|
||||
xhr.open('GET', '/' + id + '/json')
|
||||
xhr.send()
|
||||
})
|
|
@ -103,7 +103,9 @@
|
|||
</li>
|
||||
<li>
|
||||
<span class="badge small text-dark bg-success">online</span>
|
||||
Плейлист, возможно, активен.
|
||||
Плейлист, возможно, активен. <i>Если каналов 0, значит, вероятно, источник поставил
|
||||
редирект с плейлиста на куда ему вздумалось. То есть плейлист, наверное, отсутствует
|
||||
и, возможно, больше никогда не появится по текущему адресу.</i>
|
||||
</li>
|
||||
<li>
|
||||
<span class="badge small text-dark bg-warning">timeout</span>
|
||||
|
|
|
@ -62,7 +62,12 @@
|
|||
<a href="{{ base_url('faq') }}">FAQ</a> | <a
|
||||
href="https://github.com/anthonyaxenov/iptv">GitHub</a> | <a
|
||||
href="https://git.axenov.dev/anthony/iptv">Gitea</a> | <a
|
||||
href="https://axenov.dev">axenov.dev</a>
|
||||
href="https://axenov.dev">axenov.dev</a><br>
|
||||
<span class="small text-muted">
|
||||
commit <a class="text-muted" target="_blank"
|
||||
href="https://github.com/anthonyaxenov/iptv/commit/{{ commit() }}"
|
||||
>{{ commit()[:8] }}</a>
|
||||
</span>
|
||||
</footer>
|
||||
</div>
|
||||
{% if is_file("custom/custom.twig") %}
|
||||
|
|
|
@ -75,5 +75,55 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block footer %}
|
||||
<script src="{{ base_url('js/checker.js') }}"></script>
|
||||
<script>
|
||||
document.querySelectorAll('tr.pls').forEach((tr) => {
|
||||
const id = tr.attributes['data-playlist-id'].value
|
||||
const xhr = new XMLHttpRequest()
|
||||
xhr.responseType = 'json'
|
||||
xhr.timeout = 60000 // ms = 1 min
|
||||
let el_status = tr.querySelector('span.status')
|
||||
let el_count = tr.querySelector('td.count')
|
||||
xhr.onreadystatechange = () => {
|
||||
if (xhr.readyState === XMLHttpRequest.DONE) {
|
||||
console.log('[' + id + '] DONE', xhr.response)
|
||||
el_status.classList.remove('bg-secondary')
|
||||
el_status.innerText = xhr.response.status
|
||||
el_count.innerText = xhr.response?.count ?? 0
|
||||
switch (xhr.response.status) {
|
||||
case 'online':
|
||||
el_status.classList.add('bg-success')
|
||||
break
|
||||
case 'timeout':
|
||||
el_status.classList.add('bg-warning')
|
||||
break
|
||||
default:
|
||||
el_status.classList.add('bg-danger')
|
||||
break
|
||||
}
|
||||
if (xhr.response.error) {
|
||||
el_status.title = '[' + xhr.response.error.code + '] ' + xhr.response.error.message
|
||||
}
|
||||
}
|
||||
}
|
||||
xhr.onerror = () => {
|
||||
console.log('[' + id + '] ERROR', xhr.response)
|
||||
el_status.classList.add('bg-danger')
|
||||
el_status.innerText = 'error'
|
||||
el_count.innerText = 0
|
||||
}
|
||||
xhr.onabort = () => {
|
||||
console.log('[' + id + '] ABORTED', xhr.response)
|
||||
el_status.classList.add('bg-secondary')
|
||||
el_count.innerText = 0
|
||||
}
|
||||
xhr.ontimeout = () => {
|
||||
console.log('[' + id + '] TIMEOUT', xhr.response)
|
||||
el_status.classList.add('bg-secondary')
|
||||
el_status.innerText = 'timeout'
|
||||
el_count.innerText = 0
|
||||
}
|
||||
xhr.open('GET', '/' + id + '/json')
|
||||
xhr.send()
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
Loading…
Reference in New Issue