delarte_test/src/delarte/__main__.py
Barbagus 6b8f2232c4 Fix issue #13 - split code in multiple modules
Implemented modules:
 - api: deals with ArteTV JSON API
 - hls: deals with HLS protocol
 - muxing: deals with the stream multiplexing
 - naming: deals with output file naming
 - www: deals with ArteTV web interface
2022-12-13 07:29:59 +01:00

118 lines
3.3 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
def fail(message, code=1):
"""Print a message to STDERR and return a given exit code."""
print(message, file=sys.stderr)
return code
def print_available_versions(config, f):
"""Print available program versions."""
print(f"Available versions:", file=f)
for code, label in api.iter_versions(config):
print(f"\t{code} - {label}", file=f)
def print_available_resolutions(version_index, f):
"""Print available version resolutions."""
print(f"Available resolutions:", file=f)
for code, label in hls.iter_resolutions(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."""
args = sys.argv[1:]
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_versions(config, sys.stdout)
return 0
version_index_url = api.select_version(config, args.pop(0))
if version_index_url is None:
fail("Invalid version")
print_available_versions(config, sys.stderr)
return 1
version_index = hls.load_version_index(version_index_url)
if not args:
print_available_resolutions(version_index, sys.stdout)
return 0
remote_inputs = hls.select_resolution(version_index, args.pop(0))
if remote_inputs is None:
fail("Invalid resolution")
print_available_resolutions(version_index, 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())