-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmain.py
147 lines (128 loc) · 4.98 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
from rich.console import Console
#from rich import inspect
import platform
from pathlib import Path
import os
import sys
import json
import argparse
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)')
parser.add_argument('--download_archive', action='store', type=str,
help='Download only videos not listed in the archive file. Record the IDs of all downloaded videos in it.')
# oauth2client.tools.run_flow arguments
parser.add_argument('--auth_host_name', action='store', type=str, default='localhost',
help='Host name to use when running a local web server to handle redirects during OAuth authorization.')
parser.add_argument('--auth_host_port', action='store', type=int, default=8080,
help='Port to use when running a local web server to handle redirects during OAuth authorization.')
parser.add_argument('--noauth_local_webserver', action='store_true',
help='Run a local web server to handle redirects during OAuth authorization.')
args = parser.parse_args()
json_input = args.input
output_dir = args.output or 'output'
download_all = args.all
dl_format = args.format
dl_archive = args.download_archive
c = Console()
def prg_hook(d):
_filedir = os.path.join(output_dir, ch['title'])+'/'
if platform.system() == 'Windows':
_filedir = _filedir.replace('/', '\\')
_filename = d['filename'].replace(_filedir, '')
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,
'download_archive': dl_archive,
'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(args)
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()