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:
|
ytdl_options:
|
||||||
format: 'bestaudio[ext=mp3]'
|
format: 'bestaudio[ext=mp3]'
|
||||||
output_options:
|
output_options:
|
||||||
|
output_directory: "/tmp/{sanitized_artist}"
|
||||||
file_name: "[{album_year}] {sanitized_album}/{track_number_padded} - {sanitized_title}.{ext}"
|
file_name: "[{album_year}] {sanitized_album}/{track_number_padded} - {sanitized_title}.{ext}"
|
||||||
convert_thumbnail: "jpeg"
|
convert_thumbnail: "jpeg"
|
||||||
thumbnail_name: "[{album_year}] {sanitized_album}/folder.jpeg"
|
thumbnail_name: "[{album_year}] {sanitized_album}/folder.jpeg"
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,6 @@ bl00dwave:
|
||||||
preset: "soundcloud_with_id3_tags"
|
preset: "soundcloud_with_id3_tags"
|
||||||
soundcloud:
|
soundcloud:
|
||||||
username: bl00dwave
|
username: bl00dwave
|
||||||
output_options:
|
|
||||||
output_directory: "/tmp/bl00dwave"
|
|
||||||
overrides:
|
overrides:
|
||||||
artist: "bl00dwave"
|
artist: "bl00dwave"
|
||||||
genre: "Synthwave / Electronic"
|
genre: "Synthwave / Electronic"
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,84 @@
|
||||||
|
from argparse import ArgumentError
|
||||||
|
from typing import Dict
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
|
from mergedeep import mergedeep
|
||||||
|
|
||||||
|
|
||||||
class SubscriptionArgsParser:
|
class SubscriptionArgsParser:
|
||||||
"""
|
"""
|
||||||
'Unknown' arguments can be given to `ytdl-sub dl` which are meant to represent fields
|
'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
|
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`
|
:class:`~ytdl_subscribe.validators.config.preset_validator.PresetValidator`
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, unknown_arguments: List[str]):
|
def __init__(self, extra_arguments: List[str]):
|
||||||
self._unknown_arguments = unknown_arguments
|
"""
|
||||||
|
: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 argparse
|
||||||
import sys
|
import sys
|
||||||
|
from random import randint
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
###################################################################################################
|
###################################################################################################
|
||||||
# GLOBAL PARSER
|
# 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.config_file_validator import ConfigFileValidator
|
||||||
from ytdl_subscribe.validators.config.subscription_validator import SubscriptionValidator
|
from ytdl_subscribe.validators.config.subscription_validator import SubscriptionValidator
|
||||||
|
|
||||||
|
|
@ -30,15 +32,11 @@ subscription_parser.add_argument(
|
||||||
default="config.yaml",
|
default="config.yaml",
|
||||||
)
|
)
|
||||||
###################################################################################################
|
###################################################################################################
|
||||||
# INTERACTIVE DOWNLOAD PARSER
|
# DOWNLOAD PARSER
|
||||||
download_parser = subparsers.add_parser("dl")
|
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__":
|
if __name__ == "__main__":
|
||||||
args, unknown = parser.parse_known_args()
|
args, extra_args = parser.parse_known_args()
|
||||||
|
|
||||||
config: ConfigFileValidator = ConfigFileValidator.from_file_path(args.config)
|
config: ConfigFileValidator = ConfigFileValidator.from_file_path(args.config)
|
||||||
if args.subparser == "sub":
|
if args.subparser == "sub":
|
||||||
|
|
@ -53,18 +51,19 @@ if __name__ == "__main__":
|
||||||
for subscription in subscriptions:
|
for subscription in subscriptions:
|
||||||
subscription.to_subscription().download()
|
subscription.to_subscription().download()
|
||||||
|
|
||||||
print("hi")
|
print("Subscription download complete!")
|
||||||
# for subscription_path in subscription_paths:
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# subscriptions = parse_subscriptions(
|
|
||||||
# yaml_dict, presets, subscriptions=args.subscriptions
|
|
||||||
# )
|
|
||||||
# for s in subscriptions:
|
|
||||||
# s.extract_info()
|
|
||||||
|
|
||||||
# One-off download
|
# One-off download
|
||||||
if args.subparser == "dl":
|
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)
|
sys.exit(0)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
from abc import ABC
|
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from ytdl_subscribe.downloaders.soundcloud_downloader import SoundcloudDownloader
|
from ytdl_subscribe.downloaders.soundcloud_downloader import SoundcloudDownloader
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
from abc import ABC
|
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from ytdl_subscribe.downloaders.youtube_downloader import YoutubeDownloader
|
from ytdl_subscribe.downloaders.youtube_downloader import YoutubeDownloader
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import copy
|
import copy
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
from typing import Dict
|
||||||
from typing import List
|
from typing import List
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from typing import Type
|
from typing import Type
|
||||||
|
|
@ -93,6 +94,12 @@ class SubscriptionValidator(StrictDictValidator):
|
||||||
preset_options=self.preset,
|
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
|
@classmethod
|
||||||
def from_file_path(
|
def from_file_path(
|
||||||
cls, config: ConfigFileValidator, subscription_path: str
|
cls, config: ConfigFileValidator, subscription_path: str
|
||||||
|
|
@ -104,8 +111,10 @@ class SubscriptionValidator(StrictDictValidator):
|
||||||
subscriptions: List["SubscriptionValidator"] = []
|
subscriptions: List["SubscriptionValidator"] = []
|
||||||
for subscription_key, subscription_object in subscription_dict.items():
|
for subscription_key, subscription_object in subscription_dict.items():
|
||||||
subscriptions.append(
|
subscriptions.append(
|
||||||
SubscriptionValidator(
|
SubscriptionValidator.from_dict(
|
||||||
config=config, name=subscription_key, value=subscription_object
|
config=config,
|
||||||
|
subscription_name=subscription_key,
|
||||||
|
subscription_dict=subscription_object,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue