class IRS::Ripper

Attributes

authenticated[R]

Public Class Methods

args() click to toggle source
# File lib/ripper.rb, line 51
def args
  @@args
end
find_yt_url(song=nil, artist=nil, additional_search="lyrics") click to toggle source
# File lib/ripper.rb, line 69
def find_yt_url(song=nil, artist=nil, additional_search="lyrics")
  if !song
    song = @@args[:song]
  end

  if !artist
    artist = @@args[:artist]
  end

  search_terms = song + " " + artist + " " + additional_search
  query_string = CGI.escape(search_terms)

  http = "https"
  link = "#{http}://www.youtube.com/results?search_query=" + query_string
  uri = URI.parse(link)
  begin
    uri.open(redirect: false)
  rescue OpenURI::HTTPRedirect => redirect
    http = "http"
  end

  html_content = open(link).read

  doc = Nokogiri::HTML(html_content)
  results = doc.search('a').map{ |link|
    if link["class"] == "yt-uix-tile-link yt-ui-ellipsis yt-ui-ellipsis-2 yt-uix-sessionlink      spf-link "
      link if !link["href"].include?("&list=")
    end
  }.compact

  garbage_phrases = "cover  full album  live  clean  rare version".split("  ")
  utils = IRS::Utils

  results.each do |result|
    title = result["title"]

    if utils.blank_include?(title, song) and utils.blank_include?(title, artist)

      next if utils.check_garbage_phrases(garbage_phrases, title, song)
      @code = result
    end
  end

  results.each do |result|
    title = result["title"]

    next if utils.check_garbage_phrases(garbage_phrases, title, song)
    if utils.individual_word_match(song, title) >= 0.8 and utils.blank_include?(title, artist)
      @code = result
      break
    end
  end
  if additional_search == "lyrics"
    return self.find_yt_url(song, artist, "")
  else
    results.each do |result|
      @code = result
      break
    end
  end

  return ("https://www.youtube.com" + @code["href"]), @code["title"]
end
list(list_data) click to toggle source
# File lib/ripper.rb, line 237
def list(list_data)
  File.open(".irs-download-log", "w") do |file|
    file.write(IRS::Utils.format_download_log_data(list_data))
  end

  list_data.each do |track|
    loc = self.song(track[:song], track[:artist], track)

    if loc != false
      @locations.push(loc)
    end
  end
  return @locations
end
new(args={}) click to toggle source
# File lib/ripper.rb, line 29
def initialize(args={})
  @@args = args

  begin
    RSpotify::authenticate($SPOTIFY_CLIENT_ID, $SPOTIFY_CLIENT_SECRET)
    ENV["SPOTIFY_AUTHENTICATED?"] = "TRUE"
  rescue
    ENV["SPOTIFY_AUTHENTICATED?"] = "FALSE"
  end
end
post_processing() click to toggle source
# File lib/ripper.rb, line 55
def post_processing
  @@args[:post_processors] = [] if !@@args[:post_processors].is_a?(Array)

  if @@args[:post_processors].include?("traditional")
    @locations = IRS::Utils.organize_it(@locations)
  end

  if @@args[:post_processors].include?("zip")
    @locations.push(IRS::Utils.zip_it(@locations, @@args[:title] || @@args[:list].name))
  end

  return @locations
end
resume() click to toggle source
# File lib/ripper.rb, line 252
def resume
  if Pathname.exist?(".irs-download-log")
    data = IRS::Utils.read_download_log
    self.list(data)
  else
    puts "There is not .irs-download-log file in the current directory."
    return false
  end
end
song(song=nil, artist=nil, data={} ) click to toggle source
# File lib/ripper.rb, line 262
      def song(song=nil,
               artist=nil,
               data={}
               )

        if !@@args[:rip_type]
          @@args[:rip_type] = "song"
          @locations = []
        end

        # Possible data:
        # {
        #   album: "The Game",
        #   genre: ["Rock", "Pop"],
        #   tracknum: 1
        #   discnum: 1
        #   compilation: false
        #   prefix: "1 - "
        # }

        album = data[:album]
        genre = data[:genre] || []
        tracknum = data[:track_number]
        discnum = data[:disc_number]
        compilation = data[:compilation]

        if not song
          song = @@args[:song]
        end

        if not artist
          artist = @@args[:artist]
        end

        video, video_title = self.find_yt_url(song, artist)

        if video == false
          puts "Could not find \"#{song}\" by \"#{artist}\""
          return false
        end
        puts "Downloading \"#{song}\" by \"#{artist}\""

        file_prefix = ""
        if data[:prefix]
          file_prefix = data[:prefix]
        elsif tracknum
          file_prefix = tracknum.to_s + " - "
        end

        file_name = file_prefix + IRS::Utils.blank(song, d=false) + ".mp3"

        ydl_opts = {
          "format": 'bestaudio/worstvideo',
          "extract-audio": true,
          "audio-format": "mp3",
          "add-metadata": true,
        }


        YoutubeDL.download(video, ydl_opts)

        Dir.glob("./*#{video.split("/watch?v=")[-1]}*") do |file|
          File.rename(file, file_name)
        end

        if album == nil
          if @@args[:album] == nil
            album = Metadata.find_album(song, artist)
            if album and genre == []
              genre = album.artists[0].genres
            end
          else
            album = @@args[:album]
          end
        end

        if album
          if IRS::Utils.check_garbage_phrases(["remastered", "explicit"], album.name, album.name)
            split = " ("
            album_name = album.name.split(split)[0]
          else
            album_name = album.name
          end

          genre = IRS::Metadata.parse_genre(genre)

          # http://www.rubydoc.info/github/topspin/id3_tags/Id3Tags.write_tags_to
          Id3Tags.write_tags_to(file_name, {
            title:        song,
            artist:       artist,
            album:        album_name,
            genre:        genre,
            compilation:  compilation,
            track:        {number: tracknum},
            disk:         {number: discnum},
            cover_art:    {
                            mime_type: "image/png",
                            data: File.read(open(album.images[0]["url"])),
                          },
            comment:      "Downloaded from: #{video}\nVideo title: #{video_title}",
=begin
            year: 1979,
            bitrate: 128,
            channels: 2,
            length: 38,
            samplerate: 44100,
            bpm: 110,
            lyrics: "Sample lyrics line 1\rand line 2",
            composer: "Sample composer",
            grouping: "Sample group",
            album_artist: "Sample album artist",
=end
          })
        end


        if @@args[:location]
          if !File.directory?(@@args[:location])
            system "mkdir", "-p", @@args[:location]
          end
          new_file_name = @@args[:location] + "/" + file_name
          File.rename(file_name, new_file_name)
          file_name = new_file_name

        end

        if @@args[:rip_type] == "song"
          @locations = [@locations] if !@locations.is_a?(Array)

          @locations.push(file_name)

          @@args[:song] = @@args[:title] = song
          @@args[:album] = album

          file_name = self.post_processing()
        end

        return file_name
      end
spotify_list(type=nil, title=nil, username=nil) click to toggle source
# File lib/ripper.rb, line 133
def spotify_list(type=nil, title=nil, username=nil)

  if !@@args[:rip_type]
    @@args[:rip_type] = "spotify_list"
    @locations = []
  end

  if type == nil
    type = @@args[:type]
  end
  if title == nil
    title = @@args[:title]
  end
  @@args[:type] = type
  @@args[:title] = title
  @@args[:username] = username


  if type == "album"
    search = title
    if @@args[:artist]
      search += " " + @@args[:artist]
    end
    list_of_lists = RSpotify::Album.search(search)

  elsif type == "playlist"
    if username == nil
      username = @@args[:username]
    end
    list_of_lists = RSpotify::User.find(username).playlists
  end

  if list_of_lists.size > 0

    list_of_lists.each do |list|
      if list.name.downcase.include?(title.downcase)
        if @@args[:artist]
          if list.artists[0].name.include?(@@args[:artist])
            @@args[:list] = list
            break
          else
            next
          end
        end
        @@args[:list] = list
        break
      end
    end

    if @@args[:list]
      puts "#{@@args[:list].name} by #{@@args[:list].artists[0].name}"
      # For checking if it's a compilation
      compilation = false
      if type == "album"
        temp_albums = []
        temp_artists = []
        @@args[:list].tracks.each do |track|
          temp_artists.push(track.artists[0].name)
          temp_albums.push(track.album.name)
        end
        temp_albums = temp_albums.uniq
        temp_artists = temp_artists.uniq
        if temp_albums.size == 1 and temp_artists.size > 1
          compilation = true
        end
      end

      tracks = []
      prefix = nil
      @@args[:list].tracks.each do |track|

        if type == "playlist"
          prefix = "#{tracks.size + 1} - "
        end

        data = {
          song: track.name,
          artist: track.artists[0].name,
          album: track.album,
          genre: track.artists[0].genres,
          track_number: track.track_number,
          disc_number: track.disc_number,
          compilation: compilation,
          prefix: prefix,
        }

        tracks.push(data)
      end

      self.list(tracks)

      @@args[:title] = @@args[:list].name
      location = self.post_processing()

      return location
    else
      puts "no results"
      return false
    end
  else
    return false
  end
end

Public Instance Methods

rip_it() click to toggle source
# File lib/ripper.rb, line 40
def rip_it()

  if @@args[:type] != "song"
    self.spotify_list(@@args[:type], @@args[:title], @@args[:username])
  else
    self.song(@@args[:title], @@args[:artist], {})
  end
end