mirror of
				https://github.com/cooperhammond/irs.git
				synced 2025-11-03 18:14:51 +00:00 
			
		
		
		
	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:
		
							parent
							
								
									8d348031d3
								
							
						
					
					
						commit
						fa5f3bb3b7
					
				| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
name: irs
 | 
			
		||||
version: 1.3.1
 | 
			
		||||
version: 1.4.0
 | 
			
		||||
 | 
			
		||||
authors:
 | 
			
		||||
  - Cooper Hammond <kepoorh@gmail.com>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,7 @@ class CLI
 | 
			
		|||
    [["-A", "--album"], "album", "string"],
 | 
			
		||||
    [["-p", "--playlist"], "playlist", "string"],
 | 
			
		||||
    [["-u", "--url"], "url", "string"],
 | 
			
		||||
    [["-g", "--give-url"], "give-url", "bool"],
 | 
			
		||||
    [["-S", "--select"], "select", "bool"]
 | 
			
		||||
  ]
 | 
			
		||||
 | 
			
		||||
  @args : Hash(String, String)
 | 
			
		||||
| 
						 | 
				
			
			@ -50,8 +50,10 @@ class CLI
 | 
			
		|||
        #{Style.blue "-s, --song <song>"}           Specify song 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 "-u, --url <url>"}             Specify the youtube url to download from (for single songs only)
 | 
			
		||||
        #{Style.blue "-g, --give-url"}              Specify the youtube url sources while downloading (for albums or playlists only)
 | 
			
		||||
        #{Style.blue "-u, --url [<url>]"}           Specify the youtube url to download from 
 | 
			
		||||
        #{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.green %(irs --song "Bohemian Rhapsody" --artist "Queen")}
 | 
			
		||||
| 
						 | 
				
			
			@ -73,33 +75,32 @@ class CLI
 | 
			
		|||
 | 
			
		||||
    if @args["help"]? || @args.keys.size == 0
 | 
			
		||||
      help
 | 
			
		||||
 | 
			
		||||
    elsif @args["version"]?
 | 
			
		||||
      version
 | 
			
		||||
 | 
			
		||||
    elsif @args["install"]?
 | 
			
		||||
      YdlBinaries.get_both(Config.binary_location)
 | 
			
		||||
 | 
			
		||||
    elsif @args["config"]?
 | 
			
		||||
      puts ENV["IRS_CONFIG_LOCATION"]?
 | 
			
		||||
 | 
			
		||||
    elsif @args["song"]? && @args["artist"]?
 | 
			
		||||
      s = Song.new(@args["song"], @args["artist"])
 | 
			
		||||
      s.provide_client_keys(Config.client_key, Config.client_secret)
 | 
			
		||||
      s.grab_it(@args["url"]?)
 | 
			
		||||
      s.grab_it(flags: @args)
 | 
			
		||||
      s.organize_it()
 | 
			
		||||
 | 
			
		||||
    elsif @args["album"]? && @args["artist"]?
 | 
			
		||||
      a = Album.new(@args["album"], @args["artist"])
 | 
			
		||||
      a.provide_client_keys(Config.client_key, Config.client_secret)
 | 
			
		||||
      if @args["give-url"]?
 | 
			
		||||
        a.grab_it(true)
 | 
			
		||||
      else
 | 
			
		||||
        a.grab_it(false)
 | 
			
		||||
      end
 | 
			
		||||
      a.grab_it(flags: @args)
 | 
			
		||||
 | 
			
		||||
    elsif @args["playlist"]? && @args["artist"]?
 | 
			
		||||
      p = Playlist.new(@args["playlist"], @args["artist"])
 | 
			
		||||
      p.provide_client_keys(Config.client_key, Config.client_secret)
 | 
			
		||||
      if @args["give-url"]?
 | 
			
		||||
        p.grab_it(true)
 | 
			
		||||
      else
 | 
			
		||||
        p.grab_it(false)
 | 
			
		||||
      end
 | 
			
		||||
      p.grab_it(flags: @args)
 | 
			
		||||
 | 
			
		||||
    else
 | 
			
		||||
      puts Style.red("Those arguments don't do anything when used that way.")
 | 
			
		||||
      puts "Type `irs -h` to see usage."
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,7 @@ require "../search/spotify"
 | 
			
		|||
EXAMPLE_CONFIG = <<-EOP
 | 
			
		||||
#{Style.dim "exampleconfig.yml"}
 | 
			
		||||
#{Style.dim "===="}
 | 
			
		||||
#{Style.blue "search_terms"}: #{Style.green "\"lyrics\""}
 | 
			
		||||
#{Style.blue "binary_directory"}: #{Style.green "~/.irs/bin"}
 | 
			
		||||
#{Style.blue "music_directory"}: #{Style.green "~/Music"}
 | 
			
		||||
#{Style.blue "filename_pattern"}: #{Style.green "\"{track_number} - {title}\""}
 | 
			
		||||
| 
						 | 
				
			
			@ -24,6 +25,7 @@ module Config
 | 
			
		|||
  extend self
 | 
			
		||||
 | 
			
		||||
  @@arguments = [
 | 
			
		||||
    "search_terms",
 | 
			
		||||
    "binary_directory",
 | 
			
		||||
    "music_directory",
 | 
			
		||||
    "filename_pattern",
 | 
			
		||||
| 
						 | 
				
			
			@ -45,6 +47,10 @@ module Config
 | 
			
		|||
    exit 1
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def search_terms : String
 | 
			
		||||
    return @@conf["search_terms"].to_s
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def binary_location : String
 | 
			
		||||
    path = @@conf["binary_directory"].to_s
 | 
			
		||||
    return Path[path].expand(home: true).to_s
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,7 +27,9 @@ abstract class SpotifyList
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  # 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?
 | 
			
		||||
      raise("Need to call provide_client_keys on Album or Playlist class.")
 | 
			
		||||
    end
 | 
			
		||||
| 
						 | 
				
			
			@ -54,7 +56,7 @@ abstract class SpotifyList
 | 
			
		|||
      song.provide_metadata(data)
 | 
			
		||||
 | 
			
		||||
      puts Style.bold("[#{data["track_number"]}/#{contents.size}]")
 | 
			
		||||
      song.grab_it ask_url: ask_url
 | 
			
		||||
      song.grab_it(flags: flags)
 | 
			
		||||
 | 
			
		||||
      organize(song)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,7 +29,7 @@ class Song
 | 
			
		|||
      Style.green("  + ") + Style.dim("URL found                       \n"),
 | 
			
		||||
      "  Validating URL ...\r",
 | 
			
		||||
      Style.green("  + ") + Style.dim("URL validated                   \n"),
 | 
			
		||||
      "URL?: "
 | 
			
		||||
      "  URL?: "
 | 
			
		||||
    ],
 | 
			
		||||
    "download" => [
 | 
			
		||||
      "  Downloading video:\n",
 | 
			
		||||
| 
						 | 
				
			
			@ -57,7 +57,10 @@ class Song
 | 
			
		|||
  # ```
 | 
			
		||||
  # 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)
 | 
			
		||||
 | 
			
		||||
    if !@spotify_searcher.authorized? && !@metadata
 | 
			
		||||
| 
						 | 
				
			
			@ -99,7 +102,7 @@ class Song
 | 
			
		|||
 | 
			
		||||
    if !url
 | 
			
		||||
      outputter("url", 0)
 | 
			
		||||
      url = Youtube.find_url(data, search_terms: "lyrics")
 | 
			
		||||
      url = Youtube.find_url(data, flags: flags)
 | 
			
		||||
      if !url
 | 
			
		||||
        raise("There was no url found on youtube for " +
 | 
			
		||||
              %("#{@song_name}" by "#{@artist_name}. ) +
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,9 @@ require "uri"
 | 
			
		|||
 | 
			
		||||
require "./ranking"
 | 
			
		||||
 | 
			
		||||
require "../bottle/config"
 | 
			
		||||
require "../bottle/styles"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
module Youtube
 | 
			
		||||
  extend self
 | 
			
		||||
| 
						 | 
				
			
			@ -26,8 +29,13 @@ module Youtube
 | 
			
		|||
  # Youtube.find_url("Bohemian Rhapsody", "Queen")
 | 
			
		||||
  # => "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
 | 
			
		||||
  # ```
 | 
			
		||||
  def find_url(spotify_metadata : JSON::Any, search_terms = "",
 | 
			
		||||
               download_first = false, select_link = false) : String?
 | 
			
		||||
  def find_url(spotify_metadata : JSON::Any,
 | 
			
		||||
               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
 | 
			
		||||
    artist_name = spotify_metadata["artists"][0]["name"].as_s
 | 
			
		||||
| 
						 | 
				
			
			@ -52,11 +60,12 @@ module Youtube
 | 
			
		|||
      return root + yt_metadata[0]["href"] 
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    ranked = Ranker.rank_videos(spotify_metadata, yt_metadata, human_query)
 | 
			
		||||
 | 
			
		||||
    if select_link
 | 
			
		||||
      # return select_link_menu()
 | 
			
		||||
      return root + select_link_menu(spotify_metadata, yt_metadata)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    ranked = Ranker.rank_videos(spotify_metadata, yt_metadata, human_query)
 | 
			
		||||
 | 
			
		||||
    begin
 | 
			
		||||
      return root + yt_metadata[ranked[0]["index"]]["href"]
 | 
			
		||||
| 
						 | 
				
			
			@ -67,8 +76,38 @@ module Youtube
 | 
			
		|||
    exit 1
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  #
 | 
			
		||||
  private def select_link_menu() : String
 | 
			
		||||
  # Presents a menu with song info for the user to choose which url they want to download
 | 
			
		||||
  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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue