"--write-to -" for writing to to STDOUT

This commit is contained in:
Ritiek Malhotra
2020-05-12 03:49:37 +05:30
parent a365746e45
commit 635c18723b
4 changed files with 53 additions and 33 deletions

View File

@@ -283,13 +283,13 @@ class Arguments:
) )
if self.parsed.write_m3u and not self.parsed.list: if self.parsed.write_m3u and not self.parsed.list:
self.parser.error("--write-m3u can only be used with --list") self.parser.error("--write-m3u can only be used with --list.")
if self.parsed.write_to and not ( if self.parsed.write_to and not (
self.parsed.playlist or self.parsed.album or self.parsed.all_albums or self.parsed.username self.parsed.playlist or self.parsed.album or self.parsed.all_albums or self.parsed.username or self.parsed.write_m3u
): ):
self.parser.error( self.parser.error(
"--write-to can only be used with --playlist, --album, --all-albums, or --username" "--write-to can only be used with --playlist, --album, --all-albums, --username, or --write-m3u."
) )
ffmpeg_exists = shutil.which("ffmpeg") ffmpeg_exists = shutil.which("ffmpeg")

View File

@@ -118,8 +118,13 @@ class Spotdl:
total_tracks = len(tracks) total_tracks = len(tracks)
logger.info("Generating {0} from {1} YouTube URLs.".format(target_file, total_tracks)) logger.info("Generating {0} from {1} YouTube URLs.".format(target_file, total_tracks))
with open(target_file, "w") as output_file: write_to_stdout = target_file == "-"
output_file.write("#EXTM3U\n\n") m3u_headers = "#EXTM3U\n\n"
if write_to_stdout:
sys.stdout.write(m3u_headers)
else:
with open(target_file, "w") as output_file:
output_file.write(m3u_headers)
videos = [] videos = []
for n, track in enumerate(tracks, 1): for n, track in enumerate(tracks, 1):
@@ -147,8 +152,11 @@ class Spotdl:
youtube_url=video["url"], youtube_url=video["url"],
) )
logger.debug(m3u_key.strip()) logger.debug(m3u_key.strip())
with open(target_file, "a") as output_file: if write_to_stdout:
output_file.write(m3u_key) sys.stdout.write(m3u_key)
else:
with open(target_file, "a") as output_file:
output_file.write(m3u_key)
def download_track(self, track): def download_track(self, track):
logger.info('Downloading "{}"'.format(track)) logger.info('Downloading "{}"'.format(track))

View File

@@ -21,7 +21,7 @@ class SpotifyHelpers:
self.spotify = spotify self.spotify = spotify
def prompt_for_user_playlist(self, username): def prompt_for_user_playlist(self, username):
""" Write user playlists to text_file """ """ Write user playlists to target_file """
playlists = self.fetch_user_playlist_urls(username) playlists = self.fetch_user_playlist_urls(username)
for i, playlist in enumerate(playlists, 1): for i, playlist in enumerate(playlists, 1):
playlist_details = "{0}. {1:<30} ({2} tracks)".format( playlist_details = "{0}. {1:<30} ({2} tracks)".format(
@@ -65,22 +65,22 @@ class SpotifyHelpers:
return results return results
def write_playlist_tracks(self, playlist, text_file=None): def write_playlist_tracks(self, playlist, target_file=None):
tracks = playlist["tracks"] tracks = playlist["tracks"]
if not text_file: if not target_file:
text_file = u"{0}.txt".format(slugify(playlist["name"], ok="-_()[]{}")) target_file = u"{0}.txt".format(slugify(playlist["name"], ok="-_()[]{}"))
return self.write_tracks(tracks, text_file) return self.write_tracks(tracks, target_file)
def fetch_album(self, album_uri): def fetch_album(self, album_uri):
logger.debug('Fetching album "{album}".'.format(album=album_uri)) logger.debug('Fetching album "{album}".'.format(album=album_uri))
album = self.spotify.album(album_uri) album = self.spotify.album(album_uri)
return album return album
def write_album_tracks(self, album, text_file=None): def write_album_tracks(self, album, target_file=None):
tracks = self.spotify.album_tracks(album["id"]) tracks = self.spotify.album_tracks(album["id"])
if not text_file: if not target_file:
text_file = u"{0}.txt".format(slugify(album["name"], ok="-_()[]{}")) target_file = u"{0}.txt".format(slugify(album["name"], ok="-_()[]{}"))
return self.write_tracks(tracks, text_file) return self.write_tracks(tracks, target_file)
def fetch_albums_from_artist(self, artist_uri, album_type=None): def fetch_albums_from_artist(self, artist_uri, album_type=None):
""" """
@@ -106,28 +106,27 @@ class SpotifyHelpers:
return albums return albums
def write_all_albums(self, albums, text_file=None): def write_all_albums(self, albums, target_file=None):
""" """
This function gets all albums from an artist and writes it to a file in the This function gets all albums from an artist and writes it to a file in the
current working directory called [ARTIST].txt, where [ARTIST] is the artist current working directory called [ARTIST].txt, where [ARTIST] is the artist
of the album of the album
:param artist_uri - spotify artist uri :param artist_uri - spotify artist uri
:param text_file - file to write albums to :param target_file - file to write albums to
""" """
# if no file if given, the default save file is in the current working # if no file if given, the default save file is in the current working
# directory with the name of the artist # directory with the name of the artist
if text_file is None: if target_file is None:
text_file = albums[0]["artists"][0]["name"] + ".txt" target_file = albums[0]["artists"][0]["name"] + ".txt"
for album in albums: for album in albums:
logger.info('Fetching album "{album}".'.format(album=album["name"])) logger.info('Fetching album "{album}".'.format(album=album["name"]))
self.write_album_tracks(album, text_file=text_file) self.write_album_tracks(album, target_file=target_file)
def write_tracks(self, tracks, text_file): def write_tracks(self, tracks, target_file):
logger.info(u"Writing {0} tracks to {1}.".format(tracks["total"], text_file)) def writer(tracks, file_io):
track_urls = [] track_urls = []
with open(text_file, "a") as file_out:
while True: while True:
for item in tracks["items"]: for item in tracks["items"]:
if "track" in item: if "track" in item:
@@ -136,7 +135,7 @@ class SpotifyHelpers:
track = item track = item
try: try:
track_url = track["external_urls"]["spotify"] track_url = track["external_urls"]["spotify"]
file_out.write(track_url + "\n") file_io.write(track_url + "\n")
track_urls.append(track_url) track_urls.append(track_url)
except KeyError: except KeyError:
# FIXME: Write "{artist} - {name}" instead of Spotify URI for # FIXME: Write "{artist} - {name}" instead of Spotify URI for
@@ -152,5 +151,15 @@ class SpotifyHelpers:
tracks = self.spotify.next(tracks) tracks = self.spotify.next(tracks)
else: else:
break break
return track_urls
logger.info(u"Writing {0} tracks to {1}.".format(tracks["total"], target_file))
write_to_stdout = target_file == "-"
if write_to_stdout:
with open(target_file, "a") as file_out:
track_urls = writer(tracks, file_out)
else:
file_out = sys.stdout
track_urls = writer(tracks, file_out)
return track_urls return track_urls

View File

@@ -65,16 +65,19 @@ class Track:
total_chunks = self.calculate_total_chunks(stream["filesize"]) total_chunks = self.calculate_total_chunks(stream["filesize"])
progress_bar = self.make_progress_bar(total_chunks) progress_bar = self.make_progress_bar(total_chunks)
response = stream["connection"] response = stream["connection"]
if target_path == "-":
# Target is STDOUT def writer(response, progress_bar, file_io):
for _ in progress_bar: for _ in progress_bar:
chunk = response.read(self._chunksize) chunk = response.read(self._chunksize)
sys.stdout.buffer.write(chunk) file_io.write(chunk)
write_to_stdout = target_path == "-"
if write_to_stdout:
file_io = sys.stdout.buffer
writer(response, progress_bar, file_io)
else: else:
with open(target_path, "wb") as fout: with open(target_path, "wb") as file_io:
for _ in progress_bar: writer(response, progress_bar, file_io)
chunk = response.read(self._chunksize)
fout.write(chunk)
def re_encode(self, input_path, target_path, target_encoding=None, def re_encode(self, input_path, target_path, target_encoding=None,
encoder=EncoderFFmpeg(), show_progress=True): encoder=EncoderFFmpeg(), show_progress=True):