Last active
August 29, 2015 14:02
-
-
Save dpsk/8853e3aa8ec4b2ac33f6 to your computer and use it in GitHub Desktop.
get_spotify_playlist.rb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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