dis 1.0.4 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/dis/errors.rb +1 -1
- data/lib/dis/jobs.rb +2 -2
- data/lib/dis/layer.rb +13 -9
- data/lib/dis/layers.rb +6 -6
- data/lib/dis/model/class_methods.rb +1 -1
- data/lib/dis/model/data.rb +13 -11
- data/lib/dis/model.rb +6 -8
- data/lib/dis/storage.rb +16 -20
- data/lib/dis/validations/data_presence.rb +2 -4
- data/lib/dis/version.rb +1 -1
- data/lib/dis.rb +13 -13
- data/lib/rails/generators/dis/install/install_generator.rb +3 -3
- data/lib/rails/generators/dis/install/templates/initializer.rb +1 -1
- data/lib/rails/generators/dis/model/model_generator.rb +9 -6
- data/lib/tasks/dis.rake +10 -10
- metadata +30 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7b2fd660ff2a6498b73046ce44d262e49440e48e
|
4
|
+
data.tar.gz: 9008b0cd219133671c8910dc5353b3a2fe665a0d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 98d5e2fe6406b2549902eff4ce453e747b16dae2da095feffef8c66f0b0ec454d94004d2ee0045de5915f01efed958c60d0c5f7cd23b527123c06cfe03ac7a28
|
7
|
+
data.tar.gz: 1ac6bbf53d47be0dfaf54b2be0cc596389eacb9f8cde4a42a98c77d3fa8de15b85bef305c85b08af30443836827e418409e043fbbbfb54eb580f1bfeb759a4d4
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Dis [](https://travis-ci.org/elektronaut/dis) [](https://codeclimate.com/github/elektronaut/dis) [](https://codeclimate.com/github/elektronaut/dis) [](https://gemnasium.com/elektronaut/dis)
|
2
2
|
|
3
3
|
Dis handles file uploads for your Rails app.
|
4
4
|
It's similar to [Paperclip](https://github.com/thoughtbot/paperclip)
|
data/lib/dis/errors.rb
CHANGED
data/lib/dis/jobs.rb
CHANGED
data/lib/dis/layer.rb
CHANGED
@@ -47,7 +47,7 @@ module Dis
|
|
47
47
|
class Layer
|
48
48
|
attr_reader :connection
|
49
49
|
|
50
|
-
def initialize(connection, options={})
|
50
|
+
def initialize(connection, options = {})
|
51
51
|
options = default_options.merge(options)
|
52
52
|
@connection = connection
|
53
53
|
@delayed = options[:delayed]
|
@@ -101,17 +101,21 @@ module Dis
|
|
101
101
|
#
|
102
102
|
# layer.exists?("documents", hash)
|
103
103
|
def exists?(type, hash)
|
104
|
-
|
105
|
-
|
104
|
+
if directory(type, hash) &&
|
105
|
+
directory(type, hash).files.head(key_component(type, hash))
|
106
|
+
true
|
107
|
+
else
|
108
|
+
false
|
109
|
+
end
|
106
110
|
end
|
107
111
|
|
108
112
|
# Retrieves a file from the store.
|
109
113
|
#
|
110
114
|
# layer.get("documents", hash)
|
111
115
|
def get(type, hash)
|
112
|
-
|
113
|
-
|
114
|
-
|
116
|
+
dir = directory(type, hash)
|
117
|
+
return unless dir
|
118
|
+
dir.files.get(key_component(type, hash))
|
115
119
|
end
|
116
120
|
|
117
121
|
# Deletes a file from the store.
|
@@ -138,8 +142,8 @@ module Dis
|
|
138
142
|
{ delayed: false, readonly: false, public: false, path: nil }
|
139
143
|
end
|
140
144
|
|
141
|
-
def directory_component(
|
142
|
-
path ||
|
145
|
+
def directory_component(_type, _hash)
|
146
|
+
path || ''
|
143
147
|
end
|
144
148
|
|
145
149
|
def key_component(type, hash)
|
@@ -169,7 +173,7 @@ module Dis
|
|
169
173
|
file.rewind if file.respond_to?(:rewind)
|
170
174
|
directory!(type, hash).files.create(
|
171
175
|
key: key_component(type, hash),
|
172
|
-
body: (file.
|
176
|
+
body: (file.is_a?(Fog::Model) ? file.body : file),
|
173
177
|
public: public?
|
174
178
|
)
|
175
179
|
end
|
data/lib/dis/layers.rb
CHANGED
@@ -7,7 +7,7 @@ module Dis
|
|
7
7
|
class Layers
|
8
8
|
include Enumerable
|
9
9
|
|
10
|
-
def initialize(layers=[])
|
10
|
+
def initialize(layers = [])
|
11
11
|
@layers = layers
|
12
12
|
end
|
13
13
|
|
@@ -28,7 +28,7 @@ module Dis
|
|
28
28
|
|
29
29
|
# Returns a new instance containing only the delayed layers.
|
30
30
|
def delayed
|
31
|
-
self.class.new select
|
31
|
+
self.class.new select(&:delayed?)
|
32
32
|
end
|
33
33
|
|
34
34
|
# Returns true if one or more delayed layers exist.
|
@@ -38,7 +38,7 @@ module Dis
|
|
38
38
|
|
39
39
|
# Returns a new instance containing only the immediate layers.
|
40
40
|
def immediate
|
41
|
-
self.class.new select
|
41
|
+
self.class.new select(&:immediate?)
|
42
42
|
end
|
43
43
|
|
44
44
|
# Returns true if one or more immediate layers exist.
|
@@ -48,7 +48,7 @@ module Dis
|
|
48
48
|
|
49
49
|
# Returns a new instance containing only the readonly layers.
|
50
50
|
def readonly
|
51
|
-
self.class.new select
|
51
|
+
self.class.new select(&:readonly?)
|
52
52
|
end
|
53
53
|
|
54
54
|
# Returns true if one or more readonly layers exist.
|
@@ -58,7 +58,7 @@ module Dis
|
|
58
58
|
|
59
59
|
# Returns a new instance containing only the writeable layers.
|
60
60
|
def writeable
|
61
|
-
self.class.new select
|
61
|
+
self.class.new select(&:writeable?)
|
62
62
|
end
|
63
63
|
|
64
64
|
# Returns true if one or more writeable layers exist.
|
@@ -66,4 +66,4 @@ module Dis
|
|
66
66
|
writeable.any?
|
67
67
|
end
|
68
68
|
end
|
69
|
-
end
|
69
|
+
end
|
data/lib/dis/model/data.rb
CHANGED
@@ -7,16 +7,16 @@ module Dis
|
|
7
7
|
# Facilitates communication between the model and the storage,
|
8
8
|
# and holds any newly assigned data before the record is saved.
|
9
9
|
class Data
|
10
|
-
def initialize(record, raw=nil)
|
10
|
+
def initialize(record, raw = nil)
|
11
11
|
@record = record
|
12
12
|
@raw = raw
|
13
13
|
end
|
14
14
|
|
15
15
|
# Returns true if two Data objects represent the same data.
|
16
|
-
def ==(
|
16
|
+
def ==(other)
|
17
17
|
# TODO: This can be made faster by
|
18
18
|
# comparing hashes for stored objects.
|
19
|
-
|
19
|
+
other.read == read
|
20
20
|
end
|
21
21
|
|
22
22
|
# Returns true if data exists either in memory or in storage.
|
@@ -86,15 +86,19 @@ module Dis
|
|
86
86
|
if object.respond_to?(:body)
|
87
87
|
object.body
|
88
88
|
elsif object.respond_to?(:read)
|
89
|
-
object
|
90
|
-
response = object.read
|
91
|
-
object.rewind
|
92
|
-
response
|
89
|
+
rewind_and_read(object)
|
93
90
|
else
|
94
91
|
object
|
95
92
|
end
|
96
93
|
end
|
97
94
|
|
95
|
+
def rewind_and_read(object)
|
96
|
+
object.rewind
|
97
|
+
response = object.read
|
98
|
+
object.rewind
|
99
|
+
response
|
100
|
+
end
|
101
|
+
|
98
102
|
def storage_type
|
99
103
|
@record.class.dis_type
|
100
104
|
end
|
@@ -110,9 +114,7 @@ module Dis
|
|
110
114
|
)
|
111
115
|
end
|
112
116
|
|
113
|
-
|
114
|
-
@raw
|
115
|
-
end
|
117
|
+
attr_reader :raw
|
116
118
|
end
|
117
119
|
end
|
118
|
-
end
|
120
|
+
end
|
data/lib/dis/model.rb
CHANGED
@@ -76,7 +76,7 @@ module Dis
|
|
76
76
|
# If you want to validate content types, size or similar, simply use standard
|
77
77
|
# Rails validations on the metadata attributes:
|
78
78
|
#
|
79
|
-
# validates :content_type, presence: true, format: /\Aapplication\/
|
79
|
+
# validates :content_type, presence: true, format: /\Aapplication\/pdf\z/
|
80
80
|
# validates :filename, presence: true, format: /\A[\w_\-\.]+\.pdf\z/i
|
81
81
|
# validates :content_length, numericality: { less_than: 5.megabytes }
|
82
82
|
module Model
|
@@ -125,9 +125,9 @@ module Dis
|
|
125
125
|
private
|
126
126
|
|
127
127
|
def cleanup_data
|
128
|
-
|
129
|
-
|
130
|
-
|
128
|
+
previous_hash = changes[dis_attribute(:content_hash)].try(&:first)
|
129
|
+
return unless previous_hash
|
130
|
+
dis_data.expire(previous_hash)
|
131
131
|
end
|
132
132
|
|
133
133
|
def delete_data
|
@@ -135,9 +135,7 @@ module Dis
|
|
135
135
|
end
|
136
136
|
|
137
137
|
def store_data
|
138
|
-
if dis_data.changed?
|
139
|
-
dis_set :content_hash, dis_data.store!
|
140
|
-
end
|
138
|
+
dis_set :content_hash, dis_data.store! if dis_data.changed?
|
141
139
|
end
|
142
140
|
|
143
141
|
def dis_get(attribute_name)
|
@@ -158,7 +156,7 @@ module Dis
|
|
158
156
|
|
159
157
|
# We don't want the data column when doing a partial write.
|
160
158
|
def keys_for_partial_write
|
161
|
-
super.reject { |a| a ==
|
159
|
+
super.reject { |a| a == 'data' }
|
162
160
|
end
|
163
161
|
end
|
164
162
|
end
|
data/lib/dis/storage.rb
CHANGED
@@ -19,15 +19,15 @@ module Dis
|
|
19
19
|
class << self
|
20
20
|
# Returns a hex digest for a given binary. Accepts files, strings
|
21
21
|
# and Fog models.
|
22
|
-
def file_digest(file
|
22
|
+
def file_digest(file)
|
23
23
|
hash = case file
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
24
|
+
when Fog::Model
|
25
|
+
digest.hexdigest(file.body)
|
26
|
+
when String
|
27
|
+
digest.hexdigest(file)
|
28
|
+
else
|
29
|
+
digest.file(file.path).hexdigest
|
30
|
+
end
|
31
31
|
yield hash if block_given?
|
32
32
|
hash
|
33
33
|
end
|
@@ -83,15 +83,15 @@ module Dis
|
|
83
83
|
# Returns an instance of Fog::Model.
|
84
84
|
def get(type, hash)
|
85
85
|
require_layers!
|
86
|
-
|
87
|
-
layers.
|
88
|
-
|
89
|
-
|
86
|
+
|
87
|
+
layers.inject(true) do |no_misses, layer|
|
88
|
+
result = layer.get(type, hash)
|
89
|
+
if result
|
90
|
+
store_immediately!(type, result) unless no_misses
|
90
91
|
return result
|
91
|
-
else
|
92
|
-
miss = true
|
93
92
|
end
|
94
93
|
end
|
94
|
+
|
95
95
|
raise Dis::Errors::NotFoundError
|
96
96
|
end
|
97
97
|
|
@@ -136,15 +136,11 @@ module Dis
|
|
136
136
|
end
|
137
137
|
|
138
138
|
def require_layers!
|
139
|
-
unless layers.any?
|
140
|
-
raise Dis::Errors::NoLayersError
|
141
|
-
end
|
139
|
+
raise Dis::Errors::NoLayersError unless layers.any?
|
142
140
|
end
|
143
141
|
|
144
142
|
def require_writeable_layers!
|
145
|
-
unless layers.immediate.writeable.any?
|
146
|
-
raise Dis::Errors::NoLayersError
|
147
|
-
end
|
143
|
+
raise Dis::Errors::NoLayersError unless layers.immediate.writeable.any?
|
148
144
|
end
|
149
145
|
|
150
146
|
def digest
|
@@ -8,10 +8,8 @@ module Dis
|
|
8
8
|
# Validates that a record has data, either freshly assigned or
|
9
9
|
# persisted in the storage. Adds a `:blank` error on `:data`if not.
|
10
10
|
def validate(record)
|
11
|
-
unless record.data?
|
12
|
-
record.errors.add(:data, :blank)
|
13
|
-
end
|
11
|
+
record.errors.add(:data, :blank) unless record.data?
|
14
12
|
end
|
15
13
|
end
|
16
14
|
end
|
17
|
-
end
|
15
|
+
end
|
data/lib/dis/version.rb
CHANGED
data/lib/dis.rb
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
14
|
-
require
|
15
|
-
require
|
3
|
+
require 'digest/sha1'
|
4
|
+
require 'fog/core'
|
5
|
+
require 'fog/local'
|
6
|
+
require 'active_job'
|
7
|
+
require 'pmap'
|
8
|
+
require 'dis/engine'
|
9
|
+
require 'dis/errors'
|
10
|
+
require 'dis/jobs'
|
11
|
+
require 'dis/layer'
|
12
|
+
require 'dis/layers'
|
13
|
+
require 'dis/model'
|
14
|
+
require 'dis/storage'
|
15
|
+
require 'dis/validations'
|
16
16
|
|
17
17
|
module Dis
|
18
18
|
end
|
@@ -6,12 +6,12 @@ require 'rails/generators/rails/model/model_generator'
|
|
6
6
|
module Dis
|
7
7
|
module Generators
|
8
8
|
class InstallGenerator < Rails::Generators::Base
|
9
|
-
desc
|
10
|
-
source_root File.expand_path(
|
9
|
+
desc 'Creates the Dis initializer'
|
10
|
+
source_root File.expand_path('../templates', __FILE__)
|
11
11
|
|
12
12
|
def create_initializer
|
13
13
|
template 'initializer.rb', File.join('config', 'initializers', 'dis.rb')
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
17
|
-
end
|
17
|
+
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
# Creates a local storage layer in db/dis:
|
4
4
|
|
5
5
|
Dis::Storage.layers << Dis::Layer.new(
|
6
|
-
Fog::Storage.new(
|
6
|
+
Fog::Storage.new(provider: 'Local', local_root: Rails.root.join('db', 'dis')),
|
7
7
|
path: Rails.env
|
8
8
|
)
|
9
9
|
|
@@ -6,14 +6,17 @@ require 'rails/generators/rails/model/model_generator'
|
|
6
6
|
module Dis
|
7
7
|
module Generators
|
8
8
|
class ModelGenerator < Rails::Generators::ModelGenerator
|
9
|
-
desc
|
9
|
+
desc 'Creates a Dis model'
|
10
10
|
|
11
11
|
def initialize(args, *options)
|
12
12
|
super(inject_dis_attributes(args), *options)
|
13
13
|
end
|
14
14
|
|
15
15
|
def add_model_extension
|
16
|
-
inject_into_file
|
16
|
+
inject_into_file(
|
17
|
+
File.join('app/models', class_path, "#{file_name}.rb"),
|
18
|
+
after: "ActiveRecord::Base\n"
|
19
|
+
) do
|
17
20
|
" include Dis::Model\n"
|
18
21
|
end
|
19
22
|
end
|
@@ -22,20 +25,20 @@ module Dis
|
|
22
25
|
|
23
26
|
def inject_dis_attributes(args)
|
24
27
|
if args.any?
|
25
|
-
|
28
|
+
[args[0]] + dis_attributes + args[1..args.length]
|
26
29
|
else
|
27
30
|
args
|
28
31
|
end
|
29
32
|
end
|
30
33
|
|
31
34
|
def dis_attributes
|
32
|
-
%w
|
35
|
+
%w(
|
33
36
|
content_hash:string
|
34
37
|
content_type:string
|
35
38
|
content_length:integer
|
36
39
|
filename:string
|
37
|
-
|
40
|
+
)
|
38
41
|
end
|
39
42
|
end
|
40
43
|
end
|
41
|
-
end
|
44
|
+
end
|
data/lib/tasks/dis.rake
CHANGED
@@ -1,32 +1,32 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
namespace :dis do
|
4
|
-
desc
|
4
|
+
desc 'Check stuff'
|
5
5
|
task consistency_check: :environment do
|
6
|
-
unless ENV[
|
6
|
+
unless ENV['MODELS']
|
7
7
|
puts "Usage: #{$PROGRAM_NAME} dis:consistency_check " \
|
8
|
-
|
8
|
+
'MODELS=Avatar,Document'
|
9
9
|
exit
|
10
10
|
end
|
11
11
|
|
12
|
-
models = ENV[
|
12
|
+
models = ENV['MODELS'].split(',').map(&:strip).map(&:constantize)
|
13
13
|
|
14
14
|
models.each do |model|
|
15
15
|
puts "-- #{model.name} --"
|
16
16
|
|
17
17
|
content_hash_attr = model.dis_attributes[:content_hash]
|
18
18
|
objects = model
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
.select(content_hash_attr)
|
20
|
+
.uniq
|
21
|
+
.map { |r| r.send(content_hash_attr) }
|
22
22
|
|
23
23
|
puts "Unique objects: #{objects.length}"
|
24
24
|
|
25
25
|
Dis::Storage.layers.each do |layer|
|
26
26
|
existing = objects
|
27
|
-
|
28
|
-
|
29
|
-
|
27
|
+
.pmap { |hash| [hash, layer.exists?(model.dis_type, hash)] }
|
28
|
+
.select(&:last)
|
29
|
+
.map(&:first)
|
30
30
|
missing = objects - existing
|
31
31
|
puts "#{layer.name}: #{existing.length} (#{missing.length} missing)"
|
32
32
|
|
metadata
CHANGED
@@ -1,57 +1,77 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Inge Jørgensen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-08-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 4.2.0
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 5.1.0
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
|
-
- - "
|
27
|
+
- - ">="
|
25
28
|
- !ruby/object:Gem::Version
|
26
29
|
version: 4.2.0
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 5.1.0
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: fog
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
30
36
|
requirements:
|
31
37
|
- - "~>"
|
32
38
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.
|
39
|
+
version: '1.35'
|
34
40
|
type: :runtime
|
35
41
|
prerelease: false
|
36
42
|
version_requirements: !ruby/object:Gem::Requirement
|
37
43
|
requirements:
|
38
44
|
- - "~>"
|
39
45
|
- !ruby/object:Gem::Version
|
40
|
-
version: 1.
|
46
|
+
version: '1.35'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: fog-local
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
41
61
|
- !ruby/object:Gem::Dependency
|
42
62
|
name: pmap
|
43
63
|
requirement: !ruby/object:Gem::Requirement
|
44
64
|
requirements:
|
45
65
|
- - "~>"
|
46
66
|
- !ruby/object:Gem::Version
|
47
|
-
version: 1.0
|
67
|
+
version: 1.1.0
|
48
68
|
type: :runtime
|
49
69
|
prerelease: false
|
50
70
|
version_requirements: !ruby/object:Gem::Requirement
|
51
71
|
requirements:
|
52
72
|
- - "~>"
|
53
73
|
- !ruby/object:Gem::Version
|
54
|
-
version: 1.0
|
74
|
+
version: 1.1.0
|
55
75
|
- !ruby/object:Gem::Dependency
|
56
76
|
name: sqlite3
|
57
77
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,14 +92,14 @@ dependencies:
|
|
72
92
|
requirements:
|
73
93
|
- - "~>"
|
74
94
|
- !ruby/object:Gem::Version
|
75
|
-
version: 3.
|
95
|
+
version: 3.5.1
|
76
96
|
type: :development
|
77
97
|
prerelease: false
|
78
98
|
version_requirements: !ruby/object:Gem::Requirement
|
79
99
|
requirements:
|
80
100
|
- - "~>"
|
81
101
|
- !ruby/object:Gem::Version
|
82
|
-
version: 3.
|
102
|
+
version: 3.5.1
|
83
103
|
description: Dis is a Rails plugin that stores your file uploads and other binary
|
84
104
|
blobs.
|
85
105
|
email:
|