This commit is contained in:
github-actions[bot] 2025-08-17 10:05:09 -04:00
commit 6e1c25caa4
16 changed files with 80378 additions and 0 deletions

48
.github/workflows/epg.yml vendored Normal file
View file

@ -0,0 +1,48 @@
name: fetch epg
on:
schedule:
- cron: "30 2,10,18 * * *"
workflow_dispatch:
jobs:
epg-fetcher:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Cache venv
uses: actions/cache@v3
with:
path: .venv
key: shared-venv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
restore-keys: |
shared-venv-${{ runner.os }}-
- name: Install uv
uses: astral-sh/setup-uv@v6
with:
version: "latest"
enable-cache: true
ignore-nothing-to-cache: true
cache-dependency-glob: "uv.lock"
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version-file: "pyproject.toml"
- name: Fetch EPG
run: uv run EPG/fetch.py
- name: Push changes
uses: stefanzweifel/git-auto-commit-action@v6
with:
commit_message: "update EPG"
file_pattern: "EPG/TV.xml"
commit_author: "GitHub Actions Bot <actions@github.com>"
commit_user_name: "GitHub Actions Bot"
commit_user_email: "actions@github.com"

27
.github/workflows/health.yml vendored Normal file
View file

@ -0,0 +1,27 @@
name: health check
on:
schedule:
- cron: "0 2,8,14,20 * * *"
workflow_dispatch:
jobs:
health-check:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Run health.sh
run: bash health.sh
- name: Update log
uses: stefanzweifel/git-auto-commit-action@v6
with:
commit_message: "health log"
file_pattern: "readme.md"
commit_author: "GitHub Actions Bot <actions@github.com>"
commit_user_name: "GitHub Actions Bot"
commit_user_email: "actions@github.com"

56
.github/workflows/m3u8.yml vendored Normal file
View file

@ -0,0 +1,56 @@
name: fetch m3u8
on:
schedule:
- cron: "0 * * * *"
workflow_dispatch:
jobs:
m3u8-fetcher:
runs-on: ubuntu-latest
steps:
- name: Check time
run: |
hour=$(TZ=America/New_York date +%-H)
if [ "$hour" -lt 8 ] || [ "$hour" -gt 23 ]; then
exit 78
fi
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Cache venv
uses: actions/cache@v3
with:
path: .venv
key: shared-venv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
restore-keys: |
shared-venv-${{ runner.os }}-
- name: Install uv
uses: astral-sh/setup-uv@v6
with:
version: "latest"
enable-cache: true
ignore-nothing-to-cache: true
cache-dependency-glob: "uv.lock"
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version-file: "pyproject.toml"
- name: Fetch M3U8
run: uv run M3U8/fetch.py
- name: Push changes
uses: stefanzweifel/git-auto-commit-action@v6
with:
commit_message: "update M3U8"
file_pattern: "M3U8/TV.m3u8 M3U8/scrape/tvpass.json"
commit_author: "GitHub Actions Bot <actions@github.com>"
commit_user_name: "GitHub Actions Bot"
commit_user_email: "actions@github.com"

14
.gitignore vendored Normal file
View file

@ -0,0 +1,14 @@
# Python-generated files
__pycache__/
*.py[oc]
build/
dist/
wheels/
*.egg-info
# Virtual environments
.venv
# Misc
.python-version
stuff/

79271
EPG/TV.xml Normal file

File diff suppressed because it is too large Load diff

95
EPG/fetch.py Normal file
View file

@ -0,0 +1,95 @@
#!/usr/bin/env python3
import gzip
from pathlib import Path
from xml.etree import ElementTree as ET
import httpx
epg_file = Path(__file__).parent / "TV.xml"
epg_urls = [
"https://epgshare01.online/epgshare01/epg_ripper_US1.xml.gz",
"https://epgshare01.online/epgshare01/epg_ripper_US_LOCALS2.xml.gz",
"https://epgshare01.online/epgshare01/epg_ripper_FANDUEL1.xml.gz",
"https://epgshare01.online/epgshare01/epg_ripper_CA1.xml.gz",
]
def fetch_tvg_ids() -> dict[str, str]:
try:
r = httpx.get(
"https://spoo.me/mvrlVh",
follow_redirects=True,
timeout=5,
headers={
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 Edg/134.0.0.0"
},
)
r.raise_for_status()
except Exception as e:
raise SystemExit(f"Failed to fetch TVG IDs\n{e}") from e
return r.json()
def fetch_xml(url: str) -> ET.Element:
try:
r = httpx.get(
url,
follow_redirects=True,
timeout=5,
)
r.raise_for_status()
except Exception as e:
raise SystemExit(f'Failed to fetch "{url}"\n{e}') from e
try:
decompressed_data = gzip.decompress(r.content)
return ET.fromstring(decompressed_data)
except Exception as e:
raise SystemExit(f'Failed to decompress and parse XML from "{url}"\n{e}') from e
def main() -> None:
tvg_ids = fetch_tvg_ids()
root = ET.Element("tv")
for url in epg_urls:
epg_data = fetch_xml(url)
for channel in epg_data.findall("channel"):
if (channel_id := channel.get("id")) in tvg_ids:
for icon_tag in channel.findall("icon"):
icon_tag.set("src", tvg_ids[channel_id])
if (url_tag := channel.find("url")) is not None:
channel.remove(url_tag)
root.append(channel)
for program in epg_data.findall("programme"):
tvg_id = program.get("channel")
if tvg_id in tvg_ids:
if (title_text := program.find("title").text) in [
"NHL Hockey",
"Live: NFL Football",
] and (subtitle := program.find("sub-title")) is not None:
program.find("title").text = f"{title_text} {subtitle.text}"
root.append(program)
tree = ET.ElementTree(root)
tree.write(epg_file, encoding="utf-8", xml_declaration=True)
print(f"EPG saved to {epg_file.name}")
if __name__ == "__main__":
main()

24
LICENSE Normal file
View file

@ -0,0 +1,24 @@
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>

227
M3U8/TV.m3u8 Normal file
View file

@ -0,0 +1,227 @@
#EXTM3U url-tvg="https://raw.githubusercontent.com/doms9/iptv/refs/heads/default/EPG/TV.xml"
#EXTINF:-1 tvg-chno="1" tvg-id="ABC.(WABC).New.York,.NY.us" tvg-name="ABC" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s10003_dark_360w_270h.png" group-title="TV",ABC
http://fl1.moveonjoy.com/ABC_EAST/index.m3u8
#EXTINF:-1 tvg-chno="2" tvg-id="ACC.Network.us" tvg-name="ACC Network" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s111871_dark_360w_270h.png" group-title="TV",ACC Network
http://fl3.moveonjoy.com/ACC_NETWORK/index.m3u8
#EXTINF:-1 tvg-chno="3" tvg-id="AMC.-.Eastern.Feed.us" tvg-name="AMC" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s10021_dark_360w_270h.png" group-title="TV",AMC
http://fl5.moveonjoy.com/AMC_NETWORK/index.m3u8
#EXTINF:-1 tvg-chno="4" tvg-id="ASPiRE.TV.us" tvg-name="Aspire" tvg-logo="https://i.gyazo.com/0dec42cc5ef48c489cc10db906dc5b9b.png" group-title="TV",Aspire
http://fl3.moveonjoy.com/Aspire/index.m3u8
#EXTINF:-1 tvg-chno="5" tvg-id="BET.-.Eastern.Feed.us" tvg-name="BET" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s10051_dark_360w_270h.png" group-title="TV",BET
http://fl3.moveonjoy.com/BET_EAST/index.m3u8
#EXTINF:-1 tvg-chno="6" tvg-id="Big.Ten.Network.us" tvg-name="Big Ten Network" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s56783_dark_360w_270h.png" group-title="TV",Big Ten Network
http://fl3.moveonjoy.com/BIG_TEN_NETWORK/index.m3u8
#EXTINF:-1 tvg-chno="7" tvg-id="Boomerang.us" tvg-name="Boomerang" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s21883_dark_360w_270h.png" group-title="TV",Boomerang
http://fl3.moveonjoy.com/BOOMERANG/index.m3u8
#EXTINF:-1 tvg-chno="8" tvg-id="Cartoon.Network.USA.-.Eastern.Feed.us" tvg-name="Cartoon Network" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s12131_dark_360w_270h.png" group-title="TV",Cartoon Network
http://fl3.moveonjoy.com/CARTOON_NETWORK/index.m3u8
#EXTINF:-1 tvg-chno="9" tvg-id="CBS.(WCBS).New.York,.NY.us" tvg-name="CBS" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s10098_dark_360w_270h.png" group-title="TV",CBS
http://fl1.moveonjoy.com/CBSEAST/index.m3u8
#EXTINF:-1 tvg-chno="10" tvg-id="CBS.Sports.Network.USA.us" tvg-name="CBS Sports Network" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s16365_dark_360w_270h.png" group-title="TV",CBS Sports Network
http://fl3.moveonjoy.com/CBS_SPORTS_NETWORK/index.m3u8
#EXTINF:-1 tvg-chno="11" tvg-id="CNBC.USA.us" tvg-name="CNBC" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s10139_dark_360w_270h.png" group-title="TV",CNBC
https://fl5.moveonjoy.com/CNBC/index.m3u8
#EXTINF:-1 tvg-chno="12" tvg-id="CNN.us" tvg-name="CNN" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s58646_dark_360w_270h.png" group-title="TV",CNN
https://turnerlive.warnermediacdn.com/hls/live/586495/cnngo/cnn_slate/VIDEO_0_3564000.m3u8
#EXTINF:-1 tvg-chno="13" tvg-id="Comedy.Central.(US).-.Eastern.Feed.us" tvg-name="Comedy Central" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s10149_dark_360w_270h.png" group-title="TV",Comedy Central
http://fl3.moveonjoy.com/Comedy_Central/index.m3u8
#EXTINF:-1 tvg-chno="14" tvg-id="WPIX.New.York.(SUPERSTATION).us" tvg-name="CW" tvg-logo="https://i.gyazo.com/afd5b481b327d204087dfde6a7741f9d.png" group-title="TV",CW
http://user.scalecdn.co:8080/live/26725074/92867131/93093.m3u8
#EXTINF:-1 tvg-chno="15" tvg-id="Discovery.Channel.(US).-.Eastern.Feed.us" tvg-name="Discovery Channel" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s11150_dark_360w_270h.png" group-title="TV",Discovery Channel
http://fl3.moveonjoy.com/Discovery_Channel/index.m3u8
#EXTINF:-1 tvg-chno="16" tvg-id="Disney.-.Eastern.Feed.us" tvg-name="Disney" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s10171_dark_360w_270h.png" group-title="TV",Disney
http://fl5.moveonjoy.com/DISNEY/index.m3u8
#EXTINF:-1 tvg-chno="17" tvg-id="Disney.XD.USA.-.Eastern.Feed.us" tvg-name="Disney XD" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s18279_dark_360w_270h.png" group-title="TV",Disney XD
http://fl3.moveonjoy.com/DISNEY_XD/index.m3u8
#EXTINF:-1 tvg-chno="18" tvg-id="E!.Entertainment.USA.-.Eastern.Feed.us" tvg-name="E!" tvg-logo="https://i.gyazo.com/f73b80e3eb56cec06df6705d00e2f422.png" group-title="TV",E!
http://fl3.moveonjoy.com/E_ENTERTAINMENT_TELEVISION/index.m3u8
#EXTINF:-1 tvg-chno="19" tvg-id="ESPN.us" tvg-name="ESPN" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s10179_dark_360w_270h.png" group-title="TV",ESPN
http://cord-cutter.net:8080/25464931/30585186/14197
#EXTINF:-1 tvg-chno="20" tvg-id="ESPN.News.us" tvg-name="ESPN News" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s16485_dark_360w_270h.png" group-title="TV",ESPN News
http://fl1.moveonjoy.com/ESPN_NEWS/index.m3u8
#EXTINF:-1 tvg-chno="21" tvg-id="ESPN.U.us" tvg-name="ESPN U" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s45654_dark_360w_270h.png" group-title="TV",ESPN U
http://fl1.moveonjoy.com/ESPN_U/index.m3u8
#EXTINF:-1 tvg-chno="22" tvg-id="ESPN2.us" tvg-name="ESPN2" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s12444_dark_360w_270h.png" group-title="TV",ESPN2
http://fl1.moveonjoy.com/ESPN_2/index.m3u8
#EXTINF:-1 tvg-chno="23" tvg-id="FanDuel.Sports.Network.Detroit.HD.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://cord-cutter.net:8080/25464931/30585186/20936
#EXTINF:-1 tvg-chno="24" tvg-id="FanDuel.Sports.Network.North.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://cord-cutter.net:8080/25464931/30585186/58827
#EXTINF:-1 tvg-chno="25" tvg-id="FanDuel.Sports.Network.Oklahoma.us" tvg-name="FDSN Oklahoma" tvg-logo="https://i.gyazo.com/80ad6fd142cd67f06eef58d9ce5aa72b.png" group-title="TV",FDSN Oklahoma
http://cord-cutter.net:8080/25464931/30585186/20934
#EXTINF:-1 tvg-chno="26" tvg-id="FanDuel.Sports.Network.Southwest.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://cord-cutter.net:8080/25464931/30585186/21843
#EXTINF:-1 tvg-chno="27" tvg-id="FanDuel.Sports.Network.West.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://cord-cutter.net:8080/25464931/30585186/20932
#EXTINF:-1 tvg-chno="28" tvg-id="FOX.(WNYW).New.York,.NY.us" tvg-name="Fox" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s28719_dark_360w_270h.png" group-title="TV",Fox
http://fl1.moveonjoy.com/FOX_EAST/index.m3u8
#EXTINF:-1 tvg-chno="29" tvg-id="Fox.News.us" tvg-name="Fox News" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s16374_dark_360w_270h.png" group-title="TV",Fox News
https://stream.livenewsplay.com:9443/hls/foxnews/foxsd.m3u8
#EXTINF:-1 tvg-chno="30" tvg-id="Fox.Sports.1.us" tvg-name="Fox Sports 1" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s82541_dark_360w_270h.png" group-title="TV",Fox Sports 1
http://23.237.104.106:8080/USA_FS1/index.m3u8
#EXTINF:-1 tvg-chno="31" tvg-id="Fox.Sports.2.us" tvg-name="Fox Sports 2" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s33178_dark_360w_270h.png" group-title="TV",Fox Sports 2
http://23.237.104.106:8080/USA_FS2/index.m3u8
#EXTINF:-1 tvg-chno="32" tvg-id="FUSE.TV.-.Eastern.feed.us" tvg-name="FUSE" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s14929_dark_360w_270h.png" group-title="TV",FUSE
http://fl3.moveonjoy.com/FUSE/index.m3u8
#EXTINF:-1 tvg-chno="33" tvg-id="FX.Networks.East.Coast.us" tvg-name="FX" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s14321_dark_360w_270h.png" group-title="TV",FX
http://fl5.moveonjoy.com/FX/index.m3u8
#EXTINF:-1 tvg-chno="34" tvg-id="FX.Movie.Channel.us" tvg-name="FX Movie Channel" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s70253_dark_360w_270h.png" group-title="TV",FX Movie Channel
http://fl3.moveonjoy.com/FX_MOVIE/index.m3u8
#EXTINF:-1 tvg-chno="35" tvg-id="FXX.USA.-.Eastern.us" tvg-name="FXX" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/united-states/fxx-us.png" group-title="TV",FXX
http://fl3.moveonjoy.com/FXX/index.m3u8
#EXTINF:-1 tvg-chno="36" tvg-id="Game.Show.Network.-.East.us" tvg-name="Game Show Network" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s14909_dark_360w_270h.png" group-title="TV",Game Show Network
http://cord-cutter.net:8080/25464931/30585186/120633
#EXTINF:-1 tvg-chno="37" tvg-id="HBO.-.Eastern.Feed.us" tvg-name="HBO" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s10240_dark_360w_270h.png" group-title="TV",HBO
http://fl3.moveonjoy.com/HBO/index.m3u8
#EXTINF:-1 tvg-chno="38" tvg-id="ION..-.Eastern.Feed.us" tvg-name="ION TV" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s18633_dark_360w_270h.png" group-title="TV",ION TV
http://fl3.moveonjoy.com/ION_TV/index.m3u8
#EXTINF:-1 tvg-chno="39" tvg-id="Marquee.Sports.Network.us" tvg-name="Marquee Sports Network" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s113768_dark_360w_270h.png" group-title="TV",Marquee Sports Network
http://cord-cutter.net:8080/25464931/30585186/13379
#EXTINF:-1 tvg-chno="40" tvg-id="MLB.Network.us" tvg-name="MLB Network" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s62081_dark_360w_270h.png" group-title="TV",MLB Network
http://fl5.moveonjoy.com/MLB_NETWORK/index.m3u8
#EXTINF:-1 tvg-chno="41" tvg-id="MSG.(Madison.Square.Gardens).us" tvg-name="MSG" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s10979_dark_360w_270h.png" group-title="TV",MSG
https://fl3.moveonjoy.com/MSG/index.m3u8
#EXTINF:-1 tvg-chno="42" tvg-id="MSNBC.USA.us" tvg-name="MSNBC" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s16300_dark_360w_270h.png" group-title="TV",MSNBC
https://fl5.moveonjoy.com/MSNBC/index.m3u8
#EXTINF:-1 tvg-chno="43" tvg-id="NBA.TV.USA.us" tvg-name="NBA TV" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s32281_dark_360w_270h.png" group-title="TV",NBA TV
http://fl3.moveonjoy.com/NBA_TV/index.m3u8
#EXTINF:-1 tvg-chno="44" tvg-id="NBC.(WNBC).New.York,.NY.us" tvg-name="NBC" tvg-logo="https://i.gyazo.com/39d42952500205d04e448247b7889256.png" group-title="TV",NBC
http://fl1.moveonjoy.com/NBC_EAST/index.m3u8
#EXTINF:-1 tvg-chno="45" tvg-id="NBC.Sports.Boston.us" tvg-name="NBC Sports Boston" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s49198_dark_360w_270h.png" group-title="TV",NBC Sports Boston
http://cord-cutter.net:8080/25464931/30585186/20939
#EXTINF:-1 tvg-chno="46" tvg-id="NBC.Sports.Philadelphia.HDTV.(NBCSPAHD).us" tvg-name="NBC Sports Philadelphia" tvg-logo="https://i.gyazo.com/c5204722cef60da756f1b994d6d71c28.png" group-title="TV",NBC Sports Philadelphia
http://cord-cutter.net:8080/25464931/30585186/20943
#EXTINF:-1 tvg-chno="47" tvg-id="NFL.Network.us" tvg-name="NFL Network" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/united-states/nfl-network-hz-us.png" group-title="TV",NFL Network
http://fl5.moveonjoy.com/NFL_NETWORK/index.m3u8
#EXTINF:-1 tvg-chno="48" tvg-id="NFL.RedZone.us" tvg-name="NFL RedZone" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/united-states/nfl-red-zone-hz-us.png" group-title="TV",NFL RedZone
http://fl1.moveonjoy.com/NFL_RedZone/index.m3u8
#EXTINF:-1 tvg-chno="49" tvg-id="NHL.Network.USA.us" tvg-name="NHL Network" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s58570_dark_360w_270h.png" group-title="TV",NHL Network
http://fl1.moveonjoy.com/NHL_NETWORK/index.m3u8
#EXTINF:-1 tvg-chno="50" tvg-id="Nickelodeon.USA.-.East.Feed.us" tvg-name="Nickelodeon" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s11006_dark_360w_270h.png" group-title="TV",Nickelodeon
http://cord-cutter.net:8080/25464931/30585186/38
#EXTINF:-1 tvg-chno="51" tvg-id="Nicktoons.-.East.us" tvg-name="Nicktoons" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s30420_dark_360w_270h.png" group-title="TV",Nicktoons
http://fl1.moveonjoy.com/NICKTOONS/index.m3u8
#EXTINF:-1 tvg-chno="52" tvg-id="Root.Sports.Northwest.us" tvg-name="Root Sports" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s11062_dark_360w_270h.png" group-title="TV",Root Sports
http://cord-cutter.net:8080/25464931/30585186/85232
#EXTINF:-1 tvg-chno="53" tvg-id="SEC.Network.us" tvg-name="SEC Network" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s89535_dark_360w_270h.png" group-title="TV",SEC Network
http://fl1.moveonjoy.com/SEC_NETWORK/index.m3u8
#EXTINF:-1 tvg-chno="54" tvg-id="Paramount+.with.Showtime.-.Eastern.Feed.us" tvg-name="Showtime" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/united-states/showtime-us.png" group-title="TV",Showtime
http://fl3.moveonjoy.com/SHOWTIME/index.m3u8
#EXTINF:-1 tvg-chno="55" tvg-id="SNY:.SportsNet.New.York.(Comcast).us" tvg-name="SportsNet New York" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s50038_dark_360w_270h.png" group-title="TV",SportsNet New York
https://fl3.moveonjoy.com/SNY/index.m3u8
#EXTINF:-1 tvg-chno="56" tvg-id="Sportsnet.One.ca" tvg-name="Sportsnet One" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s68859_dark_360w_270h.png" group-title="TV",Sportsnet One
http://cord-cutter.net:8080/25464931/30585186/10247
#EXTINF:-1 tvg-chno="57" tvg-id="SportsNet.Pittsburgh.us" tvg-name="SportsNet Pittsburgh" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s26028_dark_360w_270h.png" group-title="TV",SportsNet Pittsburgh
http://cord-cutter.net:8080/25464931/30585186/108178
#EXTINF:-1 tvg-chno="58" tvg-id="Starz.-.Eastern.us" tvg-name="Starz" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s12719_dark_360w_270h.png" group-title="TV",Starz
https://fl3.moveonjoy.com/STARZ/index.m3u8
#EXTINF:-1 tvg-chno="59" tvg-id="TBS.-.East.us" tvg-name="TBS" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s11867_dark_360w_270h.png" group-title="TV",TBS
https://turnerlive.warnermediacdn.com/hls/live/2023172/tbseast/slate/VIDEO_0_3564000.m3u8
#EXTINF:-1 tvg-chno="60" tvg-id="TLC.USA.-.Eastern.us" tvg-name="TLC" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s11158_dark_360w_270h.png" group-title="TV",TLC
http://fl1.moveonjoy.com/TLC/index.m3u8
#EXTINF:-1 tvg-chno="61" tvg-id="TNT.-.Eastern.Feed.us" tvg-name="TNT" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s11164_dark_360w_270h.png" group-title="TV",TNT
https://turnerlive.warnermediacdn.com/hls/live/2023168/tnteast/slate/VIDEO_0_3564000.m3u8
#EXTINF:-1 tvg-chno="62" tvg-id="truTV.USA.-.Eastern.us" tvg-name="truTV" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s10153_dark_360w_270h.png" group-title="TV",truTV
https://turnerlive.warnermediacdn.com/hls/live/2023176/trueast/slate/VIDEO_0_3564000.m3u8
#EXTINF:-1 tvg-chno="63" tvg-id="TSN1.ca" tvg-name="TSN1" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s11182_dark_360w_270h.png" group-title="TV",TSN1
http://cord-cutter.net:8080/25464931/30585186/57292
#EXTINF:-1 tvg-chno="64" tvg-id="TSN2.ca" tvg-name="TSN2" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s61474_dark_360w_270h.png" group-title="TV",TSN2
http://fl5.moveonjoy.com/TSN_2/index.m3u8
#EXTINF:-1 tvg-chno="65" tvg-id="USA.Network.-.East.Feed.us" tvg-name="USA East" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s11207_dark_360w_270h.png" group-title="TV",USA East
http://4c66041f.tvclub.xyz/iptv/E3TZUWKUS8PTA7/31124/index.m3u8
#EXTINF:-1 tvg-chno="66" tvg-id="YES.Network.us" tvg-name="YES Network" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s30017_dark_360w_270h.png" group-title="TV",YES Network
https://fl5.moveonjoy.com/YES_NETWORK/index.m3u8
#EXTINF:-1 tvg-chno="67" tvg-id="(N/A)" tvg-name="[MLB] Philadelphia Phillies @ Washington Nationals" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[MLB] Philadelphia Phillies @ Washington Nationals
https://tvpass.org/live/mlb-01/sd
#EXTINF:-1 tvg-chno="68" tvg-id="(N/A)" tvg-name="[WNBA] Indiana Fever @ Connecticut Sun" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[WNBA] Indiana Fever @ Connecticut Sun
https://tvpass.org/live/WNBA01/sd
#EXTINF:-1 tvg-chno="69" tvg-id="(N/A)" tvg-name="[NFL] Jacksonville Jaguars @ New Orleans Saints" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[NFL] Jacksonville Jaguars @ New Orleans Saints
https://tvpass.org/live/NFL23/sd
#EXTINF:-1 tvg-chno="70" tvg-id="(N/A)" tvg-name="[MLB] Miami Marlins @ Boston Red Sox" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[MLB] Miami Marlins @ Boston Red Sox
https://tvpass.org/live/mlb-22/sd
#EXTINF:-1 tvg-chno="71" tvg-id="(N/A)" tvg-name="[MLB] Texas Rangers @ Toronto Blue Jays" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[MLB] Texas Rangers @ Toronto Blue Jays
https://tvpass.org/live/mlb-12/sd
#EXTINF:-1 tvg-chno="72" tvg-id="(N/A)" tvg-name="[MLB] Atlanta Braves @ Cleveland Guardians" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[MLB] Atlanta Braves @ Cleveland Guardians
https://tvpass.org/live/mlb-30/sd
#EXTINF:-1 tvg-chno="73" tvg-id="(N/A)" tvg-name="[MLB] Milwaukee Brewers @ Cincinnati Reds" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[MLB] Milwaukee Brewers @ Cincinnati Reds
https://tvpass.org/live/mlb-04/sd
#EXTINF:-1 tvg-chno="74" tvg-id="(N/A)" tvg-name="[MLB] Baltimore Orioles @ Houston Astros" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[MLB] Baltimore Orioles @ Houston Astros
https://tvpass.org/live/mlb-06/sd
#EXTINF:-1 tvg-chno="75" tvg-id="(N/A)" tvg-name="[MLB] Chicago White Sox @ Kansas City Royals" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[MLB] Chicago White Sox @ Kansas City Royals
https://tvpass.org/live/mlb-05/sd
#EXTINF:-1 tvg-chno="76" tvg-id="(N/A)" tvg-name="[MLB] Detroit Tigers @ Minnesota Twins" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[MLB] Detroit Tigers @ Minnesota Twins
https://tvpass.org/live/mlb-20/sd
#EXTINF:-1 tvg-chno="77" tvg-id="(N/A)" tvg-name="[MLB] New York Yankees @ St. Louis Cardinals" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[MLB] New York Yankees @ St. Louis Cardinals
https://tvpass.org/live/mlb-08/sd
#EXTINF:-1 tvg-chno="78" tvg-id="(N/A)" tvg-name="[MLB] Pittsburgh Pirates @ Chicago Cubs" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[MLB] Pittsburgh Pirates @ Chicago Cubs
https://tvpass.org/live/mlb-23/sd
#EXTINF:-1 tvg-chno="79" tvg-id="(N/A)" tvg-name="[WNBA] Los Angeles Sparks @ Washington Mystics" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[WNBA] Los Angeles Sparks @ Washington Mystics
https://tvpass.org/live/WNBA02/sd
#EXTINF:-1 tvg-chno="80" tvg-id="(N/A)" tvg-name="[MLB] Arizona Diamondbacks @ Colorado Rockies" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[MLB] Arizona Diamondbacks @ Colorado Rockies
https://tvpass.org/live/mlb-25/sd
#EXTINF:-1 tvg-chno="81" tvg-id="(N/A)" tvg-name="[WNBA] Dallas Wings @ Las Vegas Aces" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[WNBA] Dallas Wings @ Las Vegas Aces
https://tvpass.org/live/WNBA03/sd
#EXTINF:-1 tvg-chno="82" tvg-id="(N/A)" tvg-name="[MLB] Los Angeles Angels @ Oakland Athletics" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[MLB] Los Angeles Angels @ Oakland Athletics
https://tvpass.org/live/mlb-19/sd
#EXTINF:-1 tvg-chno="83" tvg-id="(N/A)" tvg-name="[MLB] Tampa Bay Rays @ San Francisco Giants" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[MLB] Tampa Bay Rays @ San Francisco Giants
https://tvpass.org/live/mlb-27/sd
#EXTINF:-1 tvg-chno="84" tvg-id="(N/A)" tvg-name="[MLB] San Diego Padres @ Los Angeles Dodgers" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[MLB] San Diego Padres @ Los Angeles Dodgers
https://tvpass.org/live/mlb-14/sd
#EXTINF:-1 tvg-chno="85" tvg-id="(N/A)" tvg-name="[WNBA] Phoenix Mercury @ Seattle Storm" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[WNBA] Phoenix Mercury @ Seattle Storm
https://tvpass.org/live/WNBA04/sd
#EXTINF:-1 tvg-chno="86" tvg-id="(N/A)" tvg-name="[MLB] Seattle Mariners @ New York Mets" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[MLB] Seattle Mariners @ New York Mets
https://tvpass.org/live/mlb-24/sd
#EXTINF:-1 tvg-chno="87" tvg-id="(N/A)" tvg-name="[NFL] Buffalo Bills @ Chicago Bears" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[NFL] Buffalo Bills @ Chicago Bears
https://tvpass.org/live/NFL11/sd
#EXTINF:-1 tvg-chno="88" tvg-id="(N/A)" tvg-name="[WNBA] Atlanta Dream @ Golden State Valkyries" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[WNBA] Atlanta Dream @ Golden State Valkyries
https://tvpass.org/live/WNBA05/sd
#EXTINF:-1 tvg-chno="89" tvg-id="(N/A)" tvg-name="[Premier League] Nottingham Forest vs Brentford (S1)" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[Premier League] Nottingham Forest vs Brentford (S1)
https://5nhp186eg31fofnc.chinese-restaurant-api.site/v3/director/VE1NTMwMTUyNDhlM2ExLTAwMGItNjE3NC02OGM0LThjZDU4YmQy/master.m3u8
#EXTINF:-1 tvg-chno="90" tvg-id="(N/A)" tvg-name="[Premier League] Nottingham Forest vs Brentford (S2)" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[Premier League] Nottingham Forest vs Brentford (S2)
https://5nhp186eg31fofnc.chinese-restaurant-api.site/v3/variant/VE1AO1NTbu8mbv12LxEWM21ycrNWYyR3LhdTO3kTZwcDZyczYtMWYmFWL3UGZ00CZ4MDZtQTN3czY4M2M/master.m3u8
#EXTINF:-1 tvg-chno="91" tvg-id="(N/A)" tvg-name="[Premier League] Nottingham Forest vs Brentford (S3)" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[Premier League] Nottingham Forest vs Brentford (S3)
https://subrugopuciblchlvl6uqa666p23rig.happy-ending.site/fishy-smell/ed4bbd1554e94cc86f65e40166b1fec4.m3u8?auth=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdHJlYW1JZCI6ImVkNGJiZDE1NTRlOTRjYzg2ZjY1ZTQwMTY2YjFmZWM0IiwidHlwZSI6InBsYXlsaXN0X2FjY2VzcyIsImlhdCI6MTc1NTQzNjY4MSwiZXhwIjoxNzU1NDQ3NDgxfQ.dCRhM3JFUGE0VDZZbGt1dHVDJG8
#EXTINF:-1 tvg-chno="92" tvg-id="(N/A)" tvg-name="[Championship] Hull City vs Oxford United (S1)" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[Championship] Hull City vs Oxford United (S1)
https://5nhp186eg31fofnc.chinese-restaurant-api.site/v3/director/VE1NjU5NGU0NzYwMGEwLTIwZmItMWNiNC1iMDI4LTYzZmM5NjU3/master.m3u8
#EXTINF:-1 tvg-chno="93" tvg-id="(N/A)" tvg-name="[Championship] Hull City vs Oxford United (S2)" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[Championship] Hull City vs Oxford United (S2)
https://5nhp186eg31fofnc.chinese-restaurant-api.site/v3/director/VE1YzU2MjI0ZGQ0MTBhLTllNzgtMGEzNC0yNDg3LTUyMjFjZDUw/master.m3u8
#EXTINF:-1 tvg-chno="94" tvg-id="(N/A)" tvg-name="[DFB Pokal] Lokomotive Leipzig vs FC Schalke 04 (S1)" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[DFB Pokal] Lokomotive Leipzig vs FC Schalke 04 (S1)
https://5nhp186eg31fofnc.chinese-restaurant-api.site/v3/director/VE1NWZjYWY1ZGRjOTljLWQzMjktMWZlNC1iYmZjLTM5YzY2ODFh/master.m3u8
#EXTINF:-1 tvg-chno="95" tvg-id="(N/A)" tvg-name="[Ligue 1] Stade Brestois 29 vs Lille (S1)" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[Ligue 1] Stade Brestois 29 vs Lille (S1)
https://5nhp186eg31fofnc.chinese-restaurant-api.site/v3/director/VE1NzdiN2IwMTM2MzRmLTAwNmItNjM3NC05ZWJmLWFmZmYxNzU2/master.m3u8
#EXTINF:-1 tvg-chno="96" tvg-id="(N/A)" tvg-name="[Ligue 1] Stade Brestois 29 vs Lille (S2)" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[Ligue 1] Stade Brestois 29 vs Lille (S2)
https://5nhp186eg31fofnc.chinese-restaurant-api.site/v3/director/VE1MWZlMDAwZTlmM2QyLWUzMGItYjVmNC0zMDhjLTViNGQ3YTRl/master.m3u8
#EXTINF:-1 tvg-chno="97" tvg-id="(N/A)" tvg-name="[Moto GP] MotoGP | Round 13 | Austria 🏍 (S1)" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[Moto GP] MotoGP | Round 13 | Austria 🏍 (S1)
https://5nhp186eg31fofnc.chinese-restaurant-api.site/v3/director/VE1NGY2YTlkMjFlMzNiLTNlN2ItZTQ4NC1jMWVjLWY5ZjU0Mzg5/master.m3u8
#EXTINF:-1 tvg-chno="98" tvg-id="(N/A)" tvg-name="[Moto GP] MotoGP | Round 13 | Austria 🏍 (S2)" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[Moto GP] MotoGP | Round 13 | Austria 🏍 (S2)
https://5nhp186eg31fofnc.chinese-restaurant-api.site/v3/director/VE1ZmI4NzhmOGI3ZGUwLTU4Y2ItNjJhNC1iYjlmLTYyNGM4ZGZm/master.m3u8
#EXTINF:-1 tvg-chno="99" tvg-id="(N/A)" tvg-name="[Racing] Sweden | MX2 | Race 1 & 2 (S1)" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[Racing] Sweden | MX2 | Race 1 & 2 (S1)
https://5nhp186eg31fofnc.chinese-restaurant-api.site/v3/director/VE1MzMyYzk1MGY3ZWIyLWM3NzgtNjNkNC1jODNhLWZmYjRjYzg1/master.m3u8
#EXTINF:-1 tvg-chno="100" tvg-id="(N/A)" tvg-name="[Racing] Sweden | MX2 | Race 1 & 2 (S2)" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[Racing] Sweden | MX2 | Race 1 & 2 (S2)
https://5nhp186eg31fofnc.chinese-restaurant-api.site/v3/director/VE1MDJhM2Q4MmIzYTc3LWJhMjgtMGM2NC0yN2IwLTA4M2Q2NDkz/master.m3u8
#EXTINF:-1 tvg-chno="101" tvg-id="(N/A)" tvg-name="[Eredivisie] Twente vs PSV Eindhoven (S1)" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[Eredivisie] Twente vs PSV Eindhoven (S1)
https://5nhp186eg31fofnc.chinese-restaurant-api.site/v3/director/VE1MmUzYTQyNGU1ODZjLWE1OTgtYTE5NC1lYzcwLWEyZmVjOTk1/master.m3u8
#EXTINF:-1 tvg-chno="102" tvg-id="(N/A)" tvg-name="[Eredivisie] Twente vs PSV Eindhoven (S2)" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[Eredivisie] Twente vs PSV Eindhoven (S2)
https://5nhp186eg31fofnc.chinese-restaurant-api.site/v3/director/VE1YzRkNjI0OWU1Nzc5LTMyM2EtZWE5NC1lYTZhLWViODNhMTA0/master.m3u8
#EXTINF:-1 tvg-chno="103" tvg-id="(N/A)" tvg-name="[Eredivisie] Twente vs PSV Eindhoven (S3)" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[Eredivisie] Twente vs PSV Eindhoven (S3)
https://5nhp186eg31fofnc.chinese-restaurant-api.site/v3/director/VE1OWQ3NWJhMGY1Zjk0LTU3OTgtNmUwNC05YTkyLWM1M2IyNzA0/master.m3u8
#EXTINF:-1 tvg-chno="104" tvg-id="(N/A)" tvg-name="[Superliga] Vejle vs FC Midtjylland (S1)" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[Superliga] Vejle vs FC Midtjylland (S1)
https://5nhp186eg31fofnc.chinese-restaurant-api.site/v3/director/VE1ZTkwZTUzMTE3MjEwLWYyM2ItNjE4NC04ZjVkLWNlY2ZiOWI2/master.m3u8
#EXTINF:-1 tvg-chno="105" tvg-id="(N/A)" tvg-name="[African Nations Championship] Congo DR vs Morocco (S1)" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[African Nations Championship] Congo DR vs Morocco (S1)
https://5nhp186eg31fofnc.chinese-restaurant-api.site/v3/director/VE1YWYzMWU2OTM4MGUwLWNjYTgtMjMxNC05YWMzLTNjYzFkMmI0/master.m3u8
#EXTINF:-1 tvg-chno="106" tvg-id="(N/A)" tvg-name="[Betfred Super League] St Helens vs Huddersfield (S1)" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[Betfred Super League] St Helens vs Huddersfield (S1)
https://5nhp186eg31fofnc.chinese-restaurant-api.site/v3/director/VE1NTVkYzFhNDNkNGI2LWUwMWItNDBmNC1jZDQwLTdhZmIxYWNl/master.m3u8
#EXTINF:-1 tvg-chno="107" tvg-id="(N/A)" tvg-name="[Segunda Liga] Penafiel vs Oliveirense (S1)" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[Segunda Liga] Penafiel vs Oliveirense (S1)
https://5nhp186eg31fofnc.chinese-restaurant-api.site/v3/director/VE1Yjc3YTEzYzkzODQ4LWJmMDktZjVhNC1jOWMzLWJkMzQ5ZTRi/master.m3u8
#EXTINF:-1 tvg-chno="108" tvg-id="(N/A)" tvg-name="[CYCLING] Czech Tour | Stage 4 - Men | Kroměříž - Pustevny (179km) (S1)" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[CYCLING] Czech Tour | Stage 4 - Men | Kroměříž - Pustevny (179km) (S1)
https://5nhp186eg31fofnc.chinese-restaurant-api.site/v3/director/VE1NTE5MmVjYzhmYTE3LWZkMDgtZDQ2NC0xMzU3LWE5MmE0Mzk3/master.m3u8
#EXTINF:-1 tvg-chno="109" tvg-id="(N/A)" tvg-name="[Allsvenskan] IFK Goteborg vs AIK Stockholm (S1)" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[Allsvenskan] IFK Goteborg vs AIK Stockholm (S1)
https://5nhp186eg31fofnc.chinese-restaurant-api.site/v3/director/VE1MTgwODFiMzBlYjNjLTcyMzktZTUwNC0wOWRkLTY3NzE3NWUy/master.m3u8
#EXTINF:-1 tvg-chno="110" tvg-id="(N/A)" tvg-name="[League Cup] Kilmarnock vs Dundee Utd (S1)" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[League Cup] Kilmarnock vs Dundee Utd (S1)
https://5nhp186eg31fofnc.chinese-restaurant-api.site/v3/director/VE1MmE1YzBjODczNmVhLTlmNjktYjQ5NC0xYWRhLWUzMThiMDQw/master.m3u8
#EXTINF:-1 tvg-chno="111" tvg-id="(N/A)" tvg-name="[Liga I] Csikszereda vs Universitatea Craiova (S1)" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[Liga I] Csikszereda vs Universitatea Craiova (S1)
https://5nhp186eg31fofnc.chinese-restaurant-api.site/v3/director/VE1ZmMxMGExZmZhMGU3LTg0ZmItNWVjNC1kZTg2LWU5ODZhYmQ2/master.m3u8
#EXTINF:-1 tvg-chno="112" tvg-id="(N/A)" tvg-name="[Golf] Danish Golf Championship, Final Round - European PGA Tour Golf (S1)" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[Golf] Danish Golf Championship, Final Round - European PGA Tour Golf (S1)
https://5nhp186eg31fofnc.chinese-restaurant-api.site/v3/director/VE1ZTg2ZTEzZTk2ZTQzLThiMmEtYzkxNC04ODNhLTM5MThlZGQz/master.m3u8
#EXTINF:-1 tvg-chno="113" tvg-id="(N/A)" tvg-name="[Golf] Danish Golf Championship, Final Round - European PGA Tour Golf (S2)" tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png" group-title="Live Events",[Golf] Danish Golf Championship, Final Round - European PGA Tour Golf (S2)
https://5nhp186eg31fofnc.chinese-restaurant-api.site/v3/director/VE1NmNmOTRlN2Q4ZDg2LTlhNTktYjEyNC1iZGVkLWEzNjI5NzBh/master.m3u8

78
M3U8/fetch.py Normal file
View file

@ -0,0 +1,78 @@
#!/usr/bin/env python3
import json
from datetime import datetime
from pathlib import Path
import httpx
import pytz
from scrape import fstv, tvpass
m3u8_file = Path(__file__).parent / "TV.m3u8"
base = "http://m3u4u.com/m3u/d5k2nvp8w2t3w2k1n984"
current_hour = datetime.now(pytz.timezone("America/New_York")).hour
def vanilla_fetch() -> tuple[list[str], int]:
print("Fetching base M3U8")
try:
r = httpx.get(
base,
follow_redirects=True,
timeout=5,
)
r.raise_for_status()
except Exception as e:
raise SystemExit(f'Failed to fetch "{base}"\n{e}') from e
d = r.text.splitlines()
d.pop(0)
last_chnl_number = int(r.text.split("tvg-chno=")[-1].split('"')[1])
return d, last_chnl_number
def main() -> None:
if current_hour <= 11:
tvpass.main()
else:
try:
tvpass.urls = json.loads(tvpass.base_file.read_text(encoding="utf-8"))
except (FileNotFoundError, json.JSONDecodeError):
pass
fstv.main()
base_m3u8, chnl_number = vanilla_fetch()
m3u8_file.write_text(
'#EXTM3U url-tvg="https://raw.githubusercontent.com/doms9/iptv/refs/heads/default/EPG/TV.xml"\n'
+ "\n".join(base_m3u8)
+ "\n",
encoding="utf-8",
)
additions = tvpass.urls | fstv.urls
for event, url in additions.items():
chnl_number += 1
with m3u8_file.open("a", encoding="utf-8") as f:
f.write(f'#EXTINF:-1 tvg-chno="{chnl_number}"')
f.write(f' tvg-id="(N/A)" tvg-name="{event}"')
f.write(
' tvg-logo="https://i.gyazo.com/ec27417a9644ae517196494afa72d2b9.png"'
)
f.write(' group-title="Live Events"')
f.write(f",{event}\n{url}\n")
print(f"M3U8 saved to {m3u8_file.name}")
if __name__ == "__main__":
main()

118
M3U8/scrape/fstv.py Normal file
View file

@ -0,0 +1,118 @@
from urllib.parse import urljoin
import httpx
from bs4 import BeautifulSoup
urls: dict[str, str] = {}
mirrors = {"https://fstv.online", "https://fstv.space", "https://fstv.zip"}
def check_status(l: str) -> bool:
try:
r = httpx.get(l)
r.raise_for_status()
except Exception:
return False
return r.status_code == 200
def get_base() -> str:
for url in filter(check_status, mirrors):
return url
def get_hrefs(base_url: str) -> list[tuple[str, str]] | tuple[None, None]:
print(f'Scraping from "{base_url}"')
try:
r = httpx.get(
base_url,
timeout=5,
)
r.raise_for_status()
except Exception as e:
print(f'Failed to fetch "{base_url}"\n{e}')
return None, None
soup = BeautifulSoup(r.text, "lxml")
events = {}
for wrpr in soup.find_all("div", class_="fixtures-live-wrapper"):
for games in wrpr.select(".match-table-item"):
league_name = games.select_one(".league-info a.league-name")
league_match = games.select_one(".common-table-row a[href*='/match/']")
if league_name and league_match:
full_text = league_name.get_text(strip=True)
if "]" in full_text:
event_name = full_text.split("]", 1)[1].strip()
else:
event_name = full_text
events[event_name] = urljoin(base_url, league_match["href"])
return events.items()
def fetch_m3u8(url: str) -> tuple[str, list[str]] | tuple[None, None]:
try:
r = httpx.get(
url,
timeout=5,
)
r.raise_for_status()
except Exception as e:
print(f'Failed to fetch "{url}"\n{e}')
return None, None
soup = BeautifulSoup(r.text, "lxml")
if category_links := soup.select(".common-list-category .category-item a"):
match_name = category_links[-1].get_text(strip=True)
else:
match_name = None
if not match_name or match_name.lower() == "vs":
if og_title := soup.find("meta", property="og:title"):
match_name = og_title["content"].split(" start on")[0].strip()
btns = soup.select("button.btn-server")
return match_name, [btn["data-link"] for btn in btns if btn.has_attr("data-link")]
def main() -> None:
for event, href in get_hrefs(get_base()):
if not href:
return
match_name, m3u8_urls = fetch_m3u8(href)
if not m3u8_urls:
return
for i, link in enumerate(m3u8_urls, start=1):
key = (
f"[{event}] (S{i})"
if not match_name
else f"[{event}] {match_name} (S{i})"
)
urls[key] = link
print(f"Collected {len(urls)} live events")
if __name__ == "__main__":
main()

24
M3U8/scrape/tvpass.json Normal file
View file

@ -0,0 +1,24 @@
{
"[MLB] Philadelphia Phillies @ Washington Nationals": "https://tvpass.org/live/mlb-01/sd",
"[WNBA] Indiana Fever @ Connecticut Sun": "https://tvpass.org/live/WNBA01/sd",
"[NFL] Jacksonville Jaguars @ New Orleans Saints": "https://tvpass.org/live/NFL23/sd",
"[MLB] Miami Marlins @ Boston Red Sox": "https://tvpass.org/live/mlb-22/sd",
"[MLB] Texas Rangers @ Toronto Blue Jays": "https://tvpass.org/live/mlb-12/sd",
"[MLB] Atlanta Braves @ Cleveland Guardians": "https://tvpass.org/live/mlb-30/sd",
"[MLB] Milwaukee Brewers @ Cincinnati Reds": "https://tvpass.org/live/mlb-04/sd",
"[MLB] Baltimore Orioles @ Houston Astros": "https://tvpass.org/live/mlb-06/sd",
"[MLB] Chicago White Sox @ Kansas City Royals": "https://tvpass.org/live/mlb-05/sd",
"[MLB] Detroit Tigers @ Minnesota Twins": "https://tvpass.org/live/mlb-20/sd",
"[MLB] New York Yankees @ St. Louis Cardinals": "https://tvpass.org/live/mlb-08/sd",
"[MLB] Pittsburgh Pirates @ Chicago Cubs": "https://tvpass.org/live/mlb-23/sd",
"[WNBA] Los Angeles Sparks @ Washington Mystics": "https://tvpass.org/live/WNBA02/sd",
"[MLB] Arizona Diamondbacks @ Colorado Rockies": "https://tvpass.org/live/mlb-25/sd",
"[WNBA] Dallas Wings @ Las Vegas Aces": "https://tvpass.org/live/WNBA03/sd",
"[MLB] Los Angeles Angels @ Oakland Athletics": "https://tvpass.org/live/mlb-19/sd",
"[MLB] Tampa Bay Rays @ San Francisco Giants": "https://tvpass.org/live/mlb-27/sd",
"[MLB] San Diego Padres @ Los Angeles Dodgers": "https://tvpass.org/live/mlb-14/sd",
"[WNBA] Phoenix Mercury @ Seattle Storm": "https://tvpass.org/live/WNBA04/sd",
"[MLB] Seattle Mariners @ New York Mets": "https://tvpass.org/live/mlb-24/sd",
"[NFL] Buffalo Bills @ Chicago Bears": "https://tvpass.org/live/NFL11/sd",
"[WNBA] Atlanta Dream @ Golden State Valkyries": "https://tvpass.org/live/WNBA05/sd"
}

69
M3U8/scrape/tvpass.py Normal file
View file

@ -0,0 +1,69 @@
import json
import re
from pathlib import Path
from urllib.parse import urlparse
import httpx
base_url = "https://tvpass.org/playlist/m3u"
base_file = Path(__file__).parent / "tvpass.json"
urls: dict[str, str] = {}
def fetch_m3u8() -> list[str] | None:
try:
r = httpx.get(
base_url,
follow_redirects=True,
timeout=5,
)
r.raise_for_status()
except Exception as e:
print(f'Failed to fetch "{base_url}"\n{e}')
return
return r.text.splitlines()
def main() -> None:
print(f'Scraping from "{base_url}"')
if not (data := fetch_m3u8()):
return
for i in range(len(data) - 1):
if data[i].startswith("#EXTINF"):
tvg_id_match = re.search(r'tvg-id="([^"]*)"', data[i])
tvg_name_match = re.search(r'tvg-name="([^"]*)"', data[i])
tvg_id = tvg_id_match[1] if tvg_id_match else None
tvg_name = tvg_name_match[1]
if tvg_id == "":
url = data[i + 1]
tvg_name = tvg_name.split("(")[0].strip()
if url.endswith("/sd"):
path_parts = urlparse(url).path.strip("/").split("/")
if len(path_parts) >= 2 and path_parts[-1] == "sd":
sport = "".join(x for x in path_parts[1] if x.isalpha()).upper()
else:
sport = "UNKNWN"
urls[f"[{sport}] {tvg_name}"] = url
print(f"Collected {len(urls)} live events")
if urls:
base_file.write_text(json.dumps(urls, indent=2), encoding="utf-8")
if __name__ == "__main__":
main()

130
health.sh Normal file
View file

@ -0,0 +1,130 @@
#!/bin/bash
main="http://m3u4u.com/m3u/d5k2nvp8w2t3w2k1n984"
MAX_JOBS=10
RETRY_COUNT=3
README="./readme.md"
STATUSLOG=$(mktemp)
PASSED=0
FAILED=0
REDIRECTED=0
EMPTY=0
get_status() {
local url="$1"
local channel="$2"
local attempt response status_code
[[ "$url" != http* ]] && return
for attempt in $(seq 1 "$RETRY_COUNT"); do
response=$(curl -sL -o /dev/null --max-time 10 -w "%{http_code}" "$url" 2>&1)
[[ "$response" =~ ^[0-9]+$ ]] && break
sleep 1
done
if [[ ! "$response" =~ ^[0-9]+$ ]]; then
if [[ "$response" == *"timed out"* ]]; then
echo "| $channel | Connection timed out | \`$url\` |" >>"$STATUSLOG"
else
echo "| $channel | Curl error | \`$url\` |" >>"$STATUSLOG"
fi
echo "FAIL" >>"$STATUSLOG"
return
fi
status_code="$response"
case "$status_code" in
200)
if ! curl -sL --max-time 5 "$url" | head -c 1 | grep -q '.'; then
echo "| $channel | Empty body (404) | \`$url\` |" >>"$STATUSLOG"
echo "EMPTY" >>"$STATUSLOG"
else
echo "PASS" >>"$STATUSLOG"
fi
;;
301 | 302 | 307 | 308)
redirect_url=$(curl -sI --max-time 5 "$url" | grep -i '^Location:' | sed 's/Location: //I' | tr -d '\r\n')
echo "| $channel | Redirect ($status_code) | \`$url$redirect_url\` |" >>"$STATUSLOG"
echo "REDIRECT" >>"$STATUSLOG"
;;
4* | 5*)
echo "| $channel | HTTP Error ($status_code) | \`$url\` |" >>"$STATUSLOG"
echo "FAIL" >>"$STATUSLOG"
;;
*)
if [[ "$status_code" == "000" ]]; then
echo "| $channel | Connection timed out (000) | \`$url\` |" >>"$STATUSLOG"
else
echo "| $channel | Unknown status ($status_code) | \`$url\` |" >>"$STATUSLOG"
fi
echo "FAIL" >>"$STATUSLOG"
;;
esac
}
check_links() {
echo "Checking links from: $main"
channel_num=0
name=""
jobs_running=0
echo "| Channel | Error (Code) | Link |" >"$STATUSLOG"
echo "| ------- | ------------ | ---- |" >>"$STATUSLOG"
while IFS= read -r line; do
line=$(echo "$line" | tr -d '\r\n')
if [[ "$line" == \#EXTINF* ]]; then
name=$(echo "$line" | sed -n 's/.*tvg-name="\([^"]*\)".*/\1/p')
[[ -z "$name" ]] && name="Channel $channel_num"
elif [[ "$line" =~ ^https?:// ]]; then
while (($(jobs -r | wc -l) >= MAX_JOBS)); do sleep 0.2; done
get_status "$line" "$name" &
((channel_num++))
fi
done < <(curl -sL "$main")
wait
echo "Done."
}
write_readme() {
local passed redirected empty failed
passed=$(grep -c '^PASS$' "$STATUSLOG")
redirected=$(grep -c '^REDIRECT$' "$STATUSLOG")
empty=$(grep -c '^EMPTY$' "$STATUSLOG")
failed=$(grep -c '^FAIL$' "$STATUSLOG")
{
echo "## Log @ $(date '+%Y-%m-%d %H:%M:%S UTC')"
echo
echo "### ✅ Working Streams: $passed<br>🔁 Redirected Links: $redirected<br> Empty Streams: $empty<br>❌ Dead Streams: $failed"
echo
if [ $failed -gt 0 ] || [ $empty -gt 0 ] || [ $redirected -gt 0 ]; then
head -n 1 "$STATUSLOG"
grep -v -e '^PASS$' -e '^FAIL$' -e '^EMPTY$' -e '^REDIRECT$' -e '^---' "$STATUSLOG" |
grep -v '^| Channel' | sort -u
fi
echo "---"
echo "#### M3U8 URL"
printf "\`\`\`\nhttps://raw.githubusercontent.com/doms9/iptv/refs/heads/default/M3U8/TV.m3u8\n\`\`\`\n"
echo "#### EPG URL"
printf "\`\`\`\nhttps://raw.githubusercontent.com/doms9/iptv/refs/heads/default/EPG/TV.xml\n\`\`\`\n"
echo "---"
echo "#### Legal Disclaimer"
echo "This repository lists publicly accessible IPTV streams as found on the internet at the time of checking."
echo "No video or audio content is hosted in this repository. These links may point to copyrighted material owned by third parties;"
echo "they are provided **solely for educational and research purposes.**"
echo "The author does not endorse, promote, or encourage illegal streaming or copyright infringement."
echo "End users are solely responsible for ensuring they comply with all applicable laws in their jurisdiction before using any link in this repository."
echo "If you are a rights holder and wish for a link to be removed, please open an issue."
} >"$README"
}
check_links
write_readme
rm "$STATUSLOG"

10
pyproject.toml Normal file
View file

@ -0,0 +1,10 @@
[project]
name = "iptv"
version = "0.0.2"
requires-python = ">=3.13"
dependencies = [
"beautifulsoup4>=4.13.4",
"httpx>=0.28.1",
"lxml>=6.0.0",
"pytz>=2025.2",
]

24
readme.md Normal file
View file

@ -0,0 +1,24 @@
## Log @ 2025-08-17 08:33:49 UTC
### ✅ Working Streams: 65<br>🔁 Redirected Links: 0<br> Empty Streams: 0<br>❌ Dead Streams: 1
| Channel | Error (Code) | Link |
| ------- | ------------ | ---- |
| CW | HTTP Error (401) | `http://user.scalecdn.co:8080/live/26725074/92867131/93093.m3u8` |
---
#### M3U8 URL
```
https://raw.githubusercontent.com/doms9/iptv/refs/heads/default/M3U8/TV.m3u8
```
#### EPG URL
```
https://raw.githubusercontent.com/doms9/iptv/refs/heads/default/EPG/TV.xml
```
---
#### Legal Disclaimer
This repository lists publicly accessible IPTV streams as found on the internet at the time of checking.
No video or audio content is hosted in this repository. These links may point to copyrighted material owned by third parties;
they are provided **solely for educational and research purposes.**
The author does not endorse, promote, or encourage illegal streaming or copyright infringement.
End users are solely responsible for ensuring they comply with all applicable laws in their jurisdiction before using any link in this repository.
If you are a rights holder and wish for a link to be removed, please open an issue.

163
uv.lock generated Normal file
View file

@ -0,0 +1,163 @@
version = 1
revision = 2
requires-python = ">=3.13"
[[package]]
name = "anyio"
version = "4.10.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "idna" },
{ name = "sniffio" },
]
sdist = { url = "https://files.pythonhosted.org/packages/f1/b4/636b3b65173d3ce9a38ef5f0522789614e590dab6a8d505340a4efe4c567/anyio-4.10.0.tar.gz", hash = "sha256:3f3fae35c96039744587aa5b8371e7e8e603c0702999535961dd336026973ba6", size = 213252, upload-time = "2025-08-04T08:54:26.451Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/6f/12/e5e0282d673bb9746bacfb6e2dba8719989d3660cdb2ea79aee9a9651afb/anyio-4.10.0-py3-none-any.whl", hash = "sha256:60e474ac86736bbfd6f210f7a61218939c318f43f9972497381f1c5e930ed3d1", size = 107213, upload-time = "2025-08-04T08:54:24.882Z" },
]
[[package]]
name = "beautifulsoup4"
version = "4.13.4"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "soupsieve" },
{ name = "typing-extensions" },
]
sdist = { url = "https://files.pythonhosted.org/packages/d8/e4/0c4c39e18fd76d6a628d4dd8da40543d136ce2d1752bd6eeeab0791f4d6b/beautifulsoup4-4.13.4.tar.gz", hash = "sha256:dbb3c4e1ceae6aefebdaf2423247260cd062430a410e38c66f2baa50a8437195", size = 621067, upload-time = "2025-04-15T17:05:13.836Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/50/cd/30110dc0ffcf3b131156077b90e9f60ed75711223f306da4db08eff8403b/beautifulsoup4-4.13.4-py3-none-any.whl", hash = "sha256:9bbbb14bfde9d79f38b8cd5f8c7c85f4b8f2523190ebed90e950a8dea4cb1c4b", size = 187285, upload-time = "2025-04-15T17:05:12.221Z" },
]
[[package]]
name = "certifi"
version = "2025.8.3"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/dc/67/960ebe6bf230a96cda2e0abcf73af550ec4f090005363542f0765df162e0/certifi-2025.8.3.tar.gz", hash = "sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407", size = 162386, upload-time = "2025-08-03T03:07:47.08Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/e5/48/1549795ba7742c948d2ad169c1c8cdbae65bc450d6cd753d124b17c8cd32/certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5", size = 161216, upload-time = "2025-08-03T03:07:45.777Z" },
]
[[package]]
name = "h11"
version = "0.16.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" },
]
[[package]]
name = "httpcore"
version = "1.0.9"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "certifi" },
{ name = "h11" },
]
sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" },
]
[[package]]
name = "httpx"
version = "0.28.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "anyio" },
{ name = "certifi" },
{ name = "httpcore" },
{ name = "idna" },
]
sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" },
]
[[package]]
name = "idna"
version = "3.10"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" },
]
[[package]]
name = "iptv"
version = "0.0.2"
source = { virtual = "." }
dependencies = [
{ name = "beautifulsoup4" },
{ name = "httpx" },
{ name = "lxml" },
{ name = "pytz" },
]
[package.metadata]
requires-dist = [
{ name = "beautifulsoup4", specifier = ">=4.13.4" },
{ name = "httpx", specifier = ">=0.28.1" },
{ name = "lxml", specifier = ">=6.0.0" },
{ name = "pytz", specifier = ">=2025.2" },
]
[[package]]
name = "lxml"
version = "6.0.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/c5/ed/60eb6fa2923602fba988d9ca7c5cdbd7cf25faa795162ed538b527a35411/lxml-6.0.0.tar.gz", hash = "sha256:032e65120339d44cdc3efc326c9f660f5f7205f3a535c1fdbf898b29ea01fb72", size = 4096938, upload-time = "2025-06-26T16:28:19.373Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/79/21/6e7c060822a3c954ff085e5e1b94b4a25757c06529eac91e550f3f5cd8b8/lxml-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6da7cd4f405fd7db56e51e96bff0865b9853ae70df0e6720624049da76bde2da", size = 8414372, upload-time = "2025-06-26T16:26:39.079Z" },
{ url = "https://files.pythonhosted.org/packages/a4/f6/051b1607a459db670fc3a244fa4f06f101a8adf86cda263d1a56b3a4f9d5/lxml-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b34339898bb556a2351a1830f88f751679f343eabf9cf05841c95b165152c9e7", size = 4593940, upload-time = "2025-06-26T16:26:41.891Z" },
{ url = "https://files.pythonhosted.org/packages/8e/74/dd595d92a40bda3c687d70d4487b2c7eff93fd63b568acd64fedd2ba00fe/lxml-6.0.0-cp313-cp313-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl", hash = "sha256:51a5e4c61a4541bd1cd3ba74766d0c9b6c12d6a1a4964ef60026832aac8e79b3", size = 5214329, upload-time = "2025-06-26T16:26:44.669Z" },
{ url = "https://files.pythonhosted.org/packages/52/46/3572761efc1bd45fcafb44a63b3b0feeb5b3f0066886821e94b0254f9253/lxml-6.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d18a25b19ca7307045581b18b3ec9ead2b1db5ccd8719c291f0cd0a5cec6cb81", size = 4947559, upload-time = "2025-06-28T18:47:31.091Z" },
{ url = "https://files.pythonhosted.org/packages/94/8a/5e40de920e67c4f2eef9151097deb9b52d86c95762d8ee238134aff2125d/lxml-6.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d4f0c66df4386b75d2ab1e20a489f30dc7fd9a06a896d64980541506086be1f1", size = 5102143, upload-time = "2025-06-28T18:47:33.612Z" },
{ url = "https://files.pythonhosted.org/packages/7c/4b/20555bdd75d57945bdabfbc45fdb1a36a1a0ff9eae4653e951b2b79c9209/lxml-6.0.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9f4b481b6cc3a897adb4279216695150bbe7a44c03daba3c894f49d2037e0a24", size = 5021931, upload-time = "2025-06-26T16:26:47.503Z" },
{ url = "https://files.pythonhosted.org/packages/b6/6e/cf03b412f3763d4ca23b25e70c96a74cfece64cec3addf1c4ec639586b13/lxml-6.0.0-cp313-cp313-manylinux_2_27_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8a78d6c9168f5bcb20971bf3329c2b83078611fbe1f807baadc64afc70523b3a", size = 5645469, upload-time = "2025-07-03T19:19:13.32Z" },
{ url = "https://files.pythonhosted.org/packages/d4/dd/39c8507c16db6031f8c1ddf70ed95dbb0a6d466a40002a3522c128aba472/lxml-6.0.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ae06fbab4f1bb7db4f7c8ca9897dc8db4447d1a2b9bee78474ad403437bcc29", size = 5247467, upload-time = "2025-06-26T16:26:49.998Z" },
{ url = "https://files.pythonhosted.org/packages/4d/56/732d49def0631ad633844cfb2664563c830173a98d5efd9b172e89a4800d/lxml-6.0.0-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:1fa377b827ca2023244a06554c6e7dc6828a10aaf74ca41965c5d8a4925aebb4", size = 4720601, upload-time = "2025-06-26T16:26:52.564Z" },
{ url = "https://files.pythonhosted.org/packages/8f/7f/6b956fab95fa73462bca25d1ea7fc8274ddf68fb8e60b78d56c03b65278e/lxml-6.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1676b56d48048a62ef77a250428d1f31f610763636e0784ba67a9740823988ca", size = 5060227, upload-time = "2025-06-26T16:26:55.054Z" },
{ url = "https://files.pythonhosted.org/packages/97/06/e851ac2924447e8b15a294855caf3d543424364a143c001014d22c8ca94c/lxml-6.0.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:0e32698462aacc5c1cf6bdfebc9c781821b7e74c79f13e5ffc8bfe27c42b1abf", size = 4790637, upload-time = "2025-06-26T16:26:57.384Z" },
{ url = "https://files.pythonhosted.org/packages/06/d4/fd216f3cd6625022c25b336c7570d11f4a43adbaf0a56106d3d496f727a7/lxml-6.0.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4d6036c3a296707357efb375cfc24bb64cd955b9ec731abf11ebb1e40063949f", size = 5662049, upload-time = "2025-07-03T19:19:16.409Z" },
{ url = "https://files.pythonhosted.org/packages/52/03/0e764ce00b95e008d76b99d432f1807f3574fb2945b496a17807a1645dbd/lxml-6.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7488a43033c958637b1a08cddc9188eb06d3ad36582cebc7d4815980b47e27ef", size = 5272430, upload-time = "2025-06-26T16:27:00.031Z" },
{ url = "https://files.pythonhosted.org/packages/5f/01/d48cc141bc47bc1644d20fe97bbd5e8afb30415ec94f146f2f76d0d9d098/lxml-6.0.0-cp313-cp313-win32.whl", hash = "sha256:5fcd7d3b1d8ecb91445bd71b9c88bdbeae528fefee4f379895becfc72298d181", size = 3612896, upload-time = "2025-06-26T16:27:04.251Z" },
{ url = "https://files.pythonhosted.org/packages/f4/87/6456b9541d186ee7d4cb53bf1b9a0d7f3b1068532676940fdd594ac90865/lxml-6.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:2f34687222b78fff795feeb799a7d44eca2477c3d9d3a46ce17d51a4f383e32e", size = 4013132, upload-time = "2025-06-26T16:27:06.415Z" },
{ url = "https://files.pythonhosted.org/packages/b7/42/85b3aa8f06ca0d24962f8100f001828e1f1f1a38c954c16e71154ed7d53a/lxml-6.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:21db1ec5525780fd07251636eb5f7acb84003e9382c72c18c542a87c416ade03", size = 3672642, upload-time = "2025-06-26T16:27:09.888Z" },
]
[[package]]
name = "pytz"
version = "2025.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/f8/bf/abbd3cdfb8fbc7fb3d4d38d320f2441b1e7cbe29be4f23797b4a2b5d8aac/pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3", size = 320884, upload-time = "2025-03-25T02:25:00.538Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225, upload-time = "2025-03-25T02:24:58.468Z" },
]
[[package]]
name = "sniffio"
version = "1.3.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" },
]
[[package]]
name = "soupsieve"
version = "2.7"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/3f/f4/4a80cd6ef364b2e8b65b15816a843c0980f7a5a2b4dc701fc574952aa19f/soupsieve-2.7.tar.gz", hash = "sha256:ad282f9b6926286d2ead4750552c8a6142bc4c783fd66b0293547c8fe6ae126a", size = 103418, upload-time = "2025-04-20T18:50:08.518Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/e7/9c/0e6afc12c269578be5c0c1c9f4b49a8d32770a080260c333ac04cc1c832d/soupsieve-2.7-py3-none-any.whl", hash = "sha256:6e60cc5c1ffaf1cebcc12e8188320b72071e922c2e897f737cadce79ad5d30c4", size = 36677, upload-time = "2025-04-20T18:50:07.196Z" },
]
[[package]]
name = "typing-extensions"
version = "4.14.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/98/5a/da40306b885cc8c09109dc2e1abd358d5684b1425678151cdaed4731c822/typing_extensions-4.14.1.tar.gz", hash = "sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36", size = 107673, upload-time = "2025-07-04T13:28:34.16Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/b5/00/d631e67a838026495268c2f6884f3711a15a9a2a96cd244fdaea53b823fb/typing_extensions-4.14.1-py3-none-any.whl", hash = "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76", size = 43906, upload-time = "2025-07-04T13:28:32.743Z" },
]