cortex-plugins-core 0.11.3 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/stylesheets/cortex-plugins-core/application.scss +5 -0
- data/app/assets/stylesheets/cortex-plugins-core/components/thumbnail-placeholder.scss +13 -0
- data/app/assets/stylesheets/cortex-plugins-core/variables/_colors.scss +47 -0
- data/app/assets/stylesheets/cortex-plugins-core/variables/_typography.scss +114 -0
- data/app/cells/plugins/core/asset_cell.rb +8 -3
- data/app/cells/plugins/core/asset_info/index.haml +6 -2
- data/app/cells/plugins/core/asset_info/show.haml +15 -13
- data/app/cells/plugins/core/asset_info_cell.rb +11 -3
- data/app/models/asset_field_type.rb +76 -91
- data/app/models/text_field_type.rb +1 -4
- data/app/uploaders/asset_uploader.rb +55 -0
- data/config/initializers/shrine.rb +9 -0
- data/lib/cortex/plugins/core/version.rb +1 -1
- data/lib/shrine/plugins/cortex_validation_helpers.rb +23 -0
- data/lib/tasks/cortex/core/media.rake +24 -15
- metadata +77 -16
- data/lib/tasks/cortex/test/dummy/db/development.sqlite3 +0 -0
- data/lib/tasks/cortex/test/dummy/db/test.sqlite3 +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c35c1578cd56442b0736e815a553c629af9f2dbe
|
4
|
+
data.tar.gz: 31e2be2b8f198d8a78087358b60eda6c415f896c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9e25db2a2bee5e1d941b584caa8348d83f6e62928de4d756b52bf882708d4ad3df00c4ff5be28353b07d83657f547dccaea201886ff45c71136cd6680a20360a
|
7
|
+
data.tar.gz: 7ea0cf777de1062eea373f744393dccde7e9b05db7e1733383981d4bd5419a3d572f4b58f42d4e76962f2fd2cc297bc9fe273afe0342c0ba130464296539991b
|
@@ -0,0 +1,47 @@
|
|
1
|
+
// Color Definitions
|
2
|
+
|
3
|
+
$color-teal: #63C0B9;
|
4
|
+
$color-teal-dark: #54A1A1;
|
5
|
+
$color-teal-light: #A1D9D5;
|
6
|
+
|
7
|
+
$color-orange: #F79C25;
|
8
|
+
$color-orange-dark: #E78523;
|
9
|
+
$color-orange-light: #FED473;
|
10
|
+
|
11
|
+
$color-anchor-blue-light: #747D8E;
|
12
|
+
|
13
|
+
$color-green: #009b74;
|
14
|
+
|
15
|
+
$color-slate-grey: #6E788F;
|
16
|
+
$color-grey: #BBB; // Type
|
17
|
+
$color-grey-dark: #333; // Type, Sidebar background, Login page background
|
18
|
+
$color-grey-light: #D4D4D4; // Content background color
|
19
|
+
$color-grey-lightest: #DDD; // Disabled and flat button background color
|
20
|
+
$color-grey-evenlighter: #E4E4E4;
|
21
|
+
$color-grey-reallylight: #F2F2F2;
|
22
|
+
$color-grey-extralight: #F4F4F4; // Wizard Instruction Panel background color
|
23
|
+
|
24
|
+
$color-red: #d85252;
|
25
|
+
|
26
|
+
$color-white: white; // Header
|
27
|
+
$color-black: #000000;
|
28
|
+
|
29
|
+
|
30
|
+
// Color Semantics
|
31
|
+
|
32
|
+
$employer-color: $color-teal;
|
33
|
+
$employer-color-dark: $color-teal-dark;
|
34
|
+
$employer-color-light: $color-teal-light;
|
35
|
+
|
36
|
+
$flash-error-background: $color-red;
|
37
|
+
$flash-success-background: $color-green;
|
38
|
+
|
39
|
+
$ar-color: $color-orange;
|
40
|
+
$ar-color-dark: $color-orange-dark;
|
41
|
+
$ar-color-light: $color-orange-light;
|
42
|
+
|
43
|
+
$notes-text: #6E788F;
|
44
|
+
|
45
|
+
$jumbo-button-text: #6E788F;
|
46
|
+
$jumbo-button-hover-background: $color-grey-evenlighter;
|
47
|
+
$jumbo-button-active-background: $color-grey-reallylight;
|
@@ -0,0 +1,114 @@
|
|
1
|
+
@font-face {
|
2
|
+
font-family: Montserrat;
|
3
|
+
font-style: normal;
|
4
|
+
font-weight: normal;
|
5
|
+
src: url(asset_path('Montserrat-Regular.otf')) format("opentype");
|
6
|
+
}
|
7
|
+
|
8
|
+
@font-face {
|
9
|
+
font-family: Montserrat;
|
10
|
+
font-style: normal;
|
11
|
+
font-weight: bold;
|
12
|
+
src: url(asset_path('Montserrat-Medium.otf')) format("opentype");
|
13
|
+
}
|
14
|
+
|
15
|
+
@font-face {
|
16
|
+
font-family: Montserrat;
|
17
|
+
font-style: normal;
|
18
|
+
font-weight: bolder;
|
19
|
+
src: url(asset_path('Montserrat-SemiBold.otf')) format("opentype");
|
20
|
+
}
|
21
|
+
|
22
|
+
@font-face {
|
23
|
+
font-family: Montserrat;
|
24
|
+
font-style: normal;
|
25
|
+
font-weight: lighter;
|
26
|
+
src: url(asset_path('Montserrat-Light.otf')) format("opentype");
|
27
|
+
}
|
28
|
+
|
29
|
+
$cortex-font-stack: Montserrat, sans-serif;
|
30
|
+
$base-font-size: 1rem;
|
31
|
+
|
32
|
+
%display-text { // Cortex Logo
|
33
|
+
color: $color-grey-dark;
|
34
|
+
font-family: $cortex-font-stack;
|
35
|
+
font-weight: normal;
|
36
|
+
font-size: 2.1775rem;
|
37
|
+
}
|
38
|
+
|
39
|
+
h1, h2, h3, h4, h5, h6 {
|
40
|
+
line-height: 1.5;
|
41
|
+
}
|
42
|
+
|
43
|
+
h1,
|
44
|
+
.text-style-1 { // Bread Crumbs and Page Headers
|
45
|
+
color: $color-teal;
|
46
|
+
font-family: $cortex-font-stack;
|
47
|
+
font-weight: bold;
|
48
|
+
font-size: 1.17rem;
|
49
|
+
text-decoration: none;
|
50
|
+
}
|
51
|
+
|
52
|
+
h2,
|
53
|
+
.text-style-2 {
|
54
|
+
color: $color-grey;
|
55
|
+
font-family: $cortex-font-stack;
|
56
|
+
font-weight: lighter;
|
57
|
+
font-size: 1.17rem;
|
58
|
+
}
|
59
|
+
|
60
|
+
h3,
|
61
|
+
.text-style-3 {
|
62
|
+
color: $color-grey;
|
63
|
+
font-family: $cortex-font-stack;
|
64
|
+
font-weight: bold;
|
65
|
+
font-size: 1.17rem;
|
66
|
+
}
|
67
|
+
|
68
|
+
h4,
|
69
|
+
.text-style-4 { // Section Headers, Dropdowns, Button Text
|
70
|
+
color: $color-grey-dark;
|
71
|
+
font-family: $cortex-font-stack;
|
72
|
+
font-size: 0.83rem;
|
73
|
+
}
|
74
|
+
|
75
|
+
h5,
|
76
|
+
.text-style-5 { // Field Text
|
77
|
+
color: $color-grey;
|
78
|
+
font-family: $cortex-font-stack;
|
79
|
+
font-weight: lighter;
|
80
|
+
font-size: $base-font-size;
|
81
|
+
}
|
82
|
+
|
83
|
+
h6,
|
84
|
+
.text-style-6 { // Field Text Filled
|
85
|
+
color: $color-anchor-blue-light;
|
86
|
+
font-family: $cortex-font-stack;
|
87
|
+
font-size: $base-font-size;
|
88
|
+
}
|
89
|
+
|
90
|
+
.text-style-7 { // Help Notes
|
91
|
+
color: $color-anchor-blue-light;
|
92
|
+
font-family: $cortex-font-stack;
|
93
|
+
font-weight: lighter;
|
94
|
+
font-size: 0.67rem;
|
95
|
+
}
|
96
|
+
|
97
|
+
%sidebar-nav { // Side Nav
|
98
|
+
color: $color-grey;
|
99
|
+
font-family: $cortex-font-stack;
|
100
|
+
font-weight: lighter;
|
101
|
+
font-size: 0.875rem;
|
102
|
+
text-transform: uppercase;
|
103
|
+
|
104
|
+
&.active { // Side Nav Selected
|
105
|
+
font-weight: bold;
|
106
|
+
color: $color-teal;
|
107
|
+
}
|
108
|
+
}
|
109
|
+
|
110
|
+
p {
|
111
|
+
color: $color-anchor-blue-light;
|
112
|
+
font-family: $cortex-font-stack;
|
113
|
+
font-size: $base-font-size;
|
114
|
+
}
|
@@ -19,8 +19,12 @@ module Plugins
|
|
19
19
|
field.validations['allowed_extensions']&.join(', ')
|
20
20
|
end
|
21
21
|
|
22
|
+
def allowed_asset_extensions_for_form
|
23
|
+
'.' + field.validations['allowed_extensions']&.join(',.')
|
24
|
+
end
|
25
|
+
|
22
26
|
def render_max_asset_size
|
23
|
-
number_to_human_size(field.validations['
|
27
|
+
number_to_human_size(field.validations['max_size'])
|
24
28
|
end
|
25
29
|
|
26
30
|
def input_classes
|
@@ -36,7 +40,7 @@ module Plugins
|
|
36
40
|
end
|
37
41
|
|
38
42
|
def render_input
|
39
|
-
@options[:form].file_field 'data[asset]'
|
43
|
+
@options[:form].file_field 'data[asset]', accept: allowed_asset_extensions_for_form
|
40
44
|
end
|
41
45
|
|
42
46
|
def render_tooltip
|
@@ -44,7 +48,8 @@ module Plugins
|
|
44
48
|
end
|
45
49
|
|
46
50
|
def associated_content_item_thumb_url
|
47
|
-
|
51
|
+
# TODO: The thumb version needs to be configurable
|
52
|
+
data['asset']['versions']['mini']['url']
|
48
53
|
end
|
49
54
|
|
50
55
|
def render_associated_content_item_thumb
|
@@ -1,2 +1,6 @@
|
|
1
|
-
- if asset
|
2
|
-
= image_tag(asset['
|
1
|
+
- if asset && asset['versions'][config[:thumbnail_style]]
|
2
|
+
= image_tag(asset['versions'][config[:thumbnail_style]]['url'], height: '50px')
|
3
|
+
- else
|
4
|
+
.thumbnail-placeholder
|
5
|
+
.h4
|
6
|
+
= asset['versions']['original']['extension']
|
@@ -4,24 +4,26 @@
|
|
4
4
|
new Clipboard('#copy-asset-url');
|
5
5
|
});
|
6
6
|
|
7
|
-
.asset-info.mdl-card
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
.asset-info.mdl-card
|
8
|
+
- if asset_is_image?
|
9
|
+
.mdl-card__title
|
10
|
+
%h2.mdl-card__title-text
|
11
|
+
= image_tag(asset['versions']['original']['url'], style: 'max-height: 200px;')
|
11
12
|
.mdl-card__supporting-text
|
12
13
|
%dl
|
13
14
|
%dt Original Filename
|
14
15
|
%dd
|
15
|
-
= asset['
|
16
|
-
%dt File Type
|
16
|
+
= asset['original_filename']
|
17
|
+
%dt Original File Type
|
17
18
|
%dd
|
18
|
-
= asset['
|
19
|
-
%dt File Size
|
19
|
+
= asset['versions']['original']['mime_type']
|
20
|
+
%dt Original File Size
|
20
21
|
%dd
|
21
|
-
= number_to_human_size(asset['file_size'])
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
= number_to_human_size(asset['versions']['original']['file_size'])
|
23
|
+
- if asset_is_image?
|
24
|
+
%dt Original Dimensions
|
25
|
+
%dd
|
26
|
+
= dimensions
|
25
27
|
%dt Creator
|
26
28
|
%dd
|
27
29
|
= creator.fullname
|
@@ -35,7 +37,7 @@
|
|
35
37
|
%dd
|
36
38
|
= link_to_asset
|
37
39
|
.mdl-card__menu
|
38
|
-
.mdl-button.mdl-button--icon.mdl-js-button.mdl-js-ripple-effect#copy-asset-url{data: {'clipboard-text': asset['url']}}
|
40
|
+
.mdl-button.mdl-button--icon.mdl-js-button.mdl-js-ripple-effect#copy-asset-url{data: {'clipboard-text': asset['versions']['original']['url']}}
|
39
41
|
%i.material-icons content_copy
|
40
42
|
.mdl-tooltip{for: 'copy-asset-url'}
|
41
43
|
Copy Asset URL
|
@@ -25,7 +25,7 @@ module Plugins
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def dimensions
|
28
|
-
"#{asset['dimensions']['width']} x #{asset['dimensions']['width']}"
|
28
|
+
"#{asset['versions']['original']['dimensions']['width']} x #{asset['versions']['original']['dimensions']['width']}"
|
29
29
|
end
|
30
30
|
|
31
31
|
def creator
|
@@ -37,11 +37,19 @@ module Plugins
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def updated_at
|
40
|
-
|
40
|
+
content_item.updated_at.to_formatted_s(:long_ordinal)
|
41
41
|
end
|
42
42
|
|
43
43
|
def link_to_asset
|
44
|
-
link_to asset['url'], asset['url'], target: '_blank'
|
44
|
+
link_to asset['versions']['original']['url'], asset['versions']['original']['url'], target: '_blank'
|
45
|
+
end
|
46
|
+
|
47
|
+
def asset_type
|
48
|
+
MimeMagic.new(asset['versions']['original']['mime_type']).mediatype
|
49
|
+
end
|
50
|
+
|
51
|
+
def asset_is_image?
|
52
|
+
asset_type == 'image'
|
45
53
|
end
|
46
54
|
end
|
47
55
|
end
|
@@ -1,139 +1,124 @@
|
|
1
|
+
require 'shrine/storage/s3'
|
2
|
+
|
1
3
|
class AssetFieldType < FieldType
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
:existing_data
|
10
|
-
|
11
|
-
before_save :extract_dimensions
|
12
|
-
|
13
|
-
do_not_validate_attachment_file_type :asset
|
14
|
-
validates :asset, attachment_presence: true, if: :validate_presence?
|
15
|
-
validate :validate_asset_size, if: :validate_size?
|
16
|
-
validate :validate_asset_content_type, if: :validate_content_type?
|
17
|
-
|
18
|
-
def metadata=(metadata_hash)
|
19
|
-
@metadata = metadata_hash.deep_symbolize_keys
|
20
|
-
@existing_data = metadata_hash[:existing_data]
|
21
|
-
Paperclip::HasAttachedFile.define_on(self.class, :asset, existing_metadata)
|
22
|
-
end
|
4
|
+
attr_reader :asset
|
5
|
+
attr_accessor :asset_data
|
6
|
+
|
7
|
+
before_save :promote
|
8
|
+
|
9
|
+
validate :asset_presence, if: :validate_presence?
|
10
|
+
validate :asset_errors
|
23
11
|
|
24
12
|
def data=(data_hash)
|
25
|
-
|
13
|
+
assign data_hash['asset'] if data_hash['asset']
|
14
|
+
@asset = attacher.get
|
26
15
|
end
|
27
16
|
|
28
17
|
def data
|
18
|
+
return {} if errors.any? || attacher.errors.any?
|
29
19
|
{
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
'dimensions': dimensions,
|
35
|
-
'content_type': asset_content_type,
|
36
|
-
'file_size': asset_file_size,
|
37
|
-
'updated_at': asset_updated_at
|
20
|
+
asset: {
|
21
|
+
original_filename: @original_filename,
|
22
|
+
# TODO: updated_at: asset.updated_at, -- Does Shrine give this to us? Potentially distinct from record's updated_at
|
23
|
+
versions: versions_data
|
38
24
|
},
|
39
|
-
|
40
|
-
'asset_field_type_id': id
|
25
|
+
shrine_asset: asset.to_json
|
41
26
|
}
|
42
27
|
end
|
43
28
|
|
44
29
|
def field_item_as_indexed_json_for_field_type(field_item, options = {})
|
45
30
|
json = {}
|
46
|
-
json[mapping_field_name] =
|
31
|
+
json[mapping_field_name] = field_item.data['asset']['original_filename']
|
47
32
|
json
|
48
33
|
end
|
49
34
|
|
50
35
|
def mapping
|
51
|
-
{name: mapping_field_name, type: :string, analyzer: :keyword}
|
36
|
+
{ name: mapping_field_name, type: :string, analyzer: :keyword }
|
52
37
|
end
|
53
38
|
|
54
39
|
private
|
55
40
|
|
56
41
|
def image?
|
57
|
-
|
42
|
+
MimeMagic.new(asset.mime_type).mediatype == 'image'
|
58
43
|
end
|
59
44
|
|
60
|
-
def
|
61
|
-
|
62
|
-
tempfile = asset.queued_for_write[:original]
|
63
|
-
unless tempfile.nil?
|
64
|
-
geometry = Paperclip::Geometry.from_file(tempfile)
|
65
|
-
@dimensions = {
|
66
|
-
width: geometry.width.to_i,
|
67
|
-
height: geometry.height.to_i
|
68
|
-
}
|
69
|
-
end
|
45
|
+
def mapping_field_name
|
46
|
+
"#{field_name.parameterize('_')}_asset_file_name"
|
70
47
|
end
|
71
48
|
|
72
|
-
def
|
73
|
-
|
74
|
-
MimeMagic.by_extension(allowed_content_type).type
|
75
|
-
end
|
49
|
+
def promote
|
50
|
+
@asset = attacher.promote action: :store unless asset.is_a?(Hash)
|
76
51
|
end
|
77
52
|
|
78
|
-
def
|
79
|
-
|
80
|
-
end
|
53
|
+
def assign(attachment)
|
54
|
+
@original_filename = attachment.original_filename
|
81
55
|
|
82
|
-
|
83
|
-
|
56
|
+
attachment.open
|
57
|
+
begin
|
58
|
+
attacher.assign attachment
|
59
|
+
ensure
|
60
|
+
attachment.close
|
61
|
+
end
|
84
62
|
end
|
85
63
|
|
86
|
-
def
|
87
|
-
|
64
|
+
def store
|
65
|
+
case metadata[:storage][:type]
|
66
|
+
when 's3'
|
67
|
+
Shrine::Storage::S3.new(metadata[:storage][:config]) # TODO: Encrypt credentials?
|
68
|
+
when 'file_system'
|
69
|
+
Shrine::Storage::FileSystem.new(metadata[:storage][:config])
|
70
|
+
else
|
71
|
+
AssetUploader.storages[:store]
|
72
|
+
end
|
88
73
|
end
|
89
74
|
|
90
|
-
def
|
91
|
-
|
92
|
-
|
75
|
+
def attacher
|
76
|
+
unless @attacher
|
77
|
+
AssetUploader.storages[:store_copy] = store # this may not be thread safe, but no other way to do this right now
|
78
|
+
AssetUploader.opts[:keep_files] = metadata[:keep_files] # this may not be thread safe, but no other way to do this right now
|
79
|
+
@attacher = AssetUploader::Attacher.new self, :asset, store: :store_copy
|
80
|
+
@attacher.context[:config] = {
|
81
|
+
original_filename: @original_filename,
|
82
|
+
metadata: metadata,
|
83
|
+
validations: validations
|
84
|
+
}
|
85
|
+
end
|
93
86
|
|
94
|
-
|
95
|
-
AttachmentContentTypeValidator.new({content_type: allowed_content_types}.merge(attributes: :asset))
|
87
|
+
@attacher
|
96
88
|
end
|
97
89
|
|
98
|
-
|
99
|
-
|
100
|
-
def validate_size?
|
101
|
-
begin
|
102
|
-
attachment_size_validator
|
103
|
-
true
|
104
|
-
rescue ArgumentError, NoMethodError
|
105
|
-
false
|
106
|
-
end
|
90
|
+
def host_alias
|
91
|
+
metadata[:storage][:host_alias] unless metadata[:storage][:host_alias].empty?
|
107
92
|
end
|
108
93
|
|
109
|
-
def
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
94
|
+
def versions_data
|
95
|
+
asset.transform_values do |version|
|
96
|
+
{
|
97
|
+
id: version.id,
|
98
|
+
filename: version.metadata['filename'],
|
99
|
+
extension: version.extension,
|
100
|
+
mime_type: version.mime_type,
|
101
|
+
url: version.url(public: true, host: host_alias),
|
102
|
+
file_size: version.size,
|
103
|
+
dimensions: {
|
104
|
+
width: version.width,
|
105
|
+
height: version.height
|
106
|
+
}
|
107
|
+
}
|
115
108
|
end
|
116
109
|
end
|
117
110
|
|
118
|
-
def
|
119
|
-
|
111
|
+
def validate_presence?
|
112
|
+
validations.key? :presence
|
120
113
|
end
|
121
114
|
|
122
|
-
def
|
123
|
-
|
115
|
+
def asset_presence
|
116
|
+
errors.add(:asset, 'must be present') unless asset
|
124
117
|
end
|
125
118
|
|
126
|
-
def
|
127
|
-
|
128
|
-
(
|
129
|
-
else
|
130
|
-
existing_data.deep_symbolize_keys[:asset][:style_urls]
|
119
|
+
def asset_errors
|
120
|
+
attacher.errors.each do |message|
|
121
|
+
errors.add(:asset, message)
|
131
122
|
end
|
132
123
|
end
|
133
|
-
|
134
|
-
def existing_metadata
|
135
|
-
metadata.except!(:existing_data)
|
136
|
-
metadata[:path].gsub!(":media_title", media_title) if metadata[:path]
|
137
|
-
metadata
|
138
|
-
end
|
139
124
|
end
|
@@ -26,16 +26,13 @@ class TextFieldType < FieldType
|
|
26
26
|
"#{field_name.parameterize('_')}_text"
|
27
27
|
end
|
28
28
|
|
29
|
-
def text_present
|
30
|
-
errors.add(:text, 'must be present') if @text.empty?
|
31
|
-
end
|
32
|
-
|
33
29
|
def text_length
|
34
30
|
validator = LengthValidator.new(validations[:length].merge(attributes: [:text]))
|
35
31
|
validator.validate_each(self, :text, text)
|
36
32
|
end
|
37
33
|
|
38
34
|
def text_unique
|
35
|
+
# TODO: This breaks when you try to update existing text
|
39
36
|
unless metadata[:existing_data][:text] == text || field.field_items.jsonb_contains(:data, text: text).empty?
|
40
37
|
errors.add(:text, "#{field.name} Must be unique")
|
41
38
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'image_processing/mini_magick'
|
2
|
+
|
3
|
+
class AssetUploader < Shrine
|
4
|
+
include ImageProcessing::MiniMagick
|
5
|
+
|
6
|
+
plugin :determine_mime_type
|
7
|
+
plugin :store_dimensions
|
8
|
+
plugin :validation_helpers
|
9
|
+
plugin :cortex_validation_helpers
|
10
|
+
plugin :processing
|
11
|
+
plugin :versions
|
12
|
+
plugin :keep_files, destroyed: true, replaced: true
|
13
|
+
|
14
|
+
Attacher.validate do
|
15
|
+
validate_mime_type_inclusion allowed_content_types if validate? :allowed_extensions
|
16
|
+
validate_max_size validations[:max_size] if validate? :max_size
|
17
|
+
validate_min_size validations[:min_size] if validate? :min_size
|
18
|
+
|
19
|
+
if store.image?(get)
|
20
|
+
validate_max_width validations[:max_width] if validate? :max_width
|
21
|
+
validate_max_height validations[:max_height] if validate? :max_height
|
22
|
+
validate_min_width validations[:min_width] if validate? :min_width
|
23
|
+
validate_min_height validations[:min_height] if validate? :min_height
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
process(:store) do |io, context|
|
28
|
+
# TODO: Perform image optimizations (build plugin), support versions without processors or formatters
|
29
|
+
context[:generated_hex] = SecureRandom.hex(8)
|
30
|
+
versions = { original: io.download }
|
31
|
+
|
32
|
+
if image?(io)
|
33
|
+
versions.merge!(context[:config][:metadata][:versions].transform_values do |version|
|
34
|
+
processed_version = send("#{version[:process][:method]}!", io.download, *version[:process][:config].values)
|
35
|
+
convert!(processed_version, version[:format])
|
36
|
+
end)
|
37
|
+
end
|
38
|
+
|
39
|
+
versions
|
40
|
+
end
|
41
|
+
|
42
|
+
def generate_location(io, context)
|
43
|
+
attachment = :asset
|
44
|
+
style = context[:version] || :original
|
45
|
+
original_name, _dot, original_extension = context[:config][:original_filename].rpartition('.')
|
46
|
+
generated_name, _dot, extension = super.rpartition('.')
|
47
|
+
generated_hex = context[:generated_hex]
|
48
|
+
|
49
|
+
ERB.new(context[:config][:metadata][:path]).result(binding)
|
50
|
+
end
|
51
|
+
|
52
|
+
def image?(io)
|
53
|
+
MimeMagic.new(io.data['metadata']['mime_type']).mediatype == 'image'
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'shrine'
|
2
|
+
require 'shrine/storage/file_system'
|
3
|
+
|
4
|
+
Shrine.storages = {
|
5
|
+
cache: Shrine::Storage::FileSystem.new('public', prefix: 'uploads/cache'),
|
6
|
+
store: Shrine::Storage::FileSystem.new('public', prefix: 'uploads/store')
|
7
|
+
}
|
8
|
+
|
9
|
+
Shrine.plugin :logging, logger: Rails.logger
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class Shrine
|
2
|
+
module Plugins
|
3
|
+
module CortexValidationHelpers
|
4
|
+
module AttacherMethods
|
5
|
+
def validations
|
6
|
+
context[:config][:validations]
|
7
|
+
end
|
8
|
+
|
9
|
+
def validate?(validation)
|
10
|
+
validations.key? validation
|
11
|
+
end
|
12
|
+
|
13
|
+
def allowed_content_types
|
14
|
+
validations[:allowed_extensions].collect do |allowed_content_type|
|
15
|
+
MimeMagic.by_extension(allowed_content_type).type
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
register_plugin(:cortex_validation_helpers, CortexValidationHelpers)
|
22
|
+
end
|
23
|
+
end
|
@@ -18,34 +18,43 @@ namespace :cortex do
|
|
18
18
|
puts "Creating Fields..."
|
19
19
|
|
20
20
|
allowed_asset_content_types = %w(txt css js pdf doc docx ppt pptx csv xls xlsx svg ico png jpg gif bmp)
|
21
|
-
fieldTitle = media.fields.new(name: 'Title', field_type: 'text_field_type', validations: {presence: true, uniqueness: true})
|
21
|
+
fieldTitle = media.fields.new(name: 'Title', field_type: 'text_field_type', validations: { presence: true, uniqueness: true })
|
22
22
|
fieldTitle.save
|
23
23
|
media.fields.new(name: 'Asset', field_type: 'asset_field_type',
|
24
24
|
validations:
|
25
25
|
{
|
26
26
|
presence: true,
|
27
27
|
allowed_extensions: allowed_asset_content_types,
|
28
|
-
|
29
|
-
less_than: 50.megabytes
|
30
|
-
}
|
28
|
+
max_size: 50.megabytes
|
31
29
|
},
|
32
30
|
metadata:
|
33
31
|
{
|
34
32
|
naming_data: {
|
35
33
|
title: fieldTitle.id
|
36
34
|
},
|
37
|
-
|
38
|
-
large: {
|
39
|
-
medium: {
|
40
|
-
default: {
|
41
|
-
mini: {
|
42
|
-
micro: {
|
43
|
-
post_tile: {geometry: '1140x', format: :jpg}
|
35
|
+
versions: {
|
36
|
+
large: { process: { method: 'resize_to_limit', config: { width: '1800', height: '1800' } }, format: :jpg },
|
37
|
+
medium: { process: { method: 'resize_to_limit', config: { width: '800', height: '800' } }, format: :jpg },
|
38
|
+
default: { process: { method: 'resize_to_limit', config: { width: '300', height: '300' } }, format: :jpg },
|
39
|
+
mini: { process: { method: 'resize_to_limit', config: { width: '100', height: '100' } }, format: :jpg },
|
40
|
+
micro: { process: { method: 'resize_to_limit', config: { width: '50', height: '50' } }, format: :jpg },
|
44
41
|
},
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
42
|
+
keep_files: [:destroyed, :replaced],
|
43
|
+
path: '<%= attachment %>/<%= original_name %>-<%= style %>-<%= generated_hex %>.<%= extension %>',
|
44
|
+
storage: {
|
45
|
+
type: 's3',
|
46
|
+
host_alias: ENV['HOST_ALIAS'],
|
47
|
+
config: {
|
48
|
+
access_key_id: ENV['S3_ACCESS_KEY_ID'],
|
49
|
+
secret_access_key: ENV['S3_SECRET_ACCESS_KEY'],
|
50
|
+
region: ENV['S3_REGION'],
|
51
|
+
bucket: ENV['S3_BUCKET_NAME'],
|
52
|
+
upload_options: {
|
53
|
+
acl: 'public-read',
|
54
|
+
cache_control: 'public, max-age=315576000'
|
55
|
+
}
|
56
|
+
}
|
57
|
+
}
|
49
58
|
})
|
50
59
|
media.fields.new(name: 'Description', field_type: 'text_field_type', validations: {presence: true})
|
51
60
|
media.fields.new(name: 'Tags', field_type: 'tag_field_type')
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cortex-plugins-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- CareerBuilder Employer Site & Content Products
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-04-
|
11
|
+
date: 2017-04-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '6'
|
33
|
+
version: '6.10'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '6'
|
40
|
+
version: '6.10'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: cells
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -58,56 +58,112 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0.0
|
61
|
+
version: '0.0'
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0.0
|
68
|
+
version: '0.0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: cells-haml
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 0.0
|
75
|
+
version: '0.0'
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 0.0
|
82
|
+
version: '0.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: jsonb_accessor
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 1.0.0.beta
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 1.0.0.beta
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: shrine
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '2.6'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '2.6'
|
83
111
|
- !ruby/object:Gem::Dependency
|
84
112
|
name: mimemagic
|
85
113
|
requirement: !ruby/object:Gem::Requirement
|
86
114
|
requirements:
|
87
115
|
- - "~>"
|
88
116
|
- !ruby/object:Gem::Version
|
89
|
-
version: 0.3
|
117
|
+
version: '0.3'
|
90
118
|
type: :runtime
|
91
119
|
prerelease: false
|
92
120
|
version_requirements: !ruby/object:Gem::Requirement
|
93
121
|
requirements:
|
94
122
|
- - "~>"
|
95
123
|
- !ruby/object:Gem::Version
|
96
|
-
version: 0.3
|
124
|
+
version: '0.3'
|
97
125
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
126
|
+
name: image_processing
|
99
127
|
requirement: !ruby/object:Gem::Requirement
|
100
128
|
requirements:
|
101
129
|
- - "~>"
|
102
130
|
- !ruby/object:Gem::Version
|
103
|
-
version:
|
131
|
+
version: '0.4'
|
104
132
|
type: :runtime
|
105
133
|
prerelease: false
|
106
134
|
version_requirements: !ruby/object:Gem::Requirement
|
107
135
|
requirements:
|
108
136
|
- - "~>"
|
109
137
|
- !ruby/object:Gem::Version
|
110
|
-
version:
|
138
|
+
version: '0.4'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: mini_magick
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '4.7'
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '4.7'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: fastimage
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '2.1'
|
160
|
+
type: :runtime
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '2.1'
|
111
167
|
description:
|
112
168
|
email:
|
113
169
|
- EmployerSiteContentProducts@cb.com
|
@@ -124,6 +180,10 @@ files:
|
|
124
180
|
- app/assets/javascripts/cortex-plugins-core/application.js
|
125
181
|
- app/assets/javascripts/cortex-plugins-core/cells/content_item.js
|
126
182
|
- app/assets/javascripts/cortex-plugins-core/cells/text.js
|
183
|
+
- app/assets/stylesheets/cortex-plugins-core/application.scss
|
184
|
+
- app/assets/stylesheets/cortex-plugins-core/components/thumbnail-placeholder.scss
|
185
|
+
- app/assets/stylesheets/cortex-plugins-core/variables/_colors.scss
|
186
|
+
- app/assets/stylesheets/cortex-plugins-core/variables/_typography.scss
|
127
187
|
- app/cells/plugins/core/asset/association.haml
|
128
188
|
- app/cells/plugins/core/asset/input.haml
|
129
189
|
- app/cells/plugins/core/asset_cell.rb
|
@@ -172,14 +232,15 @@ files:
|
|
172
232
|
- app/models/text_field_type.rb
|
173
233
|
- app/models/tree_field_type.rb
|
174
234
|
- app/models/user_field_type.rb
|
235
|
+
- app/uploaders/asset_uploader.rb
|
175
236
|
- config/initializers/react_on_rails.rb
|
237
|
+
- config/initializers/shrine.rb
|
176
238
|
- lib/cortex/plugins/core.rb
|
177
239
|
- lib/cortex/plugins/core/engine.rb
|
178
240
|
- lib/cortex/plugins/core/version.rb
|
241
|
+
- lib/shrine/plugins/cortex_validation_helpers.rb
|
179
242
|
- lib/tasks/cortex/core/db.rake
|
180
243
|
- lib/tasks/cortex/core/media.rake
|
181
|
-
- lib/tasks/cortex/test/dummy/db/development.sqlite3
|
182
|
-
- lib/tasks/cortex/test/dummy/db/test.sqlite3
|
183
244
|
homepage: https://github.com/cortex-cms/cortex-plugins-core
|
184
245
|
licenses:
|
185
246
|
- Apache-2.0
|
@@ -200,7 +261,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
200
261
|
version: '0'
|
201
262
|
requirements: []
|
202
263
|
rubyforge_project:
|
203
|
-
rubygems_version: 2.6.
|
264
|
+
rubygems_version: 2.6.11
|
204
265
|
signing_key:
|
205
266
|
specification_version: 4
|
206
267
|
summary: The combined set of Core FieldTypes for the Cortex CMS platform
|
File without changes
|
File without changes
|