From 72ce4f37fe9760a373f051af1d07b513c98e2258 Mon Sep 17 00:00:00 2001 From: sadorowo Date: Sun, 25 Feb 2024 17:02:13 +0100 Subject: [PATCH] Initial commit --- .gitignore | 7 +++++ README.md | 44 ++++++++++++++++++++++++++ __main__.py | 80 ++++++++++++++++++++++++++++++++++++++++++++++++ requirements.txt | 1 + 4 files changed, 132 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 __main__.py create mode 100644 requirements.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6c2d706 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.venv +bin +include +lib +__pycache__ +pyvenv.cfg +.DS_Store \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..ed83d3c --- /dev/null +++ b/README.md @@ -0,0 +1,44 @@ +## M3U Category Matcher + +Do you have IPTV provider who doesn't add categories to channels, but uses channels for it? +This script will attach channel-like categories to channels under them. +Example: + +You have these 5 channels: +1. ### GENERAL ### +2. TV1 HD +3. TV2 HD +4. ### MUSIC ### +5. METAL LIVE TV HD + +For example, if you provided `\#\#\# (.*) \#\#\#` regex: +This script will __remove__ channel with no. 1. and 5., then __attach__ categories: +- GENERAL (matched group from regex!) to channels 2, 3, +- MUSIC to channel 5. + +### NOTE! +This script is in BETA phase. Please report any bugs! + +### Based on +- argparse +- pathlib +- re +- [ipytv](https://github.com/Beer4Ever83/ipytv) + +### Usage +```bash +python3 -i "" -r "" (-v) +``` + +### Result +When everything is done, file is **OVERWRITTEN**! + +### Example usage +```bash +python3 -i "m3u_list.m3u" -r "\#\#\# (.*) \#\#\#" +``` + +### Available parameters +- -i/--input - absolute path to m3u+ file +- -r/--regex - regular expression used to match categories in channel names +- -v/--verbose - enable verbose mode diff --git a/__main__.py b/__main__.py new file mode 100644 index 0000000..7fa5344 --- /dev/null +++ b/__main__.py @@ -0,0 +1,80 @@ +from ipytv import playlist as tv_playlist +from argparse import ArgumentParser +from pathlib import Path +import re + +def parse_arguments(): + parser = ArgumentParser() + parser.add_argument("-r", "--regex", dest="regex", help="Regex to match the categories", required=True) + parser.add_argument("-i", "--input", dest="input", help="Path to m3u+ file", required=True, type=Path) + parser.add_argument("-v", "--verbose", dest="verbose", help="Enable verbose mode", action="store_true") + + return parser.parse_args() + +def debug(message: str): + global verbose + + if verbose: + print("[M3U-CATEGORY-MATCHER:DEBUG] " + message) + +def process(arguments): + debug("Processing...") + + try: + playlist = tv_playlist.loadf(str(arguments.input)) + except UnicodeDecodeError: + print("Your playlist is not UTF-8 encoded, or has invalid characters. Please convert it to UTF-8.") + exit(1) + except Exception as e: + print("Something went wrong while loading playlist.") + print(e) + exit(1) + + debug("Playlist loaded.") + debug("Matching categories...") + + try: + regex = re.compile(arguments.regex) + except re.error: + print("Invalid regex provided.") + exit(1) + + if regex.groups != 1: + print("Regex must have exactly one group to match.") + exit(1) + + # Example: + # Regex: ### ([a-zA-Z0-9]+) ### + # Channel 1 name: "### Movies ###" + # Channel 2 name: "1 HD" + # Channel 3 name: "2 HD" + # Channel 4 name: "### News ###" + # Channel 5 name: "3 HD" + # Add category "Movies" to channels: 2., 3. + # Add category "News" to channel 5. + + current_category = None + for index, channel in enumerate(playlist): + match = regex.match(channel.name) + if match: + playlist.remove_channel(index) + current_category = channel.name + + debug(f"Category matched: {current_category}") + elif current_category: + debug(f"Adding category {current_category} to channel {channel.name}") + channel.attributes["group-title"] = current_category + + # save playlist + debug("Saving playlist...") + with open(arguments.input, "w+", encoding="utf-8") as f: + f.write(playlist.to_m3u_plus_playlist()) + + print("All done!") + print("Thanks for using this script!") + +if __name__ == "__main__": + arguments = parse_arguments() + verbose = arguments.verbose + + process(arguments) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..7634c2b --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +m3u-ipytv \ No newline at end of file