Skip to content

Commit

Permalink
copy_all_playlists added, thanks to CyanideLion
Browse files Browse the repository at this point in the history
  • Loading branch information
linsomniac committed Jan 13, 2024
1 parent a7966ae commit 3be8dd5
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 0 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@ individually copy them.

## Copy Your Playlists

You can either copy **all** playlists, or do a more surgical copy of individual playlists.
Copying all playlists will use the name of the Spotify playlist as the destination
playlist name on YTMusic. To copy all playlists, run:

`s2yt_copy_all_playlists`

**NOTE**: This does not copy the Liked playlist (see above to do that).

In the list output above, find the "playlist id" (the first column) of the Spotify playlist,
and of the YTMusic playlist, and then run:

Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ build-backend = "poetry.core.masonry.api"
[tool.poetry.scripts]
s2yt_load_liked = "spotify2ytmusic.cli:load_liked"
s2yt_copy_playlist = "spotify2ytmusic.cli:copy_playlist"
s2yt_copy_all_playlists = "spotify2ytmusic.cli:copy_all_playlists"
s2yt_create_playlist = "spotify2ytmusic.cli:create_playlist"
s2yt_list_playlists = "spotify2ytmusic.cli:list_playlists"
49 changes: 49 additions & 0 deletions spotify2ytmusic/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ def parse_arguments():
print(f"Looking up playlist '{pl_name}': id={dst_pl_id}")
if dst_pl_id is None:
dst_pl_id = yt.create_playlist(title=pl_name, description=pl_name)
time.sleep(1) # seems to be needed to avoid missing playlist ID error

# create_playlist returns a dict if there was an error
if isinstance(dst_pl_id, dict):
Expand All @@ -192,6 +193,54 @@ def parse_arguments():
copier(src_pl_id, dst_pl_id, args.dry_run, args.track_sleep, yt=yt)


def copy_all_playlists():
"""
Copy all Spotify playlists (except Liked Songs) to YTMusic playlists
"""
yt = YTMusic("oauth.json")

def parse_arguments():
parser = ArgumentParser()
parser.add_argument(
"--track-sleep",
type=float,
default=0.1,
help="Time to sleep between each track that is added (default: 0.1)",
)
parser.add_argument(
"--dry-run",
action="store_true",
help="Do not add songs to destination playlist (default: False)",
)

return parser.parse_args()

args = parse_arguments()
spotify_pls = json.load(open("playlists.json", "r"))

for src_pl in spotify_pls["playlists"]:
if str(src_pl.get("name")) == "Liked Songs":
continue

pl_name = src_pl["name"]
dst_pl_id = get_playlist_id_by_name(yt, pl_name)
print(f"Looking up playlist '{pl_name}': id={dst_pl_id}")
if dst_pl_id is None:
dst_pl_id = yt.create_playlist(title=pl_name, description=pl_name)
time.sleep(1) # seems to be needed to avoid missing playlist ID error

# create_playlist returns a dict if there was an error
if isinstance(dst_pl_id, dict):
print(f"ERROR: Failed to create playlist: {dst_pl_id}")
sys.exit(1)
print(f"NOTE: Created playlist '{pl_name}' with ID: {dst_pl_id}")

copier(src_pl["id"], dst_pl_id, args.dry_run, args.track_sleep)
print("\nPlaylist done!\n")

print("All done!")


def copier(
src_pl_id: Optional[str] = None,
dst_pl_id: Optional[str] = None,
Expand Down

0 comments on commit 3be8dd5

Please sign in to comment.