Add videos to playlist

This commit is contained in:
Maks Snegov 2024-02-02 17:33:47 -08:00
parent 9a8d23592f
commit b00e309aa0

52
main.py
View File

@ -83,7 +83,7 @@ def get_playlist_name(playlist_id: str) -> str:
if plid == playlist_id), playlist_id)
def get_videos(yt_api, playlist_id):
def list_playlist(yt_api, playlist_id):
playlist_name = get_playlist_name(playlist_id)
videos = []
fetched = 0
@ -172,8 +172,8 @@ def copy_playlist_items(yt_api,
if limit < 0:
limit = len(src_playlist)
src_videos = get_videos(yt_api, src_playlist)
dst_videos = get_videos(yt_api, dst_playlist)
src_videos = list_playlist(yt_api, src_playlist)
dst_videos = list_playlist(yt_api, dst_playlist)
dst_video_map = {video['snippet']['resourceId']['videoId']: video['id']
for video in dst_videos}
@ -186,24 +186,41 @@ def copy_playlist_items(yt_api,
remove_video_from_playlist(yt_api, src_video, src_playlist, dry_run)
def get_video_info(youtube, video_id: str):
try:
response = youtube.videos().list(
part="snippet",
id=video_id
).execute()
return response['items'][0]
except HttpError as e:
exit_on_exceeded_quota(e)
print(f'Error getting video {video_id}: {e}')
return None
def main():
parser = argparse.ArgumentParser()
parser.add_argument('-n', '--dry-run', action='store_true',
help='Dry run, do not send changes to YoutubeAPI')
subparsers = parser.add_subparsers(title='commands', dest='command')
parser_move = subparsers.add_parser('move', help='Move videos from one playlist to another')
parser_move.add_argument('src_playlist', help='Source playlist ID')
parser_move.add_argument('dst_playlist', help='Destination playlist ID')
parser_move.add_argument('-l', '--limit', type=int, default=-1,
help='Limit number of videos to process')
parser_add = subparsers.add_parser('add', help='Add videos to a playlist')
parser_add.add_argument('playlist', help='Playlist name/ID')
parser_add.add_argument('video_ids', nargs='+', help='Video IDs to add')
parser_copy = subparsers.add_parser('copy', help='Copy videos from one playlist to another')
parser_copy.add_argument('src_playlist', help='Source playlist ID')
parser_copy.add_argument('dst_playlist', help='Destination playlist ID')
parser_copy.add_argument('src_playlist', help='Source playlist name/ID')
parser_copy.add_argument('dst_playlist', help='Destination playlist name/ID')
parser_copy.add_argument('-l', '--limit', type=int, default=-1,
help='Limit number of videos to process')
parser_move = subparsers.add_parser('move', help='Move videos from one playlist to another')
parser_move.add_argument('src_playlist', help='Source playlist name/ID')
parser_move.add_argument('dst_playlist', help='Destination playlist name/ID')
parser_move.add_argument('-l', '--limit', type=int, default=-1,
help='Limit number of videos to process')
args = parser.parse_args()
# Disable OAuthlib's HTTPS verification when running locally.
@ -217,12 +234,14 @@ def main():
if args.command is None:
parser.print_help()
return 1
elif args.command == 'copy':
src_playlist = get_playlist_id(args.src_playlist)
dst_playlist = get_playlist_id(args.dst_playlist)
copy_playlist_items(youtube, src_playlist, dst_playlist,
delete_from_src=False,
limit=args.limit, dry_run=args.dry_run)
elif args.command == 'move':
src_playlist = get_playlist_id(args.src_playlist)
dst_playlist = get_playlist_id(args.dst_playlist)
@ -230,6 +249,19 @@ def main():
delete_from_src=True,
limit=args.limit, dry_run=args.dry_run)
elif args.command == 'add':
playlist = get_playlist_id(args.playlist)
pl_videos = {video['snippet']['resourceId']['videoId']
for video in list_playlist(youtube, playlist)}
for video_id in args.video_ids:
if video_id in pl_videos:
print(f'Video {video_id} already in playlist {args.playlist}')
continue
video = get_video_info(youtube, video_id)
if video is None:
continue
add_video_to_playlist(youtube, video, playlist, args.dry_run)
if __name__ == '__main__':
sys.exit(main())