Files
youtube-cdl/main.py
2021-04-13 00:05:41 +03:00

134 lines
4.0 KiB
Python

from rich.console import Console
#from rich import inspect
import platform
from pathlib import Path
import os
import sys
import json
import re
import argparse
import logging
import youtube_dl
from get_channels import retrieve_youtube_subscriptions
from print_logo import print_logo
if platform.system() == 'Windows':
import msvcrt
def uni_getch():
char = str(msvcrt.getch())
if char == "b'y'":
return True
elif char == "b'n'":
return False
else:
return None
else:
from getch import getch
def uni_getch():
char = getch()
if char == "y":
return True
elif char == "n":
return False
else:
return None
parser = argparse.ArgumentParser()
parser.add_argument('-i', '--input', action='store', type=str,
help='Path to json file generated by previously running this program.')
parser.add_argument('-o', '--output', action='store', type=str,
help='Output folder.')
parser.add_argument('-a', '--all', action='store_true',
help='Download all subscriptions.')
parser.add_argument('-f', '--format', action='store', type=str, default='best',
help='Format to pass to youtube-dl. (default: best)')
args = parser.parse_args()
json_input = args.input
output_dir = args.output or 'output'
download_all = args.all
dl_format = args.format
c = Console()
def prg_hook(d):
_filename = d['filename'].replace(
os.path.join(output_dir, ch['title'])+'/', '')
if d['status'] == 'finished':
sys.stdout.write("\033[F")
sys.stdout.write("\033[K")
c.print(
':white_check_mark: {}\n'.format(_filename))
if d['status'] == 'downloading':
sys.stdout.write("\033[F")
sys.stdout.write("\033[K")
c.print(':arrow_down_small: {} {} {}'.format(_filename,
d['_percent_str'], d['_eta_str']))
ydl_opts = {
'format': dl_format,
'ignoreerrors': True,
'continuedl': True,
'quiet': True,
'progress_hooks': [prg_hook]
}
print_logo()
if json_input:
f = open(json_input, "r", encoding='utf-8')
all_channels = json.loads(f.read())
f.close()
else:
all_channels = retrieve_youtube_subscriptions()
curr_channel = 0
c.print(
f'You will be prompted if you want to download a channel for each of your subscriptions. (total {len(all_channels)})', style='bold')
for ch in all_channels:
if download_all:
ch['download'] = True
else:
curr_channel += 1
c.print(
f'[dim][{curr_channel}/{len(all_channels)}]:[/dim] {ch["title"]} [cyan]\[y/n]')
while True:
key = uni_getch()
if key == True:
ch['download'] = True
break
elif key == False:
ch['download'] = False
break
else:
c.print('Press "y" or "n"', style='yellow')
c.print('All done! :party_popper:', style='green')
c.print('Saving to download_list.json...', style='italic')
f = open("download_list.json", "w", encoding='utf-8')
f.write(json.dumps(all_channels, indent=4))
f.close()
for ch in all_channels:
if ch['download']:
# line break so that download status won't clear this
c.print('Downloading {}\n'.format(ch['title']), style='bold cyan')
ydl_opts['outtmpl'] = '{}/{}/%(title)s.%(ext)s'.format(
output_dir, ch['title'])
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
Path(os.path.join(output_dir, ch['title'])).mkdir(
parents=True, exist_ok=True)
try:
ydl.download(
['https://www.youtube.com/channel/{}'.format(ch["id"])])
except KeyboardInterrupt:
c.print('\nGoodbye!', style='orange1')
c.print(
'Start where you left off with "python main.py -i download_list.json"')
sys.exit()