Compare commits

..

No commits in common. "41bf21c3628d716e941c7cfdc1df512846beb8b2" and "b9b5681a28dce278062fb308eb098bd13d1db494" have entirely different histories.

8 changed files with 86602 additions and 88495 deletions

167880
EPG/TV.xml

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -64,7 +64,7 @@ async def main() -> None:
asyncio.create_task(roxie.scrape()),
asyncio.create_task(shark.scrape()),
asyncio.create_task(sport9.scrape()),
# asyncio.create_task(streambtw.scrape()),
asyncio.create_task(streambtw.scrape()),
asyncio.create_task(streamcenter.scrape()),
asyncio.create_task(streamfree.scrape()),
asyncio.create_task(streamhub.scrape()),

View file

@ -18,7 +18,7 @@ API_FILE = Cache(f"{TAG.lower()}-api.json", exp=28_800)
MIRRORS = [
"https://streami.su",
# "https://streamed.st",
"https://streamed.st",
"https://streamed.pk",
]

View file

@ -1,6 +1,6 @@
import re
from functools import partial
from urllib.parse import urljoin, urlparse
from urllib.parse import urljoin
from selectolax.parser import HTMLParser
@ -26,9 +26,7 @@ MIRRORS = [
]
def fix_txt(s: str) -> str:
s = " ".join(s.split())
def fix_league(s: str) -> str:
return s.upper() if s.islower() else s
@ -36,9 +34,9 @@ async def process_event(href: str, url_num: int) -> tuple[str | None, str | None
valid_m3u8 = re.compile(r'var\s+(\w+)\s*=\s*"([^"]*)"', re.IGNORECASE)
for x, mirror in enumerate(MIRRORS, start=1):
base: str = mirror["base"]
base = mirror["base"]
hex_decode: bool = mirror["hex_decode"]
hex_decode = mirror["hex_decode"]
url = urljoin(base, href)
@ -63,10 +61,11 @@ async def process_event(href: str, url_num: int) -> tuple[str | None, str | None
log.warning(f"M{x} | URL {url_num}) No Clappr source found.")
continue
raw: str = match[2]
raw = match[2]
try:
m3u8_url = bytes.fromhex(raw).decode("utf-8") if hex_decode else raw
except Exception as e:
log.warning(f"M{x} | URL {url_num}) Decoding failed: {e}")
continue
@ -76,7 +75,10 @@ async def process_event(href: str, url_num: int) -> tuple[str | None, str | None
return m3u8_url, iframe_src
log.warning(f"M{x} | URL {url_num}) No M3U8 found")
else:
log.warning(f"M{x} | URL {url_num}) No M3U8 found")
return None, None
return None, None
@ -91,42 +93,41 @@ async def get_events(url: str, cached_keys: list[str]) -> list[dict[str, str]]:
sport = "Live Event"
for node in soup.css("a"):
if not node.attributes.get("class"):
continue
for box in soup.css(".div-main-box"):
for node in box.iter():
if not (node_class := node.attributes.get("class")):
continue
if (parent := node.parent) and "my-1" in parent.attributes.get("class", ""):
if span := node.css_first("span"):
sport = span.text(strip=True)
if "my-1" in node_class:
if span := node.css_first("span"):
sport = span.text(strip=True)
sport = fix_txt(sport)
if node.tag == "a" and "nav-link2" in node_class:
if not (time_node := node.css_first(".col-3")):
continue
if not (teams := [t.text(strip=True) for t in node.css(".col-7 .col-12")]):
continue
if time_node.text(strip=True) != "MatchStarted":
continue
if not (href := node.attributes.get("href")):
continue
if not (href := node.attributes.get("href")) or href.startswith("http"):
continue
href = urlparse(href).path if href.startswith("http") else href
sport = fix_league(sport)
if not (time_node := node.css_first(".col-3 span")):
continue
teams = [t.text(strip=True) for t in node.css(".col-7 .col-12")]
if time_node.text(strip=True) != "MatchStarted":
continue
event_name = " vs ".join(teams)
event_name = fix_txt(" vs ".join(teams))
if f"[{sport}] {event_name} ({TAG})" in cached_keys:
continue
if f"[{sport}] {event_name} ({TAG})" in cached_keys:
continue
events.append(
{
"sport": sport,
"event": event_name,
"href": href,
}
)
events.append(
{
"sport": sport,
"event": event_name,
"href": href,
}
)
return events

View file

@ -216,7 +216,6 @@
"CHAMPIONSHIP": {
"logo": "https://a.espncdn.com/combiner/i?img=/i/leaguelogos/soccer/500/24.png",
"names": [
"ENGLAND CHAMPIONSHIP",
"ENGLISH CHAMPIONSHIP",
"ENGLISH FOOTBALL LEAGUE CHAMPIONSHIP",
"ENGLISH LEAGUE CHAMPIONSHIP",
@ -325,7 +324,6 @@
"logo": "https://a.espncdn.com/combiner/i?img=/i/leaguelogos/soccer/500/25.png",
"names": [
"ENGLISH FOOTBALL LEAGUE ONE",
"ENGLISH LEAGUE ONE",
"LEAGUE ONE",
"SKY BET LEAGUE ONE"
]
@ -336,7 +334,6 @@
"logo": "https://a.espncdn.com/combiner/i?img=/i/leaguelogos/soccer/500/26.png",
"names": [
"ENGLISH FOOTBALL LEAGUE TWO",
"ENGLISH LEAGUE TWO",
"LEAGUE TWO",
"SKY BET LEAGUE TWO"
]
@ -683,7 +680,7 @@
{
"UEFA CHAMPIONS LEAGUE": {
"logo": "https://a.espncdn.com/combiner/i?img=/i/leaguelogos/soccer/500/2.png",
"names": ["CHAMPIONS LEAGUE", "EUROPE UEFA CHAMPIONS LEAGUE", "UCL"]
"names": ["CHAMPIONS LEAGUE", "UCL"]
}
},
{

View file

@ -1,13 +1,10 @@
## Base Log @ 2026-01-20 22:40 UTC
## Base Log @ 2026-01-19 20:43 UTC
### ✅ Working Streams: 141<br>❌ Dead Streams: 4
### ✅ Working Streams: 144<br>❌ Dead Streams: 1
| Channel | Error (Code) | Link |
| ------- | ------------ | ---- |
| ESPN | HTTP Error (404) | `http://41.205.93.154/ESPN/index.m3u8` |
| FDSN Florida | HTTP Error (403) | `http://mytvstream.net:8080/live/A1Jay5/362586/46794.m3u8` |
| NBC Sports Bay Area | Unknown status (302) | `http://hardcoremedia.xyz:80/NW3Vk7xXwW/8375773282/257216` |
| Premier Sports 2 | HTTP Error (502) | `http://hardcoremedia.xyz:80/NW3Vk7xXwW/8375773282/117038` |
| Premier Sports 2 | Unknown status (302) | `http://hardcoremedia.xyz:80/NW3Vk7xXwW/8375773282/117038` |
---
#### Base Channels URL
```