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