Compare commits

..

No commits in common. "b6abb9371fc0549416eb0c00f6fcfa323aa6e307" and "17c574615d11f620d342c75fb3d49885fb38ba50" have entirely different histories.

23 changed files with 34756 additions and 39243 deletions

File diff suppressed because it is too large Load diff

68895
M3U8/TV.xml

File diff suppressed because one or more lines are too long

View file

@ -58,7 +58,7 @@ http://41.205.93.154/BRAVO/index.m3u8
https://buzzrota-web.amagi.tv/playlist.m3u8 https://buzzrota-web.amagi.tv/playlist.m3u8
#EXTINF:-1 tvg-chno="20" tvg-id="CSPAN.us2" tvg-name="C-SPAN" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s10161_dark_360w_270h.png" group-title="TV",C-SPAN #EXTINF:-1 tvg-chno="20" tvg-id="CSPAN.us2" tvg-name="C-SPAN" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s10161_dark_360w_270h.png" group-title="TV",C-SPAN
http://mytvstream.net:8080/live/30550113/30550113/136589.m3u8 http://mytvstream.net:8080/live/bn80NG/909467/136589.m3u8
#EXTINF:-1 tvg-chno="21" tvg-id="Cartoon.Network.HD.us2" tvg-name="Cartoon Network" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s12131_dark_360w_270h.png" group-title="TV",Cartoon Network #EXTINF:-1 tvg-chno="21" tvg-id="Cartoon.Network.HD.us2" tvg-name="Cartoon Network" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s12131_dark_360w_270h.png" group-title="TV",Cartoon Network
http://23.237.104.106:8080/USA_CARTOON_NETWORK/index.m3u8 http://23.237.104.106:8080/USA_CARTOON_NETWORK/index.m3u8
@ -127,7 +127,7 @@ http://hardcoremedia.xyz/live/rabdsbmz/3731346838/129866.ts
http://hardcoremedia.xyz/live/rabdsbmz/3731346838/129867.ts http://hardcoremedia.xyz/live/rabdsbmz/3731346838/129867.ts
#EXTINF:-1 tvg-chno="43" tvg-id="Disney.Channel.HD.us2" tvg-name="Disney" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s10171_dark_360w_270h.png" group-title="TV",Disney Channel #EXTINF:-1 tvg-chno="43" tvg-id="Disney.Channel.HD.us2" tvg-name="Disney" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s10171_dark_360w_270h.png" group-title="TV",Disney Channel
http://89.105.221.127/Disney/index.m3u8?token=test http://hardcoremedia.xyz/live/rabdsbmz/3731346838/257087.ts
#EXTINF:-1 tvg-chno="44" tvg-id="Disney.XD.HD.us2" tvg-name="Disney XD" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s18279_dark_360w_270h.png" group-title="TV",Disney XD #EXTINF:-1 tvg-chno="44" tvg-id="Disney.XD.HD.us2" tvg-name="Disney XD" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s18279_dark_360w_270h.png" group-title="TV",Disney XD
http://23.237.104.106:8080/USA_DISNEY_XD/index.m3u8 http://23.237.104.106:8080/USA_DISNEY_XD/index.m3u8
@ -148,40 +148,40 @@ http://23.237.104.106:8080/USA_ESPNU/index.m3u8
http://snowbank.houseinventer.com/6501/index.m3u8?token=M1lDdWljYkdyZGFhZzVxeGc2Mkt5OGJicWNxd2xheDkzWWVieEt5b3lZVERxNEduaVp1UnBxU2VlWmF0ZnRlRGxaMm1zNStDbnJOOXFZMlhtcStybmc9PQ== http://snowbank.houseinventer.com/6501/index.m3u8?token=M1lDdWljYkdyZGFhZzVxeGc2Mkt5OGJicWNxd2xheDkzWWVieEt5b3lZVERxNEduaVp1UnBxU2VlWmF0ZnRlRGxaMm1zNStDbnJOOXFZMlhtcStybmc9PQ==
#EXTINF:-1 tvg-chno="50" tvg-id="FanDuel.Sports.Network.Detroit.24/7.HDTV.us" tvg-name="FDSN Detroit" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s54286_dark_360w_270h.png" group-title="TV",FDSN Detroit #EXTINF:-1 tvg-chno="50" tvg-id="FanDuel.Sports.Network.Detroit.24/7.HDTV.us" tvg-name="FDSN Detroit" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s54286_dark_360w_270h.png" group-title="TV",FDSN Detroit
http://mytvstream.net:8080/live/30550113/30550113/20930.m3u8 http://mytvstream.net:8080/live/bn80NG/909467/20930.m3u8
#EXTINF:-1 tvg-chno="51" tvg-id="FanDuel.Sports.Network.Florida.HDTV.(Out.of.Market).us" tvg-name="FDSN Florida" tvg-logo="https://i.gyazo.com/fad701fbaaafe161b13b23ed9b50179b.png" group-title="TV",FDSN Florida #EXTINF:-1 tvg-chno="51" tvg-id="FanDuel.Sports.Network.Florida.HDTV.(Out.of.Market).us" tvg-name="FDSN Florida" tvg-logo="https://i.gyazo.com/fad701fbaaafe161b13b23ed9b50179b.png" group-title="TV",FDSN Florida
http://mytvstream.net:8080/live/30550113/30550113/46794.m3u8 http://mytvstream.net:8080/live/bn80NG/909467/46794.m3u8
#EXTINF:-1 tvg-chno="52" tvg-id="FanDuel.Sports.Network.Midwest.24/7.HDTV.us" tvg-name="FDSN Midwest" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s11058_dark_360w_270h.png" group-title="TV",FDSN Midwest #EXTINF:-1 tvg-chno="52" tvg-id="FanDuel.Sports.Network.Midwest.24/7.HDTV.us" tvg-name="FDSN Midwest" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s11058_dark_360w_270h.png" group-title="TV",FDSN Midwest
http://mytvstream.net:8080/live/30550113/30550113/66795.m3u8 http://mytvstream.net:8080/live/bn80NG/909467/66795.m3u8
#EXTINF:-1 tvg-chno="53" tvg-id="FanDuel.Sports.Network.North.HDTV.us" tvg-name="FDSN North" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s10977_dark_360w_270h.png" group-title="TV",FDSN North #EXTINF:-1 tvg-chno="53" tvg-id="FanDuel.Sports.Network.North.HDTV.us" tvg-name="FDSN North" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s10977_dark_360w_270h.png" group-title="TV",FDSN North
http://mytvstream.net:8080/live/30550113/30550113/58827.m3u8 http://mytvstream.net:8080/live/bn80NG/909467/58827.m3u8
#EXTINF:-1 tvg-chno="54" tvg-id="FanDuel.Sports.Network.Ohio.(Cleveland).HDTV.us" tvg-name="FDSN Ohio" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s49691_dark_360w_270h.png" group-title="TV",FDSN Ohio #EXTINF:-1 tvg-chno="54" tvg-id="FanDuel.Sports.Network.Ohio.(Cleveland).HDTV.us" tvg-name="FDSN Ohio" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s49691_dark_360w_270h.png" group-title="TV",FDSN Ohio
http://mytvstream.net:8080/live/30550113/30550113/17752.m3u8 http://mytvstream.net:8080/live/bn80NG/909467/17752.m3u8
#EXTINF:-1 tvg-chno="55" tvg-id="FanDuel.Sports.Network.Oklahoma.24/7.HDTV.(Tulsa).us" tvg-name="FDSN Oklahoma" tvg-logo="https://i.gyazo.com/80ad6fd142cd67f06eef58d9ce5aa72b.png" group-title="TV",FDSN Oklahoma #EXTINF:-1 tvg-chno="55" tvg-id="FanDuel.Sports.Network.Oklahoma.24/7.HDTV.(Tulsa).us" tvg-name="FDSN Oklahoma" tvg-logo="https://i.gyazo.com/80ad6fd142cd67f06eef58d9ce5aa72b.png" group-title="TV",FDSN Oklahoma
http://mytvstream.net:8080/live/30550113/30550113/20934.m3u8 http://mytvstream.net:8080/live/bn80NG/909467/20934.m3u8
#EXTINF:-1 tvg-chno="56" tvg-id="FanDuel.Sports.Network.SoCal.HDTV.us" tvg-name="FDSN SoCal" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s16743_dark_360w_270h.png" group-title="TV",FDSN SoCal #EXTINF:-1 tvg-chno="56" tvg-id="FanDuel.Sports.Network.SoCal.HDTV.us" tvg-name="FDSN SoCal" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s16743_dark_360w_270h.png" group-title="TV",FDSN SoCal
http://mytvstream.net:8080/live/30550113/30550113/221151.m3u8 http://mytvstream.net:8080/live/bn80NG/909467/221151.m3u8
#EXTINF:-1 tvg-chno="57" tvg-id="FanDuel.Sports.Network.Southeast.HDTV.(Mont./Birm./Dothan/Mobile.AL).us" tvg-name="FDSN Southeast" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s20789_dark_360w_270h.png" group-title="TV",FDSN Southeast #EXTINF:-1 tvg-chno="57" tvg-id="FanDuel.Sports.Network.Southeast.HDTV.(Mont./Birm./Dothan/Mobile.AL).us" tvg-name="FDSN Southeast" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s20789_dark_360w_270h.png" group-title="TV",FDSN Southeast
http://mytvstream.net:8080/live/30550113/30550113/2213.m3u8 http://mytvstream.net:8080/live/bn80NG/909467/2213.m3u8
#EXTINF:-1 tvg-chno="58" tvg-id="FanDuel.Sports.Network.Southwest.HDTV.24/7.(Main).us" tvg-name="FDSN Southwest" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s59629_dark_360w_270h.png" group-title="TV",FDSN Southwest #EXTINF:-1 tvg-chno="58" tvg-id="FanDuel.Sports.Network.Southwest.HDTV.24/7.(Main).us" tvg-name="FDSN Southwest" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s59629_dark_360w_270h.png" group-title="TV",FDSN Southwest
http://mytvstream.net:8080/live/30550113/30550113/21843.m3u8 http://mytvstream.net:8080/live/bn80NG/909467/21843.m3u8
#EXTINF:-1 tvg-chno="59" tvg-id="FanDuel.Sports.Network.Sun.South.24/7.HDTV.(South.Marlins,.Rays,.Heat).us" tvg-name="FDSN Sun" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s61084_dark_360w_270h.png" group-title="TV",FDSN Sun #EXTINF:-1 tvg-chno="59" tvg-id="FanDuel.Sports.Network.Sun.South.24/7.HDTV.(South.Marlins,.Rays,.Heat).us" tvg-name="FDSN Sun" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s61084_dark_360w_270h.png" group-title="TV",FDSN Sun
http://mytvstream.net:8080/live/30550113/30550113/104917.m3u8 http://mytvstream.net:8080/live/bn80NG/909467/104917.m3u8
#EXTINF:-1 tvg-chno="60" tvg-id="FanDuel.Sports.Network.West.HDTV.us" tvg-name="FDSN West" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s59627_dark_360w_270h.png" group-title="TV",FDSN West #EXTINF:-1 tvg-chno="60" tvg-id="FanDuel.Sports.Network.West.HDTV.us" tvg-name="FDSN West" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s59627_dark_360w_270h.png" group-title="TV",FDSN West
http://mytvstream.net:8080/live/30550113/30550113/20932.m3u8 http://mytvstream.net:8080/live/bn80NG/909467/20932.m3u8
#EXTINF:-1 tvg-chno="61" tvg-id="FanDuel.Sports.Network.Wisconsin.24/7.HDTV.us" tvg-name="FDSN Wisconsin" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s16348_dark_360w_270h.png" group-title="TV",FDSN Wisconsin #EXTINF:-1 tvg-chno="61" tvg-id="FanDuel.Sports.Network.Wisconsin.24/7.HDTV.us" tvg-name="FDSN Wisconsin" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s16348_dark_360w_270h.png" group-title="TV",FDSN Wisconsin
http://mytvstream.net:8080/live/30550113/30550113/78599.m3u8 http://mytvstream.net:8080/live/bn80NG/909467/78599.m3u8
#EXTINF:-1 tvg-chno="62" tvg-id="plex.tv.FIFA+.plex" tvg-name="FIFA+ TV" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s136235_dark_360w_270h.png" group-title="TV",FIFA+ TV #EXTINF:-1 tvg-chno="62" tvg-id="plex.tv.FIFA+.plex" tvg-name="FIFA+ TV" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s136235_dark_360w_270h.png" group-title="TV",FIFA+ TV
https://jmp2.uk/stvp-IN270000230 https://jmp2.uk/stvp-IN270000230
@ -253,7 +253,7 @@ http://23.237.104.106:8080/USA_HBO2/index.m3u8
http://23.237.104.106:8080/USA_HBO_COMEDY/index.m3u8 http://23.237.104.106:8080/USA_HBO_COMEDY/index.m3u8
#EXTINF:-1 tvg-chno="85" tvg-id="HBO.Drama.us2" tvg-name="HBO Family" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s34879_dark_360w_270h.png" group-title="TV",HBO Family #EXTINF:-1 tvg-chno="85" tvg-id="HBO.Drama.us2" tvg-name="HBO Family" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s34879_dark_360w_270h.png" group-title="TV",HBO Family
http://mytvstream.net:8080/live/30550113/30550113/17772.m3u8 http://mytvstream.net:8080/live/bn80NG/909467/17772.m3u8
#EXTINF:-1 tvg-chno="86" tvg-id="HBO.Zone.HD.us2" tvg-name="HBO Zone" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s18431_dark_360w_270h.png" group-title="TV",HBO Zone #EXTINF:-1 tvg-chno="86" tvg-id="HBO.Zone.HD.us2" tvg-name="HBO Zone" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s18431_dark_360w_270h.png" group-title="TV",HBO Zone
http://23.237.104.106:8080/USA_HBO_ZONE/index.m3u8 http://23.237.104.106:8080/USA_HBO_ZONE/index.m3u8
@ -307,10 +307,10 @@ http://212.102.60.231/NBA_TV/index.m3u8
http://stream.cammonitorplus.net/1765/index.m3u8?token=MnE3ZWg1YkgxdFdWZlo2c2hLMkltWnJhcFo1OHhxcXVyb2pKazZXaWxZRERxNEduaVp1UnBxU2VlWmF0ZnRlRGxaMm1zNStDbnJOOXFZMlhtcStybmc9PQ== http://stream.cammonitorplus.net/1765/index.m3u8?token=MnE3ZWg1YkgxdFdWZlo2c2hLMkltWnJhcFo1OHhxcXVyb2pKazZXaWxZRERxNEduaVp1UnBxU2VlWmF0ZnRlRGxaMm1zNStDbnJOOXFZMlhtcStybmc9PQ==
#EXTINF:-1 tvg-chno="103" tvg-id="NBC.Sports.Bay.Area.HD.us2" tvg-name="NBC Sports Bay Area" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s63138_dark_360w_270h.png" group-title="TV",NBC Sports Bay Area #EXTINF:-1 tvg-chno="103" tvg-id="NBC.Sports.Bay.Area.HD.us2" tvg-name="NBC Sports Bay Area" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s63138_dark_360w_270h.png" group-title="TV",NBC Sports Bay Area
http://mytvstream.net:8080/live/30550113/30550113/9900.m3u8 http://mytvstream.net:8080/live/bn80NG/909467/9900.m3u8
#EXTINF:-1 tvg-chno="104" tvg-id="NBC.Sports.Boston.HD.us2" tvg-name="NBC Sports Boston" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s49198_dark_360w_270h.png" group-title="TV",NBC Sports Boston #EXTINF:-1 tvg-chno="104" tvg-id="NBC.Sports.Boston.HD.us2" tvg-name="NBC Sports Boston" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s49198_dark_360w_270h.png" group-title="TV",NBC Sports Boston
http://mytvstream.net:8080/live/30550113/30550113/20939.m3u8 http://mytvstream.net:8080/live/bn80NG/909467/20939.m3u8
#EXTINF:-1 tvg-chno="105" tvg-id="NBC.Sports.California.SAT.us2" tvg-name="NBC Sports California" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s45540_dark_360w_270h.png" group-title="TV",NBC Sports California #EXTINF:-1 tvg-chno="105" tvg-id="NBC.Sports.California.SAT.us2" tvg-name="NBC Sports California" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s45540_dark_360w_270h.png" group-title="TV",NBC Sports California
http://hardcoremedia.xyz/live/rabdsbmz/3731346838/136474.ts http://hardcoremedia.xyz/live/rabdsbmz/3731346838/136474.ts

File diff suppressed because it is too large Load diff

View file

@ -80,7 +80,7 @@ async def main() -> None:
asyncio.create_task(fawa.scrape()), asyncio.create_task(fawa.scrape()),
asyncio.create_task(istreameast.scrape()), asyncio.create_task(istreameast.scrape()),
asyncio.create_task(ovogoal.scrape()), asyncio.create_task(ovogoal.scrape()),
# asyncio.create_task(pawa.scrape()), asyncio.create_task(pawa.scrape()),
asyncio.create_task(shark.scrape()), asyncio.create_task(shark.scrape()),
asyncio.create_task(streambtw.scrape()), asyncio.create_task(streambtw.scrape()),
asyncio.create_task(totalsportek.scrape()), asyncio.create_task(totalsportek.scrape()),

View file

@ -19,7 +19,7 @@ BASE_URL = "http://www.fawanews.sc/"
async def process_event(url: str, url_num: int) -> str | None: async def process_event(url: str, url_num: int) -> str | None:
if not (html_data := await network.request(url, log=log)): if not (html_data := await network.request(url, log=log)):
log.warning(f"URL {url_num}) Failed to load url.") log.info(f"URL {url_num}) Failed to load url.")
return return

View file

@ -19,7 +19,7 @@ BASE_URL = "https://istreameast.app"
async def process_event(url: str, url_num: int) -> str | None: async def process_event(url: str, url_num: int) -> str | None:
if not (event_data := await network.request(url, log=log)): if not (event_data := await network.request(url, log=log)):
log.warning(f"URL {url_num}) Failed to load url.") log.info(f"URL {url_num}) Failed to load url.")
return return
@ -36,7 +36,7 @@ async def process_event(url: str, url_num: int) -> str | None:
return return
if not (iframe_src_data := await network.request(iframe_src, log=log)): if not (iframe_src_data := await network.request(iframe_src, log=log)):
log.warning(f"URL {url_num}) Failed to load iframe source.") log.info(f"URL {url_num}) Failed to load iframe source.")
return return

View file

@ -47,6 +47,8 @@ async def process_event(
page: Page, page: Page,
) -> str | None: ) -> str | None:
event_id_pattern = re.compile(r"&c=(\d*)", re.I)
captured: list[str] = [] captured: list[str] = []
got_one = asyncio.Event() got_one = asyncio.Event()
@ -66,10 +68,8 @@ async def process_event(
timeout=10_000, timeout=10_000,
) )
if not resp or resp.status != 200: if resp.status != 200:
log.warning( log.warning(f"URL {url_num}) Status Code: {resp.status}")
f"URL {url_num}) Status Code: {resp.status if resp else 'None'}"
)
return return
try: try:
@ -80,6 +80,11 @@ async def process_event(
log.warning(f"URL {url_num}) No valid sources found.") log.warning(f"URL {url_num}) No valid sources found.")
return return
if (match := event_id_pattern.search(href)) and (
event_id := match[1]
).isalnum():
event_url = f"https://emb.apl392.me/player/live.php?id={event_id}"
else:
event_url = href if href.startswith("http") else f"https:{href}" event_url = href if href.startswith("http") else f"https:{href}"
await page.goto( await page.goto(

View file

@ -20,7 +20,7 @@ async def process_event(url: str, url_num: int) -> tuple[str | None, str | None]
nones = None, None nones = None, None
if not (html_data := await network.request(url, log=log)): if not (html_data := await network.request(url, log=log)):
log.warning(f"URL {url_num}) Failed to load url.") log.info(f"URL {url_num}) Failed to load url.")
return nones return nones
soup = HTMLParser(html_data.content) soup = HTMLParser(html_data.content)

View file

@ -15,12 +15,12 @@ TAG = "PAWA"
CACHE_FILE = Cache(TAG, exp=10_800) CACHE_FILE = Cache(TAG, exp=10_800)
BASE_URL = "https://pawastreams.net/feed/" BASE_URL = "https://pawastreams.net/feed"
async def process_event(url: str, url_num: int) -> str | None: async def process_event(url: str, url_num: int) -> str | None:
if not (event_data := await network.request(url, log=log)): if not (event_data := await network.request(url, log=log)):
log.warning(f"URL {url_num}) Failed to load url.") log.info(f"URL {url_num}) Failed to load url.")
return return
@ -37,7 +37,7 @@ async def process_event(url: str, url_num: int) -> str | None:
return return
if not (iframe_src_data := await network.request(iframe_src, log=log)): if not (iframe_src_data := await network.request(iframe_src, log=log)):
log.warning(f"URL {url_num}) Failed to load iframe source.") log.info(f"URL {url_num}) Failed to load iframe source.")
return return

View file

@ -25,8 +25,8 @@ async def get_api_data(page: Page) -> dict[str, list[dict, str, str]]:
timeout=6_000, timeout=6_000,
) )
if not resp or resp.status != 200: if resp.status != 200:
log.warning(f"{url} Status Code: {resp.status if resp else 'None'}") log.warning(f"{url} Status Code: {resp.status}")
return {} return {}

View file

@ -99,11 +99,8 @@ async def process_event(
timeout=6_000, timeout=6_000,
) )
if not resp or resp.status != 200: if resp.status != 200:
log.warning( log.warning(f"URL {url_num}) Status Code: {resp.status}")
f"URL {url_num}) Status Code: {resp.status if resp else 'None'}"
)
return return
try: try:

View file

@ -20,14 +20,14 @@ BASE_URL = "https://sharkstreams.net"
async def process_event(url: str, url_num: int) -> str | None: async def process_event(url: str, url_num: int) -> str | None:
if not (r := await network.request(url, log=log)): if not (r := await network.request(url, log=log)):
log.warning(f"URL {url_num}) Failed to load url.") log.info(f"URL {url_num}) Failed to load url.")
return return
data: dict[str, list[str]] = r.json() data: dict[str, list[str]] = r.json()
if not (urls := data.get("urls")): if not (urls := data.get("urls")):
log.warning(f"URL {url_num}) No M3U8 found") log.info(f"URL {url_num}) No M3U8 found")
return return
@ -39,6 +39,8 @@ async def process_event(url: str, url_num: int) -> str | None:
async def refresh_html_cache(now_ts: float) -> dict[str, dict[str, str | float]]: async def refresh_html_cache(now_ts: float) -> dict[str, dict[str, str | float]]:
log.info("Refreshing HTML cache")
events = {} events = {}
if not (html_data := await network.request(BASE_URL, log=log)): if not (html_data := await network.request(BASE_URL, log=log)):
@ -90,8 +92,6 @@ async def get_events(cached_keys: list[str]) -> list[dict[str, str]]:
now = Time.clean(Time.now()) now = Time.clean(Time.now())
if not (events := HTML_CACHE.load()): if not (events := HTML_CACHE.load()):
log.info("Refreshing HTML cache")
events = await refresh_html_cache(now.timestamp()) events = await refresh_html_cache(now.timestamp())
HTML_CACHE.write(events) HTML_CACHE.write(events)

