By Elektro H@cker
SoundCloud Leecher es una herramienta que te ayudará a mantener al día tu colección de música.
Esta utilidad está pensada para un uso (casi) diario o semanal.
El script obtiene todos los enlaces descargables de las primeras "X" páginas de "X" grupo de Soundcloud, y guarda esos enlaces en un archivo de texto para usarlos más tarde con un gestor de descargas como por ejemplo "JDownloader".
Además, todos los enlaces se listan también en un archivo log para que queden excluidos en el próximo uso del script, esa es la razón de porqué está pensado para el uso diario.
Es muy fácil de configurar.
Espero que a alguien más que a mi le sirva de ayuda.
Un saludo!
Executable: http://exoshare.com/download.php?uid=OFGDPH4C
Soundcloud Leecher.rb:
Código
# -*- coding: UTF-8 -*- # SoundCloud Leecher v0.5 # # By Elektro H@cker # Description: # ----------- # # SoundCloud Leecher it's a tool that helps you to keep updated your music collection. # # This tool is intended for (almost) daily use. # # The script retreives all the downloadable links of the first "X" pages from a "X" group of SoundCloud, # And then list the links into a text file for use it with a download magaer like "JDownloader". # # All the links are stored permanently into a log file to be excluded at the next use, # that's the reason why this tool is intended for daily use. # Info: # ---- # # SoundCloud unfortunately do not have a date search mode, # which would be much easier to search/sort by "music style + today's date" than "groups + first sorted pages", # The site has an advanced search engine that can search by "release date" but that is not the same than "uploaded date", # So i think the only way to sort by date is by entering a group page because it shows the content sorted by the last date. # How to use: # ---------- # # Configure your favorite groups and the other settings by entering into the configuration menu. require 'net/http' require 'win32/registry' require "highline/system_extensions" include HighLine::SystemExtensions exit if Object.const_defined?(:Ocra) def logo() puts " _, _, , , , , ,_ _ , _, , , ,_ , _, _, _ , , _,,_ (_ / \\ | | |\\ | | \\ / | / \\ | | | \\ | /_,/_,/ |_| /_,|_) _) \\_/ \\__| | \\| |_/ \\_ |__ \\_/ \\__| |_/ |__ \\_ \\_ \\_ | | \\_ | \\ ' ` ` ` ` ' ` ` `' ` `' v0.5 By Elektro H@cker" end def main() puts "\n\n[+] Press \"C\" to config or press any other key to start leeching..." key = get_character config("") if key.to_s =~ /^67$|^99$/ get_downloads_list() puts "\n\n\n[+] All links are stored in: #{$leecherfile}" end def get_settings() begin $logfile = regread("LOGFILEPATH") rescue $logfile = "#{ENV['WINDIR']}\\Soundcloud LOG.txt" end begin $leecherfile = regread("LEECHERFILEPATH") + "Soundcloud Leecher #{Time.new.strftime("%Y-%m-%d")}.txt" rescue $leecherfile = "#{ENV['USERPROFILE']}\\Desktop\\Soundcloud Leecher #{Time.new.strftime("%Y-%m-%d")}.txt" end begin $groups = regread("GROUPS") rescue $groups = "" end begin $max_pages = regread("MAXPAGES") $max_pages = $max_pages.to_i rescue $max_pages = 5 end begin $min_duration = regread("MINDURATION")+"00" $min_duration = $min_duration.to_i rescue $min_duration = 130 end begin $max_duration = regread("MAXDURATION")+"00" $max_duration = $max_duration.to_i rescue $max_duration = 1200 end begin $max_size = regread("MAXSIZE")+"00" $max_size = $max_size.to_i rescue $max_size = 10000 end begin $excluded_exts = regread("EXCLUDED EXTENSIONS") rescue $excluded_exts = "" end begin $excluded_tags = regread("EXCLUDED TAGNAMES") rescue $excluded_tags = "" end begin $verbose = regread("VERBOSEMODE") rescue $verbose = "no" end end def config(errorcode) puts " º---------------------------------º---------------------------------º | [1] Set the log file path | [+] Max. track duration | | [2] Set the leecher file path | [-] Min. track duration | | [3] Delete the log file | [M] Max. track filesize | |---------------------------------|---------------------------------| | [A] Add a group name | [P] Pages per group to parse | | [D] Delete a group name | [F] Filetypes to exclude | | [L] List the group names | [T] Tagnames to exclude | |---------------------------------|---------------------------------| | [V] Verbose mode (ON/OFF) | [S] Show the current settings | |---------------------------------| [R] Reset the settings | | [E] Exit | [Z] Backup all the config. | º---------------------------------º---------------------------------º " get_settings() puts errorcode keystr = "NOTHING" until keystr =~ /^43$|^45$|^49$|^50$|^51$|^65$|^68$|^69$|^70$|^76$|^77$|^80$|^82$|^83$|^84$|^86$|^90$|^97$|^100$|^101$|^102$|^108$|^109$|^112$|^114$|^115$|^116$|^118$|^121$|^122$/ print "\nChoose an option >> " key = get_character keystr = key.to_s end # Log file path if key == 49 logfilepath = "NOTHING" until File.directory?(logfilepath) print "\n\nEnter the path to an existing directory for the logfile: " logfilepath = STDIN.gets.chomp end if logfilepath[-1] == '\\' then logfilepath = logfilepath[0..-2] end regwrite("LOGFILEPATH", logfilepath + "\\Soundcloud LOG.txt") config("[+] Operation completed.") end # Leecher file path if key == 50 leecherfile = "NOTHING" until File.directory?(leecherfile) print "\n\Enter the path to an existing directory for the leecher file: " leecherfile = STDIN.gets.chomp end if not leecherfile[-1] == '\\' then leecherfile = leecherfile+"\\" end regwrite("LEECHERFILEPATH", leecherfile) config("[+] Operation completed.") end # delete log file if key == 51 filedel = "NOTHING" while not filedel =~ /^78$|^89$|^110$|^121$/ print "\n\nWant to delete the log file, Are you sure? [Y/N]: " filedel = get_character.to_s end begin if filedel =~ /^89$|^121$/ then File.delete($logfile) end config("[+] Operation completed.") rescue config("\n\nERROR\n\nCan't find the logfile.") end end # Add groupname if key == 65 or key == 97 addname = "NOTHING" until not addname == "NOTHING" print "\n\nEnter a group name to add\nor enter the word \"none\" to reset the group list: " addname = STDIN.gets.chomp end begin groups=regread("GROUPS") rescue groups="" end for addgroupname in regread("GROUPS").split(";").sort do if not addgroupname =~ /^#{Regexp.escape(addname)}$/i then addfinalgroups="#{addfinalgroups};#{addgroupname}" else found = "yes" end end if found == "yes" then config("\n\n[+] ERROR\n\nThe groupname already exists.") end if addname =~ /^none$/i then regwrite("GROUPS", "") else regwrite("GROUPS", "#{groups};#{addname}") end config("[+] Operation completed.") end # delete groupname if key == 68 or key == 100 delnum = "NOTHING" num=0 for listname in $groups.split(";").each.sort do num=num+1 puts " [#{num}] #{listname}" instance_variable_set "@_#{num}", listname end until not delnum == "NOTHING" print "\n\nEnter a reference number to delete the group\nor enter the word \"none\" to reset the group list: " delnum = STDIN.gets.chomp end choose = instance_variable_get "@_#{delnum}" begin groups=regread("GROUPS") rescue groups="" end begin for delgroupname in regread("GROUPS").split(";").sort do if not delgroupname =~ /^#{Regexp.escape(choose)}$/i then delfinalgroups="#{delfinalgroups};#{delgroupname}" end end rescue config("\n\n[+] ERROR\n\nCan't find the delgroupname.") end regwrite("GROUPS", delfinalgroups[1..-1]) config("[+] Operation completed.") end # list groupnames if key == 76 or key == 108 num = 0 puts "\n\n[+] All your groups:\n\n" for listname in $groups.split(";").each.sort do num=num+1 puts " [#{num}] #{listname}" end puts "\n\n[+] Press any other key to continue..." get_character config("[+] Operation completed.") end # Max pages if key == 80 or key == 112 maxpages = "NOTHING" puts "\n\nThis option lets you configure the maximum pages when leeching a group..." until not maxpages[/[a-z]/i] print "\nEnter a number for the max pages value: " maxpages = STDIN.gets.chomp end regwrite("MAXPAGES", maxpages) config("[+] Operation completed.") end # Min track duration if key == 45 puts "\n\nThis option lets you configure the minimum accepted minutes duration when leeching tracks..." minlenght = "NOTHING" until minlenght[/^[0-9]+$/] print "\nEnter a number to set the min. minutes for a track (Example: \"1\"): " minlenght = STDIN.gets.chomp end regwrite("MINDURATION", minlenght) config("[+] Operation completed.") end # Max track duration if key == 43 puts "\n\nThis option lets you configure the maximum accepted minutes duration when leeching tracks..." maxlenght = "NOTHING" until maxlenght[/^[0-9]+$/] print "\nEnter a number to set the max. minutes for a track (Example: \"15\"): " maxlenght = STDIN.gets.chomp end regwrite("MAXDURATION", maxlenght) config("[+] Operation completed.") end # Max track filesize if key == 77 or key == 109 puts "\n\nThis option lets you configure the maximum accepted filesize when leeching tracks..." maxsize = "NOTHING" until maxsize[/^[0-9]+$/] print "\nEnter a number to set the max. MB for a track (Example: \"20\"): " maxsize = STDIN.gets.chomp end regwrite("MAXSIZE", maxsize) config("[+] Operation completed.") end # exclude filetypes if key == 102 or key == 70 addext = "NOTHING" puts "\n\nThis option lets you exclude tracks by their file extension..." until not addext == "NOTHING" print "\n\nEnter a file extension (Example: \"wav\") \nor enter the word \"none\" to reset the exclusions: " addext = STDIN.gets.chomp end begin exts=regread("EXCLUDED EXTENSIONS") rescue exts="" end if addext =~ /^none$/i then regwrite("EXCLUDED EXTENSIONS", "") else regwrite("EXCLUDED EXTENSIONS", "#{exts};#{addext.gsub(".","")}") end config("[+] Operation completed.") end # exclude tagnames if key == 84 or key == 116 addtag = "NOTHING" puts "\n\nThis option lets you exclude tracks by a tagname..." until not addtag == "NOTHING" print "\n(The tagnames are not case sensitive)\n\nEnter a tagname (Example: \"session\") \nor enter the word \"none\" to reset the exclusions: " addtag = STDIN.gets.chomp end begin tags=regread("EXCLUDED TAGNAMES") rescue tags="" end if addtag =~ /^none$/i then regwrite("EXCLUDED TAGNAMES", "") else regwrite("EXCLUDED TAGNAMES", "#{tags};#{addtag}") end config("[+] Operation completed.") end # verbose mode if key == 118 or key == 86 verbkey = "NOTHING" puts "\n\nThe verbose mode lets you can see more info when leeching the group pages..." while not verbkey =~ /^78$|^89$|^110$|^121$/ print "\n\nWant to use the verbose mode? [Y/N]: " verbkey = get_character.to_s end if verbkey =~ /^89$|^121$/ then regwrite("VERBOSEMODE", "yes") else regwrite("VERBOSEMODE", "no") end config("[+] Operation completed.") end # show the current settings if key == 83 or key == 115 config(" Log file path : #{$logfile} Leecher file path : #{$leecherfile} Max. pages per group: #{$max_pages} pages Min. track duration : #{$min_duration.to_s[0..-3]} min Max. track duration : #{$max_duration.to_s[0..-3]} min Max. track filesize : #{$max_size.to_s[0..-3]} mb Verbose mode : #{$verbose} Excluded extensions : #{$excluded_exts.gsub(";","|")} Excluded tagnames : #{$excluded_tags.gsub(";","|")} ") end # reset the settings if key == 114 or key == 82 resetkey = "NOTHING" while not resetkey =~ /^78$|^89$|^110$|^121$/ print "\n(This not affect to group list)\n\nWant to reset all the settings, Are you sure? [Y/N]: " resetkey = get_character.to_s end if resetkey =~ /^89$|^121$/ Win32::Registry::HKEY_CURRENT_USER.open("SOFTWARE\\Soundcloud Leecher\\", Win32::Registry::KEY_ALL_ACCESS) do |reg| reg['LOGFILEPATH'] = 'DELETE' reg.delete_value("LOGFILEPATH") reg['LEECHERFILEPATH'] = 'DELETE' reg.delete_value("LEECHERFILEPATH") reg['MAXPAGES'] = 'DELETE' reg.delete_value("MAXPAGES") reg['MINDURATION'] = 'DELETE' reg.delete_value("MINDURATION") reg['MAXDURATION'] = 'DELETE' reg.delete_value("MAXDURATION") reg['MAXSIZE'] = 'DELETE' reg.delete_value("MAXSIZE") reg['VERBOSEMODE'] = 'DELETE' reg.delete_value("VERBOSEMODE") reg['EXCLUDED EXTENSIONS'] = 'DELETE' reg.delete_value("EXCLUDED EXTENSIONS") reg['EXCLUDED TAGNAMES'] = 'DELETE' reg.delete_value("EXCLUDED TAGNAMES") end config("[+] Operation completed.") end end # backup the settings if key == 90 or key == 122 system %[ regedit /e \"%USERPROFILE%\\Desktop\\Soundcloud settings %DATE:/=-%.reg\" \"HKEY_CURRENT_USER\\Software\\Soundcloud Leecher\" ] config("\n\n[+] Settings stored in #{ENV['USERPROFILE']}\\Desktop\\SoundCloud settings.reg") end # exit if key == 69 or key == 101 then main() end end def regread(keyname) Win32::Registry::HKEY_CURRENT_USER.open("SOFTWARE\\Soundcloud Leecher\\") do |reg| reg[keyname] end end def regwrite(keyname, value) Win32::Registry::HKEY_CURRENT_USER.create("SOFTWARE\\Soundcloud Leecher\\") do |reg| reg[keyname, Win32::Registry::REG_SZ] = value end end def filewrite() if not File.exist?($logfile) then File.open($logfile, "w") do |write| write.puts "SoundCloud leeched URLs\n" end end if not File.open($logfile, "r").read[@track_url.split("/download").first.split("http://soundcloud.com/").last.gsub("-","").gsub("/","")] if $verbose == "yes" then puts @info end File.open($logfile, "a+") do |write| write.puts @track_url.split("/download").first.split("http://soundcloud.com/").last.gsub("-","").gsub("/","") end File.open($leecherfile, "a+") do |write| write.puts "Added at #{Time.new.strftime("%H:%M")}: #{@track_url}" end end end def get_downloads_list() if $verbose == "no" for name in $groups.split(";").each.sort do @group = name.chomp @page = 0 print "\n\n[+] Group: #{@group}\n[+] Leeching pages " for i in 1..$max_pages do @page = @page+1 @url = "http://soundcloud.com/groups/#{@group}/tracks?page=#{@page}" print "#{@page}/#{$max_pages}..." Net::HTTP.get_response(URI.parse(@url)).body.each_line do |line| if (line['class="info-header"']) @filename = line.split('</a').first.split('>').last.gsub(/ Artwork$/,'').gsub('"','"').gsub('&','&') for excluded_tag in $excluded_tags.split(";").each do if not excluded_tag == "" and @filename[/#{Regexp.escape(excluded_tag)}/i] then @downloadable = "no" end end end if (line['button download']) then @downloadable = "yes" end if (line['button download']) then @track_url = "http://soundcloud.com#{line.split('href="').last.split('"').first}\n" end if (line['This track is not downloadable']) then @downloadable = "no" end if (line['class="file-type"']) @ext = line.split('</').first.split('>').last for excluded_ext in $excluded_exts.split(";").each do if not excluded_ext == "" and @ext =~ /^#{Regexp.escape(excluded_ext)}$/i then @downloadable = "no" end end end if (line['class="content-size"']) @size = line.split('</').first.split('>').last if @size.gsub(".","").to_i > $max_size then @downloadable = "no" end end if (line['class="duration"']) then @duration = line.split('</').first.split('>').last.gsub(".","").to_i end if (line['class="duration"']) and @downloadable == "yes" and @duration > $min_duration and @duration < $max_duration filewrite() end end end end end if $verbose == "yes" for name in $groups.split(";").each.sort do @group = name.chomp @page = 0 print "\n\n[+] Group: #{@group}\n[+] Leeching pages " for i in 1..$max_pages do @page = @page+1 @url = "http://soundcloud.com/groups/#{@group}/tracks?page=#{@page}" print "#{@page}/#{$max_pages}..." Net::HTTP.get_response(URI.parse(@url)).body.each_line do |line| if (line['class="info-header"']) @filename = line.split('</a').first.split('>').last.gsub(/ Artwork$/,'').gsub('"','"').gsub('&','&') for excluded_tag in $excluded_tags.split(";").each do if not excluded_tag == "" and @filename[/#{Regexp.escape(excluded_tag)}/i] then @downloadable = "no" end end end if (line['button download']) then @downloadable = "yes" end if (line['button download']) then @track_url = "http://soundcloud.com#{line.split('href="').last.split('"').first}\n" end if (line['This track is not downloadable']) then @downloadable = "no" end if (line['class="file-type"']) @ext = line.split('</').first.split('>').last for excluded_ext in $excluded_exts.split(";").each do if not excluded_ext == "" and @ext =~ /^#{Regexp.escape(excluded_ext)}$/i then @downloadable = "no" end end end if (line['class="content-size"']) @size = line.split('</').first.split('>').last if @size.gsub(".","").to_i > $max_size then @downloadable = "no" end end if (line['class="duration"']) then @duration = line.split('</').first.split('>').last end if (line['class="duration"']) and @downloadable == "yes" and @duration.gsub(".","").to_i > $min_duration and @duration.gsub(".","").to_i < $max_duration @info = "\n\nFilename : #{@filename} \nExtension: #{@ext} \nFilesize : #{@size} \nDuration : #{@duration} minutes\nURL : #{@track_url}\n" filewrite() end end end end end end logo() get_settings() main() __END__