Compare commits
4 commits
d7c64fdeae
...
b81e912075
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b81e912075 | ||
|
|
82fbb9193e | ||
|
|
9c1b2583c7 | ||
|
|
00000d94fc |
12 changed files with 5775 additions and 6081 deletions
8760
EPG/TV.xml
8760
EPG/TV.xml
File diff suppressed because one or more lines are too long
1468
M3U8/TV.m3u8
1468
M3U8/TV.m3u8
File diff suppressed because it is too large
Load diff
1468
M3U8/events.m3u8
1468
M3U8/events.m3u8
File diff suppressed because it is too large
Load diff
|
|
@ -60,7 +60,7 @@ async def get_events(
|
||||||
|
|
||||||
events = []
|
events = []
|
||||||
|
|
||||||
for info in api_data["days"]:
|
for info in api_data.get("days", []):
|
||||||
day = Time.from_str(info["day_et"])
|
day = Time.from_str(info["day_et"])
|
||||||
|
|
||||||
if now.date() != day.date():
|
if now.date() != day.date():
|
||||||
|
|
|
||||||
|
|
@ -55,13 +55,13 @@ async def get_events(
|
||||||
start_dt = now.delta(minutes=-30)
|
start_dt = now.delta(minutes=-30)
|
||||||
end_dt = now.delta(minutes=30)
|
end_dt = now.delta(minutes=30)
|
||||||
|
|
||||||
for stream_group in api_data["streams"]:
|
for stream_group in api_data.get("streams", []):
|
||||||
sport = stream_group["category"]
|
sport = stream_group["category"]
|
||||||
|
|
||||||
if sport == "24/7 Streams":
|
if sport == "24/7 Streams":
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for event in stream_group["streams"]:
|
for event in stream_group.get("streams", []):
|
||||||
name = event.get("name")
|
name = event.get("name")
|
||||||
start_ts = event.get("starts_at")
|
start_ts = event.get("starts_at")
|
||||||
logo = event.get("poster")
|
logo = event.get("poster")
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ CACHE_FILE = Cache("roxie.json", exp=10_800)
|
||||||
|
|
||||||
HTML_CACHE = Cache("roxie-html.json", exp=19_800)
|
HTML_CACHE = Cache("roxie-html.json", exp=19_800)
|
||||||
|
|
||||||
MIRRORS = ["https://roxiestreams.live", "https://roxiestreams.cc"]
|
BASE_URL = "https://roxiestreams.live"
|
||||||
|
|
||||||
|
|
||||||
async def process_event(
|
async def process_event(
|
||||||
|
|
@ -143,15 +143,10 @@ async def scrape(client: httpx.AsyncClient) -> None:
|
||||||
|
|
||||||
log.info(f"Loaded {cached_count} event(s) from cache")
|
log.info(f"Loaded {cached_count} event(s) from cache")
|
||||||
|
|
||||||
if not (base_url := await network.get_base(MIRRORS)):
|
log.info(f'Scraping from "{BASE_URL}"')
|
||||||
log.warning("No working Roxie mirrors")
|
|
||||||
CACHE_FILE.write(cached_urls)
|
|
||||||
return
|
|
||||||
|
|
||||||
log.info(f'Scraping from "{base_url}"')
|
|
||||||
|
|
||||||
sport_urls = {
|
sport_urls = {
|
||||||
sport: urljoin(base_url, sport.lower())
|
sport: urljoin(BASE_URL, sport.lower())
|
||||||
for sport in ["Soccer", "MLB", "NBA", "NFL", "Fighting", "Motorsports"]
|
for sport in ["Soccer", "MLB", "NBA", "NFL", "Fighting", "Motorsports"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -188,7 +183,7 @@ async def scrape(client: httpx.AsyncClient) -> None:
|
||||||
entry = {
|
entry = {
|
||||||
"url": url,
|
"url": url,
|
||||||
"logo": logo,
|
"logo": logo,
|
||||||
"base": base_url,
|
"base": BASE_URL,
|
||||||
"timestamp": ts,
|
"timestamp": ts,
|
||||||
"id": tvg_id or "Live.Event.us",
|
"id": tvg_id or "Live.Event.us",
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@ async def scrape(client: httpx.AsyncClient) -> None:
|
||||||
log.info(f"Loaded {cached_count} event(s) from cache")
|
log.info(f"Loaded {cached_count} event(s) from cache")
|
||||||
|
|
||||||
if not (base_url := await network.get_base(MIRRORS)):
|
if not (base_url := await network.get_base(MIRRORS)):
|
||||||
log.warning("No working StreamEast mirrors")
|
log.warning("No working Streameast mirrors")
|
||||||
CACHE_FILE.write(cached_urls)
|
CACHE_FILE.write(cached_urls)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ async def get_events(
|
||||||
start_dt = now.delta(hours=-1)
|
start_dt = now.delta(hours=-1)
|
||||||
end_dt = now.delta(minutes=10)
|
end_dt = now.delta(minutes=10)
|
||||||
|
|
||||||
for category, streams in api_data["streams"].items():
|
for category, streams in api_data.get("streams", {}).items():
|
||||||
if not streams:
|
if not streams:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ API_FILE = Cache("strmd-api.json", exp=28_800)
|
||||||
MIRRORS = ["https://streamed.pk", "https://streami.su", "https://streamed.st"]
|
MIRRORS = ["https://streamed.pk", "https://streami.su", "https://streamed.st"]
|
||||||
|
|
||||||
|
|
||||||
def validate_category(s: str) -> str:
|
def fix_sport(s: str) -> str:
|
||||||
if "-" in s:
|
if "-" in s:
|
||||||
return " ".join(i.capitalize() for i in s.split("-"))
|
return " ".join(i.capitalize() for i in s.split("-"))
|
||||||
|
|
||||||
|
|
@ -138,9 +138,7 @@ async def get_events(
|
||||||
pattern = re.compile(r"[\n\r]+|\s{2,}")
|
pattern = re.compile(r"[\n\r]+|\s{2,}")
|
||||||
|
|
||||||
for event in api_data:
|
for event in api_data:
|
||||||
category = event["category"]
|
if (category := event.get("category")) == "other":
|
||||||
|
|
||||||
if category == "other":
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if not (ts := event["date"]):
|
if not (ts := event["date"]):
|
||||||
|
|
@ -153,7 +151,7 @@ async def get_events(
|
||||||
if not start_dt <= event_dt <= end_dt:
|
if not start_dt <= event_dt <= end_dt:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
sport = validate_category(category)
|
sport = fix_sport(category)
|
||||||
|
|
||||||
parts = pattern.split(event["title"].strip())
|
parts = pattern.split(event["title"].strip())
|
||||||
name = " | ".join(p.strip() for p in parts if p.strip())
|
name = " | ".join(p.strip() for p in parts if p.strip())
|
||||||
|
|
@ -198,7 +196,7 @@ async def scrape(client: httpx.AsyncClient) -> None:
|
||||||
log.info(f"Loaded {cached_count} event(s) from cache")
|
log.info(f"Loaded {cached_count} event(s) from cache")
|
||||||
|
|
||||||
if not (base_url := await network.get_base(MIRRORS)):
|
if not (base_url := await network.get_base(MIRRORS)):
|
||||||
log.warning("No working PPV mirrors")
|
log.warning("No working STRMD mirrors")
|
||||||
CACHE_FILE.write(cached_urls)
|
CACHE_FILE.write(cached_urls)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ CACHE_FILE = Cache("volo.json", exp=10_800)
|
||||||
|
|
||||||
HTML_CACHE = Cache("volo-html.json", exp=86_400)
|
HTML_CACHE = Cache("volo-html.json", exp=86_400)
|
||||||
|
|
||||||
BASE_URL = "http://volokit2.com/sport/"
|
BASE_URL = "http://volokit2.com"
|
||||||
|
|
||||||
valid_sports = {
|
valid_sports = {
|
||||||
"boxing": "Boxing",
|
"boxing": "Boxing",
|
||||||
|
|
@ -131,15 +131,26 @@ async def refresh_html_cache(
|
||||||
events = {}
|
events = {}
|
||||||
|
|
||||||
for card in soup.css("#events .table .vevent.theevent"):
|
for card in soup.css("#events .table .vevent.theevent"):
|
||||||
name = card.css_first(".teamtd.event").text(strip=True)
|
|
||||||
time = card.css_first(".time").text(strip=True)
|
|
||||||
|
|
||||||
if not (href := card.css_first("a").attributes.get("href")):
|
if not (href := card.css_first("a").attributes.get("href")):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
name_node = card.css_first(".teamtd.event")
|
||||||
|
time_node = card.css_first(".time").text(strip=True)
|
||||||
|
|
||||||
|
if not (name_node and time_node):
|
||||||
|
continue
|
||||||
|
|
||||||
|
name = name_node.text(strip=True)
|
||||||
|
time = time_node.text(strip=True)
|
||||||
|
|
||||||
event_sport = valid_sports[sport]
|
event_sport = valid_sports[sport]
|
||||||
event_name = fix_event(name)
|
event_name = fix_event(name)
|
||||||
event_dt = Time.from_only_time(time, now.date(), "UTC")
|
|
||||||
|
event_dt = Time.from_only_time(
|
||||||
|
time,
|
||||||
|
now.date(),
|
||||||
|
timezone="UTC",
|
||||||
|
)
|
||||||
|
|
||||||
key = f"[{event_sport}] {event_name} (VOLO)"
|
key = f"[{event_sport}] {event_name} (VOLO)"
|
||||||
|
|
||||||
|
|
@ -204,9 +215,7 @@ async def scrape(client: httpx.AsyncClient) -> None:
|
||||||
|
|
||||||
log.info(f'Scraping from "{BASE_URL}"')
|
log.info(f'Scraping from "{BASE_URL}"')
|
||||||
|
|
||||||
sport_urls = {
|
sport_urls = {sport: urljoin(BASE_URL, f"sport/{sport}") for sport in valid_sports}
|
||||||
sport: urljoin(BASE_URL, sport.lower()) for sport in valid_sports.keys()
|
|
||||||
}
|
|
||||||
|
|
||||||
events = await get_events(
|
events = await get_events(
|
||||||
client,
|
client,
|
||||||
|
|
@ -244,7 +253,7 @@ async def scrape(client: httpx.AsyncClient) -> None:
|
||||||
entry = {
|
entry = {
|
||||||
"url": url,
|
"url": url,
|
||||||
"logo": logo,
|
"logo": logo,
|
||||||
"base": "http://volokit2.com",
|
"base": BASE_URL,
|
||||||
"timestamp": ts,
|
"timestamp": ts,
|
||||||
"id": tvg_id or "Live.Event.us",
|
"id": tvg_id or "Live.Event.us",
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -177,9 +177,12 @@ async def get_events(
|
||||||
pattern = re.compile(r"\-+|\(")
|
pattern = re.compile(r"\-+|\(")
|
||||||
|
|
||||||
for event in api_data:
|
for event in api_data:
|
||||||
match_id = event["matchId"]
|
match_id = event.get("matchId")
|
||||||
name = event["title"]
|
name = event.get("title")
|
||||||
league = event["league"]
|
league = event.get("league")
|
||||||
|
|
||||||
|
if not (match_id and name and league):
|
||||||
|
continue
|
||||||
|
|
||||||
if not (ts := event.get("ts")):
|
if not (ts := event.get("ts")):
|
||||||
continue
|
continue
|
||||||
|
|
@ -222,7 +225,7 @@ async def scrape(client: httpx.AsyncClient) -> None:
|
||||||
log.info(f"Loaded {cached_count} event(s) from cache")
|
log.info(f"Loaded {cached_count} event(s) from cache")
|
||||||
|
|
||||||
if not (base_url := await network.get_base(MIRRORS)):
|
if not (base_url := await network.get_base(MIRRORS)):
|
||||||
log.warning("No working WatchFooty mirrors")
|
log.warning("No working Watch Footy mirrors")
|
||||||
CACHE_FILE.write(cached_urls)
|
CACHE_FILE.write(cached_urls)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
||||||
89
readme.md
89
readme.md
|
|
@ -1,11 +1,92 @@
|
||||||
## Base Log @ 2025-11-15 03:27 UTC
|
## Base Log @ 2025-11-15 08:42 UTC
|
||||||
|
|
||||||
### ✅ Working Streams: 146<br>❌ Dead Streams: 2
|
### ✅ Working Streams: 65<br>❌ Dead Streams: 83
|
||||||
|
|
||||||
| Channel | Error (Code) | Link |
|
| Channel | Error (Code) | Link |
|
||||||
| ------- | ------------ | ---- |
|
| ------- | ------------ | ---- |
|
||||||
| FDSN Detroit | HTTP Error (403) | `http://nocable.cc:8080/91161088/91161088/20936` |
|
| ACC Network | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/9273` |
|
||||||
| FDSN Florida | HTTP Error (403) | `http://nocable.cc:8080/91161088/91161088/46794` |
|
| AMC | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/18925` |
|
||||||
|
| Altitude Sports | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/79545` |
|
||||||
|
| BBC America | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/20194` |
|
||||||
|
| BBC World News | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/139752` |
|
||||||
|
| Big Ten Network | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/9828` |
|
||||||
|
| Bloomberg TV | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/15158` |
|
||||||
|
| Boomerang | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/14741` |
|
||||||
|
| Bounce TV | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/48323` |
|
||||||
|
| CBS Sports Network | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/10454` |
|
||||||
|
| CBS | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/120749` |
|
||||||
|
| CW | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/120893` |
|
||||||
|
| Cartoon Network | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/46708` |
|
||||||
|
| Comedy Central | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/7466` |
|
||||||
|
| Comet TV | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/125831` |
|
||||||
|
| Court TV | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/21092` |
|
||||||
|
| Cozi TV | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/11868` |
|
||||||
|
| Discovery Channel | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/46720` |
|
||||||
|
| Discovery Family Channel | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/10538` |
|
||||||
|
| Disney XD | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/75621` |
|
||||||
|
| Disney | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/2206` |
|
||||||
|
| ESPN News | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/17707` |
|
||||||
|
| ESPN U | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/10255` |
|
||||||
|
| ESPN | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/14197` |
|
||||||
|
| ESPN2 | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/2210` |
|
||||||
|
| FDSN Detroit | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/20936` |
|
||||||
|
| FDSN Florida | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/46794` |
|
||||||
|
| FDSN Midwest | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/66795` |
|
||||||
|
| FDSN North | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/58827` |
|
||||||
|
| FDSN Ohio | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/17752` |
|
||||||
|
| FDSN Oklahoma | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/20934` |
|
||||||
|
| FDSN SoCal | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/221151` |
|
||||||
|
| FDSN Southeast | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/81111` |
|
||||||
|
| FDSN Southwest | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/21843` |
|
||||||
|
| FDSN Sun | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/104917` |
|
||||||
|
| FDSN West | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/20932` |
|
||||||
|
| FDSN Wisconsin | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/78599` |
|
||||||
|
| FX | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/46690` |
|
||||||
|
| FXX | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/46699` |
|
||||||
|
| Food Network | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/7323` |
|
||||||
|
| Fox News | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/1818` |
|
||||||
|
| Fox Sports 1 | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/1846` |
|
||||||
|
| Fox Sports 2 | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/1847` |
|
||||||
|
| Fox | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/121595` |
|
||||||
|
| Freeform TV | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/13370` |
|
||||||
|
| Game Show Network | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/120633` |
|
||||||
|
| HBO | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/46713` |
|
||||||
|
| History Channel | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/15017` |
|
||||||
|
| ION TV | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/9297` |
|
||||||
|
| MSG | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/21090` |
|
||||||
|
| Marquee Sports Network | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/13379` |
|
||||||
|
| MotorTrend TV | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/10399` |
|
||||||
|
| NBC Sports Bay Area | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/9900` |
|
||||||
|
| NBC Sports Boston | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/20939` |
|
||||||
|
| NBC Sports California | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/20940` |
|
||||||
|
| NBC Sports Philadelphia | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/20943` |
|
||||||
|
| NESN | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/31637` |
|
||||||
|
| NFL Network | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/159117` |
|
||||||
|
| NFL RedZone | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/208830` |
|
||||||
|
| NewsNation | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/161450` |
|
||||||
|
| Nickelodeon | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/38` |
|
||||||
|
| Nicktoons | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/36` |
|
||||||
|
| Reelz Channel | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/10526` |
|
||||||
|
| Root Sports | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/85232` |
|
||||||
|
| SEC Network | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/17608` |
|
||||||
|
| Space City Home Network | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/213668` |
|
||||||
|
| Spectrum SportsNet LA Dodgers | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/31636` |
|
||||||
|
| Spectrum SportsNet Lakers | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/20946` |
|
||||||
|
| SportsNet New York | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/20938` |
|
||||||
|
| SportsNet Pittsburgh | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/108178` |
|
||||||
|
| Sportsnet 360 | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/57299` |
|
||||||
|
| Sportsnet East | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/57298` |
|
||||||
|
| Sportsnet One | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/10247` |
|
||||||
|
| Sportsnet Ontario | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/11649` |
|
||||||
|
| Starz | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/9299` |
|
||||||
|
| Syfy | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/46685` |
|
||||||
|
| TLC | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/12734` |
|
||||||
|
| TSN1 | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/57292` |
|
||||||
|
| The Weather Channel | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/18926` |
|
||||||
|
| USA East | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/10252` |
|
||||||
|
| Vice TV | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/46697` |
|
||||||
|
| Willow Cricket | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/41979` |
|
||||||
|
| getTV | HTTP Error (404) | `http://nocable.cc:8080/91161088/91161088/18366` |
|
||||||
---
|
---
|
||||||
#### Base Channels URL
|
#### Base Channels URL
|
||||||
```
|
```
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue