delarte_test/src/delarte/__main__.py

118 lines
3.2 KiB
Python

# Licence: GNU AGPL v3: http://www.gnu.org/licenses/
# This file is part of [`delarte`](https://git.afpy.org/fcode/delarte.git)
"""delarte - ArteTV dowloader.
usage: delarte [-h|--help] - print this message
or: delarte program_page_url - show available versions
or: delarte program_page_url version - show available resolutions
or: delarte program_page_url version resolution - download the given video
"""
import sys
import time
from . import api
from . import hls
from . import muxing
from . import naming
from . import www
from . import cli
def _fail(message, code=1):
print(message, file=sys.stderr)
return code
def _print_available_renditions(config, f):
print(f"Available versions:", file=f)
for code, label in api.iter_renditions(config):
print(f"\t{code} - {label}", file=f)
def _print_available_variants(version_index, f):
print(f"Available resolutions:", file=f)
for code, label in hls.iter_variants(version_index):
print(f"\t{code} - {label}", file=f)
def create_progress():
"""Create a progress handler for input downloads."""
state = {
"last_update_time": 0,
"last_channel": None,
}
def progress(channel, current, total):
now = time.time()
if current == total:
print(f"\rDownloading {channel}: 100.0%")
state["last_update_time"] = now
elif channel != state["last_channel"]:
print(f"Dowloading {channel}: 0.0%", end="")
state["last_update_time"] = now
state["last_channel"] = channel
elif now - state["last_update_time"] > 1:
print(
f"\rDownloading {channel}: {int(1000.0 * current / total) / 10.0}%",
end="",
)
state["last_update_time"] = now
return progress
def main():
"""CLI command."""
parser = cli.Parser()
args = parser.get_args_as_list()
if not args or args[0] == "-h" or args[0] == "--help":
print(__doc__)
return 0
try:
www_lang, program_id = www.parse_url(args.pop(0))
except ValueError as e:
return _fail(f"Invalid url: {e}")
try:
config = api.load_config(www_lang, program_id)
except ValueError:
return _fail("Invalid program")
if not args:
_print_available_renditions(config, sys.stdout)
return 0
master_playlist_url = api.select_rendition(config, args.pop(0))
if master_playlist_url is None:
_fail("Invalid version")
_print_available_renditions(config, sys.stderr)
return 1
master_playlist = hls.load_master_playlist(master_playlist_url)
if not args:
_print_available_variants(master_playlist, sys.stdout)
return 0
remote_inputs = hls.select_variant(master_playlist, args.pop(0))
if remote_inputs is None:
_fail("Invalid resolution")
_print_available_variants(master_playlist, sys.stderr)
return 0
file_base_name = naming.build_file_base_name(config)
progress = create_progress()
with hls.download_inputs(remote_inputs, progress) as temp_inputs:
muxing.mux(temp_inputs, file_base_name, progress)
if __name__ == "__main__":
sys.exit(main())