Implement CLI parsing using docopt-ng library

This commit is contained in:
Barbagus 2022-12-29 10:54:45 +01:00
parent 3ec2961a85
commit b057bab44b
3 changed files with 38 additions and 81 deletions

View File

@ -12,7 +12,8 @@ dynamic = ["version", "description"]
dependencies = [
"m3u8",
"webvtt-py",
"requests"
"requests",
"docopt-ng"
]
[project.urls]

View File

@ -3,18 +3,34 @@
"""delarte - ArteTV downloader.
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
Usage:
delarte (-h | --help)
delarte --version
delarte [options] URL
delarte [options] URL RENDITION
delarte [options] URL RENDITION VARIANT
Download a video from ArteTV streaming service. Omit RENDITION and/or
VARIANT to print the list of available values.
Arguments:
URL the URL from ArteTV website
RENDITION the rendition code [audio/subtitles language combination]
VARIANT the variant code [video quality version]
Options:
-h --help print this message
--version print current version of the program
--debug on error, print debugging information
"""
import sys
import time
import docopt
import requests
from . import cli, download_source, error, fetch_sources, naming, www
from . import __version__, download_source, error, fetch_sources, naming, www
class Abort(error.ModuleError):
@ -82,7 +98,7 @@ def _select_rendition(sources, rendition_code):
filtered = [s for s in sources if s.rendition.code == rendition_code]
if not filtered:
print(f"{rendition_code!r} is not a valid version, possible values are:")
print(f"{rendition_code!r} is not a valid rendition code, possible values are:")
_print_renditions(sources)
raise Abort()
@ -96,7 +112,7 @@ def _select_variant(sources, variant_code):
filtered = [s for s in sources if s.variant.code == variant_code]
if not filtered:
print(f"{variant_code!r} is not a valid resolution, possible values are:")
print(f"{variant_code!r} is not a valid variant code, possible values are:")
_print_variants(sources)
raise Abort()
@ -135,33 +151,29 @@ def create_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
cli = docopt.docopt(__doc__, sys.argv[1:], version=__version__)
print(cli)
try:
target_id, www_lang = www.parse_url(args.pop(0))
target_id, www_lang = www.parse_url(cli.URL)
http_session = requests.sessions.Session()
sources = fetch_sources(http_session, target_id, www_lang)
if not args:
print(f"Available versions:")
if not cli["RENDITION"]:
print(f"Available renditions:")
_print_renditions(sources)
return 0
sources = _select_rendition(sources, args.pop(0))
sources = _select_rendition(sources, cli["RENDITION"])
if not args:
print(f"Available resolutions:")
if not cli["VARIANT"]:
print(f"Available variants:")
_print_variants(sources)
return 0
sources = _select_variant(sources, args.pop(0))
sources = _select_variant(sources, cli["VARIANT"])
file_names = [
naming.build_file_name(s, i, len(sources)) for i, s in enumerate(sources, 1)
@ -191,12 +203,14 @@ def main():
except error.ModuleError as e:
print(str(e))
# print(repr(e))
if cli["--debug"]:
print(repr(e))
return 1
except requests.HTTPError as e:
print("Network error.")
# print(str(e))
if cli["--debug"]:
print(str(e))
return 1

View File

@ -1,58 +0,0 @@
# License: GNU AGPL v3: http://www.gnu.org/licenses/
# This file is part of `delarte` (https://git.afpy.org/fcode/delarte.git)
"""
usage: delarte [-h|--help] - print this message
or: delarte program_page_url - show available versions
or: delarte program_page_url version - show available video resolutions
or: delarte program_page_url version resolution - download the given video
"""
import argparse
class Parser(argparse.ArgumentParser):
"""Parser responsible for parsing CLI arguments."""
def __init__(self):
"""Generate a parser."""
super().__init__(
description="downloads Arte's videos with subtitles",
epilog=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter,
)
self.add_argument(
"url",
help="url of Arte movie's webpage",
action="store",
type=str,
nargs="?",
)
self.add_argument(
"version",
help="one of the language code proposed by Arte",
action="store",
type=str,
nargs="?",
)
self.add_argument(
"resolution",
help="video resolution",
action="store",
type=str,
nargs="?",
)
def get_args_as_list(self):
"""Get arguments from CLI as a list.
Returns:
List: ordered list of arguments, None removed
"""
args_namespace = self.parse_args()
args_list = [
args_namespace.url,
args_namespace.version,
args_namespace.resolution,
]
return [arg for arg in args_list if arg is not None]