Add copy playlist command
This commit is contained in:
parent
439e160cdd
commit
b71bfb0674
72
main.py
72
main.py
@ -22,6 +22,7 @@ def _truncate_title(title: str, length: int = 30) -> str:
|
||||
return title
|
||||
return title[:length-3] + (title[length:] and '...')
|
||||
|
||||
|
||||
def get_yt_creds():
|
||||
""" Get YouTube API credentials """
|
||||
creds = None
|
||||
@ -70,7 +71,8 @@ def get_playlist_id(playlist_name: str) -> str:
|
||||
def get_playlist_name(playlist_id: str) -> str:
|
||||
if not _playlists:
|
||||
read_playlists_file()
|
||||
return next((name for name, id in _playlists.items() if id == playlist_id), playlist_id)
|
||||
return next((name for name, plid in _playlists.items()
|
||||
if plid == playlist_id), playlist_id)
|
||||
|
||||
|
||||
def get_videos(yt_api, playlist_id):
|
||||
@ -100,7 +102,8 @@ def get_videos(yt_api, playlist_id):
|
||||
return videos
|
||||
|
||||
|
||||
def add_video_to_playlist(yt_api, video, playlist_id, dry_run: bool = False) -> bool:
|
||||
def add_video_to_playlist(yt_api, video, playlist_id,
|
||||
dry_run: bool = False) -> bool:
|
||||
playlist_name = get_playlist_name(playlist_id)
|
||||
video_id = video['snippet']['resourceId']['videoId']
|
||||
video_title = _truncate_title(video['snippet']['title'])
|
||||
@ -127,25 +130,34 @@ def add_video_to_playlist(yt_api, video, playlist_id, dry_run: bool = False) ->
|
||||
return False
|
||||
|
||||
|
||||
def remove_video_from_playlist(yt_api, video, playlist_id, dry_run: bool = False) -> bool:
|
||||
def remove_video_from_playlist(yt_api, video, playlist_id,
|
||||
dry_run: bool = False) -> bool:
|
||||
playlist_name = get_playlist_name(playlist_id)
|
||||
video_id = video['snippet']['resourceId']['videoId']
|
||||
video_title = _truncate_title(video['snippet']['title'])
|
||||
try:
|
||||
if dry_run:
|
||||
print(f"Would remove video '{video_title}' [{video_id}] from playlist {playlist_name}")
|
||||
print(f"Would remove video '{video_title}' [{video_id}]"
|
||||
f" from playlist {playlist_name}")
|
||||
return True
|
||||
yt_api.playlistItems().delete(
|
||||
id=video['id']
|
||||
).execute()
|
||||
print(f"Removed video '{video_title}' [{video_id}] from playlist {playlist_name}")
|
||||
print(f"Removed video '{video_title}' [{video_id}]"
|
||||
f" from playlist {playlist_name}")
|
||||
return True
|
||||
except HttpError as e:
|
||||
print(f"Error removing video '{video_title}' [{video_id}] from playlist {playlist_name}: {e}")
|
||||
print(f"Error removing video '{video_title}' [{video_id}]"
|
||||
f" from playlist {playlist_name}: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def move_all_videos(yt_api, src_playlist: str, dst_playlist: str, limit: int = -1, dry_run: bool = False):
|
||||
def copy_playlist_items(yt_api,
|
||||
src_playlist: str,
|
||||
dst_playlist: str,
|
||||
delete_from_src: bool = False,
|
||||
limit: int = -1,
|
||||
dry_run: bool = False):
|
||||
if limit < 0:
|
||||
limit = len(src_playlist)
|
||||
|
||||
@ -159,36 +171,52 @@ def move_all_videos(yt_api, src_playlist: str, dst_playlist: str, limit: int = -
|
||||
video_id = src_video['snippet']['resourceId']['videoId']
|
||||
if video_id not in dst_video_map:
|
||||
add_video_to_playlist(yt_api, src_video, dst_playlist, dry_run)
|
||||
if delete_from_src:
|
||||
remove_video_from_playlist(yt_api, src_video, src_playlist, dry_run)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('src_playlist', help='Source playlist ID')
|
||||
parser.add_argument('dst_playlist', help='Destination playlist ID')
|
||||
parser.add_argument(
|
||||
'-l', '--limit', help='Limit number of videos to move', type=int, default=-1
|
||||
)
|
||||
parser.add_argument(
|
||||
'-n', '--dry-run', action='store_true',
|
||||
help='Dry run, do not send changes to YoutubeAPI'
|
||||
)
|
||||
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_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('-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.
|
||||
# *DO NOT* leave this option enabled in production.
|
||||
os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"
|
||||
|
||||
src_playlist = get_playlist_id(args.src_playlist)
|
||||
dst_playlist = get_playlist_id(args.dst_playlist)
|
||||
|
||||
api_service_name = "youtube"
|
||||
api_version = "v3"
|
||||
|
||||
creds = get_yt_creds()
|
||||
youtube = build(api_service_name, api_version, credentials=creds)
|
||||
|
||||
move_all_videos(youtube, src_playlist, dst_playlist,
|
||||
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)
|
||||
copy_playlist_items(youtube, src_playlist, dst_playlist,
|
||||
delete_from_src=True,
|
||||
limit=args.limit, dry_run=args.dry_run)
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user