added search terms config option and cli menu

-S or --select will allow you to choose your song, for playlists or for
albums
This commit is contained in:
Cooper Hammond 2021-04-15 11:22:01 -06:00
parent 8d348031d3
commit fa5f3bb3b7
6 changed files with 77 additions and 26 deletions

View file

@ -1,5 +1,5 @@
name: irs name: irs
version: 1.3.1 version: 1.4.0
authors: authors:
- Cooper Hammond <kepoorh@gmail.com> - Cooper Hammond <kepoorh@gmail.com>

View file

@ -21,7 +21,7 @@ class CLI
[["-A", "--album"], "album", "string"], [["-A", "--album"], "album", "string"],
[["-p", "--playlist"], "playlist", "string"], [["-p", "--playlist"], "playlist", "string"],
[["-u", "--url"], "url", "string"], [["-u", "--url"], "url", "string"],
[["-g", "--give-url"], "give-url", "bool"], [["-S", "--select"], "select", "bool"]
] ]
@args : Hash(String, String) @args : Hash(String, String)
@ -50,8 +50,10 @@ class CLI
#{Style.blue "-s, --song <song>"} Specify song name to download #{Style.blue "-s, --song <song>"} Specify song name to download
#{Style.blue "-A, --album <album>"} Specify the album name to download #{Style.blue "-A, --album <album>"} Specify the album name to download
#{Style.blue "-p, --playlist <playlist>"} Specify the playlist name to download #{Style.blue "-p, --playlist <playlist>"} Specify the playlist name to download
#{Style.blue "-u, --url <url>"} Specify the youtube url to download from (for single songs only) #{Style.blue "-u, --url [<url>]"} Specify the youtube url to download from
#{Style.blue "-g, --give-url"} Specify the youtube url sources while downloading (for albums or playlists only) #{Style.blue " "} (for single songs, include as an command-line
#{Style.blue " "} argument, for albums or playlists do not)
#{Style.blue "-S, --select"} Use a menu to choose each song's video source
#{Style.bold "Examples:"} #{Style.bold "Examples:"}
$ #{Style.green %(irs --song "Bohemian Rhapsody" --artist "Queen")} $ #{Style.green %(irs --song "Bohemian Rhapsody" --artist "Queen")}
@ -73,33 +75,32 @@ class CLI
if @args["help"]? || @args.keys.size == 0 if @args["help"]? || @args.keys.size == 0
help help
elsif @args["version"]? elsif @args["version"]?
version version
elsif @args["install"]? elsif @args["install"]?
YdlBinaries.get_both(Config.binary_location) YdlBinaries.get_both(Config.binary_location)
elsif @args["config"]? elsif @args["config"]?
puts ENV["IRS_CONFIG_LOCATION"]? puts ENV["IRS_CONFIG_LOCATION"]?
elsif @args["song"]? && @args["artist"]? elsif @args["song"]? && @args["artist"]?
s = Song.new(@args["song"], @args["artist"]) s = Song.new(@args["song"], @args["artist"])
s.provide_client_keys(Config.client_key, Config.client_secret) s.provide_client_keys(Config.client_key, Config.client_secret)
s.grab_it(@args["url"]?) s.grab_it(flags: @args)
s.organize_it() s.organize_it()
elsif @args["album"]? && @args["artist"]? elsif @args["album"]? && @args["artist"]?
a = Album.new(@args["album"], @args["artist"]) a = Album.new(@args["album"], @args["artist"])
a.provide_client_keys(Config.client_key, Config.client_secret) a.provide_client_keys(Config.client_key, Config.client_secret)
if @args["give-url"]? a.grab_it(flags: @args)
a.grab_it(true)
else
a.grab_it(false)
end
elsif @args["playlist"]? && @args["artist"]? elsif @args["playlist"]? && @args["artist"]?
p = Playlist.new(@args["playlist"], @args["artist"]) p = Playlist.new(@args["playlist"], @args["artist"])
p.provide_client_keys(Config.client_key, Config.client_secret) p.provide_client_keys(Config.client_key, Config.client_secret)
if @args["give-url"]? p.grab_it(flags: @args)
p.grab_it(true)
else
p.grab_it(false)
end
else else
puts Style.red("Those arguments don't do anything when used that way.") puts Style.red("Those arguments don't do anything when used that way.")
puts "Type `irs -h` to see usage." puts "Type `irs -h` to see usage."

View file

