Coverage for src/iptvtools/cli.py: 64%
47 statements
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-31 13:48 +0000
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-31 13:48 +0000
1"""Command Line Interface."""
3import logging
4import shutil
6import click
8from iptvtools import exceptions
9from iptvtools.config import Config
10from iptvtools.constants import defaults, helps
11from iptvtools.models import Playlist
14@click.group(
15 context_settings={"show_default": True},
16)
17@click.version_option()
18def cli() -> None:
19 """CLI for IPTVTools."""
22@cli.command()
23@click.option("--channel-exclude", help=helps.CHANNEL_EXCLUDE)
24@click.option("--channel-include", help=helps.CHANNEL_INCLUDE)
25@click.option("--group-exclude", help=helps.GROUP_EXCLUDE)
26@click.option("--group-include", help=helps.GROUP_INCLUDE)
27@click.option(
28 "--max-height", default=defaults.MAX_HEIGHT, type=int, help=helps.MAX_HEIGHT
29)
30@click.option(
31 "--min-height", default=defaults.MIN_HEIGHT, type=int, help=helps.MIN_HEIGHT
32)
33@click.option("-c", "--config", default=defaults.CONFIG, help=helps.CONFIG)
34@click.option(
35 "-i", "--inputs", multiple=True, default=defaults.INPUTS, help=helps.INPUTS
36)
37@click.option(
38 "-I", "--interval", default=defaults.INTERVAL, type=int, help=helps.INTERVAL
39)
40@click.option("-L", "--log-level", default=defaults.LOG_LEVEL, help=helps.LOG_LEVEL)
41@click.option(
42 "-n",
43 "--skip-connectivity-check",
44 is_flag=True,
45 help=helps.SKIP_CONNECTIVITY_CHECK,
46)
47@click.option("-o", "--output", default=defaults.OUTPUT, help=helps.OUTPUT)
48@click.option(
49 "-r",
50 "--replace-group-by-source",
51 is_flag=True,
52 help=helps.REPLACE_GROUP_BY_SOURCE,
53)
54@click.option(
55 "-R",
56 "--resolution-on-title",
57 is_flag=True,
58 help=helps.RESOLUTION_ON_TITLE,
59)
60@click.option(
61 "-s", "--sort-keys", multiple=True, default=defaults.SORT_KEYS, help=helps.SORT_KEYS
62)
63@click.option(
64 "-t", "--templates", multiple=True, default=defaults.TEMPLATES, help=helps.TEMPLATES
65)
66@click.option("-T", "--timeout", default=defaults.TIMEOUT, type=int, help=helps.TIMEOUT)
67@click.option("-u", "--udpxy", default=defaults.UDPXY, help=helps.UDPXY)
68def filter(
69 channel_exclude: str,
70 channel_include: str,
71 group_exclude: str,
72 group_include: str,
73 max_height: int,
74 min_height: int,
75 config: str,
76 inputs: list[str],
77 interval: int,
78 log_level: str,
79 skip_connectivity_check: bool,
80 output: str,
81 replace_group_by_source: bool,
82 resolution_on_title: bool,
83 sort_keys: list[str],
84 templates: list[str],
85 timeout: int,
86 udpxy: str,
87) -> None:
88 """Filter m3u playlists."""
89 logging.basicConfig(level=log_level.upper())
91 if (max_height or min_height or resolution_on_title) and shutil.which(
92 "ffprobe"
93 ) is None:
94 raise exceptions.FFmpegNotInstalledError()
96 Config.init(config)
97 playlist = Playlist(
98 channel_exclude,
99 channel_include,
100 group_exclude,
101 group_include,
102 max_height,
103 min_height,
104 inputs,
105 interval,
106 skip_connectivity_check,
107 output,
108 replace_group_by_source,
109 resolution_on_title,
110 sort_keys,
111 templates,
112 timeout,
113 udpxy,
114 )
115 playlist.parse()
116 playlist.filter()
117 playlist.export()
118 if playlist.inaccessible_urls:
119 logging.info("Inaccessible Urls:")
120 logging.info("\n".join(sorted(playlist.inaccessible_urls)))
121 if playlist.low_res_urls:
122 logging.info("Low resolution Urls:")
123 logging.info("\n".join(sorted(playlist.low_res_urls)))
124 if playlist.high_res_urls:
125 logging.info("High resolution Urls:")
126 logging.info("\n".join(sorted(playlist.high_res_urls)))