Skip to content

Commit

Permalink
rework cli
Browse files Browse the repository at this point in the history
  • Loading branch information
sigma67 committed Apr 8, 2023
1 parent 6489e5a commit 4e7058d
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 59 deletions.
109 changes: 59 additions & 50 deletions spotify_to_ytmusic/main.py
Original file line number Diff line number Diff line change
@@ -1,71 +1,86 @@
import argparse
import sys
from datetime import datetime
from pathlib import Path

from spotify_to_ytmusic.Setup import setup
from spotify_to_ytmusic.SpotifyExport import Spotify
from spotify_to_ytmusic.YouTube import YTMusicTransfer
from spotify_to_ytmusic.setup import setup
from spotify_to_ytmusic.spotify import Spotify
from spotify_to_ytmusic.ytmusic import YTMusicTransfer


def get_args():
parser = argparse.ArgumentParser(
description="Transfer spotify playlist to YouTube Music."
def get_args(args=None):
parser = argparse.ArgumentParser(description="Transfer spotify playlist to YouTube Music.")

subparsers = parser.add_subparsers(help="Provide a subcommand", dest="command")
setup_parser = subparsers.add_parser("setup", help="Set up credentials")
setup_parser.add_argument("--file", type=Path, help="Optional path to a settings.ini file")

playlist_creator = argparse.ArgumentParser(add_help=False)
playlist_creator.add_argument(
"-p",
"--public",
action="store_true",
help="Make created playlist public. Default: private",
)
parser.add_argument("playlist", type=str, help="Provide a playlist Spotify link.")
parser.add_argument(
"-u",
"--update",

create_parser = subparsers.add_parser(
"create",
help="Create a new playlist on YouTube Music.",
parents=[playlist_creator],
)
create_parser.add_argument("playlist", type=str, help="Provide a playlist Spotify link.")
create_parser.add_argument(
"-d",
"--date",
action="store_true",
help="Delete all entries in the provided Google Play Music playlist and update the playlist with entries from the Spotify playlist.",
help="Append the current date to the playlist name",
)
parser.add_argument(
create_parser.add_argument(
"-i",
"--info",
type=str,
help="Provide description information for the YouTube Music Playlist. Default: Spotify playlist description",
)
create_parser.add_argument(
"-n",
"--name",
type=str,
help="Provide a name for the YouTube Music playlist. Default: Spotify playlist name",
)
parser.add_argument(
"-i",
"--info",
type=str,
help="Provide description information for the YouTube Music Playlist. Default: Spotify playlist description",

update_parser = subparsers.add_parser(
"update",
help="Delete all entries in the provided Google Play Music playlist and update the playlist with entries from the Spotify playlist.",
)
parser.add_argument(
"-d",
"--date",
action="store_true",
help="Append the current date to the playlist name",
update_parser.add_argument(
"name", type=str, help="The name of the YouTube Music playlist to update."
)
parser.add_argument(
"-p",
"--public",
action="store_true",
help="Make the playlist public. Default: private",
update_parser.add_argument(
"--append", help="Do not delete items, append to target playlist instead"
)
parser.add_argument(
"-r",
"--remove",
action="store_true",
help="Remove playlists with specified regex pattern.",

remove_parser = subparsers.add_parser(
"remove", help="Remove playlists with specified regex pattern."
)
parser.add_argument(
"-a",
"--all",
action="store_true",
remove_parser.add_argument("pattern", help="regex pattern")

all_parser = subparsers.add_parser(
"all",
help="Transfer all public playlists of the specified user (Spotify User ID).",
parents=[playlist_creator],
)
parser.add_argument("--setup", help="Set up credentials")
return parser.parse_args()

return parser.parse_args(args)


def main():
args = get_args()
ytmusic = YTMusicTransfer()

if args.setup:
setup()
sys.exit()

ytmusic = YTMusicTransfer()
if args.all:
s = Spotify()
pl = s.getUserPlaylists(args.playlist)
Expand All @@ -85,13 +100,11 @@ def main():
)
print(playlist_id)
except Exception as ex:
print(
"Could not transfer playlist " + p["name"] + ". Exception" + str(ex)
)
print(f"Could not transfer playlist {p['name']}. {str(ex)}")
return

if args.remove:
ytmusic.remove_playlists(args.playlist)
ytmusic.remove_playlists(args.pattern)
return

date = ""
Expand All @@ -101,8 +114,7 @@ def main():
playlist = Spotify().getSpotifyPlaylist(args.playlist)
except Exception as ex:
print(
"Could not get Spotify playlist. Please check the playlist link.\n Error: "
+ repr(ex)
"Could not get Spotify playlist. Please check the playlist link.\n Error: " + repr(ex)
)
return

Expand All @@ -122,11 +134,8 @@ def main():
)

print(
'Success: created playlist "'
+ name
+ '"\n'
+ "https://music.youtube.com/playlist?list="
+ playlistId
f"Success: created playlist {name}\n"
f"https://music.youtube.com/playlist?list={playlistId}"
)


Expand Down
8 changes: 2 additions & 6 deletions spotify_to_ytmusic/match.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ def get_best_fit_song_id(ytm_results, spoti) -> str:
if "duration" in ytm and ytm["duration"] and spoti["duration"]:
duration_items = ytm["duration"].split(":")
duration = int(duration_items[0]) * 60 + int(duration_items[1])
duration_match_score = (
1 - abs(duration - spoti["duration"]) * 2 / spoti["duration"]
)
duration_match_score = 1 - abs(duration - spoti["duration"]) * 2 / spoti["duration"]

title = ytm["title"]
# for videos,
Expand All @@ -37,9 +35,7 @@ def get_best_fit_song_id(ytm_results, spoti) -> str:
).ratio()
scores = [
title_score[ytm["videoId"]],
difflib.SequenceMatcher(
a=artists.lower(), b=spoti["artist"].lower()
).ratio(),
difflib.SequenceMatcher(a=artists.lower(), b=spoti["artist"].lower()).ratio(),
]
if duration_match_score:
scores.append(duration_match_score * 5)
Expand Down
8 changes: 5 additions & 3 deletions spotify_to_ytmusic/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ class Settings:

def __init__(self, filepath: Optional[Path] = None):
self.config = configparser.ConfigParser(interpolation=None)
self.filepath = (
filepath if filepath else Path(__file__).parent.joinpath("settings.ini")
)
self.filepath = filepath if filepath else Path(__file__).parent.joinpath("settings.ini")
if not self.filepath.is_file():
raise FileNotFoundError(
f"{self.filepath} not found! Please set up your credentials first."
)
self.config.read(self.filepath)

def __getitem__(self, key):
Expand Down
15 changes: 15 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import unittest

from spotify_to_ytmusic.main import get_args


class TestCli(unittest.TestCase):
def test_get_args(self):
args = get_args(["all", "--public"])
self.assertEqual(len(vars(args)), 2)
args = get_args(["create", "playlist-link"])
self.assertEqual(len(vars(args)), 6)
args = get_args(["update", "playlist-link"])
self.assertEqual(len(vars(args)), 3)
args = get_args(["setup"])
self.assertEqual(len(vars(args)), 2)

0 comments on commit 4e7058d

Please sign in to comment.