rename app, change api url, fix media op path
This commit is contained in:
parent
64f49414ec
commit
fe62710f76
@ -1,5 +0,0 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class ApiConfig(AppConfig):
|
||||
name = 'api'
|
@ -1,28 +0,0 @@
|
||||
# Generated by Django 3.0.5 on 2020-04-16 09:27
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='GuiSettings',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('player_url', models.CharField(max_length=255)),
|
||||
('playout_config', models.CharField(default='/etc/ffplayout/ffplayout.yml', max_length=255)),
|
||||
('net_interface', models.CharField(choices=[('lo', 'lo'), ('br0', 'br0'), ('virbr0', 'virbr0'), ('eno1', 'eno1'), ('virbr0-nic', 'virbr0-nic')], default=None, max_length=20)),
|
||||
('media_disk', models.CharField(default='/', help_text='should be a mount point, for statistics', max_length=255)),
|
||||
('extra_extensions', models.CharField(blank=True, default='', help_text='file extensions, that are only visible in GUI', max_length=255, null=True)),
|
||||
],
|
||||
options={
|
||||
'verbose_name_plural': 'guisettings',
|
||||
},
|
||||
),
|
||||
]
|
@ -1,32 +0,0 @@
|
||||
# Generated by Django 3.0.5 on 2020-04-28 13:47
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('api', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='MessengePresets',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(help_text='the preset name', max_length=255)),
|
||||
('message', models.CharField(blank=True, default='', max_length=1024, null=True)),
|
||||
('x', models.CharField(blank=True, default='', max_length=512, null=True)),
|
||||
('y', models.CharField(blank=True, default='', max_length=512, null=True)),
|
||||
('font_size', models.IntegerField(default=24)),
|
||||
('font_spacing', models.IntegerField(default=4)),
|
||||
('font_color', models.CharField(default='#ffffff', max_length=12)),
|
||||
('font_alpha', models.FloatField(default=1.0)),
|
||||
('show_box', models.BooleanField(default=True)),
|
||||
('box_color', models.CharField(default='#000000', max_length=12)),
|
||||
('box_alpha', models.FloatField(default=0.8)),
|
||||
('border_width', models.IntegerField(default=4)),
|
||||
('overall_alpha', models.CharField(blank=True, default='', max_length=255, null=True)),
|
||||
],
|
||||
),
|
||||
]
|
@ -1,7 +1,6 @@
|
||||
from api_player.models import GuiSettings
|
||||
from django.contrib import admin
|
||||
|
||||
from api.models import GuiSettings
|
||||
|
||||
|
||||
class GuiSettingsAdmin(admin.ModelAdmin):
|
||||
|
5
ffplayout/api_player/apps.py
Normal file
5
ffplayout/api_player/apps.py
Normal file
@ -0,0 +1,5 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class ApiPlayerConfig(AppConfig):
|
||||
name = 'api_player'
|
@ -1,9 +1,7 @@
|
||||
from api_player.models import GuiSettings, MessengePresets
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
from api.models import GuiSettings, MessengePresets
|
||||
|
||||
|
||||
class UserSerializer(serializers.ModelSerializer):
|
||||
new_password = serializers.CharField(write_only=True, required=False)
|
26
ffplayout/api_player/urls.py
Normal file
26
ffplayout/api_player/urls.py
Normal file
@ -0,0 +1,26 @@
|
||||
from django.urls import include, path, re_path
|
||||
from rest_framework import routers
|
||||
|
||||
from . import views
|
||||
|
||||
router = routers.DefaultRouter()
|
||||
router.register(r'users', views.UserViewSet)
|
||||
router.register(r'guisettings', views.GuiSettingsViewSet, 'guisettings')
|
||||
router.register(r'messenger', views.MessengerViewSet, 'messenger')
|
||||
|
||||
app_name = 'api_player'
|
||||
|
||||
urlpatterns = [
|
||||
path('player/', include(router.urls)),
|
||||
path('player/config/', views.Config.as_view()),
|
||||
path('player/system/', views.SystemCtl.as_view()),
|
||||
path('player/playlist/', views.Playlist.as_view()),
|
||||
path('player/stats/', views.Statistics.as_view()),
|
||||
path('player/log/', views.LogReader.as_view()),
|
||||
path('player/current/user/', views.CurrentUserView.as_view()),
|
||||
path('player/media/', views.Media.as_view()),
|
||||
path('player/send/', views.MessegeSender.as_view()),
|
||||
re_path(r'^player/media/upload/(?P<filename>[^/]+)$',
|
||||
views.FileUpload.as_view()),
|
||||
path('player/media/op/', views.FileOperations.as_view()),
|
||||
]
|
@ -1,17 +1,17 @@
|
||||
import json
|
||||
import os
|
||||
from platform import uname
|
||||
from subprocess import run, PIPE, STDOUT
|
||||
from subprocess import PIPE, STDOUT, run
|
||||
from time import sleep
|
||||
|
||||
import psutil
|
||||
|
||||
import yaml
|
||||
import zmq
|
||||
from api_player.models import GuiSettings
|
||||
from django.conf import settings
|
||||
from pymediainfo import MediaInfo
|
||||
|
||||
from api.models import GuiSettings
|
||||
from natsort import natsorted
|
||||
from pymediainfo import MediaInfo
|
||||
|
||||
|
||||
def read_yaml():
|
||||
@ -244,8 +244,6 @@ def get_media_path(extensions, dir=None):
|
||||
media_dir = media_path.split('/')[-1]
|
||||
media_root = os.path.dirname(media_path)
|
||||
if not dir:
|
||||
if not os.path.isdir(media_path):
|
||||
return ''
|
||||
dir = media_path
|
||||
else:
|
||||
if '/..' in dir:
|
||||
@ -257,7 +255,8 @@ def get_media_path(extensions, dir=None):
|
||||
if dir.startswith(media_dir):
|
||||
dir = dir[len(media_dir):]
|
||||
|
||||
dir = os.path.join(media_root, media_dir, os.path.abspath('/' + dir).strip('/'))
|
||||
dir = os.path.join(
|
||||
media_root, media_dir, os.path.abspath('/' + dir).strip('/'))
|
||||
|
||||
for root, dirs, files in os.walk(dir, topdown=True):
|
||||
root = root.rstrip('/')
|
@ -2,9 +2,9 @@ import os
|
||||
import shutil
|
||||
from urllib.parse import unquote
|
||||
|
||||
from api.models import GuiSettings, MessengePresets
|
||||
from api.serializers import (GuiSettingsSerializer, MessengerSerializer,
|
||||
UserSerializer)
|
||||
from api_player.models import GuiSettings, MessengePresets
|
||||
from api_player.serializers import (GuiSettingsSerializer, MessengerSerializer,
|
||||
UserSerializer)
|
||||
from django.contrib.auth.models import User
|
||||
from django_filters import rest_framework as filters
|
||||
from rest_framework import viewsets
|
||||
@ -13,7 +13,7 @@ from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
|
||||
from .utils import (PlayoutService, SystemStats, get_media_path, read_json,
|
||||
read_yaml, write_json, write_yaml, read_log, send_message)
|
||||
read_log, read_yaml, send_message, write_json, write_yaml)
|
||||
|
||||
|
||||
class CurrentUserView(APIView):
|
||||
@ -71,7 +71,7 @@ class MessegeSender(APIView):
|
||||
class Config(APIView):
|
||||
"""
|
||||
read and write config from ffplayout engine
|
||||
for reading endpoint is: http://127.0.0.1:8000/api/config/?config
|
||||
for reading endpoint is: http://127.0.0.1:8000/api/player/config/?config
|
||||
"""
|
||||
parser_classes = [JSONParser]
|
||||
|
||||
@ -148,7 +148,8 @@ class LogReader(APIView):
|
||||
class Playlist(APIView):
|
||||
"""
|
||||
read and write config from ffplayout engine
|
||||
for reading endpoint: http://127.0.0.1:8000/api/playlist/?date=2020-04-12
|
||||
for reading endpoint:
|
||||
http://127.0.0.1:8000/api/player/playlist/?date=2020-04-12
|
||||
"""
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
@ -176,7 +177,7 @@ class Playlist(APIView):
|
||||
class Statistics(APIView):
|
||||
"""
|
||||
get system statistics: cpu, ram, etc.
|
||||
for reading, endpoint is: http://127.0.0.1:8000/api/stats/?stats=all
|
||||
for reading, endpoint is: http://127.0.0.1:8000/api/player/stats/?stats=all
|
||||
"""
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
@ -192,7 +193,7 @@ class Statistics(APIView):
|
||||
class Media(APIView):
|
||||
"""
|
||||
get folder/files tree, for building a file explorer
|
||||
for reading, endpoint is: http://127.0.0.1:8000/api/media/?path
|
||||
for reading, endpoint is: http://127.0.0.1:8000/api/player/media/?path
|
||||
"""
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
Binary file not shown.
@ -29,7 +29,7 @@ INSTALLED_APPS = [
|
||||
'django_filters',
|
||||
'rest_framework',
|
||||
'corsheaders',
|
||||
'api'
|
||||
'api_player'
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
|
@ -14,34 +14,13 @@ Including another URLconf
|
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||
"""
|
||||
from django.contrib import admin
|
||||
from django.urls import include, path, re_path
|
||||
|
||||
from rest_framework import routers
|
||||
from api import views
|
||||
|
||||
from rest_framework_simplejwt.views import (
|
||||
TokenObtainPairView,
|
||||
TokenRefreshView,
|
||||
)
|
||||
|
||||
router = routers.DefaultRouter()
|
||||
router.register(r'users', views.UserViewSet)
|
||||
router.register(r'guisettings', views.GuiSettingsViewSet, 'guisettings')
|
||||
router.register(r'messenger', views.MessengerViewSet, 'messenger')
|
||||
from django.urls import include, path
|
||||
from rest_framework_simplejwt.views import (TokenObtainPairView,
|
||||
TokenRefreshView)
|
||||
|
||||
urlpatterns = [
|
||||
path('admin/', admin.site.urls),
|
||||
path('api/', include(router.urls)),
|
||||
path('api/config/', views.Config.as_view()),
|
||||
path('api/system/', views.SystemCtl.as_view()),
|
||||
path('api/playlist/', views.Playlist.as_view()),
|
||||
path('api/stats/', views.Statistics.as_view()),
|
||||
path('api/log/', views.LogReader.as_view()),
|
||||
path('api/current/user/', views.CurrentUserView.as_view()),
|
||||
path('api/media/', views.Media.as_view()),
|
||||
path('api/send/', views.MessegeSender.as_view()),
|
||||
re_path(r'^api/media/upload/(?P<filename>[^/]+)$', views.FileUpload.as_view()),
|
||||
path('api/media/op/', views.FileOperations.as_view()),
|
||||
path('api/', include('api_player.urls', namespace='api_player')),
|
||||
path('api-auth/', include(
|
||||
'rest_framework.urls', namespace='rest_framework')),
|
||||
path('auth/token/', TokenObtainPairView.as_view(),
|
||||
|
@ -210,13 +210,13 @@ export default {
|
||||
},
|
||||
|
||||
async sysStats () {
|
||||
const response = await this.$axios.get('api/stats/?stats=all')
|
||||
const response = await this.$axios.get('api/player/stats/?stats=all')
|
||||
this.stat = response.data
|
||||
|
||||
if (process.browser) {
|
||||
this.interval = setInterval(async () => {
|
||||
await this.$store.dispatch('auth/inspectToken')
|
||||
const response = await this.$axios.get('api/stats/?stats=all')
|
||||
const response = await this.$axios.get('api/player/stats/?stats=all')
|
||||
this.stat = response.data
|
||||
}, 2000)
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ export default {
|
||||
methods: {
|
||||
async getLog (type) {
|
||||
await this.$store.dispatch('auth/inspectToken')
|
||||
const response = await this.$axios.get(`api/log/?type=${type}`)
|
||||
const response = await this.$axios.get(`api/player/log/?type=${type}`)
|
||||
|
||||
if (response.data.log) {
|
||||
this.currentLog = response.data.log
|
||||
@ -83,7 +83,7 @@ export default {
|
||||
},
|
||||
async getSystemLog () {
|
||||
await this.$store.dispatch('auth/inspectToken')
|
||||
const response = await this.$axios.post('api/system/', { run: 'log' })
|
||||
const response = await this.$axios.post('api/player/system/', { run: 'log' })
|
||||
|
||||
if (response.data.data) {
|
||||
this.currentLog = response.data.data
|
||||
|
@ -36,7 +36,7 @@
|
||||
</b-link>
|
||||
</b-col>
|
||||
<b-col v-if="folder !== '..'" cols="1" class="folder-delete">
|
||||
<b-link @click="showDeleteModal('Folder', `/${folderTree.tree[0]}/${folder}`)">
|
||||
<b-link @click="showDeleteModal('Folder', `${folderTree.tree[0]}/${folder}`)">
|
||||
<b-icon-x-circle-fill />
|
||||
</b-link>
|
||||
</b-col>
|
||||
@ -70,7 +70,7 @@
|
||||
{{ file.file }}
|
||||
</b-col>
|
||||
<b-col cols="1" class="browser-play-col">
|
||||
<b-link @click="showPreviewModal(`/${folderTree.tree[0]}/${file.file}`)">
|
||||
<b-link @click="showPreviewModal(`${folderTree.tree[0]}/${file.file}`)">
|
||||
<b-icon-play-fill />
|
||||
</b-link>
|
||||
</b-col>
|
||||
@ -78,7 +78,7 @@
|
||||
<span class="duration">{{ file.duration | toMin }}</span>
|
||||
</b-col>
|
||||
<b-col cols="1" class="text-center">
|
||||
<b-link @click="showDeleteModal('File', `/${folderTree.tree[0]}/${file.file}`)">
|
||||
<b-link @click="showDeleteModal('File', `${folderTree.tree[0]}/${file.file}`)">
|
||||
<b-icon-x-circle-fill />
|
||||
</b-link>
|
||||
</b-col>
|
||||
@ -276,7 +276,7 @@ export default {
|
||||
await this.$store.dispatch('auth/inspectToken')
|
||||
|
||||
await this.$axios.post(
|
||||
'api/media/op/',
|
||||
'api/player/media/op/',
|
||||
{ folder: this.folderName, path: this.crumbs.map(e => e.text).join('/') }
|
||||
)
|
||||
|
||||
@ -322,7 +322,7 @@ export default {
|
||||
}
|
||||
|
||||
await this.$axios.put(
|
||||
`api/media/upload/${encodeURIComponent(file.name)}?path=${encodeURIComponent(this.crumbs.map(e => e.text).join('/'))}`,
|
||||
`api/player/media/upload/${encodeURIComponent(file.name)}?path=${encodeURIComponent(this.crumbs.map(e => e.text).join('/'))}`,
|
||||
file,
|
||||
config
|
||||
)
|
||||
@ -403,7 +403,7 @@ export default {
|
||||
pathName = this.deleteSource
|
||||
}
|
||||
|
||||
await this.$axios.delete(`api/media/op/?file=${encodeURIComponent(file)}&path=${encodeURIComponent(pathName)}`)
|
||||
await this.$axios.delete(`api/player/media/op/?file=${encodeURIComponent(file)}&path=${encodeURIComponent(pathName)}`)
|
||||
.catch(err => console.log(err))
|
||||
|
||||
this.$root.$emit('bv::hide::modal', 'delete-modal')
|
||||
|
@ -281,7 +281,7 @@ export default {
|
||||
if (preset) {
|
||||
req = `?name=${preset}`
|
||||
}
|
||||
const response = await this.$axios.get(`api/messenger/${req}`)
|
||||
const response = await this.$axios.get(`api/player/messenger/${req}`)
|
||||
|
||||
if (response.data && !preset) {
|
||||
for (const item of response.data) {
|
||||
@ -333,7 +333,7 @@ export default {
|
||||
overall_alpha: this.form.overallAlpha
|
||||
}
|
||||
|
||||
const response = await this.$axios.post('api/messenger/', preset)
|
||||
const response = await this.$axios.post('api/player/messenger/', preset)
|
||||
|
||||
if (response.status === 201) {
|
||||
this.success = true
|
||||
@ -365,7 +365,7 @@ export default {
|
||||
overall_alpha: this.form.overallAlpha
|
||||
}
|
||||
|
||||
const response = await this.$axios.put(`api/messenger/${this.form.id}/`, preset)
|
||||
const response = await this.$axios.put(`api/player/messenger/${this.form.id}/`, preset)
|
||||
|
||||
if (response.status === 200) {
|
||||
this.success = true
|
||||
@ -385,7 +385,7 @@ export default {
|
||||
async deletePreset () {
|
||||
await this.$store.dispatch('auth/inspectToken')
|
||||
if (this.selected) {
|
||||
await this.$axios.delete(`api/messenger/${this.form.id}/`)
|
||||
await this.$axios.delete(`api/player/messenger/${this.form.id}/`)
|
||||
}
|
||||
|
||||
this.$bvModal.hide('delete-modal')
|
||||
@ -411,7 +411,7 @@ export default {
|
||||
boxborderw: this.form.border
|
||||
}
|
||||
|
||||
const response = await this.$axios.post('api/send/', { data: obj })
|
||||
const response = await this.$axios.post('api/player/send/', { data: obj })
|
||||
|
||||
if (response.data && response.data.status.Success && response.data.status.Success === '0 Success') {
|
||||
this.success = true
|
||||
|
@ -372,7 +372,7 @@ export default {
|
||||
async getStatus () {
|
||||
await this.$store.dispatch('auth/inspectToken')
|
||||
|
||||
const status = await this.$axios.post('api/system/', { run: 'status' })
|
||||
const status = await this.$axios.post('api/player/system/', { run: 'status' })
|
||||
|
||||
if (status.data.data && status.data.data === 'active') {
|
||||
this.isPlaying = 'is-playing'
|
||||
@ -382,7 +382,7 @@ export default {
|
||||
},
|
||||
async playoutControl (state) {
|
||||
await this.$store.dispatch('auth/inspectToken')
|
||||
await this.$axios.post('api/system/', { run: state })
|
||||
await this.$axios.post('api/player/system/', { run: state })
|
||||
|
||||
setTimeout(() => { this.getStatus() }, 1000)
|
||||
},
|
||||
@ -447,7 +447,7 @@ export default {
|
||||
const saveList = this.playlist.map(({ begin, ...item }) => item)
|
||||
|
||||
await this.$axios.post(
|
||||
'api/playlist/',
|
||||
'api/player/playlist/',
|
||||
{ data: { channel: this.$store.state.playlist.playlistChannel, date: this.listDate, program: saveList } }
|
||||
)
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ export default function ({ $axios, store, redirect }) {
|
||||
}
|
||||
|
||||
// disable progress on auth and stats
|
||||
if (config.url.includes('stats') || config.url.includes('auth')) {
|
||||
if (config.url.includes('stats') || config.url.includes('auth') || config.url.includes('system')) {
|
||||
config.progress = false
|
||||
}
|
||||
})
|
||||
|
@ -26,8 +26,8 @@ export const mutations = {
|
||||
|
||||
export const actions = {
|
||||
async getGuiConfig ({ commit, state }) {
|
||||
const options = await this.$axios.options('api/guisettings/')
|
||||
const response = await this.$axios.get('api/guisettings/')
|
||||
const options = await this.$axios.options('api/player/guisettings/')
|
||||
const response = await this.$axios.get('api/player/guisettings/')
|
||||
|
||||
if (options.data) {
|
||||
const choices = options.data.actions.POST.net_interface.choices.map(function (obj) {
|
||||
@ -46,12 +46,12 @@ export const actions = {
|
||||
async setGuiConfig ({ commit, state }, obj) {
|
||||
const stringObj = JSON.parse(JSON.stringify(obj))
|
||||
stringObj.extra_extensions = obj.extra_extensions.join(' ')
|
||||
const update = await this.$axios.put('api/guisettings/1/', stringObj)
|
||||
const update = await this.$axios.put('api/player/guisettings/1/', stringObj)
|
||||
return update
|
||||
},
|
||||
|
||||
async getPlayoutConfig ({ commit, state }) {
|
||||
const response = await this.$axios.get('api/config/?configPlayout')
|
||||
const response = await this.$axios.get('api/player/config/?configPlayout')
|
||||
|
||||
if (response.data) {
|
||||
commit('UPDATE_PLAYLOUT_CONFIG', response.data)
|
||||
@ -59,13 +59,13 @@ export const actions = {
|
||||
},
|
||||
|
||||
async setPlayoutConfig ({ commit, state }, obj) {
|
||||
const update = await this.$axios.post('api/config/?configPlayout', { data: obj })
|
||||
const update = await this.$axios.post('api/player/config/?configPlayout', { data: obj })
|
||||
return update
|
||||
},
|
||||
|
||||
async getUserConfig ({ commit, state }) {
|
||||
const user = await this.$axios.get('api/current/user/')
|
||||
const response = await this.$axios.get(`api/users/?username=${user.data.username}`)
|
||||
const user = await this.$axios.get('api/player/current/user/')
|
||||
const response = await this.$axios.get(`api/player/users/?username=${user.data.username}`)
|
||||
|
||||
if (user.data) {
|
||||
commit('SET_CURRENT_USER', user.data.username)
|
||||
@ -76,7 +76,7 @@ export const actions = {
|
||||
},
|
||||
|
||||
async setUserConfig ({ commit, state }, obj) {
|
||||
const update = await this.$axios.put(`api/users/${obj.id}/`, obj)
|
||||
const update = await this.$axios.put(`api/player/users/${obj.id}/`, obj)
|
||||
return update
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ export const actions = {
|
||||
async getTree ({ commit, dispatch, state }, { extensions, path }) {
|
||||
const crumbs = []
|
||||
let root = '/'
|
||||
const response = await this.$axios.get(`api/media/?extensions=${extensions}&path=${path}`)
|
||||
const response = await this.$axios.get(`api/player/media/?extensions=${extensions}&path=${path}`)
|
||||
|
||||
if (response.data.tree) {
|
||||
const pathArr = response.data.tree[0].split('/')
|
||||
|
@ -46,7 +46,7 @@ export const mutations = {
|
||||
|
||||
export const actions = {
|
||||
async getPlaylist ({ commit, dispatch, state }, { dayStart, date }) {
|
||||
const response = await this.$axios.get(`api/playlist/?date=${date}`)
|
||||
const response = await this.$axios.get(`api/player/playlist/?date=${date}`)
|
||||
|
||||
if (response.data && response.data.program) {
|
||||
commit('UPDATE_PLAYLIST_CHANNEL', response.data.channel)
|
||||
|
Loading…
x
Reference in New Issue
Block a user