Skip to content

Instantly share code, notes, and snippets.

@dpsk
Last active August 29, 2015 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dpsk/8853e3aa8ec4b2ac33f6 to your computer and use it in GitHub Desktop.
Save dpsk/8853e3aa8ec4b2ac33f6 to your computer and use it in GitHub Desktop.
get_spotify_playlist.rb
# Provide desired spotify playlist url you want to save as first argument.
# For obtianing links for the tracks you would need vk token.
# VK token should have offline and audio permissions.
# First argument should be a link to spotify playlist with the open.spotify.com based domen
# Second argument is optional for base directory, in which all files would go
# For details refer to VK documentation http://vk.com/dev
require 'nokogiri'
require 'open-uri'
require 'vkontakte_api'
require 'ruby-progressbar'
require 'fileutils'
DIRECTORY = "#{ENV['HOME']}/Music/Spotify Playlists/"
public
def get_song_info(song)
url = "http://open.spotify.com" + "/track/" + song["data-id"]
page = Nokogiri::HTML(open(url))
"#{page.css('.player-header h2 a').text} #{page.css('.player-header h1').text}" #artist title
end
def get_songs(url)
songs = []
page = Nokogiri::HTML(open(url))
songs_html = page.css('li.single-track')
progressbar = ProgressBar.create(:title => "Getting information about songs", :starting_at => 0, :total => songs_html.size)
songs_html.each do |song|
songs << get_song_info(song)
progressbar.increment
end
songs
end
def get_songs_url(songs)
urls = []
vk = VkontakteApi::Client.new(ENV["VK_TOKEN"])
songs.each do |song|
begin
results = vk.audio.search(q: song, sort: "2")
rescue VkontakteApi::Error => e
p "#{e.message}"
p "Going too sleep for 5 seconds."
sleep(5)
retry
end
if results[1]
song_added = false
results[1..results.size].each do |result|
size = (open(result.url.split(/\?extra/).first).meta['content-length']).to_i / 1024
bitrate = (size.to_i * 8) / result.duration.to_i
p "Found version of #{song} with #{bitrate} kbps"
if bitrate.to_i > 300
urls << {url: result.url.split(/\?extra/).first, name: song}
break
end
end
end
end
urls
end
def save_songs_to_the_directory(full_path, urls)
progressbar = ProgressBar.create(:title => "Downloading songs", :starting_at => 0, :total => urls.size)
urls.each do |url|
File.open("#{full_path}#{url[:name]}.mp3", "wb") do |saved_file|
open("#{url[:url]}", "rb") do |read_file|
saved_file.write(read_file.read)
progressbar.increment
end
end
end
end
raise "You need to set VK_TOKEN" unless ENV["VK_TOKEN"]
urls = get_songs_url(get_songs(ARGV[0]))
base_directory = ARGV[1] || DIRECTORY
subdirectory = Nokogiri::HTML(open(ARGV[0])).css('.player-header h1').text
full_path = "#{base_directory}#{subdirectory}/"
FileUtils::mkdir_p full_path
save_songs_to_the_directory(full_path, urls)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment