mirror of
https://github.com/Dispatcharr/Dispatcharr.git
synced 2026-07-28 20:41:19 +00:00
fix(epg): address second round of reviewer feedback
- Fix NameError in sd_lineups_search: add dispatcharr_version import - Fix DELETE handler: persist changesRemaining from SD response to custom_properties - Fix lockout reset time: calculate next midnight UTC (00:00Z) instead of rolling now+24h, matching SD's documented reset behavior - Remove redundant explicit index from SDProgramMD5: unique_together already creates this index in Postgres
This commit is contained in:
parent
6f316977ad
commit
d8c0850fd8
3 changed files with 35 additions and 10 deletions
|
|
@ -188,17 +188,22 @@ class EPGSourceViewSet(viewsets.ModelViewSet):
|
|||
|
||||
def _save_sd_lockout(self, source):
|
||||
"""
|
||||
Persist a hard lockout to EPGSource model fields when SD returns
|
||||
4100 MAX_LINEUP_CHANGES_REACHED. Lockout clears automatically at next
|
||||
midnight UTC per SD's documented reset schedule.
|
||||
Persist a hard lockout to EPGSource custom_properties when SD returns
|
||||
4100 MAX_LINEUP_CHANGES_REACHED. SD lineup change counters reset at
|
||||
00:00Z (midnight UTC) per SD's documented behavior — error 4100 states
|
||||
"lineup changes for today" and all SD rate counters reset at midnight UTC.
|
||||
Lockout clears automatically when the next midnight UTC passes.
|
||||
"""
|
||||
from django.utils import timezone
|
||||
from datetime import datetime, timedelta, timezone as dt_timezone
|
||||
|
||||
now = timezone.now()
|
||||
# SD resets on a 24-hour rolling window from when the limit was hit.
|
||||
# We use 24 hours from now rather than next midnight UTC to be safe.
|
||||
reset_at = now + timedelta(hours=24)
|
||||
# Calculate next midnight UTC — SD resets at 00:00Z not on a rolling window
|
||||
tomorrow = (now + timedelta(days=1)).replace(
|
||||
hour=0, minute=0, second=0, microsecond=0,
|
||||
tzinfo=dt_timezone.utc
|
||||
)
|
||||
reset_at = tomorrow
|
||||
|
||||
cp = source.custom_properties or {}
|
||||
cp['sd_changes_remaining'] = 0
|
||||
|
|
@ -357,9 +362,14 @@ class EPGSourceViewSet(viewsets.ModelViewSet):
|
|||
"changes_remaining": self._get_sd_changes_remaining(source),
|
||||
})
|
||||
resp.raise_for_status()
|
||||
sd_data = resp.json()
|
||||
# SD returns changesRemaining on deletes — persist it
|
||||
changes_remaining = sd_data.get('changesRemaining')
|
||||
if changes_remaining is not None:
|
||||
self._save_sd_changes_remaining(source, changes_remaining)
|
||||
logger.info(f"SD lineup deleted for source {source.id}: {lineup_id}")
|
||||
return Response({
|
||||
**resp.json(),
|
||||
**sd_data,
|
||||
"changes_remaining": self._get_sd_changes_remaining(source),
|
||||
})
|
||||
except http_requests.exceptions.RequestException as e:
|
||||
|
|
@ -377,6 +387,7 @@ class EPGSourceViewSet(viewsets.ModelViewSet):
|
|||
"""
|
||||
import requests as http_requests
|
||||
from apps.epg.tasks import SD_BASE_URL
|
||||
from version import __version__ as dispatcharr_version
|
||||
|
||||
source = self.get_object()
|
||||
if source.source_type != 'schedules_direct':
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
# Generated by Django 6.0.4 on 2026-05-19 23:46
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('epg', '0023_schedules_direct'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveIndex(
|
||||
model_name='sdprogrammd5',
|
||||
name='epg_sdprogr_epg_sou_222ce1_idx',
|
||||
),
|
||||
]
|
||||
|
|
@ -208,9 +208,6 @@ class SDProgramMD5(models.Model):
|
|||
|
||||
class Meta:
|
||||
unique_together = ('epg_source', 'program_id')
|
||||
indexes = [
|
||||
models.Index(fields=['epg_source', 'program_id']),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return f"SDProgramMD5: {self.program_id} ({self.epg_source.name})"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue