Skip to content

Instantly share code, notes, and snippets.

@valeth
Last active September 23, 2017 17:03
Show Gist options
  • Save valeth/f811c8a433b8b2b2480da1ceab90f003 to your computer and use it in GitHub Desktop.
Save valeth/f811c8a433b8b2b2480da1ceab90f003 to your computer and use it in GitHub Desktop.
DJ Kuro hearthis.at song downloader script
#!/usr/bin/env ruby
# frozen_string_literal: true
require "rest-client"
require "json"
require "fileutils"
USER = "kuro-soundworks"
BASE_URL = "https://api-v2.hearthis.at"
MANIFEST_FILE = "tracks.json"
def request(user, type: :tracks, count: 20, page: 1)
url = "#{BASE_URL}/#{user}/?type=#{type}&count=#{count}&page=#{page}"
puts "Fetching info from #{url}"
response = RestClient.get(url)
JSON.parse response
rescue JSON::ParserError
raise "Failed to parse JSON response"
end
def download_track(track)
return unless track["downloadable"] == "1"
name = track["title"]
url = track["download_url"]
if File.exist?("#{name}.mp3") || File.exist?("#{name}.ogg")
puts "[SKIP] #{name}"
return
end
header = {
user_agent: "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.89 Safari/537.36",
content_type: "audio/mpeg"
}
raw_response = RestClient::Request.execute(method: :get, url: url, headers: header, raw_response: true)
FileUtils.mv raw_response.file.path, "#{name}.mp3"
puts "[DONE] #{name}"
end
def update_json(new_data)
return if new_data&.empty?
open("tracks.json", "r") do |tracks_json|
json = JSON.parse(tracks_json.read)
json += new_data
open(".#{MANIFEST_FILE}.new", "w") do |tmp_json|
tmp_json.write(JSON.pretty_generate(json))
end
end
FileUtils.mv ".#{MANIFEST_FILE}.new", MANIFEST_FILE
rescue => e
puts "Failed to write json file: #{e}"
FileUtils.rm ".#{MANIFEST_FILE}.new"
end
def main
json = JSON.parse(File.read("tracks.json"))
puts "#{json.size} tracks in JSON"
tmp = []
(1..20).each do |page|
response = request(USER, page: page)
break if response.empty?
tmp += response
end
puts "#{tmp.size} tracks"
tmp.reject! { |x| json.any? { |y| y["id"] == x["id"] } }
puts "#{tmp.size} tracks to download"
tmp.each { |track| download_track(track) }
update_json(tmp)
end
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment