Compare commits

..

No commits in common. "00000d9f2b90930f23a0c6b154cf83f2457f3b79" and "5cbfb6888edc63db833f73b49592b9d9cb560da0" have entirely different histories.

14 changed files with 109711 additions and 109074 deletions

File diff suppressed because it is too large Load diff

215644
M3U8/TV.xml

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

View file

@ -72,7 +72,7 @@ async def main() -> None:
asyncio.create_task(streamsgate.scrape(xtrnl_brwsr)), asyncio.create_task(streamsgate.scrape(xtrnl_brwsr)),
asyncio.create_task(totalsportek.scrape(hdl_brwsr)), asyncio.create_task(totalsportek.scrape(hdl_brwsr)),
asyncio.create_task(tvpass.scrape(hdl_brwsr)), asyncio.create_task(tvpass.scrape(hdl_brwsr)),
# asyncio.create_task(webcast.scrape(hdl_brwsr)), asyncio.create_task(webcast.scrape(hdl_brwsr)),
] ]
httpx_tasks = [ httpx_tasks = [

View file

@ -24,7 +24,7 @@ SPORT_ENDPOINTS = {
# "mlb": "MLB", # "mlb": "MLB",
"motorsports": "Racing", "motorsports": "Racing",
"nba": "NBA", "nba": "NBA",
# "nfl": "American Football", "nfl": "American Football",
"nhl": "NHL", "nhl": "NHL",
"soccer": "Soccer", "soccer": "Soccer",
} }

View file

@ -1,7 +1,9 @@
import base64 import base64
import json
import re import re
from functools import partial from functools import partial
from urllib.parse import urljoin
from selectolax.parser import HTMLParser
from .utils import Cache, Time, get_logger, leagues, network from .utils import Cache, Time, get_logger, leagues, network
@ -13,8 +15,6 @@ TAG = "STRMBTW"
CACHE_FILE = Cache(TAG, exp=3_600) CACHE_FILE = Cache(TAG, exp=3_600)
API_FILE = Cache(f"{TAG}-api", exp=28_800)
BASE_URL = "https://hiteasport.info" BASE_URL = "https://hiteasport.info"
@ -32,6 +32,7 @@ async def process_event(url: str, url_num: int) -> str | None:
if not (match := valid_m3u8.search(html_data.text)): if not (match := valid_m3u8.search(html_data.text)):
log.info(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]
@ -45,47 +46,54 @@ async def process_event(url: str, url_num: int) -> str | None:
async def get_events() -> list[dict[str, str]]: async def get_events() -> list[dict[str, str]]:
now = Time.clean(Time.now())
if not (api_data := API_FILE.load(per_entry=False)):
log.info("Refreshing API cache")
api_data = {"timestamp": now.timestamp()}
if r := await network.request(
urljoin(BASE_URL, "public/api.php"),
log=log,
params={"action": "get"},
):
api_data: dict = r.json()
api_data["timestamp"] = now.timestamp()
API_FILE.write(api_data)
events = [] events = []
if last_update := api_data.get("updated_at"): if not (html_data := await network.request(BASE_URL, log=log)):
last_update_dt = Time.from_str(last_update, timezone="UTC")
if last_update_dt.date() != now.date():
return events return events
for info in api_data.get("groups", []): soup = HTMLParser(html_data.content)
if not (sport := info["title"]):
sport = "Live Event"
if items := info.get("items"): script_text = None
for event in items:
event_name: str = event["title"]
link: str = event["url"] for s in soup.css("script"):
t = s.text() or ""
if "const DATA" in t:
script_text = t
break
if not script_text:
return events
if not (
match := re.search(r"const\s+DATA\s*=\s*(\[\s*.*?\s*\]);", script_text, re.S)
):
return events
data_js = match[1].replace("\n ", "").replace("\n ", "")
s1 = re.sub(r"{\s", '{"', data_js)
s2 = re.sub(r':"', '":"', s1)
s3 = re.sub(r":\[", '":[', s2)
s4 = re.sub(r"},\]", "}]", s3)
s5 = re.sub(r'",\s', '","', s4)
data: list[dict[str, str]] = json.loads(s5)
for matches in data:
league = matches["title"]
items: list[dict[str, str]] = matches["items"]
for info in items:
title = info["title"]
url = info["url"]
events.append( events.append(
{ {
"sport": fix_league(sport), "sport": fix_league(league),
"event": event_name, "event": title,
"link": link, "link": url,
} }
) )

View file

@ -19,8 +19,8 @@ BASE_URL = "https://backend.streamcenter.live/api/Parties"
CATEGORIES = { CATEGORIES = {
4: "Basketball", 4: "Basketball",
9: "Football", 9: "Football",
# 13: "Baseball", 13: "Baseball",
# 14: "American Football", 14: "American Football",
15: "Motor Sport", 15: "Motor Sport",
16: "Hockey", 16: "Hockey",
17: "Fight MMA", 17: "Fight MMA",

View file

@ -21,7 +21,7 @@ BASE_URL = "https://streamhub.pro/"
CATEGORIES = { CATEGORIES = {
"Soccer": "sport_68c02a4464a38", "Soccer": "sport_68c02a4464a38",
# "American Football": "sport_68c02a4465113", "American Football": "sport_68c02a4465113",
# "Baseball": "sport_68c02a446582f", # "Baseball": "sport_68c02a446582f",
"Basketball": "sport_68c02a4466011", "Basketball": "sport_68c02a4466011",
"Cricket": "sport_68c02a44669f3", "Cricket": "sport_68c02a44669f3",

View file

@ -22,10 +22,10 @@ BASE_URL = "https://streamingon.org"
SPORT_ENDPOINTS = [ SPORT_ENDPOINTS = [
"soccer", "soccer",
# "nfl", "nfl",
"nba", "nba",
"cfb", "cfb",
# "mlb", "mlb",
"nhl", "nhl",
"ufc", "ufc",
"boxing", "boxing",

View file

@ -101,7 +101,6 @@ class Time(datetime):
"%Y-%m-%d %H:%M %p", "%Y-%m-%d %H:%M %p",
"%Y-%m-%dT%H:%M:%S", "%Y-%m-%dT%H:%M:%S",
"%Y-%m-%dT%H:%M:%SZ", "%Y-%m-%dT%H:%M:%SZ",
"%Y-%m-%dT%H:%M:%S%z",
"%Y-%m-%dT%H:%M:%S.%fZ", "%Y-%m-%dT%H:%M:%S.%fZ",
"%Y/%m/%d %H:%M", "%Y/%m/%d %H:%M",
"%Y/%m/%d %H:%M:%S", "%Y/%m/%d %H:%M:%S",

View file

@ -28,7 +28,7 @@ BASE_MIRRORS = [
] ]
VALID_SPORTS = [ VALID_SPORTS = [
# "american-football", "american-football",
# "australian-football", # "australian-football",
# "baseball", # "baseball",
"basketball", "basketball",

View file

@ -16,10 +16,7 @@ CACHE_FILE = Cache(TAG, exp=10_800)
HTML_CACHE = Cache(f"{TAG}-html", exp=86_400) HTML_CACHE = Cache(f"{TAG}-html", exp=86_400)
BASE_URLS = { BASE_URLS = {"NFL": "https://nflwebcast.com", "NHL": "https://slapstreams.com"}
# "NFL": "https://nflwebcast.com",
"NHL": "https://slapstreams.com",
}
def fix_event(s: str) -> str: def fix_event(s: str) -> str:

View file

@ -22,7 +22,7 @@ SPORT_ENDPOINTS = [
# "mlb", # "mlb",
"mma", "mma",
"nba", "nba",
# "nfl", "nfl",
"nhl", "nhl",
"soccer", "soccer",
"wwe", "wwe",

View file

@ -1,13 +1,16 @@
## Base Log @ 2026-02-09 04:37 UTC ## Base Log @ 2026-02-08 04:41 UTC
### ✅ Working Streams: 142<br>❌ Dead Streams: 4 ### ✅ Working Streams: 139<br>❌ Dead Streams: 7
| Channel | Error (Code) | Link | | Channel | Error (Code) | Link |
| ------- | ------------ | ---- | | ------- | ------------ | ---- |
| CW | HTTP Error (404) | `https://fl1.moveonjoy.com/CW_ORLANDO/index.m3u8` | | CW | HTTP Error (404) | `https://fl1.moveonjoy.com/CW_ORLANDO/index.m3u8` |
| ESPN | HTTP Error (404) | `http://41.205.93.154/ESPN/index.m3u8` |
| FXX | HTTP Error (404) | `https://fl1.moveonjoy.com/FXX/index.m3u8` | | FXX | HTTP Error (404) | `https://fl1.moveonjoy.com/FXX/index.m3u8` |
| Spectrum SportsNet LA Dodgers | HTTP Error (403) | `http://mytvstream.net:8080/live/bn80NG/909467/31636.m3u8` | | Spectrum SportsNet LA Dodgers | HTTP Error (403) | `http://mytvstream.net:8080/live/bn80NG/909467/31636.m3u8` |
| Sportsnet 360 | HTTP Error (403) | `http://mytvstream.net:8080/live/bn80NG/909467/2219.m3u8` | | Sportsnet 360 | HTTP Error (403) | `http://mytvstream.net:8080/live/bn80NG/909467/2219.m3u8` |
| Sportsnet One | HTTP Error (403) | `http://mytvstream.net:8080/live/bn80NG/909467/57297.m3u8` |
| TSN1 | HTTP Error (403) | `http://mytvstream.net:8080/live/bn80NG/909467/57292.m3u8` |
--- ---
#### Base Channels URL #### Base Channels URL
``` ```