diora-web/podcasts/management/commands/refresh_feeds.py
mrwnslz 176771a407
All checks were successful
Build and push Docker image / build (push) Successful in 19s
Test / test (push) Successful in 2m0s
Podcasts: Position in der Warteschlange einstellbar; Feeds nur noch auf dem Server holen (SW v51)
Warteschlange
- PodcastSettings: wohin neue Folgen kommen, getrennt für Hinzufügen von
  Hand (auch beim Abspielen einer Folge außerhalb der Warteschlange) und
  für automatisch eingereihte neue Folgen: ans Ende, an den Anfang oder
  nach die laufende Folge. Voreinstellung wie bisher (Hand: Ende,
  automatisch: Anfang). GET/POST /podcasts/settings/.
- queue/add nimmt auch mehrere Folgen (episode_ids), eine Position
  (where) und die laufende Folge (current_episode_id); ohne Angabe gilt
  die zuletzt angehörte, nicht fertige Folge als laufende.
- Positionen werden lückenlos neu durchnummeriert.

Feeds
- POST /podcasts/feeds/refresh-all/ aktualisiert alle Feeds des Nutzers
  auf dem Server: Downloads parallel, jede Feed-Adresse nur einmal (auch
  über Nutzer hinweg), mit Timeout; kürzlich aktualisierte werden
  übersprungen. Der stündliche Cron-Job nutzt dasselbe.
- GET /podcasts/state/ liefert Abos, Warteschlange, Inbox und
  Einstellungen in einer Antwort (für die Apps).
- Web: „↻ All“ ist eine Anfrage statt einer pro Feed; die stündliche
  Schleife im Browser lädt nur noch die Listen neu, statt jeden Feed
  selbst anzustoßen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 07:26:16 +02:00

31 lines
1 KiB
Python

import sys
from django.core.management.base import BaseCommand
from podcasts.models import PodcastFeed
from podcasts.views import _refresh_feeds
class Command(BaseCommand):
help = 'Refresh podcast feeds (fetch new episodes from RSS)'
def add_arguments(self, parser):
parser.add_argument('--feed-id', type=int, help='Refresh only this feed ID')
parser.add_argument('--limit', type=int, default=0, help='Max number of feeds to refresh')
def handle(self, *args, **options):
qs = PodcastFeed.objects.all().order_by('last_refreshed_at')
if options['feed_id']:
qs = qs.filter(pk=options['feed_id'])
if options['limit']:
qs = qs[: options['limit']]
if not qs.exists():
self.stdout.write('No feeds to refresh.')
return
# Parallel downloads, one per distinct feed URL (see _refresh_feeds).
refreshed, failed, new = _refresh_feeds(qs)
self.stdout.write(f'{refreshed} feeds refreshed, {failed} failed, +{new} episodes')