-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.py
executable file
·171 lines (157 loc) · 8.37 KB
/
app.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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#!/usr/bin/env python
import argparse
import cmds
import os
import sys
from googleapiclient.discovery import build
def get_args():
parser = argparse.ArgumentParser(description="Command-line interface for managing channels, videos, and playlists.")
subparsers = parser.add_subparsers(dest="command_group", help="Sub-command help")
admin_parser = subparsers.add_parser("admin", help="Manage channels")
admin_subparser = admin_parser.add_subparsers(dest="admin_command")
admin_subparser.add_parser(
"build-thumbnails",
help="Build thumbnails for videos that have already been retrieved").add_argument(
"channel_name", help="The name of the channel")
admin_subparser.add_parser(
"update-video-root-path",
help="Update the root path of all saved videos. Use if you changed the path.")
admin_subparser.add_parser(
"update-video-saved-path",
help="Update the whole path of all saved videos. Use if the download path scheme has changed.")
admin_subparser.add_parser(
"update-video-info",
help="Update video cache records with duration and resolution").add_argument(
"channel_name", help="The name of the channel")
channels_parser = subparsers.add_parser("channels", help="Manage channels")
channels_subparser = channels_parser.add_subparsers(dest="channels_command")
channels_subparser.add_parser("delete", help="Remove a channel. The videos and playlists will be cleared from the cache.").add_argument(
"channel_username", help="The username of the channel")
channels_subparser.add_parser("generate-index", help="Generate index for a channel").add_argument(
"channel_name", help="The name of the channel")
channels_subparser.add_parser("get", help="Get the channel details from YouTube").add_argument(
"channel_username", help="The username of the channel")
channel_info_parser = channels_subparser.add_parser("info", help="Display cached channel details")
channel_info_parser.add_argument("--username", help="The username for the channel")
channel_info_parser.add_argument("--id", help="The id for the channel")
channels_subparser.add_parser("ls", help="List all the channels in the cache")
channels_subparser.add_parser(
"report", help="Create a spreadsheet of videos for the given channels").add_argument(
"channel_usernames", nargs="+")
channels_subparser.add_parser("sync").add_argument("channel_names", nargs="+")
channels_subparser.add_parser(
"update", help="Obtain new information for channel from the YouTube API").add_argument(
"--channel-usernames", nargs="+")
videos_parser = subparsers.add_parser("videos", help="Manage videos")
videos_subparser = videos_parser.add_subparsers(dest="videos_command")
download_parser = videos_subparser.add_parser("download", help="Download videos")
download_parser.add_argument(
"--channel-username", help="Download all videos for the given channel")
download_parser.add_argument(
"--path", help="Download all links in the given text file")
download_parser.add_argument(
"--mark-unlisted",
action="store_true",
help="Mark the video unlisted. The YouTube Data API does not contain that information.")
download_parser.add_argument(
"--skip-ids",
type=str,
help="A comma-separated list of video IDs to skip. Only applies to the --channel-name argument.")
download_parser.add_argument(
"--video-id", help="Download the video with the given ID and cache its info in the database")
videos_subparser.add_parser(
"get",
help="Use the YouTube API to get and cache video information for a channel").add_argument(
"channel_name", help="The name of the channel")
ls_parser = videos_subparser.add_parser("ls", help="List all the videos in the cache")
ls_parser.add_argument("channel_name", help="The name of the channel")
ls_parser.add_argument(
"--not-downloaded",
action="store_true",
help="Display only videos that haven't yet been downloaded")
ls_parser.add_argument("--xls", action="store_true", help="Generate the list as a spreadsheet")
playlists_parser = subparsers.add_parser("playlists", help="Manage playlists")
playlists_subparser = playlists_parser.add_subparsers(dest="playlists_command")
playlists_subparser.add_parser(
"delete",
help="Delete playlists for a channel").add_argument(
"channel_name", help="The name of the channel")
playlist_download_parser = playlists_subparser.add_parser(
"download",
help="Download playlist items for playlists on a channel")
playlist_download_parser.add_argument("channel_username", help="The username of the channel")
playlist_download_parser.add_argument(
"--playlist-title", help="Only download this specific playlist. The title must match exactly.")
playlists_subparser.add_parser(
"get",
help="Get playlists for a channel").add_argument("channel_name", help="The name of the channel")
ls_playlist_parser = playlists_subparser.add_parser("ls", help="List playlists for a channel")
ls_playlist_parser.add_argument("channel_name", help="The name of the channel")
ls_playlist_parser.add_argument(
"--add-unlisted",
action="store_true",
help="Add unlisted videos to the cache")
ls_playlist_parser.add_argument(
"--add-external",
action="store_true",
help="Add videos that are external to the channel to the cache")
return parser.parse_args()
def main():
api_key = os.getenv("YT_CH_ARCHIVER_API_KEY")
if not api_key:
raise Exception(
"The YT_CH_ARCHIVER_API_KEY environment variable must be set with your API key"
)
args = get_args()
youtube = build("youtube", "v3", developerKey=api_key)
if args.command_group == "admin":
if args.admin_command == "build-thumbnails":
cmds.admin_build_thumbnails(args.channel_name)
elif args.admin_command == "remove-channel-images":
cmds.admin_remove_channel_images()
elif args.admin_command == "update-video-info":
cmds.admin_update_video_info(args.channel_name)
elif args.admin_command == "update-video-root-path":
cmds.admin_update_video_root_path()
elif args.admin_command == "update-video-saved-path":
cmds.admin_update_video_saved_path()
elif args.command_group == "channels":
if args.channels_command == "delete":
cmds.channels_delete(args.channel_username)
if args.channels_command == "generate-index":
cmds.channels_generate_index(args.channel_name)
if args.channels_command == "get":
cmds.channels_get(youtube, args.channel_username)
if args.channels_command == "info":
cmds.channels_info(args.username, args.id)
elif args.channels_command == "ls":
cmds.channels_ls()
if args.channels_command == "report":
cmds.channels_report(args.channel_usernames)
elif args.channels_command == "sync":
cmds.channels_sync(youtube, args.channel_names)
if args.channels_command == "update":
cmds.channels_update(youtube, args.channel_usernames)
elif args.command_group == "playlists":
if args.playlists_command == "delete":
cmds.playlists_delete(args.channel_name)
elif args.playlists_command == "download":
cmds.playlists_download(youtube, args.channel_username, args.playlist_title)
elif args.playlists_command == "get":
cmds.playlists_get(youtube, args.channel_name)
elif args.playlists_command == "ls":
cmds.playlists_ls(args.channel_name, args.add_unlisted, args.add_external)
elif args.command_group == "videos":
if args.videos_command == "download":
skip_ids = []
if args.skip_ids:
skip_ids = args.skip_ids.split(",")
cmds.videos_download(
youtube, args.channel_username, skip_ids, args.video_id, False, args.path)
elif args.videos_command == "get":
cmds.videos_get(youtube, args.channel_name)
elif args.videos_command == "ls":
cmds.videos_ls(args.channel_name, args.not_downloaded, args.xls)
return 0
if __name__ == "__main__":
sys.exit(main())