one-off downloader working

This commit is contained in:
jbannon 2022-04-13 05:30:29 +00:00
parent beb48ac5aa
commit d6fe2505f6
7 changed files with 103 additions and 26 deletions

View file

@ -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"

View file

@ -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"

View file

@ -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

View file

@ -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)

View file

@ -1,4 +1,3 @@
from abc import ABC
from typing import List
from ytdl_subscribe.downloaders.soundcloud_downloader import SoundcloudDownloader

View file

@ -1,4 +1,3 @@
from abc import ABC
from typing import List
from ytdl_subscribe.downloaders.youtube_downloader import YoutubeDownloader

View file

@ -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,
)
)