Initial commit

This commit is contained in:
Kevin MacMartin 2023-03-10 22:37:30 -05:00
commit 0c9cc7f5fc
9 changed files with 1308 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
.m3u
node_modules

22
config/categories.json Normal file
View file

@ -0,0 +1,22 @@
[
"auto",
"animation",
"business",
"classic",
"comedy",
"cooking",
"culture",
"documentary",
"education",
"entertainment",
"family",
"general",
"kids",
"lifestyle",
"movies",
"news",
"outdoor",
"series",
"science",
"sports"
]

4
config/countries.json Normal file
View file

@ -0,0 +1,4 @@
[
"CA",
"US"
]

3
config/languages.json Normal file
View file

@ -0,0 +1,3 @@
[
"eng"
]

96
iptv-m3u-update Executable file
View file

@ -0,0 +1,96 @@
#!/usr/bin/env bash
# Dependencies
deps=('curl' 'dos2unix' 'grep' 'node' 'rows' 'sqlite3')
# URLs
tmp_m3u_url='https://iptv-org.github.io/iptv/index.m3u'
tmp_csv_url='https://raw.githubusercontent.com/iptv-org/database/master/data/channels.csv'
# Temporary files
tmp_m3u_file='/tmp/iptv.m3u'
tmp_csv_file='/tmp/iptv.csv'
tmp_processed_csv_file='/tmp/iptv-processed.csv'
tmp_sqlite_file='/tmp/iptv.sqlite'
# Final m3u
final_m3u='channels.m3u'
function cleanup {
[[ -f "$tmp_m3u_file" ]] && rm "$tmp_m3u_file"
[[ -f "$tmp_csv_file" ]] && rm "$tmp_csv_file"
[[ -f "$tmp_processed_csv_file" ]] && rm "$tmp_processed_csv_file"
[[ -f "$tmp_sqlite_file" ]] && rm "$tmp_sqlite_file"
}
function cleanup_and_exit {
cleanup
exit "$1"
}
function update {
# Ensure old temporary files don't exist
cleanup
if ! curl -s "$tmp_m3u_url" > "$tmp_m3u_file"; then
printf '%s\n' "Unable to download $tmp_m3u_url"
cleanup_and_exit 1
fi
if curl -s "$tmp_csv_url" > "$tmp_csv_file"; then
# Convert to unix format
dos2unix "$tmp_csv_file"
# Add links to each channel
while read -r; do
if [[ "$REPLY" =~ ^([^,]*), ]]; then
id="${BASH_REMATCH[1]}"
if [[ "$id" = 'id' ]]; then
printf '%s\n' "${REPLY},link"
else
match="$(grep -A1 'tvg-id="'"$id"'"' "$tmp_m3u_file")"
if (( $? == 0 )); then
link="$(grep -e '^http' <<< "$match")"
printf '%s\n' "$REPLY,$link"
fi
fi
fi
done < "$tmp_csv_file" > "$tmp_processed_csv_file"
# Convert to sqlite
rows csv2sqlite "$tmp_processed_csv_file" "$tmp_sqlite_file"
# Create the m3u
./scripts/iptv-generate-m3u > "$final_m3u"
# Delete temporary files
cleanup_and_exit 0
else
printf '%s\n' "Unable to download $tmp_csv_url"
cleanup_and_exit 1
fi
}
# Check for missing dependencies
declare -a missing_deps=()
for dep in "${deps[@]}"; do
type -P "$dep" >/dev/null \
|| missing_deps=( "${missing_deps[@]}" "$dep" )
done
[[ -n "${missing_deps[*]}" ]] && {
printf '%s\n' "missing dependencies ($(
for (( x=0; x < ${#missing_deps[@]}; x++ )); do
printf '%s' "${missing_deps[$x]}"
(( ( x + 1 ) < ${#missing_deps[@]} )) && printf '%s' ', '
done
))"
exit 1
}
# Update M3U
update

1115
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

5
package.json Normal file
View file

@ -0,0 +1,5 @@
{
"dependencies": {
"sqlite3": "^5.1.4"
}
}

19
readme.md Normal file
View file

@ -0,0 +1,19 @@
# IPTV M3U
Takes [iptv-org](https://github.com/iptv-org) data and creates a custom m3u
## Dependencies
* curl: https://curl.haxx.se/
* dos2unix: https://waterlan.home.xs4all.nl/dos2unix.html
* grep: https://www.gnu.org/software/grep/
* node/npm: https://nodejs.org/en/
* rows[cli]: http://turicas.info/rows/cli/
* sqlite3: https://www.sqlite.org
## Usage
1. Customize the languages, countries and categories in the respective json files in the `config` folder using the ids from the respective csv here: https://github.com/iptv-org/database/blob/master/data
2. Run `npm install`
3. Run `./iptv-m3u-update`
4. Load your freshly generated `channels.m3u`

42
scripts/iptv-generate-m3u Executable file
View file

@ -0,0 +1,42 @@
#!/usr/bin/env node
const sqlite3 = require("sqlite3").verbose(),
db = new sqlite3.Database("/tmp/iptv.sqlite"),
languages = require("../config/languages.json"),
countries = require("../config/countries.json"),
categories = require("../config/categories.json");
let languageMatch = "",
countryMatch = "",
categoryMatch = "";
languages.forEach((language, index) => {
languageMatch += `languages='${language}'`;
if (index < languages.length - 1) {
languageMatch += " OR ";
}
});
countries.forEach((country, index) => {
countryMatch += `country='${country}'`;
if (index < countries.length - 1) {
countryMatch += " OR ";
}
});
categories.forEach((category, index) => {
categoryMatch += `categories LIKE '%${category}%'`;
if (index < categories.length - 1) {
categoryMatch += " OR ";
}
});
db.serialize(() => {
db.each(`SELECT * FROM iptv_processed WHERE is_nsfw='FALSE' AND (${languageMatch}) AND link NOT LIKE '' AND (${countryMatch}) AND (${categoryMatch})`, (err, row) => {
console.log(`#EXTINF:-1 tvg-id="${row.id}" tvg-logo="${row.logo}" group-title="${row.name}"`);
console.log(row.link);
});
});