one-off downloader working
This commit is contained in:
parent
beb48ac5aa
commit
d6fe2505f6
7 changed files with 103 additions and 26 deletions
|
|
@ -10,6 +10,7 @@ presets:
|
|||
ytdl_options:
|
||||
format: 'bestaudio[ext=mp3]'
|
||||
output_options:
|
||||
output_directory: "/tmp/{sanitized_artist}"
|
||||
file_name: "[{album_year}] {sanitized_album}/{track_number_padded} - {sanitized_title}.{ext}"
|
||||
convert_thumbnail: "jpeg"
|
||||
thumbnail_name: "[{album_year}] {sanitized_album}/folder.jpeg"
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@ bl00dwave:
|
|||
preset: "soundcloud_with_id3_tags"
|
||||
soundcloud:
|
||||
username: bl00dwave
|
||||
output_options:
|
||||
output_directory: "/tmp/bl00dwave"
|
||||
overrides:
|
||||
artist: "bl00dwave"
|
||||
genre: "Synthwave / Electronic"
|
||||
|
|
|
|||
|
|
@ -1,12 +1,84 @@
|
|||
from argparse import ArgumentError
|
||||
from typing import Dict
|
||||
from typing import List
|
||||
|
||||
from mergedeep import mergedeep
|
||||
|
||||
|
||||
class SubscriptionArgsParser:
|
||||
"""
|
||||
'Unknown' arguments can be given to `ytdl-sub dl` which are meant to represent fields
|
||||
in a subscription yaml. This class will convert those extra args into a
|
||||
'Extra' arguments can be given to `ytdl-sub dl` which are meant to represent fields
|
||||
in a subscription yaml. This class will convert those extra args into a dict that can be
|
||||
passed in to instantiate a
|
||||
:class:`~ytdl_subscribe.validators.config.preset_validator.PresetValidator`
|
||||
"""
|
||||
|
||||
def __init__(self, unknown_arguments: List[str]):
|
||||
self._unknown_arguments = unknown_arguments
|
||||
def __init__(self, extra_arguments: List[str]):
|
||||
"""
|
||||
:param extra_arguments: List of extra arguments from argparse
|
||||
"""
|
||||
self._unknown_arguments = extra_arguments
|
||||
|
||||
@property
|
||||
def _argument_exception(self) -> ArgumentError:
|
||||
"""
|
||||
:return: Exception to raise if a parsing error occurs.
|
||||
"""
|
||||
return ArgumentError(
|
||||
argument=None,
|
||||
message="dl arguments must be in the form of --subscription.option.name 'value' "
|
||||
"proceeding the url",
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _is_argument_name(cls, arg: str) -> bool:
|
||||
"""
|
||||
:param arg: Arg value from the unknown args list
|
||||
:return: True if it's an argument name, denoted by starting with '--'. False otherwise.
|
||||
"""
|
||||
return arg.startswith("--")
|
||||
|
||||
@classmethod
|
||||
def _argument_name_and_value_to_dict(cls, arg_name: str, arg_value: str) -> Dict:
|
||||
"""
|
||||
:param arg_name: Argument name in the form of 'key1.key2.key3'
|
||||
:param arg_value: Argument value
|
||||
:return: dict containing {'key1':{'key2':{'key3': value}}}
|
||||
"""
|
||||
argument_dict = {}
|
||||
|
||||
# Remove the argument --'s, then split on period
|
||||
arg_name_split = arg_name.replace("--", "", 1).split(".")
|
||||
|
||||
next_arg_name = arg_name_split[0]
|
||||
next_dict = argument_dict
|
||||
for next_arg_name in arg_name_split[:-1]:
|
||||
next_dict[next_arg_name] = {}
|
||||
next_dict = next_dict[next_arg_name]
|
||||
|
||||
next_dict[arg_name_split[-1]] = arg_value
|
||||
|
||||
return argument_dict
|
||||
|
||||
def to_subscription_dict(self) -> Dict:
|
||||
"""
|
||||
Converts the extra arguments into a dict equivalent to a subscription yaml.
|
||||
:return: dict containing argument names and values
|
||||
"""
|
||||
subscription_dict = {}
|
||||
if len(self._unknown_arguments) % 2 != 0:
|
||||
raise self._argument_exception
|
||||
|
||||
for idx in range(0, len(self._unknown_arguments), 2):
|
||||
argument_name = self._unknown_arguments[idx]
|
||||
argument_value = self._unknown_arguments[idx + 1]
|
||||
|
||||
if not self._is_argument_name(arg=argument_name):
|
||||
raise self._argument_exception
|
||||
|
||||
argument_dict = self._argument_name_and_value_to_dict(
|
||||
arg_name=argument_name, arg_value=argument_value
|
||||
)
|
||||
mergedeep.merge(subscription_dict, argument_dict, strategy=mergedeep.Strategy.REPLACE)
|
||||
|
||||
return subscription_dict
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
import argparse
|
||||
import sys
|
||||
from random import randint
|
||||
from typing import List
|
||||
|
||||
###################################################################################################
|
||||
# GLOBAL PARSER
|
||||
from ytdl_subscribe.cli.subscription_args_parser import SubscriptionArgsParser
|
||||
from ytdl_subscribe.validators.config.config_file_validator import ConfigFileValidator
|
||||
from ytdl_subscribe.validators.config.subscription_validator import SubscriptionValidator
|
||||
|
||||
|
|
@ -30,15 +32,11 @@ subscription_parser.add_argument(
|
|||
default="config.yaml",
|
||||
)
|
||||
###################################################################################################
|
||||
# INTERACTIVE DOWNLOAD PARSER
|
||||
# DOWNLOAD PARSER
|
||||
download_parser = subparsers.add_parser("dl")
|
||||
download_parser.add_argument(
|
||||
"url",
|
||||
help="url to the desired content to download, will prompt for further arguments needed",
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
args, unknown = parser.parse_known_args()
|
||||
args, extra_args = parser.parse_known_args()
|
||||
|
||||
config: ConfigFileValidator = ConfigFileValidator.from_file_path(args.config)
|
||||
if args.subparser == "sub":
|
||||
|
|
@ -53,18 +51,19 @@ if __name__ == "__main__":
|
|||
for subscription in subscriptions:
|
||||
subscription.to_subscription().download()
|
||||
|
||||
print("hi")
|
||||
# for subscription_path in subscription_paths:
|
||||
#
|
||||
#
|
||||
# subscriptions = parse_subscriptions(
|
||||
# yaml_dict, presets, subscriptions=args.subscriptions
|
||||
# )
|
||||
# for s in subscriptions:
|
||||
# s.extract_info()
|
||||
print("Subscription download complete!")
|
||||
|
||||
# One-off download
|
||||
if args.subparser == "dl":
|
||||
print("Interactive download is not supported yet. Stay tuned!")
|
||||
subscription_name = f"cli-dl-{randint(0, 999)}"
|
||||
subscription_args_dict = SubscriptionArgsParser(
|
||||
extra_arguments=extra_args
|
||||
).to_subscription_dict()
|
||||
SubscriptionValidator.from_dict(
|
||||
config=config,
|
||||
subscription_name=subscription_name,
|
||||
subscription_dict=subscription_args_dict,
|
||||
).to_subscription().download()
|
||||
print("Download complete!")
|
||||
|
||||
sys.exit(0)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
from abc import ABC
|
||||
from typing import List
|
||||
|
||||
from ytdl_subscribe.downloaders.soundcloud_downloader import SoundcloudDownloader
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
from abc import ABC
|
||||
from typing import List
|
||||
|
||||
from ytdl_subscribe.downloaders.youtube_downloader import YoutubeDownloader
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import copy
|
||||
from typing import Any
|
||||
from typing import Dict
|
||||
from typing import List
|
||||
from typing import Optional
|
||||
from typing import Type
|
||||
|
|
@ -93,6 +94,12 @@ class SubscriptionValidator(StrictDictValidator):
|
|||
preset_options=self.preset,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_dict(
|
||||
cls, config: ConfigFileValidator, subscription_name, subscription_dict: Dict
|
||||
) -> "SubscriptionValidator":
|
||||
return SubscriptionValidator(config=config, name=subscription_name, value=subscription_dict)
|
||||
|
||||
@classmethod
|
||||
def from_file_path(
|
||||
cls, config: ConfigFileValidator, subscription_path: str
|
||||
|
|
@ -104,8 +111,10 @@ class SubscriptionValidator(StrictDictValidator):
|
|||
subscriptions: List["SubscriptionValidator"] = []
|
||||
for subscription_key, subscription_object in subscription_dict.items():
|
||||
subscriptions.append(
|
||||
SubscriptionValidator(
|
||||
config=config, name=subscription_key, value=subscription_object
|
||||
SubscriptionValidator.from_dict(
|
||||
config=config,
|
||||
subscription_name=subscription_key,
|
||||
subscription_dict=subscription_object,
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue