From 60a3267932f43cd32875528a66cd1d2f74068732 Mon Sep 17 00:00:00 2001 From: Karol Labus Date: Fri, 18 Sep 2026 22:21:03 +0200 Subject: [PATCH] feat: implement caching and redirect endpoints for premium live streams --- core/scrapers/radio357.py | 23 +++++++++++++++++++++++ core/scrapers/rns.py | 31 +++++++++++++++++++++++++++++++ main.py | 13 +++++++++++++ templates/base.html | 4 +++- 4 files changed, 70 insertions(+), 1 deletion(-) diff --git a/core/scrapers/radio357.py b/core/scrapers/radio357.py index 07d2146..6c70bf6 100644 --- a/core/scrapers/radio357.py +++ b/core/scrapers/radio357.py @@ -276,7 +276,30 @@ class Radio357Scraper: self.db.commit() self.logger(f"R357: [{self.requests_made}/{self.hard_limit}] Pomyślnie pobrano {fetched} nowych linków.") + def update_live_stream_url(self): + token = self.get_token() + if not token: + return + + self.logger("R357: Aktualizacja adresu live stream...") + url = "https://stream.radio357.pl/?s=www" + try: + r = requests.get(url, headers={"User-Agent": "Mozilla/5.0"}, cookies={"token": token}, allow_redirects=False, timeout=5) + if r.status_code in (301, 302, 307) and "Location" in r.headers: + target_url = r.headers["Location"] + config_url = self.db.query(Config).filter_by(key="r357_live_url").first() + if not config_url: + self.db.add(Config(key="r357_live_url", value=target_url)) + else: + config_url.value = target_url + self.db.commit() + self.logger(f"R357: Zapisano nowy strumień: {target_url}") + except Exception as e: + self.logger(f"R357 Błąd podczas pobierania streamu premium: {e}") + def run_full_sync(self, specific_program_slug=None): self.sync_episodes(specific_program_slug) self.backfill_urls(specific_program_slug) + if not specific_program_slug: + self.update_live_stream_url() self.logger(f"R357: Koniec. Wysłano zapytania: {self.requests_made}/{self.hard_limit} (w tym backfill ograniczony do {self.backfill_limit}).") diff --git a/core/scrapers/rns.py b/core/scrapers/rns.py index 9475445..e63fe6a 100644 --- a/core/scrapers/rns.py +++ b/core/scrapers/rns.py @@ -501,6 +501,34 @@ class RNScraper: self.db.commit() time.sleep(0.5) + def update_live_stream_url(self): + self.logger("RNŚ: Aktualizacja adresu live stream...") + try: + html = self._get_html(f"{BASE_URL}/") + if html: + soup = BeautifulSoup(html, "html.parser") + target_url = None + for btn in soup.find_all(class_="rns-stream-tile__btn"): + src = btn.get("data-neo-player-src") + parent = btn.parent + if parent and src: + text = parent.get_text(" ", strip=True).lower() + if "256" in text or "wysoka" in text: + target_url = src + break + + if target_url: + if not target_url.startswith("http"): target_url = f"{BASE_URL}/{target_url.lstrip('/')}" + config_url = self.db.query(Config).filter_by(key="rns_live_url").first() + if not config_url: + self.db.add(Config(key="rns_live_url", value=target_url)) + else: + config_url.value = target_url + self.db.commit() + self.logger(f"RNS: Zaktualizowano adres streamu na {target_url}") + except Exception as e: + self.logger(f"RNS: Błąd aktualizacji streamu: {e}") + def run_full_sync(self, specific_program_slug=None): if not self.ensure_auth(): self.logger("RNŚ: Błąd logowania przed startem!") @@ -511,4 +539,7 @@ class RNScraper: if self.requests_made < self.hard_limit: self.phase_2_backfill(specific_program_slug) + if not specific_program_slug: + self.update_live_stream_url() + self.logger(f"RNŚ: Koniec. Wysłano zapytania: {self.requests_made}/{self.hard_limit} (w tym backfill ograniczony do {self.backfill_limit}).") diff --git a/main.py b/main.py index 41c321c..6eddec3 100644 --- a/main.py +++ b/main.py @@ -611,3 +611,16 @@ def podcast_rss(station: str, slug_with_ext: str, request: Request, db: Session if not xml: return Response(status_code=404) return Response(content=xml, media_type="application/xml") + +@app.get("/live/{station}") +def live_stream_redirect(station: str, db: Session = Depends(db_session)): + if station == "radio357": + config_url = db.query(Config).filter_by(key="r357_live_url").first() + target_url = config_url.value if config_url else "https://stream.rcs.revma.com/ye5kghkgcm0uv" + return RedirectResponse(url=target_url) + elif station == "rns": + config_url = db.query(Config).filter_by(key="rns_live_url").first() + target_url = config_url.value if config_url else "https://stream.rcs.revma.com/4md4m0a0fs8uv" + return RedirectResponse(url=target_url) + else: + raise HTTPException(status_code=404, detail="Brak streamu dla podanej stacji") diff --git a/templates/base.html b/templates/base.html index ef1abc3..96688ce 100644 --- a/templates/base.html +++ b/templates/base.html @@ -92,7 +92,9 @@ -
+