mirror of
https://github.com/Dispatcharr/Dispatcharr.git
synced 2026-07-21 01:05:30 +00:00
Fix vods not displaying in the webui.
This commit is contained in:
parent
d9192d003d
commit
88a9f8b14e
5 changed files with 190 additions and 115 deletions
|
|
@ -26,6 +26,7 @@ urlpatterns = [
|
|||
path('hdhr/', include(('apps.hdhr.api_urls', 'hdhr'), namespace='hdhr')),
|
||||
path('m3u/', include(('apps.m3u.api_urls', 'm3u'), namespace='m3u')),
|
||||
path('core/', include(('core.api_urls', 'core'), namespace='core')),
|
||||
path('vod/', include(('apps.vod.api_urls', 'vod'), namespace='vod')),
|
||||
# path('output/', include(('apps.output.api_urls', 'output'), namespace='output')),
|
||||
#path('player/', include(('apps.player.api_urls', 'player'), namespace='player')),
|
||||
#path('settings/', include(('apps.settings.api_urls', 'settings'), namespace='settings')),
|
||||
|
|
|
|||
20
apps/vod/api_urls.py
Normal file
20
apps/vod/api_urls.py
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
from django.urls import path, include
|
||||
from rest_framework.routers import DefaultRouter
|
||||
from .api_views import (
|
||||
MovieViewSet,
|
||||
EpisodeViewSet,
|
||||
SeriesViewSet,
|
||||
VODCategoryViewSet,
|
||||
VODConnectionViewSet,
|
||||
)
|
||||
|
||||
app_name = 'vod'
|
||||
|
||||
router = DefaultRouter()
|
||||
router.register(r'movies', MovieViewSet, basename='movie')
|
||||
router.register(r'episodes', EpisodeViewSet, basename='episode')
|
||||
router.register(r'series', SeriesViewSet, basename='series')
|
||||
router.register(r'categories', VODCategoryViewSet, basename='vodcategory')
|
||||
router.register(r'connections', VODConnectionViewSet, basename='vodconnection')
|
||||
|
||||
urlpatterns = router.urls
|
||||
|
|
@ -1700,16 +1700,39 @@ export default class API {
|
|||
}
|
||||
|
||||
// VOD Methods
|
||||
static async getVODs(params = {}) {
|
||||
static async getVODs(params = new URLSearchParams()) {
|
||||
try {
|
||||
const searchParams = new URLSearchParams(params);
|
||||
const response = await request(`${host}/api/vod/movies/?${searchParams.toString()}`);
|
||||
const response = await request(
|
||||
`${host}/api/vod/movies/?${params.toString()}`
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
errorNotification('Failed to retrieve VODs', e);
|
||||
}
|
||||
}
|
||||
|
||||
static async getVODSeries(params = new URLSearchParams()) {
|
||||
try {
|
||||
const response = await request(
|
||||
`${host}/api/vod/series/?${params.toString()}`
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
errorNotification('Failed to retrieve VOD series', e);
|
||||
}
|
||||
}
|
||||
|
||||
static async getSeriesEpisodes(seriesId) {
|
||||
try {
|
||||
const response = await request(
|
||||
`${host}/api/vod/series/${seriesId}/episodes/`
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
errorNotification('Failed to retrieve series episodes', e);
|
||||
}
|
||||
}
|
||||
|
||||
static async getVODCategories() {
|
||||
try {
|
||||
const response = await request(`${host}/api/vod/categories/`);
|
||||
|
|
@ -1719,43 +1742,21 @@ export default class API {
|
|||
}
|
||||
}
|
||||
|
||||
static async getSeries(params = {}) {
|
||||
static async getVODInfo(vodId) {
|
||||
try {
|
||||
const searchParams = new URLSearchParams(params);
|
||||
const response = await request(`${host}/api/vod/series/?${searchParams.toString()}`);
|
||||
const response = await request(`${host}/api/vod/movies/${vodId}/`);
|
||||
return response;
|
||||
} catch (e) {
|
||||
errorNotification('Failed to retrieve series', e);
|
||||
errorNotification('Failed to retrieve VOD info', e);
|
||||
}
|
||||
}
|
||||
|
||||
static async getSeriesEpisodes(seriesId, params = {}) {
|
||||
static async getSeriesInfo(seriesId) {
|
||||
try {
|
||||
const searchParams = new URLSearchParams(params);
|
||||
const response = await request(`${host}/api/vod/series/${seriesId}/episodes/?${searchParams.toString()}`);
|
||||
const response = await request(`${host}/api/vod/series/${seriesId}/`);
|
||||
return response;
|
||||
} catch (e) {
|
||||
errorNotification('Failed to retrieve series episodes', e);
|
||||
}
|
||||
}
|
||||
|
||||
static async getVODConnections() {
|
||||
try {
|
||||
const response = await request(`${host}/api/vod/connections/`);
|
||||
return response;
|
||||
} catch (e) {
|
||||
errorNotification('Failed to retrieve VOD connections', e);
|
||||
}
|
||||
}
|
||||
|
||||
static async refreshVODContent(accountId) {
|
||||
try {
|
||||
const response = await request(`${host}/api/m3u/accounts/${accountId}/refresh-vod/`, {
|
||||
method: 'POST'
|
||||
});
|
||||
return response;
|
||||
} catch (e) {
|
||||
errorNotification('Failed to refresh VOD content', e);
|
||||
errorNotification('Failed to retrieve series info', e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import useUserAgentsStore from './userAgents';
|
|||
import useUsersStore from './users';
|
||||
import API from '../api';
|
||||
import { USER_LEVELS } from '../constants';
|
||||
import useVODStore from './useVODStore';
|
||||
|
||||
const decodeToken = (token) => {
|
||||
if (!token) return null;
|
||||
|
|
@ -57,6 +58,7 @@ const useAuthStore = create((set, get) => ({
|
|||
useChannelsStore.getState().fetchLogos(),
|
||||
useStreamProfilesStore.getState().fetchProfiles(),
|
||||
useUserAgentsStore.getState().fetchUserAgents(),
|
||||
useVODStore.getState().fetchCategories(), // Add VOD categories
|
||||
]);
|
||||
|
||||
if (user.user_level >= USER_LEVELS.ADMIN) {
|
||||
|
|
|
|||
|
|
@ -1,131 +1,182 @@
|
|||
import { create } from 'zustand';
|
||||
import API from '../api';
|
||||
|
||||
const host = window.location.origin;
|
||||
import api from '../api';
|
||||
|
||||
const useVODStore = create((set, get) => ({
|
||||
// State
|
||||
vods: {},
|
||||
series: {},
|
||||
categories: {},
|
||||
loading: false,
|
||||
error: null,
|
||||
|
||||
// Filters and pagination
|
||||
currentPage: 1,
|
||||
pageSize: 50,
|
||||
totalCount: 0,
|
||||
filters: {
|
||||
type: 'all', // 'all', 'movies', 'series'
|
||||
category: '',
|
||||
search: '',
|
||||
year: null,
|
||||
seriesId: null
|
||||
category: '',
|
||||
},
|
||||
currentPage: 1,
|
||||
totalCount: 0,
|
||||
pageSize: 20,
|
||||
|
||||
// Actions
|
||||
setLoading: (loading) => set({ loading }),
|
||||
setError: (error) => set({ error }),
|
||||
setFilters: (newFilters) =>
|
||||
set((state) => ({
|
||||
filters: { ...state.filters, ...newFilters },
|
||||
currentPage: 1, // Reset to first page when filters change
|
||||
})),
|
||||
|
||||
setFilters: (newFilters) => set((state) => ({
|
||||
filters: { ...state.filters, ...newFilters },
|
||||
currentPage: 1 // Reset to first page when filters change
|
||||
})),
|
||||
|
||||
setPage: (page) => set({ currentPage: page }),
|
||||
setPage: (page) =>
|
||||
set(() => ({
|
||||
currentPage: page,
|
||||
})),
|
||||
|
||||
fetchVODs: async () => {
|
||||
const { filters, currentPage, pageSize } = get();
|
||||
set({ loading: true, error: null });
|
||||
|
||||
try {
|
||||
const params = new URLSearchParams({
|
||||
page: currentPage.toString(),
|
||||
page_size: pageSize.toString(),
|
||||
...Object.fromEntries(
|
||||
Object.entries(filters).filter(([_, value]) =>
|
||||
value !== null && value !== '' && value !== 'all'
|
||||
)
|
||||
)
|
||||
});
|
||||
const state = get();
|
||||
const params = new URLSearchParams();
|
||||
|
||||
const response = await API.request(`${host}/api/vod/vods/?${params}`);
|
||||
params.append('page', state.currentPage);
|
||||
params.append('page_size', state.pageSize);
|
||||
|
||||
if (state.filters.search) {
|
||||
params.append('search', state.filters.search);
|
||||
}
|
||||
|
||||
if (state.filters.category) {
|
||||
params.append('category', state.filters.category);
|
||||
}
|
||||
|
||||
if (state.filters.type === 'movies') {
|
||||
params.append('type', 'movie');
|
||||
}
|
||||
|
||||
const response = await api.getVODs(params);
|
||||
|
||||
// Handle both paginated and non-paginated responses
|
||||
const results = response.results || response;
|
||||
const count = response.count || results.length;
|
||||
|
||||
set({
|
||||
vods: response.results || response,
|
||||
totalCount: response.count || response.length || 0,
|
||||
loading: false
|
||||
vods: results.reduce((acc, vod) => {
|
||||
acc[vod.id] = vod;
|
||||
return acc;
|
||||
}, {}),
|
||||
totalCount: count,
|
||||
loading: false,
|
||||
});
|
||||
} catch (error) {
|
||||
set({ error: error.message, loading: false });
|
||||
console.error('Failed to fetch VODs:', error);
|
||||
set({ error: 'Failed to load VODs.', loading: false });
|
||||
}
|
||||
},
|
||||
|
||||
fetchSeries: async () => {
|
||||
const { filters, currentPage, pageSize } = get();
|
||||
set({ loading: true, error: null });
|
||||
|
||||
try {
|
||||
const params = new URLSearchParams({
|
||||
page: currentPage.toString(),
|
||||
page_size: pageSize.toString(),
|
||||
search: filters.search || ''
|
||||
});
|
||||
const state = get();
|
||||
const params = new URLSearchParams();
|
||||
|
||||
const response = await API.request(`${host}/api/vod/series/?${params}`);
|
||||
params.append('page', state.currentPage);
|
||||
params.append('page_size', state.pageSize);
|
||||
|
||||
if (state.filters.search) {
|
||||
params.append('search', state.filters.search);
|
||||
}
|
||||
|
||||
if (state.filters.category) {
|
||||
params.append('category', state.filters.category);
|
||||
}
|
||||
|
||||
const response = await api.getVODSeries(params);
|
||||
|
||||
// Handle both paginated and non-paginated responses
|
||||
const results = response.results || response;
|
||||
const count = response.count || results.length;
|
||||
|
||||
set({
|
||||
series: response.results || response,
|
||||
totalCount: response.count || response.length || 0,
|
||||
loading: false
|
||||
series: results.reduce((acc, series) => {
|
||||
acc[series.id] = series;
|
||||
return acc;
|
||||
}, {}),
|
||||
totalCount: count,
|
||||
loading: false,
|
||||
});
|
||||
} catch (error) {
|
||||
set({ error: error.message, loading: false });
|
||||
}
|
||||
},
|
||||
|
||||
fetchCategories: async () => {
|
||||
set({ loading: true, error: null });
|
||||
|
||||
try {
|
||||
const response = await API.request(`${host}/api/vod/categories/`);
|
||||
set({
|
||||
categories: response.results || response,
|
||||
loading: false
|
||||
});
|
||||
} catch (error) {
|
||||
set({ error: error.message, loading: false });
|
||||
console.error('Failed to fetch series:', error);
|
||||
set({ error: 'Failed to load series.', loading: false });
|
||||
}
|
||||
},
|
||||
|
||||
fetchSeriesEpisodes: async (seriesId) => {
|
||||
set({ loading: true, error: null });
|
||||
|
||||
try {
|
||||
const response = await API.request(`${host}/api/vod/series/${seriesId}/episodes/`);
|
||||
set({
|
||||
vods: response.results || response,
|
||||
totalCount: response.count || response.length || 0,
|
||||
loading: false
|
||||
});
|
||||
const response = await api.getSeriesEpisodes(seriesId);
|
||||
|
||||
set((state) => ({
|
||||
vods: {
|
||||
...state.vods,
|
||||
...response.reduce((acc, episode) => {
|
||||
acc[episode.id] = episode;
|
||||
return acc;
|
||||
}, {}),
|
||||
},
|
||||
loading: false,
|
||||
}));
|
||||
} catch (error) {
|
||||
set({ error: error.message, loading: false });
|
||||
console.error('Failed to fetch series episodes:', error);
|
||||
set({ error: 'Failed to load episodes.', loading: false });
|
||||
}
|
||||
},
|
||||
|
||||
// Clear data
|
||||
clearVODs: () => set({ vods: {}, totalCount: 0 }),
|
||||
clearSeries: () => set({ series: {} }),
|
||||
clearFilters: () => set({
|
||||
filters: {
|
||||
type: 'all',
|
||||
category: '',
|
||||
search: '',
|
||||
year: null,
|
||||
seriesId: null
|
||||
},
|
||||
currentPage: 1
|
||||
})
|
||||
fetchCategories: async () => {
|
||||
try {
|
||||
const response = await api.getVODCategories();
|
||||
// Handle both array and paginated responses
|
||||
const results = response.results || response;
|
||||
|
||||
set({
|
||||
categories: results.reduce((acc, category) => {
|
||||
acc[category.id] = category;
|
||||
return acc;
|
||||
}, {}),
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch VOD categories:', error);
|
||||
set({ error: 'Failed to load categories.' });
|
||||
}
|
||||
},
|
||||
|
||||
addVOD: (vod) =>
|
||||
set((state) => ({
|
||||
vods: { ...state.vods, [vod.id]: vod },
|
||||
})),
|
||||
|
||||
updateVOD: (vod) =>
|
||||
set((state) => ({
|
||||
vods: { ...state.vods, [vod.id]: vod },
|
||||
})),
|
||||
|
||||
removeVOD: (vodId) =>
|
||||
set((state) => {
|
||||
const updatedVODs = { ...state.vods };
|
||||
delete updatedVODs[vodId];
|
||||
return { vods: updatedVODs };
|
||||
}),
|
||||
|
||||
addSeries: (series) =>
|
||||
set((state) => ({
|
||||
series: { ...state.series, [series.id]: series },
|
||||
})),
|
||||
|
||||
updateSeries: (series) =>
|
||||
set((state) => ({
|
||||
series: { ...state.series, [series.id]: series },
|
||||
})),
|
||||
|
||||
removeSeries: (seriesId) =>
|
||||
set((state) => {
|
||||
const updatedSeries = { ...state.series };
|
||||
delete updatedSeries[seriesId];
|
||||
return { series: updatedSeries };
|
||||
}),
|
||||
}));
|
||||
|
||||
export default useVODStore;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue