Guest User

Untitled

a guest
Jun 24th, 2018
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.60 KB | None | 0 0
  1. require 'net/ftp'
  2. require 'tmpdir'
  3. require 'thwait'
  4.  
  5. DEBUG = !ENV.fetch('DEBUG', '').empty?
  6. CONCURRENT = ENV.fetch('CONCURRENT').to_i
  7. FTP_HOST = ENV.fetch('FTP_HOST')
  8. FTP_PORT = ENV.fetch('FTP_PORT').to_i
  9. FTP_USER = ENV.fetch('FTP_USER')
  10. FTP_PASS = ENV.fetch('FTP_PASS')
  11. FTP_PATH = ENV.fetch('FTP_PATH')
  12.  
  13. def establish_connection
  14. Net::FTP.new(FTP_HOST, port: FTP_PORT, username: FTP_USER, password: FTP_PASS, passive: true, debug_mode: DEBUG)
  15. end
  16.  
  17. content_size = establish_connection.size(FTP_PATH)
  18. page_size = (content_size.to_f / CONCURRENT).ceil
  19.  
  20. Dir.mktmpdir do |dir|
  21. threads = []
  22. CONCURRENT.times do |i|
  23. offset = page_size * i
  24. next if offset >= content_size
  25.  
  26. threads << Thread.start(i) do |t|
  27. File.open("#{dir}/#{t}", 'wb') do |page|
  28. ftp = establish_connection
  29. ftp.resume = true
  30.  
  31. retrieved = 0
  32. ftp.retrbinary("RETR #{FTP_PATH}", Net::FTP::DEFAULT_BLOCKSIZE, offset) do |chunk|
  33. rest = page_size - retrieved
  34. retrievable = [rest, chunk.bytesize].min
  35. break if retrievable <= 0
  36.  
  37. retrieved += page.write(chunk[0, retrievable])
  38. end
  39. end
  40. end
  41. end
  42. ThreadsWait.all_waits(*threads)
  43.  
  44. File.open('downloaded', 'wb') do |output|
  45. CONCURRENT.times do |i|
  46. path = "#{dir}/#{i}"
  47. next unless File.exist?(path)
  48. IO.copy_stream(path, output)
  49. end
  50. end
  51. end
  52.  
  53. __END__
  54.  
  55. ### e.g. 495MB CentOS ISO file
  56.  
  57. ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin17]
  58.  
  59. 1: 165.29 real 5.34 user 4.74 sys
  60. 3: 99.68 real 5.23 user 6.12 sys
  61. 5: 88.19 real 5.56 user 7.43 sys
Add Comment
Please, Sign In to add comment