mirror of https://github.com/iptv-org/iptv
Replace LF with CRLF
parent
bbf2dfa1f3
commit
8e166f97d5
@ -1,13 +1,13 @@
|
||||
# Contributor Code of Conduct
|
||||
|
||||
As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
|
||||
|
||||
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
|
||||
|
||||
Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant](http:contributor-covenant.org), version 1.0.0, available at https://www.contributor-covenant.org/version/1/0/0/code-of-conduct.html
|
||||
# Contributor Code of Conduct
|
||||
|
||||
As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
|
||||
|
||||
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
|
||||
|
||||
Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant](http:contributor-covenant.org), version 1.0.0, available at https://www.contributor-covenant.org/version/1/0/0/code-of-conduct.html
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: iptv-org
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: iptv-org
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
node_modules
|
||||
.artifacts
|
||||
.secrets
|
||||
.actrc
|
||||
.DS_Store
|
||||
/.gh-pages/
|
||||
/.api/
|
||||
.env
|
||||
node_modules
|
||||
.artifacts
|
||||
.secrets
|
||||
.actrc
|
||||
.DS_Store
|
||||
/.gh-pages/
|
||||
/.api/
|
||||
.env
|
||||
/temp/
|
||||
@ -1,4 +1,4 @@
|
||||
_categories.md
|
||||
_countries.md
|
||||
_languages.md
|
||||
_categories.md
|
||||
_countries.md
|
||||
_languages.md
|
||||
_regions.md
|
||||
@ -1,88 +1,88 @@
|
||||
## Playlists
|
||||
|
||||
There are several versions of playlists that differ in the way they are grouped. As of January 30th, 2024, we have stopped distributing NSFW channels. For more information, please look at [this issue](https://github.com/iptv-org/iptv/issues/15723).
|
||||
|
||||
### Grouped by category
|
||||
|
||||
Playlists in which channels are grouped by category.
|
||||
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
<br>
|
||||
|
||||
```
|
||||
https://iptv-org.github.io/iptv/index.category.m3u
|
||||
```
|
||||
|
||||
Same thing, but split up into separate files:
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
#include "./.readme/_categories.md"
|
||||
|
||||
</details>
|
||||
|
||||
### Grouped by language
|
||||
|
||||
Playlists in which channels are grouped by the language in which they are broadcast.
|
||||
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
<br>
|
||||
|
||||
```
|
||||
https://iptv-org.github.io/iptv/index.language.m3u
|
||||
```
|
||||
|
||||
Same thing, but split up into separate files:
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
#include "./.readme/_languages.md"
|
||||
|
||||
</details>
|
||||
|
||||
### Grouped by broadcast area
|
||||
|
||||
Playlists in which channels are grouped by broadcast area.
|
||||
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
#### Countries
|
||||
|
||||
```
|
||||
https://iptv-org.github.io/iptv/index.country.m3u
|
||||
```
|
||||
|
||||
Same thing, but split up into separate files:
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
#include "./.readme/_countries.md"
|
||||
|
||||
#### Regions
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
#include "./.readme/_regions.md"
|
||||
|
||||
</details>
|
||||
|
||||
### Grouped by sources
|
||||
|
||||
Playlists in which channels are grouped by broadcast source.
|
||||
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
<br>
|
||||
|
||||
To use the playlist, simply replace `<FILENAME>` in the link below with the name of one of the files in the [streams](streams) folder.
|
||||
|
||||
```
|
||||
https://iptv-org.github.io/iptv/sources/<FILENAME>.m3u
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
Also, any of our internal playlists are available in raw form (without any filtering or sorting) at this link:
|
||||
|
||||
```
|
||||
https://iptv-org.github.io/iptv/raw/<FILENAME>.m3u
|
||||
```
|
||||
## Playlists
|
||||
|
||||
There are several versions of playlists that differ in the way they are grouped. As of January 30th, 2024, we have stopped distributing NSFW channels. For more information, please look at [this issue](https://github.com/iptv-org/iptv/issues/15723).
|
||||
|
||||
### Grouped by category
|
||||
|
||||
Playlists in which channels are grouped by category.
|
||||
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
<br>
|
||||
|
||||
```
|
||||
https://iptv-org.github.io/iptv/index.category.m3u
|
||||
```
|
||||
|
||||
Same thing, but split up into separate files:
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
#include "./.readme/_categories.md"
|
||||
|
||||
</details>
|
||||
|
||||
### Grouped by language
|
||||
|
||||
Playlists in which channels are grouped by the language in which they are broadcast.
|
||||
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
<br>
|
||||
|
||||
```
|
||||
https://iptv-org.github.io/iptv/index.language.m3u
|
||||
```
|
||||
|
||||
Same thing, but split up into separate files:
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
#include "./.readme/_languages.md"
|
||||
|
||||
</details>
|
||||
|
||||
### Grouped by broadcast area
|
||||
|
||||
Playlists in which channels are grouped by broadcast area.
|
||||
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
#### Countries
|
||||
|
||||
```
|
||||
https://iptv-org.github.io/iptv/index.country.m3u
|
||||
```
|
||||
|
||||
Same thing, but split up into separate files:
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
#include "./.readme/_countries.md"
|
||||
|
||||
#### Regions
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
#include "./.readme/_regions.md"
|
||||
|
||||
</details>
|
||||
|
||||
### Grouped by sources
|
||||
|
||||
Playlists in which channels are grouped by broadcast source.
|
||||
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
<br>
|
||||
|
||||
To use the playlist, simply replace `<FILENAME>` in the link below with the name of one of the files in the [streams](streams) folder.
|
||||
|
||||
```
|
||||
https://iptv-org.github.io/iptv/sources/<FILENAME>.m3u
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
Also, any of our internal playlists are available in raw form (without any filtering or sorting) at this link:
|
||||
|
||||
```
|
||||
https://iptv-org.github.io/iptv/raw/<FILENAME>.m3u
|
||||
```
|
||||
|
||||
@ -1,23 +1,23 @@
|
||||
# Frequently Asked Questions
|
||||
|
||||
### My favorite channel is not on the playlist.
|
||||
|
||||
Start by asking our community for help via [Discussions](https://github.com/orgs/iptv-org/discussions). It is quite possible that someone already has a link to the channel you need and they just haven't added it to our playlist yet.
|
||||
|
||||
But keep in mind that not all TV channels are available for viewing online, and in this case there is little we can do about it.
|
||||
|
||||
### Are you planning to include a Video On Demand (VOD) to the playlist?
|
||||
|
||||
No.
|
||||
|
||||
### Why is the channel on the iptv-org.github.io but not in the playlist?
|
||||
|
||||
The site contains a list of all TV channels in the world and only those of them for which we have working stream links are included in the playlists.
|
||||
|
||||
### Can I add a radio broadcast?
|
||||
|
||||
Yes, if it is a [visual radio](https://en.wikipedia.org/wiki/Visual_radio) in which a video and audio are shown at the same time.
|
||||
|
||||
### Why don't you accept links to Xtream Codes server?
|
||||
|
||||
Xtream Codes streams tend to be very unstable, and often links to them fail very quickly, so it's easier for us to initially exclude them from the playlist than to search for expired ones every day.
|
||||
# Frequently Asked Questions
|
||||
|
||||
### My favorite channel is not on the playlist.
|
||||
|
||||
Start by asking our community for help via [Discussions](https://github.com/orgs/iptv-org/discussions). It is quite possible that someone already has a link to the channel you need and they just haven't added it to our playlist yet.
|
||||
|
||||
But keep in mind that not all TV channels are available for viewing online, and in this case there is little we can do about it.
|
||||
|
||||
### Are you planning to include a Video On Demand (VOD) to the playlist?
|
||||
|
||||
No.
|
||||
|
||||
### Why is the channel on the iptv-org.github.io but not in the playlist?
|
||||
|
||||
The site contains a list of all TV channels in the world and only those of them for which we have working stream links are included in the playlists.
|
||||
|
||||
### Can I add a radio broadcast?
|
||||
|
||||
Yes, if it is a [visual radio](https://en.wikipedia.org/wiki/Visual_radio) in which a video and audio are shown at the same time.
|
||||
|
||||
### Why don't you accept links to Xtream Codes server?
|
||||
|
||||
Xtream Codes streams tend to be very unstable, and often links to them fail very quickly, so it's easier for us to initially exclude them from the playlist than to search for expired ones every day.
|
||||
|
||||
@ -1,24 +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/>
|
||||
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/>
|
||||
|
||||
@ -1,79 +1,79 @@
|
||||
# IPTV [](https://github.com/iptv-org/iptv/actions/workflows/update.yml)
|
||||
|
||||
Collection of publicly available IPTV (Internet Protocol television) channels from all over the world.
|
||||
|
||||
## Table of contents
|
||||
|
||||
- 🚀 [How to use?](#how-to-use)
|
||||
- 📺 [Playlists](#playlists)
|
||||
- 🗓 [EPG](#epg)
|
||||
- 🗄 [Database](#database)
|
||||
- 👨💻 [API](#api)
|
||||
- 📚 [Resources](#resources)
|
||||
- 💬 [Discussions](#discussions)
|
||||
- ❓ [FAQ](#faq)
|
||||
- 🛠 [Contribution](#contribution)
|
||||
- ⚖ [Legal](#legal)
|
||||
- © [License](#license)
|
||||
|
||||
## How to use?
|
||||
|
||||
Simply paste the link to one of the playlists into [any video player](https://github.com/iptv-org/awesome-iptv#apps) that supports live streaming and press _Open_.
|
||||
|
||||

|
||||
|
||||
## Playlists
|
||||
|
||||
The main playlist containing all channels available in the repository can be found at:
|
||||
|
||||
```
|
||||
https://iptv-org.github.io/iptv/index.m3u
|
||||
```
|
||||
|
||||
Links to other playlists can be found in the [PLAYLISTS.md](PLAYLISTS.md) file.
|
||||
|
||||
## EPG
|
||||
|
||||
[Electronic Program Guide](https://en.wikipedia.org/wiki/Electronic_program_guide) for most of the channels can be downloaded using utilities published in the [iptv-org/epg](https://github.com/iptv-org/epg) repository.
|
||||
|
||||
## Database
|
||||
|
||||
All channel data is taken from the [iptv-org/database](https://github.com/iptv-org/database) repository. If you find any errors please open a new [issue](https://github.com/iptv-org/database/issues) there.
|
||||
|
||||
## API
|
||||
|
||||
The API documentation can be found in the [iptv-org/api](https://github.com/iptv-org/api) repository.
|
||||
|
||||
## Resources
|
||||
|
||||
Links to other useful IPTV-related resources can be found in the [iptv-org/awesome-iptv](https://github.com/iptv-org/awesome-iptv) repository.
|
||||
|
||||
## Discussions
|
||||
|
||||
If you need help finding a channel, have a question or idea, welcome to the [Discussions](https://github.com/orgs/iptv-org/discussions).
|
||||
|
||||
## FAQ
|
||||
|
||||
The answers to the most popular questions can be found in the [FAQ.md](FAQ.md) file.
|
||||
|
||||
## Contribution
|
||||
|
||||
Please make sure to read the [Contributing Guide](CONTRIBUTING.md) before sending an issue or making a pull request.
|
||||
|
||||
And thank you to everyone who has already contributed!
|
||||
|
||||
### Backers
|
||||
|
||||
<a href="https://opencollective.com/iptv-org"><img src="https://opencollective.com/iptv-org/backers.svg?width=890" /></a>
|
||||
|
||||
### Contributors
|
||||
|
||||
<a href="https://github.com/iptv-org/iptv/graphs/contributors"><img src="https://opencollective.com/iptv-org/contributors.svg?width=890" /></a>
|
||||
|
||||
## Legal
|
||||
|
||||
No video files are stored in this repository. The repository simply contains user-submitted links to publicly available video stream URLs, which to the best of our knowledge have been intentionally made publicly by the copyright holders. If any links in these playlists infringe on your rights as a copyright holder, they may be removed by sending a [pull request](https://github.com/iptv-org/iptv/pulls) or opening an [issue](https://github.com/iptv-org/iptv/issues/new?assignees=freearhey&labels=removal+request&template=--removal-request.yml&title=Remove%3A+). However, note that we have **no control** over the destination of the link, and just removing the link from the playlist will not remove its contents from the web. Note that linking does not directly infringe copyright because no copy is made on the site providing the link, and thus this is **not** a valid reason to send a DMCA notice to GitHub. To remove this content from the web, you should contact the web host that's actually hosting the content (**not** GitHub, nor the maintainers of this repository).
|
||||
|
||||
## License
|
||||
|
||||
[](LICENSE)
|
||||
# IPTV [](https://github.com/iptv-org/iptv/actions/workflows/update.yml)
|
||||
|
||||
Collection of publicly available IPTV (Internet Protocol television) channels from all over the world.
|
||||
|
||||
## Table of contents
|
||||
|
||||
- 🚀 [How to use?](#how-to-use)
|
||||
- 📺 [Playlists](#playlists)
|
||||
- 🗓 [EPG](#epg)
|
||||
- 🗄 [Database](#database)
|
||||
- 👨💻 [API](#api)
|
||||
- 📚 [Resources](#resources)
|
||||
- 💬 [Discussions](#discussions)
|
||||
- ❓ [FAQ](#faq)
|
||||
- 🛠 [Contribution](#contribution)
|
||||
- ⚖ [Legal](#legal)
|
||||
- © [License](#license)
|
||||
|
||||
## How to use?
|
||||
|
||||
Simply paste the link to one of the playlists into [any video player](https://github.com/iptv-org/awesome-iptv#apps) that supports live streaming and press _Open_.
|
||||
|
||||

|
||||
|
||||
## Playlists
|
||||
|
||||
The main playlist containing all channels available in the repository can be found at:
|
||||
|
||||
```
|
||||
https://iptv-org.github.io/iptv/index.m3u
|
||||
```
|
||||
|
||||
Links to other playlists can be found in the [PLAYLISTS.md](PLAYLISTS.md) file.
|
||||
|
||||
## EPG
|
||||
|
||||
[Electronic Program Guide](https://en.wikipedia.org/wiki/Electronic_program_guide) for most of the channels can be downloaded using utilities published in the [iptv-org/epg](https://github.com/iptv-org/epg) repository.
|
||||
|
||||
## Database
|
||||
|
||||
All channel data is taken from the [iptv-org/database](https://github.com/iptv-org/database) repository. If you find any errors please open a new [issue](https://github.com/iptv-org/database/issues) there.
|
||||
|
||||
## API
|
||||
|
||||
The API documentation can be found in the [iptv-org/api](https://github.com/iptv-org/api) repository.
|
||||
|
||||
## Resources
|
||||
|
||||
Links to other useful IPTV-related resources can be found in the [iptv-org/awesome-iptv](https://github.com/iptv-org/awesome-iptv) repository.
|
||||
|
||||
## Discussions
|
||||
|
||||
If you need help finding a channel, have a question or idea, welcome to the [Discussions](https://github.com/orgs/iptv-org/discussions).
|
||||
|
||||
## FAQ
|
||||
|
||||
The answers to the most popular questions can be found in the [FAQ.md](FAQ.md) file.
|
||||
|
||||
## Contribution
|
||||
|
||||
Please make sure to read the [Contributing Guide](CONTRIBUTING.md) before sending an issue or making a pull request.
|
||||
|
||||
And thank you to everyone who has already contributed!
|
||||
|
||||
### Backers
|
||||
|
||||
<a href="https://opencollective.com/iptv-org"><img src="https://opencollective.com/iptv-org/backers.svg?width=890" /></a>
|
||||
|
||||
### Contributors
|
||||
|
||||
<a href="https://github.com/iptv-org/iptv/graphs/contributors"><img src="https://opencollective.com/iptv-org/contributors.svg?width=890" /></a>
|
||||
|
||||
## Legal
|
||||
|
||||
No video files are stored in this repository. The repository simply contains user-submitted links to publicly available video stream URLs, which to the best of our knowledge have been intentionally made publicly by the copyright holders. If any links in these playlists infringe on your rights as a copyright holder, they may be removed by sending a [pull request](https://github.com/iptv-org/iptv/pulls) or opening an [issue](https://github.com/iptv-org/iptv/issues/new?assignees=freearhey&labels=removal+request&template=--removal-request.yml&title=Remove%3A+). However, note that we have **no control** over the destination of the link, and just removing the link from the playlist will not remove its contents from the web. Note that linking does not directly infringe copyright because no copy is made on the site providing the link, and thus this is **not** a valid reason to send a DMCA notice to GitHub. To remove this content from the web, you should contact the web host that's actually hosting the content (**not** GitHub, nor the maintainers of this repository).
|
||||
|
||||
## License
|
||||
|
||||
[](LICENSE)
|
||||
|
||||
@ -1,17 +1,17 @@
|
||||
{
|
||||
"files": ["streams/*.m3u"],
|
||||
"rules": {
|
||||
"no-empty-lines": true,
|
||||
"require-header": true,
|
||||
"attribute-quotes": true,
|
||||
"require-info": true,
|
||||
"require-title": true,
|
||||
"no-trailing-spaces": false,
|
||||
"no-whitespace-before-title": true,
|
||||
"no-multi-spaces": true,
|
||||
"no-extra-comma": true,
|
||||
"space-before-paren": true,
|
||||
"no-dash": true,
|
||||
"require-link": true
|
||||
}
|
||||
}
|
||||
{
|
||||
"files": ["streams/*.m3u"],
|
||||
"rules": {
|
||||
"no-empty-lines": true,
|
||||
"require-header": true,
|
||||
"attribute-quotes": true,
|
||||
"require-info": true,
|
||||
"require-title": true,
|
||||
"no-trailing-spaces": false,
|
||||
"no-whitespace-before-title": true,
|
||||
"no-multi-spaces": true,
|
||||
"no-extra-comma": true,
|
||||
"space-before-paren": true,
|
||||
"no-dash": true,
|
||||
"require-link": true
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
export const ROOT_DIR = process.env.ROOT_DIR || './'
|
||||
export const STREAMS_DIR = process.env.STREAMS_DIR || './streams'
|
||||
export const PUBLIC_DIR = process.env.PUBLIC_DIR || './.gh-pages'
|
||||
export const README_DIR = process.env.README_DIR || './.readme'
|
||||
export const API_DIR = process.env.API_DIR || './.api'
|
||||
export const DATA_DIR = process.env.DATA_DIR || './temp/data'
|
||||
export const LOGS_DIR = process.env.LOGS_DIR || './temp/logs'
|
||||
export const TESTING = process.env.NODE_ENV === 'test' ? true : false
|
||||
export const OWNER = 'iptv-org'
|
||||
export const REPO = 'iptv'
|
||||
export const EOL = '\r\n'
|
||||
export const ROOT_DIR = process.env.ROOT_DIR || './'
|
||||
export const STREAMS_DIR = process.env.STREAMS_DIR || './streams'
|
||||
export const PUBLIC_DIR = process.env.PUBLIC_DIR || './.gh-pages'
|
||||
export const README_DIR = process.env.README_DIR || './.readme'
|
||||
export const API_DIR = process.env.API_DIR || './.api'
|
||||
export const DATA_DIR = process.env.DATA_DIR || './temp/data'
|
||||
export const LOGS_DIR = process.env.LOGS_DIR || './temp/logs'
|
||||
export const TESTING = process.env.NODE_ENV === 'test' ? true : false
|
||||
export const OWNER = 'iptv-org'
|
||||
export const REPO = 'iptv'
|
||||
export const EOL = '\r\n'
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
export type LogItem = {
|
||||
type: string
|
||||
filepath: string
|
||||
count: number
|
||||
}
|
||||
|
||||
export class LogParser {
|
||||
parse(content: string): LogItem[] {
|
||||
if (!content) return []
|
||||
const lines = content.split('\n')
|
||||
|
||||
return lines.map(line => (line ? JSON.parse(line) : null)).filter(l => l)
|
||||
}
|
||||
}
|
||||
export type LogItem = {
|
||||
type: string
|
||||
filepath: string
|
||||
count: number
|
||||
}
|
||||
|
||||
export class LogParser {
|
||||
parse(content: string): LogItem[] {
|
||||
if (!content) return []
|
||||
const lines = content.split('\n')
|
||||
|
||||
return lines.map(line => (line ? JSON.parse(line) : null)).filter(l => l)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
export default class NumberParser {
|
||||
async parse(number: string) {
|
||||
const parsed = parseInt(number)
|
||||
if (isNaN(parsed)) {
|
||||
throw new Error('numberParser:parse() Input value is not a number')
|
||||
}
|
||||
|
||||
return parsed
|
||||
}
|
||||
}
|
||||
export default class NumberParser {
|
||||
async parse(number: string) {
|
||||
const parsed = parseInt(number)
|
||||
if (isNaN(parsed)) {
|
||||
throw new Error('numberParser:parse() Input value is not a number')
|
||||
}
|
||||
|
||||
return parsed
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,31 +1,31 @@
|
||||
import { URL } from 'node:url'
|
||||
|
||||
interface ProxyParserResult {
|
||||
protocol: string | null
|
||||
auth?: {
|
||||
username?: string
|
||||
password?: string
|
||||
}
|
||||
host: string
|
||||
port: number | null
|
||||
}
|
||||
|
||||
export class ProxyParser {
|
||||
parse(_url: string): ProxyParserResult {
|
||||
const parsed = new URL(_url)
|
||||
|
||||
const result: ProxyParserResult = {
|
||||
protocol: parsed.protocol.replace(':', '') || null,
|
||||
host: parsed.hostname,
|
||||
port: parsed.port ? parseInt(parsed.port) : null
|
||||
}
|
||||
|
||||
if (parsed.username || parsed.password) {
|
||||
result.auth = {}
|
||||
if (parsed.username) result.auth.username = parsed.username
|
||||
if (parsed.password) result.auth.password = parsed.password
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
import { URL } from 'node:url'
|
||||
|
||||
interface ProxyParserResult {
|
||||
protocol: string | null
|
||||
auth?: {
|
||||
username?: string
|
||||
password?: string
|
||||
}
|
||||
host: string
|
||||
port: number | null
|
||||
}
|
||||
|
||||
export class ProxyParser {
|
||||
parse(_url: string): ProxyParserResult {
|
||||
const parsed = new URL(_url)
|
||||
|
||||
const result: ProxyParserResult = {
|
||||
protocol: parsed.protocol.replace(':', '') || null,
|
||||
host: parsed.hostname,
|
||||
port: parsed.port ? parseInt(parsed.port) : null
|
||||
}
|
||||
|
||||
if (parsed.username || parsed.password) {
|
||||
result.auth = {}
|
||||
if (parsed.username) result.auth.username = parsed.username
|
||||
if (parsed.password) result.auth.password = parsed.password
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
export interface Generator {
|
||||
generate(): Promise<void>
|
||||
}
|
||||
export interface Generator {
|
||||
generate(): Promise<void>
|
||||
}
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
import { IssueData } from '../core'
|
||||
|
||||
type IssueProps = {
|
||||
number: number
|
||||
labels: string[]
|
||||
data: IssueData
|
||||
}
|
||||
|
||||
export class Issue {
|
||||
number: number
|
||||
labels: string[]
|
||||
data: IssueData
|
||||
|
||||
constructor({ number, labels, data }: IssueProps) {
|
||||
this.number = number
|
||||
this.labels = labels
|
||||
this.data = data
|
||||
}
|
||||
}
|
||||
import { IssueData } from '../core'
|
||||
|
||||
type IssueProps = {
|
||||
number: number
|
||||
labels: string[]
|
||||
data: IssueData
|
||||
}
|
||||
|
||||
export class Issue {
|
||||
number: number
|
||||
labels: string[]
|
||||
data: IssueData
|
||||
|
||||
constructor({ number, labels, data }: IssueProps) {
|
||||
this.number = number
|
||||
this.labels = labels
|
||||
this.data = data
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export * from './categoriesTable'
|
||||
export * from './countriesTable'
|
||||
export * from './languagesTable'
|
||||
export * from './regionsTable'
|
||||
export * from './categoriesTable'
|
||||
export * from './countriesTable'
|
||||
export * from './languagesTable'
|
||||
export * from './regionsTable'
|
||||
|
||||
@ -1,85 +1,85 @@
|
||||
{"type":"raw","filepath":"raw/ad.m3u","count":4}
|
||||
{"type":"raw","filepath":"raw/ca.m3u","count":2}
|
||||
{"type":"raw","filepath":"raw/in.m3u","count":1}
|
||||
{"type":"raw","filepath":"raw/kg.m3u","count":1}
|
||||
{"type":"raw","filepath":"raw/uk.m3u","count":1}
|
||||
{"type":"raw","filepath":"raw/unsorted.m3u","count":4}
|
||||
{"type":"category","filepath":"categories/auto.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/animation.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/classic.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/comedy.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/culture.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/documentary.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/business.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/cooking.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/education.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/family.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/legislative.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/news.m3u","count":1}
|
||||
{"type":"category","filepath":"categories/kids.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/lifestyle.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/movies.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/religious.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/outdoor.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/general.m3u","count":3}
|
||||
{"type":"category","filepath":"categories/relax.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/music.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/series.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/travel.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/sports.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/science.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/weather.m3u","count":1}
|
||||
{"type":"category","filepath":"categories/shop.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/xxx.m3u","count":1}
|
||||
{"type":"category","filepath":"categories/undefined.m3u","count":7}
|
||||
{"type":"category","filepath":"categories/entertainment.m3u","count":0}
|
||||
{"type":"language","filepath":"languages/cat.m3u","count":1}
|
||||
{"type":"language","filepath":"languages/eng.m3u","count":1}
|
||||
{"type":"language","filepath":"languages/undefined.m3u","count":8}
|
||||
{"type":"language","filepath":"languages/rus.m3u","count":1}
|
||||
{"type":"country","filepath":"countries/ad.m3u","count":1}
|
||||
{"type":"country","filepath":"countries/ru.m3u","count":1}
|
||||
{"type":"country","filepath":"countries/ca.m3u","count":2}
|
||||
{"type":"country","filepath":"countries/int.m3u","count":4}
|
||||
{"type":"country","filepath":"countries/undefined.m3u","count":4}
|
||||
{"type":"subdivision","filepath":"subdivisions/ad-02.m3u","count":1}
|
||||
{"type":"city","filepath":"cities/adcan.m3u","count":1}
|
||||
{"type":"region","filepath":"regions/afr.m3u","count":2}
|
||||
{"type":"source","filepath":"sources/in.m3u","count":1}
|
||||
{"type":"subdivision","filepath":"subdivisions/ad-07.m3u","count":1}
|
||||
{"type":"subdivision","filepath":"subdivisions/ca-on.m3u","count":1}
|
||||
{"type":"region","filepath":"regions/amer.m3u","count":5}
|
||||
{"type":"region","filepath":"regions/apac.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/cas.m3u","count":3}
|
||||
{"type":"region","filepath":"regions/asean.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/cis.m3u","count":4}
|
||||
{"type":"region","filepath":"regions/carib.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/arab.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/emea.m3u","count":5}
|
||||
{"type":"region","filepath":"regions/asia.m3u","count":4}
|
||||
{"type":"region","filepath":"regions/cenamer.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/ww.m3u","count":7}
|
||||
{"type":"region","filepath":"regions/eur.m3u","count":5}
|
||||
{"type":"region","filepath":"regions/lac.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/maghreb.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/latam.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/hispam.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/mena.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/mideast.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/nam.m3u","count":5}
|
||||
{"type":"region","filepath":"regions/oce.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/nord.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/southam.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/noram.m3u","count":5}
|
||||
{"type":"region","filepath":"regions/wafr.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/sas.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/ssa.m3u","count":2}
|
||||
{"type":"source","filepath":"sources/unsorted.m3u","count":4}
|
||||
{"type":"source","filepath":"sources/ca.m3u","count":2}
|
||||
{"type":"source","filepath":"sources/ad.m3u","count":3}
|
||||
{"type":"source","filepath":"sources/uk.m3u","count":1}
|
||||
{"type":"source","filepath":"sources/kg.m3u","count":1}
|
||||
{"type":"index","filepath":"index.m3u","count":11}
|
||||
{"type":"index","filepath":"index.category.m3u","count":12}
|
||||
{"type":"index","filepath":"index.country.m3u","count":12}
|
||||
{"type":"index","filepath":"index.language.m3u","count":11}
|
||||
{"type":"raw","filepath":"raw/ad.m3u","count":4}
|
||||
{"type":"raw","filepath":"raw/ca.m3u","count":2}
|
||||
{"type":"raw","filepath":"raw/in.m3u","count":1}
|
||||
{"type":"raw","filepath":"raw/kg.m3u","count":1}
|
||||
{"type":"raw","filepath":"raw/uk.m3u","count":1}
|
||||
{"type":"raw","filepath":"raw/unsorted.m3u","count":4}
|
||||
{"type":"category","filepath":"categories/auto.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/animation.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/classic.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/comedy.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/culture.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/documentary.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/business.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/cooking.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/education.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/family.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/legislative.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/news.m3u","count":1}
|
||||
{"type":"category","filepath":"categories/kids.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/lifestyle.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/movies.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/religious.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/outdoor.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/general.m3u","count":3}
|
||||
{"type":"category","filepath":"categories/relax.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/music.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/series.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/travel.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/sports.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/science.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/weather.m3u","count":1}
|
||||
{"type":"category","filepath":"categories/shop.m3u","count":0}
|
||||
{"type":"category","filepath":"categories/xxx.m3u","count":1}
|
||||
{"type":"category","filepath":"categories/undefined.m3u","count":7}
|
||||
{"type":"category","filepath":"categories/entertainment.m3u","count":0}
|
||||
{"type":"language","filepath":"languages/cat.m3u","count":1}
|
||||
{"type":"language","filepath":"languages/eng.m3u","count":1}
|
||||
{"type":"language","filepath":"languages/undefined.m3u","count":8}
|
||||
{"type":"language","filepath":"languages/rus.m3u","count":1}
|
||||
{"type":"country","filepath":"countries/ad.m3u","count":1}
|
||||
{"type":"country","filepath":"countries/ru.m3u","count":1}
|
||||
{"type":"country","filepath":"countries/ca.m3u","count":2}
|
||||
{"type":"country","filepath":"countries/int.m3u","count":4}
|
||||
{"type":"country","filepath":"countries/undefined.m3u","count":4}
|
||||
{"type":"subdivision","filepath":"subdivisions/ad-02.m3u","count":1}
|
||||
{"type":"city","filepath":"cities/adcan.m3u","count":1}
|
||||
{"type":"region","filepath":"regions/afr.m3u","count":2}
|
||||
{"type":"source","filepath":"sources/in.m3u","count":1}
|
||||
{"type":"subdivision","filepath":"subdivisions/ad-07.m3u","count":1}
|
||||
{"type":"subdivision","filepath":"subdivisions/ca-on.m3u","count":1}
|
||||
{"type":"region","filepath":"regions/amer.m3u","count":5}
|
||||
{"type":"region","filepath":"regions/apac.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/cas.m3u","count":3}
|
||||
{"type":"region","filepath":"regions/asean.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/cis.m3u","count":4}
|
||||
{"type":"region","filepath":"regions/carib.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/arab.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/emea.m3u","count":5}
|
||||
{"type":"region","filepath":"regions/asia.m3u","count":4}
|
||||
{"type":"region","filepath":"regions/cenamer.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/ww.m3u","count":7}
|
||||
{"type":"region","filepath":"regions/eur.m3u","count":5}
|
||||
{"type":"region","filepath":"regions/lac.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/maghreb.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/latam.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/hispam.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/mena.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/mideast.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/nam.m3u","count":5}
|
||||
{"type":"region","filepath":"regions/oce.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/nord.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/southam.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/noram.m3u","count":5}
|
||||
{"type":"region","filepath":"regions/wafr.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/sas.m3u","count":2}
|
||||
{"type":"region","filepath":"regions/ssa.m3u","count":2}
|
||||
{"type":"source","filepath":"sources/unsorted.m3u","count":4}
|
||||
{"type":"source","filepath":"sources/ca.m3u","count":2}
|
||||
{"type":"source","filepath":"sources/ad.m3u","count":3}
|
||||
{"type":"source","filepath":"sources/uk.m3u","count":1}
|
||||
{"type":"source","filepath":"sources/kg.m3u","count":1}
|
||||
{"type":"index","filepath":"index.m3u","count":11}
|
||||
{"type":"index","filepath":"index.category.m3u","count":12}
|
||||
{"type":"index","filepath":"index.country.m3u","count":12}
|
||||
{"type":"index","filepath":"index.language.m3u","count":11}
|
||||
|
||||
@ -1,177 +1,177 @@
|
||||
## Playlists
|
||||
|
||||
There are several versions of playlists that differ in the way they are grouped. As of January 30th, 2024, we have stopped distributing NSFW channels. For more information, please look at [this issue](https://github.com/iptv-org/iptv/issues/15723).
|
||||
|
||||
### Grouped by category
|
||||
|
||||
Playlists in which channels are grouped by category.
|
||||
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
<br>
|
||||
|
||||
```
|
||||
https://iptv-org.github.io/iptv/index.category.m3u
|
||||
```
|
||||
|
||||
Same thing, but split up into separate files:
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th align="left">Category</th><th align="left">Channels</th><th align="left">Playlist</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>Animation</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/animation.m3u</code></td></tr>
|
||||
<tr><td>Auto</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/auto.m3u</code></td></tr>
|
||||
<tr><td>Business</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/business.m3u</code></td></tr>
|
||||
<tr><td>Classic</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/classic.m3u</code></td></tr>
|
||||
<tr><td>Comedy</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/comedy.m3u</code></td></tr>
|
||||
<tr><td>Cooking</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/cooking.m3u</code></td></tr>
|
||||
<tr><td>Culture</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/culture.m3u</code></td></tr>
|
||||
<tr><td>Documentary</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/documentary.m3u</code></td></tr>
|
||||
<tr><td>Education</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/education.m3u</code></td></tr>
|
||||
<tr><td>Entertainment</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/entertainment.m3u</code></td></tr>
|
||||
<tr><td>Family</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/family.m3u</code></td></tr>
|
||||
<tr><td>General</td><td align="right">2</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/general.m3u</code></td></tr>
|
||||
<tr><td>Kids</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/kids.m3u</code></td></tr>
|
||||
<tr><td>Legislative</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/legislative.m3u</code></td></tr>
|
||||
<tr><td>Lifestyle</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/lifestyle.m3u</code></td></tr>
|
||||
<tr><td>Movies</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/movies.m3u</code></td></tr>
|
||||
<tr><td>Music</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/music.m3u</code></td></tr>
|
||||
<tr><td>News</td><td align="right">1</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/news.m3u</code></td></tr>
|
||||
<tr><td>Outdoor</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/outdoor.m3u</code></td></tr>
|
||||
<tr><td>Relax</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/relax.m3u</code></td></tr>
|
||||
<tr><td>Religious</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/religious.m3u</code></td></tr>
|
||||
<tr><td>Science</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/science.m3u</code></td></tr>
|
||||
<tr><td>Series</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/series.m3u</code></td></tr>
|
||||
<tr><td>Shop</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/shop.m3u</code></td></tr>
|
||||
<tr><td>Sports</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/sports.m3u</code></td></tr>
|
||||
<tr><td>Travel</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/travel.m3u</code></td></tr>
|
||||
<tr><td>Weather</td><td align="right">1</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/weather.m3u</code></td></tr>
|
||||
<tr><td>XXX</td><td align="right">1</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/xxx.m3u</code></td></tr>
|
||||
<tr><td>Undefined</td><td align="right">3</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/undefined.m3u</code></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</details>
|
||||
|
||||
### Grouped by language
|
||||
|
||||
Playlists in which channels are grouped by the language in which they are broadcast.
|
||||
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
<br>
|
||||
|
||||
```
|
||||
https://iptv-org.github.io/iptv/index.language.m3u
|
||||
```
|
||||
|
||||
Same thing, but split up into separate files:
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th align="left">Language</th><th align="left">Channels</th><th align="left">Playlist</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td align="left">Catalan</td><td align="right">1</td><td align="left" nowrap><code>https://iptv-org.github.io/iptv/languages/cat.m3u</code></td></tr>
|
||||
<tr><td align="left">English</td><td align="right">1</td><td align="left" nowrap><code>https://iptv-org.github.io/iptv/languages/eng.m3u</code></td></tr>
|
||||
<tr><td align="left">French</td><td align="right">1</td><td align="left" nowrap><code>https://iptv-org.github.io/iptv/languages/fra.m3u</code></td></tr>
|
||||
<tr><td align="left">Russian</td><td align="right">1</td><td align="left" nowrap><code>https://iptv-org.github.io/iptv/languages/rus.m3u</code></td></tr>
|
||||
<tr><td align="left">Undefined</td><td align="right">2</td><td align="left" nowrap><code>https://iptv-org.github.io/iptv/languages/undefined.m3u</code></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</details>
|
||||
|
||||
### Grouped by broadcast area
|
||||
|
||||
Playlists in which channels are grouped by broadcast area.
|
||||
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
#### Countries
|
||||
|
||||
```
|
||||
https://iptv-org.github.io/iptv/index.country.m3u
|
||||
```
|
||||
|
||||
Same thing, but split up into separate files:
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
- 🇦🇩 Andorra <code>https://iptv-org.github.io/iptv/countries/ad.m3u</code>
|
||||
- Canillo <code>https://iptv-org.github.io/iptv/subdivisions/ad-02.m3u</code>
|
||||
- Canillo <code>https://iptv-org.github.io/iptv/cities/adcan.m3u</code>
|
||||
- 🇨🇲 Cameroon <code>https://iptv-org.github.io/iptv/countries/cm.m3u</code>
|
||||
- 🇨🇦 Canada <code>https://iptv-org.github.io/iptv/countries/ca.m3u</code>
|
||||
- Ontario <code>https://iptv-org.github.io/iptv/subdivisions/ca-on.m3u</code>
|
||||
- 🇨🇻 Cape Verde <code>https://iptv-org.github.io/iptv/countries/cv.m3u</code>
|
||||
- 🇭🇰 Hong Kong <code>https://iptv-org.github.io/iptv/countries/hk.m3u</code>
|
||||
- Sai Kung <code>https://iptv-org.github.io/iptv/cities/hk9sk.m3u</code>
|
||||
- 🇨🇬 Republic of the Congo <code>https://iptv-org.github.io/iptv/countries/cg.m3u</code>
|
||||
- 🇷🇪 Réunion <code>https://iptv-org.github.io/iptv/countries/re.m3u</code>
|
||||
- 🇷🇴 Romania <code>https://iptv-org.github.io/iptv/countries/ro.m3u</code>
|
||||
- 🇷🇺 Russia <code>https://iptv-org.github.io/iptv/countries/ru.m3u</code>
|
||||
- 🇷🇼 Rwanda <code>https://iptv-org.github.io/iptv/countries/rw.m3u</code>
|
||||
- 🇧🇱 Saint Barthélemy <code>https://iptv-org.github.io/iptv/countries/bl.m3u</code>
|
||||
- 🇸🇭 Saint Helena <code>https://iptv-org.github.io/iptv/countries/sh.m3u</code>
|
||||
- 🇰🇳 Saint Kitts and Nevis <code>https://iptv-org.github.io/iptv/countries/kn.m3u</code>
|
||||
- 🌐 International <code>https://iptv-org.github.io/iptv/countries/int.m3u</code>
|
||||
- Undefined <code>https://iptv-org.github.io/iptv/countries/undefined.m3u</code>
|
||||
|
||||
#### Regions
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
- Africa <code>https://iptv-org.github.io/iptv/regions/afr.m3u</code>
|
||||
- Americas <code>https://iptv-org.github.io/iptv/regions/amer.m3u</code>
|
||||
- Arab world <code>https://iptv-org.github.io/iptv/regions/arab.m3u</code>
|
||||
- Asia <code>https://iptv-org.github.io/iptv/regions/asia.m3u</code>
|
||||
- Asia-Pacific <code>https://iptv-org.github.io/iptv/regions/apac.m3u</code>
|
||||
- Association of Southeast Asian Nations <code>https://iptv-org.github.io/iptv/regions/asean.m3u</code>
|
||||
- Caribbean <code>https://iptv-org.github.io/iptv/regions/carib.m3u</code>
|
||||
- Central America <code>https://iptv-org.github.io/iptv/regions/cenamer.m3u</code>
|
||||
- Central Asia <code>https://iptv-org.github.io/iptv/regions/cas.m3u</code>
|
||||
- Commonwealth of Independent States <code>https://iptv-org.github.io/iptv/regions/cis.m3u</code>
|
||||
- Europe <code>https://iptv-org.github.io/iptv/regions/eur.m3u</code>
|
||||
- Europe, the Middle East and Africa <code>https://iptv-org.github.io/iptv/regions/emea.m3u</code>
|
||||
- Hispanic America <code>https://iptv-org.github.io/iptv/regions/hispam.m3u</code>
|
||||
- Latin America <code>https://iptv-org.github.io/iptv/regions/latam.m3u</code>
|
||||
- Latin America and the Caribbean <code>https://iptv-org.github.io/iptv/regions/lac.m3u</code>
|
||||
- Maghreb <code>https://iptv-org.github.io/iptv/regions/maghreb.m3u</code>
|
||||
- Middle East <code>https://iptv-org.github.io/iptv/regions/mideast.m3u</code>
|
||||
- Middle East and North Africa <code>https://iptv-org.github.io/iptv/regions/mena.m3u</code>
|
||||
- Nordics <code>https://iptv-org.github.io/iptv/regions/nord.m3u</code>
|
||||
- North America <code>https://iptv-org.github.io/iptv/regions/noram.m3u</code>
|
||||
- Northern America <code>https://iptv-org.github.io/iptv/regions/nam.m3u</code>
|
||||
- Oceania <code>https://iptv-org.github.io/iptv/regions/oce.m3u</code>
|
||||
- South America <code>https://iptv-org.github.io/iptv/regions/southam.m3u</code>
|
||||
- South Asia <code>https://iptv-org.github.io/iptv/regions/sas.m3u</code>
|
||||
- Sub-Saharan Africa <code>https://iptv-org.github.io/iptv/regions/ssa.m3u</code>
|
||||
- West Africa <code>https://iptv-org.github.io/iptv/regions/wafr.m3u</code>
|
||||
|
||||
</details>
|
||||
|
||||
### Grouped by sources
|
||||
|
||||
Playlists in which channels are grouped by broadcast source.
|
||||
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
<br>
|
||||
|
||||
To use the playlist, simply replace `<FILENAME>` in the link below with the name of one of the files in the [streams](streams) folder.
|
||||
|
||||
```
|
||||
https://iptv-org.github.io/iptv/sources/<FILENAME>.m3u
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
Also, any of our internal playlists are available in raw form (without any filtering or sorting) at this link:
|
||||
|
||||
```
|
||||
https://iptv-org.github.io/iptv/raw/<FILENAME>.m3u
|
||||
```
|
||||
## Playlists
|
||||
|
||||
There are several versions of playlists that differ in the way they are grouped. As of January 30th, 2024, we have stopped distributing NSFW channels. For more information, please look at [this issue](https://github.com/iptv-org/iptv/issues/15723).
|
||||
|
||||
### Grouped by category
|
||||
|
||||
Playlists in which channels are grouped by category.
|
||||
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
<br>
|
||||
|
||||
```
|
||||
https://iptv-org.github.io/iptv/index.category.m3u
|
||||
```
|
||||
|
||||
Same thing, but split up into separate files:
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th align="left">Category</th><th align="left">Channels</th><th align="left">Playlist</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>Animation</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/animation.m3u</code></td></tr>
|
||||
<tr><td>Auto</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/auto.m3u</code></td></tr>
|
||||
<tr><td>Business</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/business.m3u</code></td></tr>
|
||||
<tr><td>Classic</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/classic.m3u</code></td></tr>
|
||||
<tr><td>Comedy</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/comedy.m3u</code></td></tr>
|
||||
<tr><td>Cooking</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/cooking.m3u</code></td></tr>
|
||||
<tr><td>Culture</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/culture.m3u</code></td></tr>
|
||||
<tr><td>Documentary</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/documentary.m3u</code></td></tr>
|
||||
<tr><td>Education</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/education.m3u</code></td></tr>
|
||||
<tr><td>Entertainment</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/entertainment.m3u</code></td></tr>
|
||||
<tr><td>Family</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/family.m3u</code></td></tr>
|
||||
<tr><td>General</td><td align="right">2</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/general.m3u</code></td></tr>
|
||||
<tr><td>Kids</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/kids.m3u</code></td></tr>
|
||||
<tr><td>Legislative</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/legislative.m3u</code></td></tr>
|
||||
<tr><td>Lifestyle</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/lifestyle.m3u</code></td></tr>
|
||||
<tr><td>Movies</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/movies.m3u</code></td></tr>
|
||||
<tr><td>Music</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/music.m3u</code></td></tr>
|
||||
<tr><td>News</td><td align="right">1</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/news.m3u</code></td></tr>
|
||||
<tr><td>Outdoor</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/outdoor.m3u</code></td></tr>
|
||||
<tr><td>Relax</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/relax.m3u</code></td></tr>
|
||||
<tr><td>Religious</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/religious.m3u</code></td></tr>
|
||||
<tr><td>Science</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/science.m3u</code></td></tr>
|
||||
<tr><td>Series</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/series.m3u</code></td></tr>
|
||||
<tr><td>Shop</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/shop.m3u</code></td></tr>
|
||||
<tr><td>Sports</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/sports.m3u</code></td></tr>
|
||||
<tr><td>Travel</td><td align="right">0</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/travel.m3u</code></td></tr>
|
||||
<tr><td>Weather</td><td align="right">1</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/weather.m3u</code></td></tr>
|
||||
<tr><td>XXX</td><td align="right">1</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/xxx.m3u</code></td></tr>
|
||||
<tr><td>Undefined</td><td align="right">3</td><td nowrap><code>https://iptv-org.github.io/iptv/categories/undefined.m3u</code></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</details>
|
||||
|
||||
### Grouped by language
|
||||
|
||||
Playlists in which channels are grouped by the language in which they are broadcast.
|
||||
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
<br>
|
||||
|
||||
```
|
||||
https://iptv-org.github.io/iptv/index.language.m3u
|
||||
```
|
||||
|
||||
Same thing, but split up into separate files:
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th align="left">Language</th><th align="left">Channels</th><th align="left">Playlist</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td align="left">Catalan</td><td align="right">1</td><td align="left" nowrap><code>https://iptv-org.github.io/iptv/languages/cat.m3u</code></td></tr>
|
||||
<tr><td align="left">English</td><td align="right">1</td><td align="left" nowrap><code>https://iptv-org.github.io/iptv/languages/eng.m3u</code></td></tr>
|
||||
<tr><td align="left">French</td><td align="right">1</td><td align="left" nowrap><code>https://iptv-org.github.io/iptv/languages/fra.m3u</code></td></tr>
|
||||
<tr><td align="left">Russian</td><td align="right">1</td><td align="left" nowrap><code>https://iptv-org.github.io/iptv/languages/rus.m3u</code></td></tr>
|
||||
<tr><td align="left">Undefined</td><td align="right">2</td><td align="left" nowrap><code>https://iptv-org.github.io/iptv/languages/undefined.m3u</code></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</details>
|
||||
|
||||
### Grouped by broadcast area
|
||||
|
||||
Playlists in which channels are grouped by broadcast area.
|
||||
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
#### Countries
|
||||
|
||||
```
|
||||
https://iptv-org.github.io/iptv/index.country.m3u
|
||||
```
|
||||
|
||||
Same thing, but split up into separate files:
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
- 🇦🇩 Andorra <code>https://iptv-org.github.io/iptv/countries/ad.m3u</code>
|
||||
- Canillo <code>https://iptv-org.github.io/iptv/subdivisions/ad-02.m3u</code>
|
||||
- Canillo <code>https://iptv-org.github.io/iptv/cities/adcan.m3u</code>
|
||||
- 🇨🇲 Cameroon <code>https://iptv-org.github.io/iptv/countries/cm.m3u</code>
|
||||
- 🇨🇦 Canada <code>https://iptv-org.github.io/iptv/countries/ca.m3u</code>
|
||||
- Ontario <code>https://iptv-org.github.io/iptv/subdivisions/ca-on.m3u</code>
|
||||
- 🇨🇻 Cape Verde <code>https://iptv-org.github.io/iptv/countries/cv.m3u</code>
|
||||
- 🇭🇰 Hong Kong <code>https://iptv-org.github.io/iptv/countries/hk.m3u</code>
|
||||
- Sai Kung <code>https://iptv-org.github.io/iptv/cities/hk9sk.m3u</code>
|
||||
- 🇨🇬 Republic of the Congo <code>https://iptv-org.github.io/iptv/countries/cg.m3u</code>
|
||||
- 🇷🇪 Réunion <code>https://iptv-org.github.io/iptv/countries/re.m3u</code>
|
||||
- 🇷🇴 Romania <code>https://iptv-org.github.io/iptv/countries/ro.m3u</code>
|
||||
- 🇷🇺 Russia <code>https://iptv-org.github.io/iptv/countries/ru.m3u</code>
|
||||
- 🇷🇼 Rwanda <code>https://iptv-org.github.io/iptv/countries/rw.m3u</code>
|
||||
- 🇧🇱 Saint Barthélemy <code>https://iptv-org.github.io/iptv/countries/bl.m3u</code>
|
||||
- 🇸🇭 Saint Helena <code>https://iptv-org.github.io/iptv/countries/sh.m3u</code>
|
||||
- 🇰🇳 Saint Kitts and Nevis <code>https://iptv-org.github.io/iptv/countries/kn.m3u</code>
|
||||
- 🌐 International <code>https://iptv-org.github.io/iptv/countries/int.m3u</code>
|
||||
- Undefined <code>https://iptv-org.github.io/iptv/countries/undefined.m3u</code>
|
||||
|
||||
#### Regions
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
- Africa <code>https://iptv-org.github.io/iptv/regions/afr.m3u</code>
|
||||
- Americas <code>https://iptv-org.github.io/iptv/regions/amer.m3u</code>
|
||||
- Arab world <code>https://iptv-org.github.io/iptv/regions/arab.m3u</code>
|
||||
- Asia <code>https://iptv-org.github.io/iptv/regions/asia.m3u</code>
|
||||
- Asia-Pacific <code>https://iptv-org.github.io/iptv/regions/apac.m3u</code>
|
||||
- Association of Southeast Asian Nations <code>https://iptv-org.github.io/iptv/regions/asean.m3u</code>
|
||||
- Caribbean <code>https://iptv-org.github.io/iptv/regions/carib.m3u</code>
|
||||
- Central America <code>https://iptv-org.github.io/iptv/regions/cenamer.m3u</code>
|
||||
- Central Asia <code>https://iptv-org.github.io/iptv/regions/cas.m3u</code>
|
||||
- Commonwealth of Independent States <code>https://iptv-org.github.io/iptv/regions/cis.m3u</code>
|
||||
- Europe <code>https://iptv-org.github.io/iptv/regions/eur.m3u</code>
|
||||
- Europe, the Middle East and Africa <code>https://iptv-org.github.io/iptv/regions/emea.m3u</code>
|
||||
- Hispanic America <code>https://iptv-org.github.io/iptv/regions/hispam.m3u</code>
|
||||
- Latin America <code>https://iptv-org.github.io/iptv/regions/latam.m3u</code>
|
||||
- Latin America and the Caribbean <code>https://iptv-org.github.io/iptv/regions/lac.m3u</code>
|
||||
- Maghreb <code>https://iptv-org.github.io/iptv/regions/maghreb.m3u</code>
|
||||
- Middle East <code>https://iptv-org.github.io/iptv/regions/mideast.m3u</code>
|
||||
- Middle East and North Africa <code>https://iptv-org.github.io/iptv/regions/mena.m3u</code>
|
||||
- Nordics <code>https://iptv-org.github.io/iptv/regions/nord.m3u</code>
|
||||
- North America <code>https://iptv-org.github.io/iptv/regions/noram.m3u</code>
|
||||
- Northern America <code>https://iptv-org.github.io/iptv/regions/nam.m3u</code>
|
||||
- Oceania <code>https://iptv-org.github.io/iptv/regions/oce.m3u</code>
|
||||
- South America <code>https://iptv-org.github.io/iptv/regions/southam.m3u</code>
|
||||
- South Asia <code>https://iptv-org.github.io/iptv/regions/sas.m3u</code>
|
||||
- Sub-Saharan Africa <code>https://iptv-org.github.io/iptv/regions/ssa.m3u</code>
|
||||
- West Africa <code>https://iptv-org.github.io/iptv/regions/wafr.m3u</code>
|
||||
|
||||
</details>
|
||||
|
||||
### Grouped by sources
|
||||
|
||||
Playlists in which channels are grouped by broadcast source.
|
||||
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
<br>
|
||||
|
||||
To use the playlist, simply replace `<FILENAME>` in the link below with the name of one of the files in the [streams](streams) folder.
|
||||
|
||||
```
|
||||
https://iptv-org.github.io/iptv/sources/<FILENAME>.m3u
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
Also, any of our internal playlists are available in raw form (without any filtering or sorting) at this link:
|
||||
|
||||
```
|
||||
https://iptv-org.github.io/iptv/raw/<FILENAME>.m3u
|
||||
```
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,14 +1,14 @@
|
||||
module.exports = {
|
||||
'https://query-streamlink.herokuapp.com/iptv-query?streaming-ip=https://www.twitch.tv/absliveantigua3':
|
||||
{
|
||||
url: 'https://query-streamlink.herokuapp.com/iptv-query?streaming-ip=https://www.twitch.tv/absliveantigua3',
|
||||
http: { referrer: '', 'user-agent': '' },
|
||||
status: { ok: false, code: 'HTTP_NOT_FOUND', message: 'HTTP 404 Not Found' }
|
||||
},
|
||||
'https://tego-cdn2a.sibercdn.com/Live_TV-ABSTV-10/tracks-v3a1/rewind-7200.m3u8?token=e5f61e7be8363eb781b4bdfe591bf917dd529c1a-SjY3NzRTbDZQNnFQVkZaNkZja2RxV3JKc1VBa05zQkdMNStJakRGV0VTTzNrOEVGVUlIQmxta1NLV0o3bzdVdQ-1736094545-1736008145':
|
||||
{
|
||||
url: 'https://tego-cdn2a.sibercdn.com/Live_TV-ABSTV-10/tracks-v3a1/rewind-7200.m3u8?token=e5f61e7be8363eb781b4bdfe591bf917dd529c1a-SjY3NzRTbDZQNnFQVkZaNkZja2RxV3JKc1VBa05zQkdMNStJakRGV0VTTzNrOEVGVUlIQmxta1NLV0o3bzdVdQ-1736094545-1736008145',
|
||||
http: { referrer: '', 'user-agent': '' },
|
||||
status: { ok: false, code: 'HTTP_FORBIDDEN', message: 'HTTP 403 Forbidden' }
|
||||
}
|
||||
}
|
||||
module.exports = {
|
||||
'https://query-streamlink.herokuapp.com/iptv-query?streaming-ip=https://www.twitch.tv/absliveantigua3':
|
||||
{
|
||||
url: 'https://query-streamlink.herokuapp.com/iptv-query?streaming-ip=https://www.twitch.tv/absliveantigua3',
|
||||
http: { referrer: '', 'user-agent': '' },
|
||||
status: { ok: false, code: 'HTTP_NOT_FOUND', message: 'HTTP 404 Not Found' }
|
||||
},
|
||||
'https://tego-cdn2a.sibercdn.com/Live_TV-ABSTV-10/tracks-v3a1/rewind-7200.m3u8?token=e5f61e7be8363eb781b4bdfe591bf917dd529c1a-SjY3NzRTbDZQNnFQVkZaNkZja2RxV3JKc1VBa05zQkdMNStJakRGV0VTTzNrOEVGVUlIQmxta1NLV0o3bzdVdQ-1736094545-1736008145':
|
||||
{
|
||||
url: 'https://tego-cdn2a.sibercdn.com/Live_TV-ABSTV-10/tracks-v3a1/rewind-7200.m3u8?token=e5f61e7be8363eb781b4bdfe591bf917dd529c1a-SjY3NzRTbDZQNnFQVkZaNkZja2RxV3JKc1VBa05zQkdMNStJakRGV0VTTzNrOEVGVUlIQmxta1NLV0o3bzdVdQ-1736094545-1736008145',
|
||||
http: { referrer: '', 'user-agent': '' },
|
||||
status: { ok: false, code: 'HTTP_FORBIDDEN', message: 'HTTP 403 Forbidden' }
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,26 +1,26 @@
|
||||
import { pathToFileURL } from 'node:url'
|
||||
import { execSync } from 'child_process'
|
||||
import fs from 'fs-extra'
|
||||
|
||||
const ENV_VAR =
|
||||
'cross-env DATA_DIR=tests/__data__/input/data STREAMS_DIR=tests/__data__/input/api_generate API_DIR=tests/__data__/output/.api'
|
||||
|
||||
beforeEach(() => {
|
||||
fs.emptyDirSync('tests/__data__/output')
|
||||
})
|
||||
|
||||
describe('api:generate', () => {
|
||||
it('can create streams.json', () => {
|
||||
const cmd = `${ENV_VAR} npm run api:generate`
|
||||
const stdout = execSync(cmd, { encoding: 'utf8' })
|
||||
if (process.env.DEBUG === 'true') console.log(cmd, stdout)
|
||||
|
||||
expect(content('tests/__data__/output/.api/streams.json')).toMatchObject(
|
||||
content('tests/__data__/expected/api_generate/.api/streams.json')
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
function content(filepath: string) {
|
||||
return JSON.parse(fs.readFileSync(pathToFileURL(filepath), { encoding: 'utf8' }))
|
||||
}
|
||||
import { pathToFileURL } from 'node:url'
|
||||
import { execSync } from 'child_process'
|
||||
import fs from 'fs-extra'
|
||||
|
||||
const ENV_VAR =
|
||||
'cross-env DATA_DIR=tests/__data__/input/data STREAMS_DIR=tests/__data__/input/api_generate API_DIR=tests/__data__/output/.api'
|
||||
|
||||
beforeEach(() => {
|
||||
fs.emptyDirSync('tests/__data__/output')
|
||||
})
|
||||
|
||||
describe('api:generate', () => {
|
||||
it('can create streams.json', () => {
|
||||
const cmd = `${ENV_VAR} npm run api:generate`
|
||||
const stdout = execSync(cmd, { encoding: 'utf8' })
|
||||
if (process.env.DEBUG === 'true') console.log(cmd, stdout)
|
||||
|
||||
expect(content('tests/__data__/output/.api/streams.json')).toMatchObject(
|
||||
content('tests/__data__/expected/api_generate/.api/streams.json')
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
function content(filepath: string) {
|
||||
return JSON.parse(fs.readFileSync(pathToFileURL(filepath), { encoding: 'utf8' }))
|
||||
}
|
||||
|
||||
@ -1,38 +1,38 @@
|
||||
import { execSync } from 'child_process'
|
||||
import fs from 'fs-extra'
|
||||
|
||||
type ExecError = {
|
||||
status: number
|
||||
stdout: string
|
||||
}
|
||||
|
||||
const ENV_VAR = 'cross-env DATA_DIR=tests/__data__/input/data'
|
||||
|
||||
beforeEach(() => {
|
||||
fs.emptyDirSync('tests/__data__/output')
|
||||
fs.copySync(
|
||||
'tests/__data__/input/playlist_edit/playlist.m3u',
|
||||
'tests/__data__/output/playlist.m3u'
|
||||
)
|
||||
})
|
||||
|
||||
describe('playlist:edit', () => {
|
||||
it('shows list of options for a streams', () => {
|
||||
const cmd = `${ENV_VAR} npm run playlist:edit --- tests/__data__/output/playlist.m3u`
|
||||
try {
|
||||
const stdout = execSync(cmd, { encoding: 'utf8' })
|
||||
if (process.env.DEBUG === 'true') console.log(cmd, stdout)
|
||||
checkStdout(stdout)
|
||||
} catch (error) {
|
||||
// NOTE: for Windows only
|
||||
if (process.env.DEBUG === 'true') console.log(cmd, error)
|
||||
checkStdout((error as ExecError).stdout)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
function checkStdout(stdout: string) {
|
||||
expect(stdout).toContain('TF1.fr (TF1, Télévision française 1)')
|
||||
expect(stdout).toContain('Type...')
|
||||
expect(stdout).toContain('Skip')
|
||||
}
|
||||
import { execSync } from 'child_process'
|
||||
import fs from 'fs-extra'
|
||||
|
||||
type ExecError = {
|
||||
status: number
|
||||
stdout: string
|
||||
}
|
||||
|
||||
const ENV_VAR = 'cross-env DATA_DIR=tests/__data__/input/data'
|
||||
|
||||
beforeEach(() => {
|
||||
fs.emptyDirSync('tests/__data__/output')
|
||||
fs.copySync(
|
||||
'tests/__data__/input/playlist_edit/playlist.m3u',
|
||||
'tests/__data__/output/playlist.m3u'
|
||||
)
|
||||
})
|
||||
|
||||
describe('playlist:edit', () => {
|
||||
it('shows list of options for a streams', () => {
|
||||
const cmd = `${ENV_VAR} npm run playlist:edit --- tests/__data__/output/playlist.m3u`
|
||||
try {
|
||||
const stdout = execSync(cmd, { encoding: 'utf8' })
|
||||
if (process.env.DEBUG === 'true') console.log(cmd, stdout)
|
||||
checkStdout(stdout)
|
||||
} catch (error) {
|
||||
// NOTE: for Windows only
|
||||
if (process.env.DEBUG === 'true') console.log(cmd, error)
|
||||
checkStdout((error as ExecError).stdout)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
function checkStdout(stdout: string) {
|
||||
expect(stdout).toContain('TF1.fr (TF1, Télévision française 1)')
|
||||
expect(stdout).toContain('Type...')
|
||||
expect(stdout).toContain('Skip')
|
||||
}
|
||||
|
||||
@ -1,36 +1,37 @@
|
||||
import { pathToFileURL } from 'node:url'
|
||||
import { execSync } from 'child_process'
|
||||
import * as fs from 'fs-extra'
|
||||
import { glob } from 'glob'
|
||||
|
||||
const ENV_VAR = 'cross-env STREAMS_DIR=tests/__data__/output/streams DATA_DIR=tests/__data__/input/data'
|
||||
|
||||
beforeEach(() => {
|
||||
fs.emptyDirSync('tests/__data__/output')
|
||||
fs.copySync('tests/__data__/input/playlist_format', 'tests/__data__/output/streams')
|
||||
})
|
||||
|
||||
describe('playlist:format', () => {
|
||||
it('can format playlists', () => {
|
||||
const cmd = `${ENV_VAR} npm run playlist:format`
|
||||
const stdout = execSync(cmd, { encoding: 'utf8' })
|
||||
if (process.env.DEBUG === 'true') console.log(cmd, stdout)
|
||||
|
||||
const files = glob.sync('tests/__data__/expected/playlist_format/*.m3u').map(filepath => {
|
||||
const fileUrl = pathToFileURL(filepath).toString()
|
||||
const pathToRemove = pathToFileURL('tests/__data__/expected/playlist_format/').toString()
|
||||
|
||||
return fileUrl.replace(pathToRemove, '')
|
||||
})
|
||||
|
||||
files.forEach(filepath => {
|
||||
expect(content(`tests/__data__/output/streams/${filepath}`)).toBe(
|
||||
content(`tests/__data__/expected/playlist_format/${filepath}`)
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
function content(filepath: string) {
|
||||
return fs.readFileSync(pathToFileURL(filepath), { encoding: 'utf8' })
|
||||
}
|
||||
import { pathToFileURL } from 'node:url'
|
||||
import { execSync } from 'child_process'
|
||||
import * as fs from 'fs-extra'
|
||||
import { glob } from 'glob'
|
||||
|
||||
const ENV_VAR =
|
||||
'cross-env STREAMS_DIR=tests/__data__/output/streams DATA_DIR=tests/__data__/input/data'
|
||||
|
||||
beforeEach(() => {
|
||||
fs.emptyDirSync('tests/__data__/output')
|
||||
fs.copySync('tests/__data__/input/playlist_format', 'tests/__data__/output/streams')
|
||||
})
|
||||
|
||||
describe('playlist:format', () => {
|
||||
it('can format playlists', () => {
|
||||
const cmd = `${ENV_VAR} npm run playlist:format`
|
||||
const stdout = execSync(cmd, { encoding: 'utf8' })
|
||||
if (process.env.DEBUG === 'true') console.log(cmd, stdout)
|
||||
|
||||
const files = glob.sync('tests/__data__/expected/playlist_format/*.m3u').map(filepath => {
|
||||
const fileUrl = pathToFileURL(filepath).toString()
|
||||
const pathToRemove = pathToFileURL('tests/__data__/expected/playlist_format/').toString()
|
||||
|
||||
return fileUrl.replace(pathToRemove, '')
|
||||
})
|
||||
|
||||
files.forEach(filepath => {
|
||||
expect(content(`tests/__data__/output/streams/${filepath}`)).toBe(
|
||||
content(`tests/__data__/expected/playlist_format/${filepath}`)
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
function content(filepath: string) {
|
||||
return fs.readFileSync(pathToFileURL(filepath), { encoding: 'utf8' })
|
||||
}
|
||||
|
||||
@ -1,43 +1,43 @@
|
||||
import { pathToFileURL } from 'node:url'
|
||||
import { execSync } from 'child_process'
|
||||
import { EOL } from 'node:os'
|
||||
import * as fs from 'fs-extra'
|
||||
import * as glob from 'glob'
|
||||
|
||||
const ENV_VAR =
|
||||
'cross-env STREAMS_DIR=tests/__data__/input/playlist_generate DATA_DIR=tests/__data__/input/data PUBLIC_DIR=tests/__data__/output/.gh-pages LOGS_DIR=tests/__data__/output/logs'
|
||||
|
||||
beforeEach(() => {
|
||||
fs.emptyDirSync('tests/__data__/output')
|
||||
})
|
||||
|
||||
describe('playlist:generate', () => {
|
||||
it('can generate playlists and logs', () => {
|
||||
const cmd = `${ENV_VAR} npm run playlist:generate`
|
||||
const stdout = execSync(cmd, { encoding: 'utf8' })
|
||||
if (process.env.DEBUG === 'true') console.log(cmd, stdout)
|
||||
|
||||
const playlists = glob
|
||||
.sync('tests/__data__/expected/playlist_generate/.gh-pages/**/*.m3u')
|
||||
.map(filepath => {
|
||||
const fileUrl = pathToFileURL(filepath).toString()
|
||||
const pathToRemove = pathToFileURL('tests/__data__/expected/playlist_generate/').toString()
|
||||
|
||||
return fileUrl.replace(pathToRemove, '')
|
||||
})
|
||||
|
||||
playlists.forEach((filepath: string) => {
|
||||
expect(content(`tests/__data__/output/${filepath}`), filepath).toBe(
|
||||
content(`tests/__data__/expected/playlist_generate/${filepath}`)
|
||||
)
|
||||
})
|
||||
|
||||
expect(content('tests/__data__/output/logs/generators.log').split(EOL).sort()).toStrictEqual(
|
||||
content('tests/__data__/expected/playlist_generate/logs/generators.log').split(EOL).sort()
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
function content(filepath: string) {
|
||||
return fs.readFileSync(pathToFileURL(filepath), { encoding: 'utf8' })
|
||||
}
|
||||
import { pathToFileURL } from 'node:url'
|
||||
import { execSync } from 'child_process'
|
||||
import { EOL } from 'node:os'
|
||||
import * as fs from 'fs-extra'
|
||||
import * as glob from 'glob'
|
||||
|
||||
const ENV_VAR =
|
||||
'cross-env STREAMS_DIR=tests/__data__/input/playlist_generate DATA_DIR=tests/__data__/input/data PUBLIC_DIR=tests/__data__/output/.gh-pages LOGS_DIR=tests/__data__/output/logs'
|
||||
|
||||
beforeEach(() => {
|
||||
fs.emptyDirSync('tests/__data__/output')
|
||||
})
|
||||
|
||||
describe('playlist:generate', () => {
|
||||
it('can generate playlists and logs', () => {
|
||||
const cmd = `${ENV_VAR} npm run playlist:generate`
|
||||
const stdout = execSync(cmd, { encoding: 'utf8' })
|
||||
if (process.env.DEBUG === 'true') console.log(cmd, stdout)
|
||||
|
||||
const playlists = glob
|
||||
.sync('tests/__data__/expected/playlist_generate/.gh-pages/**/*.m3u')
|
||||
.map(filepath => {
|
||||
const fileUrl = pathToFileURL(filepath).toString()
|
||||
const pathToRemove = pathToFileURL('tests/__data__/expected/playlist_generate/').toString()
|
||||
|
||||
return fileUrl.replace(pathToRemove, '')
|
||||
})
|
||||
|
||||
playlists.forEach((filepath: string) => {
|
||||
expect(content(`tests/__data__/output/${filepath}`), filepath).toBe(
|
||||
content(`tests/__data__/expected/playlist_generate/${filepath}`)
|
||||
)
|
||||
})
|
||||
|
||||
expect(content('tests/__data__/output/logs/generators.log').split(EOL).sort()).toStrictEqual(
|
||||
content('tests/__data__/expected/playlist_generate/logs/generators.log').split(EOL).sort()
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
function content(filepath: string) {
|
||||
return fs.readFileSync(pathToFileURL(filepath), { encoding: 'utf8' })
|
||||
}
|
||||
|
||||
@ -1,21 +1,21 @@
|
||||
import { execSync } from 'child_process'
|
||||
|
||||
type ExecError = {
|
||||
status: number
|
||||
stdout: string
|
||||
}
|
||||
|
||||
const ENV_VAR = 'cross-env ROOT_DIR=tests/__data__/input DATA_DIR=tests/__data__/input/data'
|
||||
|
||||
describe('playlist:test', () => {
|
||||
it('shows an error if the playlist contains a broken link', () => {
|
||||
const cmd = `${ENV_VAR} npm run playlist:test playlist_test/ag.m3u`
|
||||
try {
|
||||
execSync(cmd, { encoding: 'utf8' })
|
||||
} catch (error) {
|
||||
if (process.env.DEBUG === 'true') console.log(cmd, error)
|
||||
expect((error as ExecError).stdout).toContain('playlist_test/ag.m3u')
|
||||
expect((error as ExecError).stdout).toContain('2 problems (1 errors, 1 warnings)')
|
||||
}
|
||||
})
|
||||
})
|
||||
import { execSync } from 'child_process'
|
||||
|
||||
type ExecError = {
|
||||
status: number
|
||||
stdout: string
|
||||
}
|
||||
|
||||
const ENV_VAR = 'cross-env ROOT_DIR=tests/__data__/input DATA_DIR=tests/__data__/input/data'
|
||||
|
||||
describe('playlist:test', () => {
|
||||
it('shows an error if the playlist contains a broken link', () => {
|
||||
const cmd = `${ENV_VAR} npm run playlist:test playlist_test/ag.m3u`
|
||||
try {
|
||||
execSync(cmd, { encoding: 'utf8' })
|
||||
} catch (error) {
|
||||
if (process.env.DEBUG === 'true') console.log(cmd, error)
|
||||
expect((error as ExecError).stdout).toContain('playlist_test/ag.m3u')
|
||||
expect((error as ExecError).stdout).toContain('2 problems (1 errors, 1 warnings)')
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
@ -1,44 +1,45 @@
|
||||
import { execSync } from 'child_process'
|
||||
|
||||
type ExecError = {
|
||||
status: number
|
||||
stdout: string
|
||||
}
|
||||
|
||||
const ENV_VAR = 'cross-env DATA_DIR=tests/__data__/input/data ROOT_DIR=tests/__data__/input/playlist_validate'
|
||||
|
||||
describe('playlist:validate', () => {
|
||||
it('show an error if channel id in the blocklist', () => {
|
||||
const cmd = `${ENV_VAR} npm run playlist:validate -- us_blocked.m3u`
|
||||
try {
|
||||
execSync(cmd, { encoding: 'utf8' })
|
||||
} catch (error) {
|
||||
if (process.env.DEBUG === 'true') console.log(cmd, error)
|
||||
expect((error as ExecError).stdout).toContain('us_blocked.m3u')
|
||||
expect((error as ExecError).stdout).toContain(
|
||||
'2 error "FoxSports2.us" is on the blocklist due to claims of copyright holders (https://github.com/iptv-org/iptv/issues/0002)'
|
||||
)
|
||||
expect((error as ExecError).stdout).toContain(
|
||||
'4 error "TVN.pl" is on the blocklist due to NSFW content (https://github.com/iptv-org/iptv/issues/0003)'
|
||||
)
|
||||
expect((error as ExecError).stdout).toContain('2 problems (2 errors, 0 warnings)')
|
||||
}
|
||||
})
|
||||
|
||||
it('show a warning if channel has wrong id', () => {
|
||||
const cmd = `${ENV_VAR} npm run playlist:validate -- wrong_id.m3u`
|
||||
try {
|
||||
execSync(cmd, { encoding: 'utf8' })
|
||||
} catch (error) {
|
||||
if (process.env.DEBUG === 'true') console.log(cmd, error)
|
||||
expect((error as ExecError).stdout).toContain(
|
||||
'wrong_id.m3u\n 2 warning "qib22lAq1L.us" is not in the database\n\n1 problems (0 errors, 1 warnings)\n'
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
it('skip the file if it does not exist', () => {
|
||||
const cmd = `${ENV_VAR} npm run playlist:validate -- missing.m3u`
|
||||
execSync(cmd, { encoding: 'utf8' })
|
||||
})
|
||||
})
|
||||
import { execSync } from 'child_process'
|
||||
|
||||
type ExecError = {
|
||||
status: number
|
||||
stdout: string
|
||||
}
|
||||
|
||||
const ENV_VAR =
|
||||
'cross-env DATA_DIR=tests/__data__/input/data ROOT_DIR=tests/__data__/input/playlist_validate'
|
||||
|
||||
describe('playlist:validate', () => {
|
||||
it('show an error if channel id in the blocklist', () => {
|
||||
const cmd = `${ENV_VAR} npm run playlist:validate -- us_blocked.m3u`
|
||||
try {
|
||||
execSync(cmd, { encoding: 'utf8' })
|
||||
} catch (error) {
|
||||
if (process.env.DEBUG === 'true') console.log(cmd, error)
|
||||
expect((error as ExecError).stdout).toContain('us_blocked.m3u')
|
||||
expect((error as ExecError).stdout).toContain(
|
||||
'2 error "FoxSports2.us" is on the blocklist due to claims of copyright holders (https://github.com/iptv-org/iptv/issues/0002)'
|
||||
)
|
||||
expect((error as ExecError).stdout).toContain(
|
||||
'4 error "TVN.pl" is on the blocklist due to NSFW content (https://github.com/iptv-org/iptv/issues/0003)'
|
||||
)
|
||||
expect((error as ExecError).stdout).toContain('2 problems (2 errors, 0 warnings)')
|
||||
}
|
||||
})
|
||||
|
||||
it('show a warning if channel has wrong id', () => {
|
||||
const cmd = `${ENV_VAR} npm run playlist:validate -- wrong_id.m3u`
|
||||
try {
|
||||
execSync(cmd, { encoding: 'utf8' })
|
||||
} catch (error) {
|
||||
if (process.env.DEBUG === 'true') console.log(cmd, error)
|
||||
expect((error as ExecError).stdout).toContain(
|
||||
'wrong_id.m3u\n 2 warning "qib22lAq1L.us" is not in the database\n\n1 problems (0 errors, 1 warnings)\n'
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
it('skip the file if it does not exist', () => {
|
||||
const cmd = `${ENV_VAR} npm run playlist:validate -- missing.m3u`
|
||||
execSync(cmd, { encoding: 'utf8' })
|
||||
})
|
||||
})
|
||||
|
||||
@ -1,26 +1,26 @@
|
||||
import { pathToFileURL } from 'node:url'
|
||||
import { execSync } from 'child_process'
|
||||
import fs from 'fs-extra'
|
||||
|
||||
const ENV_VAR =
|
||||
'cross-env DATA_DIR=tests/__data__/input/data LOGS_DIR=tests/__data__/input/readme_update ROOT_DIR=tests/__data__/output'
|
||||
|
||||
beforeEach(() => {
|
||||
fs.emptyDirSync('tests/__data__/output')
|
||||
})
|
||||
|
||||
describe('readme:update', () => {
|
||||
it('can update readme.md', () => {
|
||||
const cmd = `${ENV_VAR} npm run readme:update`
|
||||
const stdout = execSync(cmd, { encoding: 'utf8' })
|
||||
if (process.env.DEBUG === 'true') console.log(cmd, stdout)
|
||||
|
||||
expect(content('tests/__data__/output/PLAYLISTS.md')).toEqual(
|
||||
content('tests/__data__/expected/readme_update/playlists.md')
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
function content(filepath: string) {
|
||||
return JSON.stringify(fs.readFileSync(pathToFileURL(filepath), { encoding: 'utf8' }))
|
||||
}
|
||||
import { pathToFileURL } from 'node:url'
|
||||
import { execSync } from 'child_process'
|
||||
import fs from 'fs-extra'
|
||||
|
||||
const ENV_VAR =
|
||||
'cross-env DATA_DIR=tests/__data__/input/data LOGS_DIR=tests/__data__/input/readme_update ROOT_DIR=tests/__data__/output'
|
||||
|
||||
beforeEach(() => {
|
||||
fs.emptyDirSync('tests/__data__/output')
|
||||
})
|
||||
|
||||
describe('readme:update', () => {
|
||||
it('can update readme.md', () => {
|
||||
const cmd = `${ENV_VAR} npm run readme:update`
|
||||
const stdout = execSync(cmd, { encoding: 'utf8' })
|
||||
if (process.env.DEBUG === 'true') console.log(cmd, stdout)
|
||||
|
||||
expect(content('tests/__data__/output/PLAYLISTS.md')).toEqual(
|
||||
content('tests/__data__/expected/readme_update/playlists.md')
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
function content(filepath: string) {
|
||||
return JSON.stringify(fs.readFileSync(pathToFileURL(filepath), { encoding: 'utf8' }))
|
||||
}
|
||||
|
||||
@ -1,20 +1,20 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"strict": true,
|
||||
"target": "es2022",
|
||||
"module": "nodeNext",
|
||||
"moduleResolution": "nodeNext",
|
||||
"typeRoots": [
|
||||
"./scripts/types",
|
||||
"./node_modules/@types"
|
||||
],
|
||||
"esModuleInterop": true
|
||||
},
|
||||
"ts-node": {
|
||||
"esm": true,
|
||||
"transpileOnly": true
|
||||
},
|
||||
"files": [
|
||||
"node_modules/jest-expect-message/types/index.d.ts"
|
||||
]
|
||||
{
|
||||
"compilerOptions": {
|
||||
"strict": true,
|
||||
"target": "es2022",
|
||||
"module": "nodeNext",
|
||||
"moduleResolution": "nodeNext",
|
||||
"typeRoots": [
|
||||
"./scripts/types",
|
||||
"./node_modules/@types"
|
||||
],
|
||||
"esModuleInterop": true
|
||||
},
|
||||
"ts-node": {
|
||||
"esm": true,
|
||||
"transpileOnly": true
|
||||
},
|
||||
"files": [
|
||||
"node_modules/jest-expect-message/types/index.d.ts"
|
||||
]
|
||||
}
|
||||
Loading…
Reference in New Issue