View file

@ -31,7 +31,7 @@ async def process_event(url: str, url_num: int) -> str | None:
valid_m3u8 = re.compile(r'var\s+(\w+)\s*=\s*"([^"]*)"', re.I) valid_m3u8 = re.compile(r'var\s+(\w+)\s*=\s*"([^"]*)"', re.I)
if not (match := valid_m3u8.search(html_data.text)): if not (match := valid_m3u8.search(html_data.text)):
log.warning(f"URL {url_num}) No M3U8 found") log.info(f"URL {url_num}) No M3U8 found")
return return
stream_link: str = match[2] stream_link: str = match[2]

View file

@ -46,6 +46,8 @@ def get_event(t1: str, t2: str) -> str:
async def refresh_api_cache(now_ts: float) -> list[dict[str, Any]]: async def refresh_api_cache(now_ts: float) -> list[dict[str, Any]]:
log.info("Refreshing API cache")
tasks = [ tasks = [
network.request( network.request(
urljoin(BASE_URL, f"data/{sport}.json"), urljoin(BASE_URL, f"data/{sport}.json"),
@ -71,8 +73,6 @@ async def get_events(cached_keys: list[str]) -> list[dict[str, str]]:
now = Time.clean(Time.now()) now = Time.clean(Time.now())
if not (api_data := API_FILE.load(per_entry=False, index=-1)): if not (api_data := API_FILE.load(per_entry=False, index=-1)):
log.info("Refreshing API cache")
api_data = await refresh_api_cache(now.timestamp()) api_data = await refresh_api_cache(now.timestamp())
API_FILE.write(api_data) API_FILE.write(api_data)

View file

@ -26,7 +26,7 @@ def fix_txt(s: str) -> str:
async def process_event(url: str, url_num: int) -> str | None: async def process_event(url: str, url_num: int) -> str | None:
if not (event_data := await network.request(url, log=log)): if not (event_data := await network.request(url, log=log)):
log.warning(f"URL {url_num}) Failed to load url.") log.info(f"URL {url_num}) Failed to load url.")
return return
@ -43,7 +43,7 @@ async def process_event(url: str, url_num: int) -> str | None:
return return
if not (iframe_1_src_data := await network.request(iframe_1_src, log=log)): if not (iframe_1_src_data := await network.request(iframe_1_src, log=log)):
log.warning(f"URL {url_num}) Failed to load iframe source.") log.info(f"URL {url_num}) Failed to load iframe source.")
return return
@ -66,7 +66,7 @@ async def process_event(url: str, url_num: int) -> str | None:
headers={"Referer": iframe_1_src}, headers={"Referer": iframe_1_src},
) )
): ):
log.warning(f"URL {url_num}) Failed to load iframe source.") log.info(f"URL {url_num}) Failed to load iframe source.")
return return

View file

@ -18,7 +18,7 @@ BASE_URL = "https://thetvapp.to"
async def process_event(url: str, url_num: int) -> str | None: async def process_event(url: str, url_num: int) -> str | None:
if not (html_data := await network.request(url, log=log)): if not (html_data := await network.request(url, log=log)):
log.warning(f"URL {url_num}) Failed to load url.") log.info(f"URL {url_num}) Failed to load url.")
return return

View file

@ -256,10 +256,8 @@ class Network:
timeout=6_000, timeout=6_000,
) )
if not resp or resp.status != 200: if resp.status != 200:
log.warning( log.warning(f"URL {url_num}) Status Code: {resp.status}")
f"URL {url_num}) Status Code: {resp.status if resp else 'None'}"
)
return return

View file

@ -30,7 +30,7 @@ def fix_event(s: str) -> str:
async def process_event(url: str, url_num: int) -> str | None: async def process_event(url: str, url_num: int) -> str | None:
if not (event_data := await network.request(url, log=log)): if not (event_data := await network.request(url, log=log)):
log.warning(f"URL {url_num}) Failed to load url.") log.info(f"URL {url_num}) Failed to load url.")
return return
@ -53,7 +53,7 @@ async def process_event(url: str, url_num: int) -> str | None:
log=log, log=log,
) )
): ):
log.warning(f"URL {url_num}) Failed to load iframe source.") log.info(f"URL {url_num}) Failed to load iframe source.")
return return

View file

@ -5,7 +5,7 @@ from itertools import chain
from typing import Any from typing import Any
from urllib.parse import urljoin from urllib.parse import urljoin
from playwright.async_api import Browser, Page, Response, TimeoutError from playwright.async_api import Browser, Page, TimeoutError
from .utils import Cache, Time, get_logger, leagues, network from .utils import Cache, Time, get_logger, leagues, network
@ -42,6 +42,8 @@ VALID_SPORTS = [
async def refresh_api_cache(now: Time) -> list[dict[str, Any]]: async def refresh_api_cache(now: Time) -> list[dict[str, Any]]:
log.info("Refreshing API cache")
tasks = [ tasks = [
network.request( network.request(
urljoin(API_URL, "api/v1/matches/all"), urljoin(API_URL, "api/v1/matches/all"),
@ -64,25 +66,16 @@ async def refresh_api_cache(now: Time) -> list[dict[str, Any]]:
return data return data
def sift_xhr(resp: Response, match_id: int) -> bool:
resp_url = resp.url
return (
f"/en/stream/{match_id}/" in resp_url
and "_rsc=" not in resp_url
and resp.status == 200
)
async def process_event( async def process_event(
url: str, url: str,
match_id: int,
url_num: int, url_num: int,
page: Page, page: Page,
) -> tuple[str | None, str | None]: ) -> tuple[str | None, str | None]:
nones = None, None nones = None, None
pattern = re.compile(r"\((\d+)\)")
captured: list[str] = [] captured: list[str] = []
got_one = asyncio.Event() got_one = asyncio.Event()
@ -93,38 +86,54 @@ async def process_event(
got_one=got_one, got_one=got_one,
) )
strm_handler = partial(sift_xhr, match_id=match_id)
page.on("request", handler) page.on("request", handler)
try: try:
try:
async with page.expect_response(strm_handler, timeout=2_500) as strm_resp:
resp = await page.goto( resp = await page.goto(
url, url,
wait_until="domcontentloaded", wait_until="domcontentloaded",
timeout=6_000, timeout=8_000,
) )
if not resp or resp.status != 200: if resp.status != 200:
log.warning( log.warning(f"URL {url_num}) Status Code: {resp.status}")
f"URL {url_num}) Status Code: {resp.status if resp else 'None'}" return
)
await page.wait_for_timeout(2_000)
try:
header = await page.wait_for_selector("text=/Stream Links/i", timeout=4_000)
text = await header.inner_text()
except TimeoutError:
log.warning(f"URL {url_num}) Can't find stream links header.")
return nones return nones
response = await strm_resp.value if not (match := pattern.search(text)) or int(match[1]) == 0:
log.warning(f"URL {url_num}) No available stream links.")
stream_url = response.url return nones
try:
first_available = await page.wait_for_selector(
'a[href*="/stream/"]',
timeout=3_000,
)
except TimeoutError: except TimeoutError:
log.warning(f"URL {url_num}) No available stream links.") log.warning(f"URL {url_num}) No available stream links.")
return nones return nones
if not (href := await first_available.get_attribute("href")):
log.warning(f"URL {url_num}) No available stream links.")
return nones
embed = re.sub( embed = re.sub(
pattern=r"^.*\/stream", pattern=r"^.*\/stream",
repl="https://spiderembed.top/embed", repl="https://spiderembed.top/embed",
string=stream_url, string=href,
) )
await page.goto( await page.goto(
@ -173,8 +182,6 @@ async def get_events(base_url: str, cached_keys: list[str]) -> list[dict[str, st
now = Time.clean(Time.now()) now = Time.clean(Time.now())
if not (api_data := API_FILE.load(per_entry=False, index=-1)): if not (api_data := API_FILE.load(per_entry=False, index=-1)):
log.info("Refreshing API cache")
api_data = await refresh_api_cache(now) api_data = await refresh_api_cache(now)
API_FILE.write(api_data) API_FILE.write(api_data)
@ -219,7 +226,6 @@ async def get_events(base_url: str, cached_keys: list[str]) -> list[dict[str, st
"sport": sport, "sport": sport,
"event": name, "event": name,
"link": urljoin(base_url, f"stream/{match_id}"), "link": urljoin(base_url, f"stream/{match_id}"),
"match-id": match_id,
"logo": logo, "logo": logo,
"timestamp": event_dt.timestamp(), "timestamp": event_dt.timestamp(),
} }
@ -257,7 +263,6 @@ async def scrape(browser: Browser) -> None:
handler = partial( handler = partial(
process_event, process_event,
url=(link := ev["link"]), url=(link := ev["link"]),
match_id=ev["match-id"],
url_num=i, url_num=i,
page=page, page=page,
) )

View file

@ -27,7 +27,7 @@ def fix_event(s: str) -> str:
async def process_event(url: str, url_num: int) -> str | None: async def process_event(url: str, url_num: int) -> str | None:
if not (event_data := await network.request(url, log=log)): if not (event_data := await network.request(url, log=log)):
log.warning(f"URL {url_num}) Failed to load url.") log.info(f"URL {url_num}) Failed to load url.")
return return
@ -50,7 +50,7 @@ async def process_event(url: str, url_num: int) -> str | None:
log=log, log=log,
) )
): ):
log.warning(f"URL {url_num}) Failed to load iframe source.") log.info(f"URL {url_num}) Failed to load iframe source.")
return return

View file

@ -32,7 +32,7 @@ async def process_event(url: str, url_num: int) -> tuple[str | None, str | None]
nones = None, None nones = None, None
if not (html_data := await network.request(url, log=log)): if not (html_data := await network.request(url, log=log)):
log.warning(f"URL {url_num}) Failed to load url.") log.info(f"URL {url_num}) Failed to load url.")
return nones return nones
soup = HTMLParser(html_data.content) soup = HTMLParser(html_data.content)

View file

@ -1,11 +1,10 @@
## Base Log @ 2026-03-04 09:02 UTC ## Base Log @ 2026-03-03 09:07 UTC
### ✅ Working Streams: 159<br>❌ Dead Streams: 2 ### ✅ Working Streams: 160<br>❌ Dead Streams: 1
| Channel | Error (Code) | Link | | Channel | Error (Code) | Link |
| ------- | ------------ | ---- | | ------- | ------------ | ---- |
| Altitude Sports | HTTP Error (403) | `http://hardcoremedia.xyz/live/rabdsbmz/3731346838/141447.ts` | | Golf Channel | HTTP Error (000) | `http://hardcoremedia.xyz/live/rabdsbmz/3731346838/258721.ts` |
| Space City Home Network | HTTP Error (403) | `http://hardcoremedia.xyz/live/rabdsbmz/3731346838/229934.ts` |
--- ---
#### Base Channels URL #### Base Channels URL
``` ```