feature: CLI download messages have been updated to be prettier

This commit is contained in:
Cooper Hammond 2020-05-21 19:23:44 -07:00
parent 451ef33cca
commit 5f8acac053
4 changed files with 75 additions and 14 deletions

View file

@ -2,22 +2,22 @@ require "colorize"
class Style class Style
def self.bold(txt) def self.bold(txt)
txt.colorize.mode(:bold) txt.colorize.mode(:bold).to_s
end end
def self.dim(txt) def self.dim(txt)
txt.colorize.mode(:dim) txt.colorize.mode(:dim).to_s
end end
def self.blue(txt) def self.blue(txt)
txt.colorize(:light_blue) txt.colorize(:light_blue).to_s
end end
def self.green(txt) def self.green(txt)
txt.colorize(:light_green) txt.colorize(:light_green).to_s
end end
def self.red(txt) def self.red(txt)
txt.colorize(:light_red) txt.colorize(:light_red).to_s
end end
end end

View file

@ -13,6 +13,13 @@ abstract class SpotifyList
@spotify_searcher = SpotifySearcher.new @spotify_searcher = SpotifySearcher.new
@file_names = [] of String @file_names = [] of String
@outputs : Hash(String, Array(String)) = {
"searching" => [
Style.bold("Searching for %l by %a ... \r"),
Style.green("+ ") + Style.bold("%l by %a \n")
]
}
def initialize(@list_name : String, @list_author : String?) def initialize(@list_name : String, @list_author : String?)
end end
@ -22,7 +29,9 @@ abstract class SpotifyList
raise("Need to call provide_client_keys on Album or Playlist class.") raise("Need to call provide_client_keys on Album or Playlist class.")
end end
outputter("searching", 0)
list = find_it() list = find_it()
outputter("searching", 1)
contents = list["tracks"]["items"].as_a contents = list["tracks"]["items"].as_a
i = 0 i = 0
@ -36,6 +45,8 @@ abstract class SpotifyList
song = Song.new(data["name"].to_s, data["artists"][0]["name"].to_s) song = Song.new(data["name"].to_s, data["artists"][0]["name"].to_s)
song.provide_spotify(@spotify_searcher) song.provide_spotify(@spotify_searcher)
song.provide_metadata(data) song.provide_metadata(data)
puts Style.bold("[#{data["track_number"]}/#{contents.size}]")
song.grab_it song.grab_it
organize(song) organize(song)
@ -49,6 +60,13 @@ abstract class SpotifyList
@spotify_searcher.authorize(client_key, client_secret) @spotify_searcher.authorize(client_key, client_secret)
end end
private def outputter(key : String, index : Int32)
text = @outputs[key][index]
.gsub("%l", @list_name)
.gsub("%a", @list_author)
print text
end
# Defined in subclasses, will return the appropriate information or call an # Defined in subclasses, will return the appropriate information or call an
# error if the info is not found and exit # error if the info is not found and exit
abstract def find_it : JSON::Any abstract def find_it : JSON::Any

View file

@ -4,6 +4,8 @@ require "../search/youtube"
require "../interact/ripper" require "../interact/ripper"
require "../interact/tagger" require "../interact/tagger"
require "../bottle/styles"
class Song class Song
@spotify_searcher = SpotifySearcher.new @spotify_searcher = SpotifySearcher.new
@client_id = "" @client_id = ""
@ -14,6 +16,33 @@ class Song
@artist = "" @artist = ""
@album = "" @album = ""
@outputs : Hash(String, Array(String)) = {
"intro" => [Style.bold("[%s by %a]\n")],
"metadata" => [
" Searching for metadata ...\r",
Style.green(" + ") + Style.dim("Metadata found \n")
],
"url" => [
" Searching for URL ...\r",
Style.green(" + ") + Style.dim("URL found \n")
],
"download" => [
" Downloading video:\n",
Style.green("\r + ") + Style.dim("Converted to mp3 \n")
],
"albumart" => [
" Downloading album art ...\r",
Style.green(" + ") + Style.dim("Album art downloaded \n")
],
"tagging" => [
" Attaching metadata ...\r",
Style.green(" + ") + Style.dim("Metadata attached \n")
],
"finished" => [
Style.green(" + ") + "Finished!\n"
]
}
def initialize(@song_name : String, @artist_name : String) def initialize(@song_name : String, @artist_name : String)
end end
@ -23,6 +52,8 @@ class Song
# Song.new("Bohemian Rhapsody", "Queen").grab_it # Song.new("Bohemian Rhapsody", "Queen").grab_it
# ``` # ```
def grab_it def grab_it
outputter("intro", 0)
if !@spotify_searcher.authorized? && !@metadata if !@spotify_searcher.authorized? && !@metadata
if @client_id != "" && @client_secret != "" if @client_id != "" && @client_secret != ""
@spotify_searcher.authorize(@client_id, @client_secret) @spotify_searcher.authorize(@client_id, @client_secret)
@ -33,7 +64,7 @@ class Song
end end
if !@metadata if !@metadata
puts "Searching for metadata ..." outputter("metadata", 0)
@metadata = @spotify_searcher.find_item("track", { @metadata = @spotify_searcher.find_item("track", {
"name" => @song_name, "name" => @song_name,
"artist" => @artist_name, "artist" => @artist_name,
@ -44,28 +75,31 @@ class Song
%("#{@song_name}" by "#{@artist_name}". ) + %("#{@song_name}" by "#{@artist_name}". ) +
"Check your input and try again.") "Check your input and try again.")
end end
outputter("metadata", 1)
end end
data = @metadata.as(JSON::Any) data = @metadata.as(JSON::Any)
@filename = data["track_number"].to_s + " - #{data["name"].to_s}.mp3" @filename = data["track_number"].to_s + " - #{data["name"].to_s}.mp3"
puts "Searching for url ..." outputter("url", 0)
# TODO: should this search_term be here?
url = Youtube.find_url(@song_name, @artist_name, search_terms: "lyrics") url = Youtube.find_url(@song_name, @artist_name, search_terms: "lyrics")
if !url if !url
raise("There was no url found on youtube for " + raise("There was no url found on youtube for " +
%("#{@song_name}" by "#{@artist_name}. ) + %("#{@song_name}" by "#{@artist_name}. ) +
"Check your input and try again.") "Check your input and try again.")
end end
outputter("url", 1)
puts "Downloading video:" outputter("download", 0)
Ripper.download_mp3(url.as(String), @filename) Ripper.download_mp3(url.as(String), @filename)
outputter("download", 1)
outputter("albumart", 0)
temp_albumart_filename = ".tempalbumart.jpg" temp_albumart_filename = ".tempalbumart.jpg"
HTTP::Client.get(data["album"]["images"][0]["url"].to_s) do |response| HTTP::Client.get(data["album"]["images"][0]["url"].to_s) do |response|
File.write(temp_albumart_filename, response.body_io) File.write(temp_albumart_filename, response.body_io)
end end
outputter("albumart", 0)
# check if song's metadata has been modded in playlist, update artist accordingly # check if song's metadata has been modded in playlist, update artist accordingly
if data["artists"][-1]["owner"]? if data["artists"][-1]["owner"]?
@ -85,11 +119,12 @@ class Song
tagger.add_text_tag("track", data["track_number"].to_s) tagger.add_text_tag("track", data["track_number"].to_s)
tagger.add_text_tag("disc", data["disc_number"].to_s) tagger.add_text_tag("disc", data["disc_number"].to_s)
puts "Tagging metadata ..." outputter("tagging", 0)
tagger.save tagger.save
File.delete(temp_albumart_filename) File.delete(temp_albumart_filename)
outputter("tagging", 1)
puts %("#{data["name"].to_s}" by "#{data["artists"][0]["name"].to_s}" downloaded.) outputter("finished", 0)
end end
# Will organize the song into the user's provided music directory as # Will organize the song into the user's provided music directory as
@ -150,4 +185,11 @@ class Song
@client_secret = client_secret @client_secret = client_secret
return self return self
end end
private def outputter(key : String, index : Int32)
text = @outputs[key][index]
.gsub("%s", @song_name)
.gsub("%a", @artist_name)
print text
end
end end

View file

@ -1,5 +1,6 @@
require "./logger" require "./logger"
require "../bottle/config" require "../bottle/config"
require "../bottle/styles"
module Ripper module Ripper
extend self extend self
@ -58,7 +59,7 @@ module Ripper
@dl_status_index += 1 @dl_status_index += 1
if line.includes? "100%" if line.includes? "100%"
puts "Converting to mp3 ..." print " Converting to mp3 ..."
end end
end end
end end