class GrooveDl::Downloader

Downloader Class

Attributes

client[W]
count[R]
download_count[W]
download_queue[W]
download_skip[W]
output_directory[R]
queue[R]
skip[R]
type[RW]

Public Class Methods

new(client, options = {}) click to toggle source

Initialize download

@return [Downloader]

# File lib/groove-dl/downloader.rb, line 13
def initialize(client, options = {})
  @client = client
  @output_directory = options[:o] || Dir.tmpdir
  @queue = []
  @count = 0
  @skip = 0
  @type = 'cli'
end

Public Instance Methods

build_path(output_directory, song) click to toggle source

Build path

@param [String] output_directory destination directory @param [Grooveshark::Song] song Song

# File lib/groove-dl/downloader.rb, line 99
def build_path(output_directory, song)
  format('%s/%s/%s/%s.mp3',
         output_directory,
         song.artist,
         song.album,
         song.name)
end
download(song, object) click to toggle source

Download song

@param [Grooveshark::Song] song Song object @param [Gtk::TreeIter/String] callback Proc function to execute during download

@return [Net::HTTP]

# File lib/groove-dl/downloader.rb, line 62
def download(song, object)
  url = URI.parse(@client.get_song_url_by_id(song.id))
  @client.get_stream_auth_by_songid(song.id)

  callback = process_gui_response(object) if @type == 'gui'
  callback = process_cli_response(object) if @type == 'cli'

  RestClient::Request
    .execute(method: :get,
             url: url.to_s,
             block_response: callback)
end
download_queue() click to toggle source

Download queue

@return [false|Array]

# File lib/groove-dl/downloader.rb, line 80
def download_queue
  return false if @queue.empty?
  @queue.each do |song|
    begin
      download(song, build_path(@output_directory, song))
    rescue StandardError => e
      GrooveDl.configuration.logger.error(e.message)
    end
  end

  { skipped: @skip, downloaded: @count }
end
playlist(playlist_id) click to toggle source

Download playlist

@param [String] playlist_id Playlist id

@return [Array]

# File lib/groove-dl/downloader.rb, line 43
def playlist(playlist_id)
  playlist = Grooveshark::Playlist.new(@client,
                                       'playlist_id' => playlist_id)
  songs = playlist.load_songs
  return false unless songs
  @queue += songs

  download_queue
end
process_cli_response(destination) click to toggle source

Process response to display a progress bar and download file into destination.

@param [String] destination Destination

@return [Proc]

# File lib/groove-dl/downloader.rb, line 115
def process_cli_response(destination)
  proc do |response|
    total_size = response['content-length'].to_i
    if File.exist?(destination) &&
       File.size?(destination) == total_size

      @skip += 1
      fail Errors::AlreadyDownloaded, "#{destination} already downloaded"
    end

    pbar = ProgressBar.create(title: destination.split('/').last,
                              format: '%a |%b>>%i| %p%% %t',
                              total: response['content-length'].to_i)

    dirname = File.dirname(destination)
    FileUtils.mkdir_p(dirname) unless File.directory?(dirname)

    File.open(destination, 'w') do |f|
      response.read_body do |chunk|
        f.write(chunk)
        pbar.progress += chunk.length
      end
    end

    pbar.finish
    @count += 1
  end
end
process_gui_response(object) click to toggle source

Process response to pulse progressbar stored in the TreeIter object.

@param [Gtk::TreeIter] object TreeIter

@return [Proc]

# File lib/groove-dl/downloader.rb, line 152
def process_gui_response(object)
  proc do |response|
    pgbar_value = Widgets::Download::QUEUE_COLUMN_PGBAR_VALUE
    pgbar_text = Widgets::Download::QUEUE_COLUMN_PGBAR_TEXT

    total_size = response['content-length'].to_i
    path = object[Widgets::Download::QUEUE_COLUMN_PATH]
    if File.exist?(path) &&
       File.size?(path) == total_size
      object[pgbar_value] = 100
      object[pgbar_text] = 'Complete'
      fail Errors::AlreadyDownloaded, "#{path} already downloaded"
    end

    dirname = File.dirname(path)
    FileUtils.mkdir_p(dirname) unless File.directory?(dirname)

    File.open(path, 'w') do |f|
      file_size = 0
      response.read_body do |chunk|
        f.write(chunk)
        file_size += chunk.length
        result = ((file_size * 100) / total_size).to_i
        object[pgbar_value] = result
        object[pgbar_text] = 'Complete' if
          object[pgbar_value] >= 100
      end
    end
  end
end
song(song_id) click to toggle source

Download song

@param [String] song_id Song id

@return [Array]

# File lib/groove-dl/downloader.rb, line 29
def song(song_id)
  @queue << Grooveshark::Song.new('song_id' => song_id,
                                  'artist_name' => 'unknown',
                                  'song_name' => 'unknown')
  download_queue
end