file_pool 0.3.10 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/file_pool/version.rb +1 -1
- data/lib/file_pool.rb +38 -164
- metadata +36 -60
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c7f119ba9e27968da351cae536fb49dcb7e8c967
|
4
|
+
data.tar.gz: 5f774c28a82bbca70a397343132c3258aea9cadd
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ed3d39e566dc996e3c0f5909443190514770bd1a48c87fbbf65fdc950d2a92bb0e6c5df897070a5acdda1fc82157d2b40bf27fdf4d8eca48b70b0adec4536f2e
|
7
|
+
data.tar.gz: 366078e33a3fa105a5254cc41acaf625033ad3daff5417bcecc1487b3b23f99a345e8fc03dc3389983affe6478cd600d9451d5c6b5a3f38d5e494f7af3cec581
|
data/lib/file_pool/version.rb
CHANGED
data/lib/file_pool.rb
CHANGED
@@ -26,33 +26,13 @@ module FilePool
|
|
26
26
|
# * :encryption_block_size (Integer) sets the block size for
|
27
27
|
# encryption/decryption in bytes. Larger blocks need more memory and less time (less IO).
|
28
28
|
# Defaults to 1'048'576 (1 MiB).
|
29
|
-
# * :copy_source (true,false)
|
30
|
-
# if +false+ files added to the pool are hard-linked with the source if source and file pool
|
31
|
-
# are on the same file system (default). If set to +true+ files are always copied into the pool.
|
32
|
-
# * :mode (Integer)
|
33
|
-
# File mode to set on all files added to the pool. E.g. +mode:+ +0640+ for +rw-r-----+ or symbolic "u=wrx,go=rx"
|
34
|
-
# (see Ruby stdlib FileUtils#chmod).
|
35
|
-
# Note that the desired mode is not set if the file is hard-linked with the source.
|
36
|
-
# Use +copy_source:true+ when to ensure.
|
37
|
-
# * :owner
|
38
|
-
# Owner of the files added to the pool.
|
39
|
-
# Note that the desired owner is not set if the file is hard-linked with the source.
|
40
|
-
# Use +copy_source:true+ when to ensure.
|
41
|
-
# * :group
|
42
|
-
# Group of the files added to the pool.
|
43
|
-
# Note that the desired group is not set if the file is hard-linked with the source.
|
44
|
-
# Use +copy_source:true+ when to ensure.
|
45
29
|
def self.setup root, options={}
|
46
|
-
unless(unknown = options.keys - [:encryption_block_size, :secrets_file
|
30
|
+
unless(unknown = options.keys - [:encryption_block_size, :secrets_file]).empty?
|
47
31
|
puts "FilePool Warning: unknown option(s) passed to #setup: #{unknown.inspect}"
|
48
32
|
end
|
49
33
|
@@root = root
|
50
34
|
@@crypted_mode = false
|
51
35
|
@@block_size = options[:encryption_block_size] || (1024*1024)
|
52
|
-
@@copy_source = options[:copy_source] || false
|
53
|
-
@@mode = options[:mode]
|
54
|
-
@@group = options[:group]
|
55
|
-
@@owner = options[:owner]
|
56
36
|
configure options[:secrets_file]
|
57
37
|
end
|
58
38
|
|
@@ -70,49 +50,27 @@ module FilePool
|
|
70
50
|
#
|
71
51
|
# path (String)::
|
72
52
|
# path of the file to add.
|
73
|
-
# options (Hash)::
|
74
|
-
# :background (true,false) adding large files can take long (esp. with encryption), +true+ won't block, default is +false+
|
75
53
|
#
|
76
54
|
# === Return Value:
|
77
55
|
#
|
78
56
|
# :: *String* containing a new unique ID for the file added.
|
79
|
-
def self.add!
|
57
|
+
def self.add! path
|
80
58
|
newid = uuid
|
59
|
+
target = path newid
|
81
60
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
if @@crypted_mode
|
86
|
-
FileUtils.mkpath(id2dir_secured newid)
|
87
|
-
path = crypt(orig_path)
|
88
|
-
else
|
89
|
-
path = orig_path
|
90
|
-
FileUtils.mkpath(id2dir newid)
|
91
|
-
end
|
92
|
-
|
93
|
-
if !@@copy_source and (File.stat(path).dev == File.stat(File.dirname(target)).dev)
|
94
|
-
FileUtils.link(path, target)
|
95
|
-
else
|
96
|
-
FileUtils.copy(path, target)
|
97
|
-
end
|
98
|
-
|
99
|
-
# don't chmod if orginal file is same as target (hard-linked)
|
100
|
-
if File.stat(orig_path).ino != File.stat(File.dirname(target)).ino
|
101
|
-
FileUtils.chmod(@@mode, target) if @@mode
|
102
|
-
FileUtils.chown(@@owner, @@group, target)
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
|
107
|
-
if options[:background]
|
108
|
-
# don't wait, avoid zombies
|
109
|
-
Process.detach(child)
|
61
|
+
if @@crypted_mode
|
62
|
+
FileUtils.mkpath(id2dir_secured newid)
|
63
|
+
path = crypt(path)
|
110
64
|
else
|
111
|
-
|
112
|
-
Process.waitpid(child)
|
65
|
+
FileUtils.mkpath(id2dir newid)
|
113
66
|
end
|
67
|
+
FileUtils.link(path, target)
|
68
|
+
|
69
|
+
return newid
|
114
70
|
|
115
|
-
|
71
|
+
rescue Errno::EXDEV
|
72
|
+
FileUtils.copy(path, target)
|
73
|
+
return newid
|
116
74
|
end
|
117
75
|
|
118
76
|
#
|
@@ -124,17 +82,15 @@ module FilePool
|
|
124
82
|
#
|
125
83
|
# source (String)::
|
126
84
|
# path of the file to add.
|
127
|
-
#
|
128
|
-
# :background (true,false) adding large files can take long (esp. with encryption), +true+ won't block, default is +false+
|
129
|
-
#
|
85
|
+
#
|
130
86
|
# === Return Value:
|
131
87
|
#
|
132
88
|
# :: *String* containing a new unique ID for the file added.
|
133
89
|
# :: +false+ when the file could not be stored.
|
134
|
-
def self.add path
|
135
|
-
self.add!(path
|
90
|
+
def self.add path
|
91
|
+
self.add!(path)
|
136
92
|
|
137
|
-
rescue Exception
|
93
|
+
rescue Exception => ex
|
138
94
|
return false
|
139
95
|
end
|
140
96
|
|
@@ -167,7 +123,7 @@ module FilePool
|
|
167
123
|
if @@crypted_mode
|
168
124
|
if options[:decrypt]
|
169
125
|
# return path of decrypted file (tmp path)
|
170
|
-
|
126
|
+
decrypt id2dir_secured(fid) + "/#{fid}"
|
171
127
|
else
|
172
128
|
id2dir_secured(fid) + "/#{fid}"
|
173
129
|
end
|
@@ -187,33 +143,6 @@ module FilePool
|
|
187
143
|
end
|
188
144
|
end
|
189
145
|
|
190
|
-
# Returns an IO object providing an (unencrypted) stream of data of the given file ID
|
191
|
-
# To get the stream of the encrypted data pass :decrypt => false, as an option.
|
192
|
-
#
|
193
|
-
# === Parameters:
|
194
|
-
#
|
195
|
-
# fid (String)::
|
196
|
-
# File ID which was generated by a previous #add operation.
|
197
|
-
#
|
198
|
-
# options (Hash)::
|
199
|
-
# :decrypt (true,false) In encryption mode don't decrypt, but prioved the encrypted data. Defaults to +true+.
|
200
|
-
#
|
201
|
-
# === Return Value:
|
202
|
-
#
|
203
|
-
# :: *IO*, IO stream open for reading
|
204
|
-
#
|
205
|
-
def self.stream fid, options={}
|
206
|
-
options[:decrypt] = true unless options[:decrypt] == false
|
207
|
-
|
208
|
-
if path = path(fid, :decrypt => false)
|
209
|
-
if @@crypted_mode and options[:decrypt]
|
210
|
-
decrypt_to_stream path
|
211
|
-
else
|
212
|
-
open(path)
|
213
|
-
end
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
146
|
#
|
218
147
|
# Remove a previously added file by its ID. Same as FilePool.remove,
|
219
148
|
# but throws exceptions on failure.
|
@@ -325,18 +254,18 @@ module FilePool
|
|
325
254
|
#
|
326
255
|
# === Return Value:
|
327
256
|
#
|
328
|
-
# :: *String*
|
257
|
+
# :: *String*Path and name of the crypted file.
|
329
258
|
def self.crypt path
|
330
259
|
# Crypt the file in the temp folder and copy after
|
331
260
|
cipher = create_cipher
|
332
261
|
result = Tempfile.new 'FilePool-encrypt'
|
333
|
-
|
334
|
-
|
262
|
+
|
263
|
+
result.set_encoding Encoding::BINARY,Encoding::BINARY
|
264
|
+
buf = ''.encode(Encoding::BINARY)
|
335
265
|
|
336
266
|
File.open(path) do |inf|
|
337
|
-
|
338
|
-
|
339
|
-
result << cipher.update(buf)
|
267
|
+
while inf.read(@@block_size, buf)
|
268
|
+
result << cipher.update(buf)
|
340
269
|
end
|
341
270
|
result << cipher.final
|
342
271
|
end
|
@@ -346,7 +275,7 @@ module FilePool
|
|
346
275
|
end
|
347
276
|
|
348
277
|
#
|
349
|
-
# Decrypt file
|
278
|
+
# Decrypt a file and give a path to it.
|
350
279
|
#
|
351
280
|
# Returns the path to the decrypted file.
|
352
281
|
#
|
@@ -356,80 +285,25 @@ module FilePool
|
|
356
285
|
# path of the file to decrypt.
|
357
286
|
#
|
358
287
|
# === Return Value:
|
359
|
-
#
|
360
|
-
# :: *String* Path and name of the decrypted file.
|
361
|
-
def self.decrypt_to_file path
|
362
|
-
tmpfile = Tempfile.new 'FilePool-decrypt'
|
363
|
-
|
364
|
-
File.open(path) do |crpt|
|
365
|
-
decrypt_io crpt, tmpfile
|
366
|
-
end
|
367
|
-
|
368
|
-
tmpfile.open # re-open for reading, prevents early deletion of tempfile
|
369
|
-
tmpfile.path
|
370
|
-
end
|
371
|
-
|
372
|
-
#
|
373
|
-
# Decrypt file to a stream (IO) non-blocking by forking a child process.
|
374
|
-
#
|
375
|
-
# === Parameters:
|
376
|
-
#
|
377
|
-
# path (String)::
|
378
|
-
# path of the file to decrypt.
|
379
288
|
#
|
380
|
-
#
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
pipe_read, pipe_write = IO.pipe
|
386
|
-
|
387
|
-
child = fork do
|
388
|
-
# in child process: decrypting
|
389
|
-
pipe_read.close
|
390
|
-
|
391
|
-
# open encrypted file
|
392
|
-
File.open(path) do |crpt|
|
393
|
-
decrypt_io crpt, pipe_write
|
394
|
-
end
|
395
|
-
|
396
|
-
pipe_write.close
|
397
|
-
end
|
289
|
+
# :: *String*Path and name of the crypted file.
|
290
|
+
def self.decrypt path
|
291
|
+
decipher = create_decipher
|
292
|
+
# Now decrypt the data:
|
293
|
+
output = Tempfile.new 'FilePool-decrypt'
|
398
294
|
|
399
|
-
|
400
|
-
|
401
|
-
pipe_write.close
|
402
|
-
pipe_read
|
403
|
-
end
|
295
|
+
output.set_encoding Encoding::BINARY,Encoding::BINARY
|
296
|
+
buf = ''.encode(Encoding::BINARY)
|
404
297
|
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
# === Parameters:
|
409
|
-
#
|
410
|
-
# in_io (IO)::
|
411
|
-
# provide encrypted data, must be open for reading
|
412
|
-
# out_io (IO)::
|
413
|
-
# provides decrypted data, must be open for writing
|
414
|
-
#
|
415
|
-
# === Retrun value:
|
416
|
-
#
|
417
|
-
# nil
|
418
|
-
def self.decrypt_io in_io, out_io
|
419
|
-
decipher = create_decipher
|
420
|
-
buf = ''
|
421
|
-
|
422
|
-
while in_io.read(@@block_size, buf)
|
423
|
-
out_io << decipher.update(buf)
|
424
|
-
if out_io.is_a?(File)
|
425
|
-
# avoid memory buffering
|
426
|
-
out_io.flush
|
427
|
-
out_io.fsync
|
298
|
+
File.open(path) do |inf|
|
299
|
+
while inf.read(@@block_size, buf)
|
300
|
+
output << decipher.update(buf)
|
428
301
|
end
|
302
|
+
output << decipher.final
|
429
303
|
end
|
430
304
|
|
431
|
-
|
432
|
-
|
305
|
+
output.open # re-open for reading, prevents early deletion of tempfile
|
306
|
+
output.path
|
433
307
|
end
|
434
308
|
|
435
309
|
#
|
metadata
CHANGED
@@ -1,89 +1,65 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: file_pool
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 3
|
9
|
-
- 10
|
10
|
-
version: 0.3.10
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.0
|
11
5
|
platform: ruby
|
12
|
-
authors:
|
13
|
-
-
|
6
|
+
authors:
|
7
|
+
- robokopp (Robert Anniés)
|
14
8
|
autorequire:
|
15
9
|
bindir: bin
|
16
10
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
dependencies:
|
21
|
-
- !ruby/object:Gem::Dependency
|
11
|
+
date: 2017-06-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
22
14
|
name: uuidtools
|
23
|
-
|
24
|
-
|
25
|
-
none: false
|
26
|
-
requirements:
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
27
17
|
- - ~>
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
hash: 15
|
30
|
-
segments:
|
31
|
-
- 2
|
32
|
-
- 1
|
33
|
-
- 2
|
18
|
+
- !ruby/object:Gem::Version
|
34
19
|
version: 2.1.2
|
35
20
|
type: :runtime
|
36
|
-
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.1.2
|
37
27
|
description: |
|
38
28
|
FilePool helps to manage a large number of files in a Ruby
|
39
29
|
project. It takes care of the storage of files in a balanced directory
|
40
30
|
tree and generates unique identifiers for all files.
|
41
|
-
|
42
|
-
email:
|
31
|
+
email:
|
43
32
|
- robokopp@fernwerk.net
|
44
33
|
executables: []
|
45
|
-
|
46
34
|
extensions: []
|
47
|
-
|
48
|
-
|
35
|
+
extra_rdoc_files:
|
36
|
+
- README.md
|
37
|
+
files:
|
49
38
|
- README.md
|
50
|
-
files:
|
51
39
|
- lib/file_pool.rb
|
52
40
|
- lib/file_pool/version.rb
|
53
|
-
- README.md
|
54
|
-
has_rdoc: true
|
55
41
|
homepage: https://github.com/robokopp/file_pool
|
56
42
|
licenses: []
|
57
|
-
|
43
|
+
metadata: {}
|
58
44
|
post_install_message:
|
59
45
|
rdoc_options: []
|
60
|
-
|
61
|
-
require_paths:
|
46
|
+
require_paths:
|
62
47
|
- lib
|
63
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
none: false
|
74
|
-
requirements:
|
75
|
-
- - ">="
|
76
|
-
- !ruby/object:Gem::Version
|
77
|
-
hash: 3
|
78
|
-
segments:
|
79
|
-
- 0
|
80
|
-
version: "0"
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ~>
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '2.0'
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - '>='
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
81
58
|
requirements: []
|
82
|
-
|
83
59
|
rubyforge_project:
|
84
|
-
rubygems_version:
|
60
|
+
rubygems_version: 2.4.6
|
85
61
|
signing_key:
|
86
|
-
specification_version:
|
62
|
+
specification_version: 4
|
87
63
|
summary: Manage a large number files in a pool
|
88
64
|
test_files: []
|
89
|
-
|
65
|
+
has_rdoc:
|