From bd43ee4c3f124606eec831092a9a04f67f261198 Mon Sep 17 00:00:00 2001 From: Mohamed Zumair Date: Thu, 29 Aug 2024 10:05:39 +0530 Subject: [PATCH] Bugfixes (#272) * Kodi: handle connection errors in fetch data * feat: Update scraper URLs and fix streamed.su live sport event * use only url for cache validation in live stream validation * Handle debrid service downtime error & tracker fetch error * handle review --- kodi/dev-requirements.txt | 2 +- kodi/plugin.video.mediafusion/lib/utils.py | 16 ++++++++++++- mediafusion_scrapy/spiders/dlhd.py | 6 +++-- mediafusion_scrapy/spiders/streamed.py | 28 ++++++++++------------ streaming_providers/debrid_client.py | 5 ++++ utils/torrent.py | 2 +- utils/validation_helper.py | 3 ++- 7 files changed, 40 insertions(+), 22 deletions(-) diff --git a/kodi/dev-requirements.txt b/kodi/dev-requirements.txt index ca1a6bd..550987b 100644 --- a/kodi/dev-requirements.txt +++ b/kodi/dev-requirements.txt @@ -1 +1 @@ -pydevd-pycharm~=241.18034.82 +pydevd-pycharm diff --git a/kodi/plugin.video.mediafusion/lib/utils.py b/kodi/plugin.video.mediafusion/lib/utils.py index 7bcfe6d..199026a 100644 --- a/kodi/plugin.video.mediafusion/lib/utils.py +++ b/kodi/plugin.video.mediafusion/lib/utils.py @@ -64,6 +64,16 @@ def fetch_data(url, force_refresh=False): if "no-store" in cache_control or "no-cache" in cache_control: remove_cache(response.url) return response.json() + except requests.ConnectionError as e: + xbmc.log(f"Connection failed: {e}", xbmc.LOGERROR) + xbmcgui.Dialog().notification( + "MediaFusion", "Connection failed", xbmcgui.NOTIFICATION_ERROR + ) + except requests.Timeout as e: + xbmc.log(f"Request timed out: {e}", xbmc.LOGERROR) + xbmcgui.Dialog().notification( + "MediaFusion", "Request timed out", xbmcgui.NOTIFICATION_ERROR + ) except requests.RequestException as e: if e.response is None: xbmc.log(f"Request failed: {e}", xbmc.LOGERROR) @@ -87,7 +97,11 @@ def fetch_data(url, force_refresh=False): xbmcgui.Dialog().notification( "MediaFusion", "Request failed", xbmcgui.NOTIFICATION_ERROR ) - return None + except Exception as e: + xbmc.log(f"Failed to fetch data: {e}", xbmc.LOGERROR) + xbmcgui.Dialog().notification( + "MediaFusion", "Failed to fetch data", xbmcgui.NOTIFICATION_ERROR + ) def build_url(action, **params): diff --git a/mediafusion_scrapy/spiders/dlhd.py b/mediafusion_scrapy/spiders/dlhd.py index a40bee9..3fe4d3a 100644 --- a/mediafusion_scrapy/spiders/dlhd.py +++ b/mediafusion_scrapy/spiders/dlhd.py @@ -61,7 +61,7 @@ class DaddyLiveHDSpider(scrapy.Spider): } m3u8_base_url = "https://webhdrunns.mizhls.ru/lb/premium{}/index.m3u8" - referer = "https://qqwebplay.xyz/" + referer = "https://cookiewebplay.xyz/" def __init__(self, *args, **kwargs): super(DaddyLiveHDSpider, self).__init__(*args, **kwargs) @@ -97,7 +97,9 @@ class DaddyLiveHDSpider(scrapy.Spider): # Convert to UNIX timestamp event_start_timestamp = int(aware_datetime.timestamp()) if event_start_timestamp != 0: - event_start_time = datetime.fromtimestamp(event_start_timestamp).strftime("%I:%M%p GMT") + event_start_time = datetime.fromtimestamp( + event_start_timestamp + ).strftime("%I:%M%p GMT") description = f'{event["event"]} - {event_start_time}' else: description = event["event"] diff --git a/mediafusion_scrapy/spiders/streamed.py b/mediafusion_scrapy/spiders/streamed.py index 791a46d..9eaaf22 100644 --- a/mediafusion_scrapy/spiders/streamed.py +++ b/mediafusion_scrapy/spiders/streamed.py @@ -28,9 +28,6 @@ class StreamedSpider(scrapy.Spider): } m3u8_base_url = "https://rr.vipstreams.in/alpha/js" - sub_domains = { - "rr.": "Main Server", - } mediafusion_referer = "https://mediafusion.addon/" custom_settings = { @@ -112,16 +109,15 @@ class StreamedSpider(scrapy.Spider): stream_quality = link.xpath(".//h2/text()").get().strip() language = link.xpath(".//div[last()]/text()").get().strip() - for sub_domain, sub_domain_name in self.sub_domains.items(): - m3u8_url = f"{self.m3u8_base_url}{stream_url.replace('/watch', '').replace('/alpha', '')}/playlist.m3u8" - item = response.meta["item"].copy() - item.update( - { - "stream_name": f"{stream_name} - šŸ“” {sub_domain_name}\nšŸ“ŗ {stream_quality} - 🌐 {language}", - "stream_url": m3u8_url, - "referer": self.mediafusion_referer, - "description": description, - "event_start_timestamp": event_start_timestamp, - } - ) - yield item + m3u8_url = f"{self.m3u8_base_url}{stream_url.replace('/watch', '').replace('/alpha', '')}/playlist.m3u8" + item = response.meta["item"].copy() + item.update( + { + "stream_name": f"{stream_name}\nšŸ“ŗ {stream_quality} - 🌐 {language}", + "stream_url": m3u8_url, + "referer": self.mediafusion_referer, + "description": description, + "event_start_timestamp": event_start_timestamp, + } + ) + yield item diff --git a/streaming_providers/debrid_client.py b/streaming_providers/debrid_client.py index 1cd1c35..bb017b3 100644 --- a/streaming_providers/debrid_client.py +++ b/streaming_providers/debrid_client.py @@ -55,6 +55,11 @@ class DebridClient: try: response.raise_for_status() except RequestException as error: + if error.response.status_code in [502, 503, 504]: + raise ProviderException( + "Debrid service is down.", "debrid_service_down_error.mp4" + ) from error + if is_expected_to_fail: return self._handle_service_specific_errors(error) diff --git a/utils/torrent.py b/utils/torrent.py index d5a7eca..b6750b5 100644 --- a/utils/torrent.py +++ b/utils/torrent.py @@ -175,7 +175,7 @@ async def init_best_trackers(): ) else: logging.error(f"Failed to load trackers: {response.status_code}") - except httpx.ConnectTimeout as e: + except (httpx.ConnectTimeout, Exception) as e: logging.error(f"Failed to load trackers: {e}") diff --git a/utils/validation_helper.py b/utils/validation_helper.py index 226d04c..a372a08 100644 --- a/utils/validation_helper.py +++ b/utils/validation_helper.py @@ -1,6 +1,7 @@ import asyncio import json import logging +from urllib import parse from urllib.parse import urlparse import aiohttp @@ -58,7 +59,7 @@ async def validate_m3u8_url( async def validate_m3u8_url_with_cache(redis: Redis, url: str, behaviour_hint: dict): - cache_key = f"m3u8_url:{url}" + cache_key = f"m3u8_url:{parse.urlparse(url).netloc}" cache_data = await redis.get(cache_key) if cache_data: return json.loads(cache_data)