Module: Rmega::Nodes::Downloadable
- Included in:
- File
- Defined in:
- lib/rmega/nodes/downloadable.rb
Instance Method Summary collapse
-
#allocate(path) ⇒ Object
Creates the local file allocating filesize-n bytes (of /dev/zero) for it.
- #decrypt_chunk(start, encrypted_buffer) ⇒ Object
- #download(path) ⇒ Object
-
#download_chunk(start, size) ⇒ Object
Downloads a part of the remote file, starting from the start-n byte and ending after size-n bytes.
-
#write_chunk(file, start, buffer) ⇒ Object
Writes a buffer in the local file, starting from the start-n byte.
Instance Method Details
#allocate(path) ⇒ Object
Creates the local file allocating filesize-n bytes (of /dev/zero) for it. Opens the local file to start writing from the beginning of it.
10 11 12 13 14 15 |
# File 'lib/rmega/nodes/downloadable.rb', line 10 def allocate(path) `dd if=/dev/zero of="#{path}" bs=1 count=0 seek=#{filesize} > /dev/null 2>&1` raise "Unable to create file #{path}" if ::File.size(path) != filesize ::File.open(path, 'r+b').tap { |f| f.rewind } end |
#decrypt_chunk(start, encrypted_buffer) ⇒ Object
31 32 33 34 35 36 |
# File 'lib/rmega/nodes/downloadable.rb', line 31 def decrypt_chunk(start, encrypted_buffer) k = decrypted_file_key nonce = [k[4], k[5], (start/0x1000000000) >> 0, (start/0x10) >> 0] decrypt_key = [k[0] ^ k[4], k[1] ^ k[5], k[2] ^ k[6], k[3] ^ k[7]] Crypto::AesCtr.decrypt(decrypt_key, nonce, encrypted_buffer)[:data] end |
#download(path) ⇒ Object
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/rmega/nodes/downloadable.rb', line 38 def download(path) path = ::File.(path) path = Dir.exists?(path) ? ::File.join(path, name) : path logger.info "Download #{name} (#{filesize} bytes) => #{path}" pool = Pool.new write_mutex = Mutex.new file = allocate(path) progress = Progress.new(total: filesize, caption: 'Download') Utils.chunks(filesize).each do |start, size| pool.defer do encrypted_buffer = download_chunk(start, size) write_mutex.synchronize do clean_buffer = decrypt_chunk(start, encrypted_buffer) progress.increment(size) write_chunk(file, start, clean_buffer) end end end # waits for the last running threads to finish pool.wait_done file.flush ensure file.close rescue nil end |
#download_chunk(start, size) ⇒ Object
Downloads a part of the remote file, starting from the start-n byte and ending after size-n bytes.
19 20 21 22 23 |
# File 'lib/rmega/nodes/downloadable.rb', line 19 def download_chunk(start, size) stop = start + size - 1 url = "#{storage_url}/#{start}-#{stop}" HTTPClient.new.get_content(url) end |
#write_chunk(file, start, buffer) ⇒ Object
Writes a buffer in the local file, starting from the start-n byte.
26 27 28 29 |
# File 'lib/rmega/nodes/downloadable.rb', line 26 def write_chunk(file, start, buffer) file.seek(start) file.write(buffer) end |