@ -7,6 +7,7 @@ require "../search/spotify"
EXAMPLE_CONFIG = <<-EOP EXAMPLE_CONFIG = <<-EOP
#{Style.dim "exampleconfig.yml"} #{Style.dim "exampleconfig.yml"}
#{Style.dim "===="} #{Style.dim "===="}
#{Style.blue "search_terms"}: #{Style.green "\"lyrics\""}
#{Style.blue "binary_directory"}: #{Style.green "~/.irs/bin"} #{Style.blue "binary_directory"}: #{Style.green "~/.irs/bin"}
#{Style.blue "music_directory"}: #{Style.green "~/Music"} #{Style.blue "music_directory"}: #{Style.green "~/Music"}
#{Style.blue "filename_pattern"}: #{Style.green "\"{track_number} - {title}\""} #{Style.blue "filename_pattern"}: #{Style.green "\"{track_number} - {title}\""}
@ -24,6 +25,7 @@ module Config
extend self extend self
@@arguments = [ @@arguments = [
"search_terms",
"binary_directory", "binary_directory",
"music_directory", "music_directory",
"filename_pattern", "filename_pattern",
@ -45,6 +47,10 @@ module Config
exit 1 exit 1
end end
def search_terms : String
return @@conf["search_terms"].to_s
end
def binary_location : String def binary_location : String
path = @@conf["binary_directory"].to_s path = @@conf["binary_directory"].to_s
return Path[path].expand(home: true).to_s return Path[path].expand(home: true).to_s

View file

@ -27,7 +27,9 @@ abstract class SpotifyList
end end
# Finds the list, and downloads all of the songs using the `Song` class # Finds the list, and downloads all of the songs using the `Song` class
def grab_it(ask_url : Bool = false) def grab_it(flags = {} of String => String)
ask_url = flags["url"]?
if !@spotify_searcher.authorized? if !@spotify_searcher.authorized?
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
@ -54,7 +56,7 @@ abstract class SpotifyList
song.provide_metadata(data) song.provide_metadata(data)
puts Style.bold("[#{data["track_number"]}/#{contents.size}]") puts Style.bold("[#{data["track_number"]}/#{contents.size}]")
song.grab_it ask_url: ask_url song.grab_it(flags: flags)
organize(song) organize(song)

View file

@ -29,7 +29,7 @@ class Song
Style.green(" + ") + Style.dim("URL found \n"), Style.green(" + ") + Style.dim("URL found \n"),
" Validating URL ...\r", " Validating URL ...\r",
Style.green(" + ") + Style.dim("URL validated \n"), Style.green(" + ") + Style.dim("URL validated \n"),
"URL?: " " URL?: "
], ],
"download" => [ "download" => [
" Downloading video:\n", " Downloading video:\n",
@ -57,7 +57,10 @@ class Song
# ``` # ```
# Song.new("Bohemian Rhapsody", "Queen").grab_it # Song.new("Bohemian Rhapsody", "Queen").grab_it
# ``` # ```
def grab_it(url : (String | Nil) = nil, ask_url : Bool = false) def grab_it(url : (String | Nil) = nil, flags = {} of String => String)
ask_url = flags["url"]?
select_link = flags["select"]?
outputter("intro", 0) outputter("intro", 0)
if !@spotify_searcher.authorized? && !@metadata if !@spotify_searcher.authorized? && !@metadata
@ -99,7 +102,7 @@ class Song
if !url if !url
outputter("url", 0) outputter("url", 0)
url = Youtube.find_url(data, search_terms: "lyrics") url = Youtube.find_url(data, flags: flags)
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}. ) +

View file

@ -5,6 +5,9 @@ require "uri"
require "./ranking" require "./ranking"
require "../bottle/config"
require "../bottle/styles"
module Youtube module Youtube
extend self extend self
@ -26,8 +29,13 @@ module Youtube
# Youtube.find_url("Bohemian Rhapsody", "Queen") # Youtube.find_url("Bohemian Rhapsody", "Queen")
# => "https://www.youtube.com/watch?v=dQw4w9WgXcQ" # => "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
# ``` # ```
def find_url(spotify_metadata : JSON::Any, search_terms = "", def find_url(spotify_metadata : JSON::Any,
download_first = false, select_link = false) : String? flags = {} of String => String) : String?
search_terms = Config.search_terms
download_first = flags["dl_first"]?
select_link = flags["select"]?
song_name = spotify_metadata["name"].as_s song_name = spotify_metadata["name"].as_s
artist_name = spotify_metadata["artists"][0]["name"].as_s artist_name = spotify_metadata["artists"][0]["name"].as_s
@ -52,11 +60,12 @@ module Youtube
return root + yt_metadata[0]["href"] return root + yt_metadata[0]["href"]
end end
ranked = Ranker.rank_videos(spotify_metadata, yt_metadata, human_query)
if select_link if select_link
# return select_link_menu() return root + select_link_menu(spotify_metadata, yt_metadata)
end end
ranked = Ranker.rank_videos(spotify_metadata, yt_metadata, human_query)
begin begin
return root + yt_metadata[ranked[0]["index"]]["href"] return root + yt_metadata[ranked[0]["index"]]["href"]
@ -67,8 +76,38 @@ module Youtube
exit 1 exit 1
end end
# # Presents a menu with song info for the user to choose which url they want to download
private def select_link_menu() : String private def select_link_menu(spotify_metadata : JSON::Any,
yt_metadata : YT_METADATA_CLASS) : String
puts Style.dim(" Spotify info: ") +
Style.bold("\"" + spotify_metadata["name"].to_s) + "\" by \"" +
Style.bold(spotify_metadata["artists"][0]["name"].to_s + "\"") +
" @ " + Style.blue((spotify_metadata["duration_ms"].as_i / 1000).to_i.to_s) + "s"
puts " Choose video to download:"
index = 1
yt_metadata.each do |vid|
print " " + Style.bold(index.to_s + " ")
puts "\"" + vid["title"] + "\" @ " + Style.blue((vid["duration_ms"].to_i / 1000).to_i.to_s) + "s"
index += 1
if index > 5
break
end
end
input = 0
while true # not between 1 and 5
begin
print Style.bold(" > ")
input = gets.not_nil!.chomp.to_i
if input < 6 && input > 0
break
end
rescue
puts Style.red(" Invalid input, try again.")
end
end
return yt_metadata[input]["href"]
end end