Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/ruby
- #encoding: UTF-8
- =begin
- /***************************************************************************
- * ©2011-2014 Michael Uplawski <michael.uplawski@uplawski.eu> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************
- =end
- require 'open-uri'
- require 'io/console'
- require_relative 'busy_indicator'
- require_relative 'download_history'
- require_relative 'download'
- $VERSION = 0.5
- CULT = "http://www.franceculture.fr/"
- INTER = "http://www.franceinter.fr/"
- =begin
- Returns a connection to 'host' via 'port', taking into account the
- possibility of a system-wide proxy-setting. For the time being, the
- proxy must be defined in the environment variable 'http_proxy', like
- this: http_proxy="http://proxy.url:port".
- Example: http_proxy="http://localhost:8080"
- Example: http_proxy="http://my.proxy.provider.com:3128"
- If not defined in this way, no proxy is used and the connection will be
- direct.
- =end
- def http(host, port)
- hos = nil
- begin
- hos = RbConfig['host_os']
- rescue Exception => ex
- hos = RUBY_PLATFORM
- end
- connection = nil
- if(hos && /linux/ =~ hos )
- proxy = ENV['http_proxy']
- if(proxy)
- parray = proxy.split(':')
- if(parray.size == 3)
- http, phost, pport = parray
- if(phost.start_with?('//'))
- phost = phost[2..phost.size]
- end
- puts 'Using proxy at ' << phost << ', port ' << pport
- connection = Net::HTTP.new(host, nil, phost,pport)
- end
- end
- end
- puts 'direct connection, no useable proxy-setting found' if !connection
- connection ||= Net::HTTP.new(host,port)
- end
- =begin
- Download url, save to filename.
- Copied&Pasted from https://stackoverflow.com/questions/2263540/how-do-i-download-a-binary-file-over-http/6964173#6964173
- =end
- def http_to_file(filename,url,opt={})
- opt = {
- :init_pause => 0.1, #start by waiting this long each time
- # it's deliberately long so we can see
- # what a full buffer looks like
- :learn_period => 0.3, #keep the initial pause for at least this many seconds
- :drop => 1.5, #fast reducing factor to find roughly optimized pause time
- :adjust => 1.05 #during the normal period, adjust up or down by this factor
- }.merge(opt)
- pause = opt[:init_pause]
- learn = 1 + (opt[:learn_period]/pause).to_i
- drop_period = true
- delta = 0
- max_delta = 0
- last_pos = 0
- File.open(filename,'w') do |f|
- uri = URI.parse(url)
- http(uri.host, uri.port).start do |http|
- bi = BusyIndicator.new(true)
- http.request_get(uri.path) do |res|
- res.read_body do |seg|
- f << seg
- delta = f.pos - last_pos
- last_pos += delta
- $HISTORY.update(url, :position => last_pos)
- if delta > max_delta then max_delta = delta end
- if learn <= 0 then
- learn -= 1
- elsif delta == max_delta then
- if drop_period then
- pause /= opt[:drop]
- else
- pause /= opt[:adjust]
- end
- elsif delta < max_delta then
- drop_period = false
- pause *= opt[:adjust]
- end
- sleep(pause)
- end
- end
- bi.stop('Okay')
- end
- end
- end
- =begin
- Creates and outputs on STDOUT a usage-message containing two exemplary
- command-lines.
- =end
- def usage
- puts "\nUsage:"
- puts "Call with the URL of the audio-player"
- puts "\t" << __FILE__.split(File::SEPARATOR).last << " http://www.france[culture|inter].fr/sites/..../xxxxxxxxx"
- puts "or an URL and a local file-name:"
- puts "\t" << __FILE__.split(File::SEPARATOR).last << " http://www.france[culture|inter].fr/sites/..../xxxxxxxxx local_file.mp3"
- puts
- end
- def check_history(url)
- previous_download = $HISTORY.previous_download(url)
- if(previous_download)
- puts "\nA previous attempt to download this file has been interrupted."
- puts previous_download.date.to_s << " local file: " << previous_download.local_file << " current size: " << File.size(previous_download.local_file)
- puts "Do you want to continue downloading to " << previous_download.local_file << "(Y/n)?"
- resp = STDIN.getch
- return previous_download if('y' == resp || 'Y' == resp)
- end
- return nil
- end
- =begin
- This program allows you to download broadcasts in MP3-format from the
- web-site of either France-Culture or France-Inter, two popular french
- radio-stations.
- These broadcasts are usually made available in the form of Podcasts
- but the proposed procedure is inconvenient in several ways.
- With get_mp3 (or however I choose to name the program in the future) you
- just name the URL to a 'player' and the script will try to locate the
- mp3-file, then download it either to a file of your choice, or
- 'download.mp3' in the current directory.
- You can execute the program (get_mp3.rb) once without arguments or with
- the option -h to see two examplary command-lines.
- Note, that there is a specific 'player-URL' for each individual broadcast,
- each ending in a numeric suffix (not .html).
- I cannot foresee the decisions which might be taken at Radio France in
- the future, but the program is functional in march 2014. Should they
- choose a different way to publish their audio-files, it will probably
- render this program useless, immediately.
- =end
- def get_mp3(args)
- if(args.empty?)
- puts "\nMissing parameters!!"
- usage
- exit false
- elsif '-h' == args[0]
- usage
- exit true
- elsif '-v' == args[0]
- puts "version " << $VERSION.to_s
- exit true
- else
- p_url = args[0]
- end
- site = nil
- local = args[1] if args.length > 1
- local ||= "download.mp3"
- if(p_url.match("^" + CULT))
- site = CULT
- elsif(p_url.match("^" + INTER))
- site = INTER
- end
- page = open(p_url).read
- match = page.match(/(sites%2Fdefault.*\.mp3)/)
- match ||= page.match(/(sites%2Fdefault.*\.MP3)/)
- if match
- line = match[1]
- uri = URI.unescape(line)
- file = site + uri
- rd = check_history(file)
- if(rd )
- local = rd.local_file
- end
- puts 'Will download ' << file
- $HISTORY.update(file, :local=>local)
- http_to_file(local, file)
- end
- end
- # -----------------------
- if($0 == __FILE__ )
- get_mp3(ARGV)
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement