mirror of
https://github.com/Dispatcharr/Dispatcharr.git
synced 2026-07-17 16:50:53 +00:00
proxy SD country list fetch through backend to fix CORS failure
This commit is contained in:
parent
d3ecefb7d6
commit
887a177581
4 changed files with 45 additions and 13 deletions
|
|
@ -53,7 +53,7 @@ class EPGSourceViewSet(viewsets.ModelViewSet):
|
|||
try:
|
||||
return [perm() for perm in permission_classes_by_action[self.action]]
|
||||
except KeyError:
|
||||
if self.action in ('sd_lineups', 'sd_lineups_search'):
|
||||
if self.action in ('sd_lineups', 'sd_lineups_search', 'sd_countries'):
|
||||
if self.request.method == 'GET':
|
||||
return [IsStandardUser()]
|
||||
return [IsAdmin()]
|
||||
|
|
@ -390,6 +390,31 @@ class EPGSourceViewSet(viewsets.ModelViewSet):
|
|||
status=status.HTTP_502_BAD_GATEWAY
|
||||
)
|
||||
|
||||
@action(detail=True, methods=["get"], url_path="sd-countries")
|
||||
def sd_countries(self, request, pk=None):
|
||||
"""Proxy /available/countries from the SD API to avoid browser CORS restrictions."""
|
||||
import requests as http_requests
|
||||
from apps.epg.tasks import SD_BASE_URL
|
||||
|
||||
source = self.get_object()
|
||||
if source.source_type != 'schedules_direct':
|
||||
return Response(
|
||||
{"error": "This action is only available for Schedules Direct sources."},
|
||||
status=status.HTTP_400_BAD_REQUEST,
|
||||
)
|
||||
try:
|
||||
resp = http_requests.get(
|
||||
f"{SD_BASE_URL}/available/countries",
|
||||
timeout=15,
|
||||
)
|
||||
resp.raise_for_status()
|
||||
return Response(resp.json())
|
||||
except http_requests.exceptions.RequestException as e:
|
||||
return Response(
|
||||
{"error": f"Failed to fetch countries: {str(e)}"},
|
||||
status=status.HTTP_502_BAD_GATEWAY,
|
||||
)
|
||||
|
||||
@action(detail=True, methods=["post"], url_path="sd-lineups/search")
|
||||
def sd_lineups_search(self, request, pk=None):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -3889,6 +3889,14 @@ export default class API {
|
|||
}
|
||||
}
|
||||
|
||||
static async getSDCountries(sourceId) {
|
||||
try {
|
||||
return await request(`${host}/api/epg/sources/${sourceId}/sd-countries/`);
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static async getSDLineups(sourceId) {
|
||||
try {
|
||||
const response = await request(
|
||||
|
|
|
|||
|
|
@ -325,18 +325,16 @@ const SDLineupManager = ({ sourceId }) => {
|
|||
useEffect(() => {
|
||||
if (sourceId) {
|
||||
fetchActiveLineups();
|
||||
// Fetch country list from SD API per their recommendation to not hardcode
|
||||
fetch('https://json.schedulesdirect.org/20141201/available/countries')
|
||||
.then((r) => r.json())
|
||||
.then((data) => {
|
||||
const all = Object.values(data).flat();
|
||||
const mapped = all
|
||||
.filter((c) => c.shortName && c.fullName)
|
||||
.map((c) => ({ value: c.shortName, label: c.fullName }))
|
||||
.sort((a, b) => a.label.localeCompare(b.label));
|
||||
if (mapped.length > 0) setCountries(mapped);
|
||||
})
|
||||
.catch(() => {}); // fallback list remains if fetch fails
|
||||
// Fetch country list via backend proxy to avoid browser CORS restrictions
|
||||
API.getSDCountries(sourceId).then((data) => {
|
||||
if (!data) return;
|
||||
const all = Object.values(data).flat();
|
||||
const mapped = all
|
||||
.filter((c) => c.shortName && c.fullName)
|
||||
.map((c) => ({ value: c.shortName, label: c.fullName }))
|
||||
.sort((a, b) => a.label.localeCompare(b.label));
|
||||
if (mapped.length > 0) setCountries(mapped);
|
||||
});
|
||||
}
|
||||
}, [sourceId, fetchActiveLineups]);
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ global.fetch = vi.fn().mockResolvedValue({
|
|||
|
||||
vi.mock('../../../api.js', () => ({
|
||||
default: {
|
||||
getSDCountries: vi.fn().mockResolvedValue({}),
|
||||
getSDLineups: vi.fn().mockResolvedValue([]),
|
||||
addSDLineup: vi.fn().mockResolvedValue({ success: true }),
|
||||
deleteSDLineup: vi.fn().mockResolvedValue({ success: true }),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue