cas-cms 1.0.0.alpha1 → 1.0.0.alpha2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -1
- data/app/assets/javascripts/cas/fileupload_manifest.js +12 -16
- data/app/controllers/cas/api/files_controller.rb +21 -13
- data/app/controllers/cas/sites/sections/contents_controller.rb +4 -1
- data/app/jobs/cas/images/delete_job.rb +5 -2
- data/app/jobs/cas/images/promote_job.rb +12 -3
- data/app/models/cas/media_file.rb +33 -9
- data/app/uploaders/file_uploader.rb +6 -7
- data/config/initializers/shrine.rb +19 -12
- data/config/routes.rb +6 -1
- data/lib/cas/remote_callbacks.rb +3 -3
- data/lib/cas/version.rb +1 -1
- metadata +20 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 96db3f49e7ef1be93244ed68bf8a6b7a9ed8fd063c7a8eef270028d3c5a0fe49
|
4
|
+
data.tar.gz: 769019cb609a44cb5e10ddae58d9914f6276b373002e8bad542b3988175744b5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b116b21f10eb582ad68d7664d89b15e9619a459f4f83d0bba55701e77da658a7fecae9900ba56b9bf4f68e8621fb6231d619eb3d64fe7bfb295dce508b87fe2d
|
7
|
+
data.tar.gz: 56517fae5fb373605c9c323c1c72a8441564e88419c87af7dbdf73a16b723d81dc38d332680cf8f048a159b894a4ce151ca4fad0b30f22f02a6f74ae99e1147c
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# Cas
|
2
2
|
|
3
|
+
For branches for specific versions: [rails-5](https://github.com/cas-cms/cas-core/tree/rails-5)
|
4
|
+
|
3
5
|
## Usage
|
4
6
|
|
5
7
|
Add this line to your application's Gemfile:
|
@@ -16,7 +18,7 @@ bin/rails generate cas:install
|
|
16
18
|
|
17
19
|
This adds an `/admin` entry to `config/routes.rb` and generates a new file,
|
18
20
|
`config/cas.config.yml` which contains all sections your site is supposed to
|
19
|
-
have.
|
21
|
+
have.
|
20
22
|
|
21
23
|
Once the file is edited, run
|
22
24
|
|
@@ -77,14 +77,12 @@ var ImageGalleryUploadFunctions = {
|
|
77
77
|
data.progressBar.remove();
|
78
78
|
|
79
79
|
var file = {
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
mime_type: data.files[0].type
|
87
|
-
}
|
80
|
+
id: data.formData.key.match(/cache\/(.+)/)[1], // we have to remove the prefix part
|
81
|
+
storage: 'cache',
|
82
|
+
metadata: {
|
83
|
+
size: data.files[0].size,
|
84
|
+
filename: data.files[0].name.match(/[^\/\\]*$/)[0], // IE returns full path
|
85
|
+
mime_type: data.files[0].type
|
88
86
|
}
|
89
87
|
}
|
90
88
|
|
@@ -148,14 +146,12 @@ var AttachmentUploadFunctions = {
|
|
148
146
|
data.progressBar.remove();
|
149
147
|
|
150
148
|
var file = {
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
mime_type: data.files[0].type
|
158
|
-
}
|
149
|
+
id: data.formData.key.match(/cache\/(.+)/)[1], // we have to remove the prefix part
|
150
|
+
storage: 'cache',
|
151
|
+
metadata: {
|
152
|
+
size: data.files[0].size,
|
153
|
+
filename: data.files[0].name.match(/[^\/\\]*$/)[0], // IE returns full path
|
154
|
+
mime_type: data.files[0].type
|
159
155
|
}
|
160
156
|
}
|
161
157
|
|
@@ -5,17 +5,27 @@ class Cas::Api::FilesController < Cas::ApplicationController
|
|
5
5
|
if ENV.fetch("S3_BUCKET")
|
6
6
|
service = "s3"
|
7
7
|
end
|
8
|
+
|
8
9
|
metadata = resource_params[:attributes][:metadata]
|
9
10
|
file = ::Cas::MediaFile.new(
|
10
11
|
service: service,
|
11
|
-
size: metadata[:
|
12
|
-
original_name: metadata[:
|
13
|
-
mime_type: metadata[:
|
12
|
+
size: metadata[:metadata][:size].to_i,
|
13
|
+
original_name: metadata[:metadata][:filename],
|
14
|
+
mime_type: metadata[:metadata][:mime_type],
|
14
15
|
media_type: resource_params[:attributes][:media_type],
|
15
16
|
file: metadata.to_json,
|
16
|
-
attachable: attachable_record
|
17
|
+
attachable: attachable_record,
|
18
|
+
author: current_user,
|
17
19
|
)
|
18
|
-
|
20
|
+
|
21
|
+
Rails.logger.debug metadata.inspect
|
22
|
+
|
23
|
+
unless !file.valid?
|
24
|
+
Rails.logger.debug "File upload failed: #{file.errors.inspect}"
|
25
|
+
end
|
26
|
+
|
27
|
+
file.save!
|
28
|
+
|
19
29
|
Cas::RemoteCallbacks.callbacks[:after_file_upload].call(file)
|
20
30
|
render json: {
|
21
31
|
data: {
|
@@ -53,11 +63,9 @@ class Cas::Api::FilesController < Cas::ApplicationController
|
|
53
63
|
:cover,
|
54
64
|
:media_type,
|
55
65
|
metadata: [
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
metadata: [:size, :filename, :mime_type, 'mime-type']
|
60
|
-
]
|
66
|
+
:id,
|
67
|
+
:storage,
|
68
|
+
metadata: [:size, :filename, :mime_type, 'mime-type']
|
61
69
|
]
|
62
70
|
],
|
63
71
|
relationships: [
|
@@ -68,10 +76,10 @@ class Cas::Api::FilesController < Cas::ApplicationController
|
|
68
76
|
)
|
69
77
|
|
70
78
|
if r[:attributes][:metadata].present?
|
71
|
-
if r[:attributes][:metadata][:
|
72
|
-
r[:attributes][:metadata][:
|
79
|
+
if r[:attributes][:metadata][:metadata][:mime_type].blank?
|
80
|
+
r[:attributes][:metadata][:metadata][:mime_type] = r[:attributes][:metadata][:metadata][:"mime-type"]
|
73
81
|
end
|
74
|
-
r[:attributes][:metadata][:
|
82
|
+
r[:attributes][:metadata][:metadata].delete(:"mime-type")
|
75
83
|
end
|
76
84
|
r
|
77
85
|
end
|
@@ -25,6 +25,7 @@ module Cas
|
|
25
25
|
@content.section_id = @section.id
|
26
26
|
@content.tag_list = content_params[:tag_list] if content_params[:tag_list]
|
27
27
|
success = @content.save!
|
28
|
+
|
28
29
|
::Cas::Activity.create!(user: current_user, site: @site, subject: @content, event_name: 'create')
|
29
30
|
associate_files(@content, :images)
|
30
31
|
associate_files(@content, :attachments)
|
@@ -96,7 +97,9 @@ module Cas
|
|
96
97
|
# When no file is uploaded, when the content form is submitted the
|
97
98
|
# `file` input ends up being sent empty (e.g file: [""]). This confuses
|
98
99
|
# Rails.
|
99
|
-
|
100
|
+
if params[:content][:file].present?
|
101
|
+
params[:content].delete(:file) if params[:content][:file].map(&:presence)&.compact.blank?
|
102
|
+
end
|
100
103
|
|
101
104
|
result = params.require(:content).permit(
|
102
105
|
:category_id,
|
@@ -3,8 +3,11 @@ module Cas
|
|
3
3
|
class DeleteJob
|
4
4
|
include ::Sidekiq::Worker
|
5
5
|
|
6
|
-
def perform(data)
|
7
|
-
|
6
|
+
def perform(attacher_class, data)
|
7
|
+
attacher_class = Object.const_get(attacher_class)
|
8
|
+
|
9
|
+
attacher = attacher_class.from_data(data)
|
10
|
+
attacher.destroy
|
8
11
|
end
|
9
12
|
end
|
10
13
|
end
|
@@ -1,10 +1,19 @@
|
|
1
1
|
module Cas
|
2
2
|
module Images
|
3
3
|
class PromoteJob
|
4
|
-
include ::Sidekiq::Worker
|
5
4
|
|
6
|
-
|
7
|
-
|
5
|
+
include Sidekiq::Worker
|
6
|
+
|
7
|
+
def perform(attacher_class, record_class, record_id, name, file_data)
|
8
|
+
attacher_class = Object.const_get(attacher_class)
|
9
|
+
record = Object.const_get(record_class).find(record_id) # if using Active Record
|
10
|
+
|
11
|
+
attacher = attacher_class.retrieve(model: record, name: name, file: file_data)
|
12
|
+
attacher.create_derivatives # call derivatives processor
|
13
|
+
attacher.atomic_promote
|
14
|
+
rescue Shrine::AttachmentChanged, ActiveRecord::RecordNotFound => e
|
15
|
+
Rails.logger.info e.inspect
|
16
|
+
# attachment has changed or record has been deleted, nothing to do
|
8
17
|
end
|
9
18
|
end
|
10
19
|
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
module Cas
|
2
2
|
class MediaFile < ApplicationRecord
|
3
|
-
include FileUploader::Attachment.new(:file)
|
3
|
+
include FileUploader::Attachment.new(:file) # This is for the Shrine gem
|
4
4
|
|
5
5
|
class UnknownPath < StandardError; end
|
6
6
|
class UnknownFileService < StandardError; end
|
7
7
|
|
8
|
-
belongs_to :attachable, polymorphic: true
|
9
|
-
belongs_to :author, class_name: "::Cas::User"
|
8
|
+
belongs_to :attachable, polymorphic: true, optional: true
|
9
|
+
belongs_to :author, class_name: "::Cas::User", optional: true
|
10
10
|
|
11
11
|
before_validation :set_media_type
|
12
12
|
before_save :set_image_as_unique_cover
|
@@ -39,13 +39,37 @@ module Cas
|
|
39
39
|
raise UnknownFileService
|
40
40
|
end
|
41
41
|
|
42
|
-
# Shrine gem uses `file_data`
|
42
|
+
# Shrine gem uses `file_data` because `file` is the name we specified for
|
43
|
+
# the Attachment at the top of this model.
|
43
44
|
elsif JSON.parse(file_data).present?
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
45
|
+
params = {
|
46
|
+
public: true
|
47
|
+
}
|
48
|
+
params[:host] = cdn if cdn.present?
|
49
|
+
|
50
|
+
# With Shrine, the default image version is :original. Other versions
|
51
|
+
# are called derivatives. The `file_url` method expects a derivative
|
52
|
+
# name as first argument.
|
53
|
+
#
|
54
|
+
# When we pass :original, it just returns `nil` because the main file is
|
55
|
+
# not considered a derivative. If we had something like :larger, then
|
56
|
+
# that would be the argument.
|
57
|
+
url = if version.to_sym == :original
|
58
|
+
file_url(params)
|
59
|
+
else
|
60
|
+
file_url(version, params)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Shrine 3 returns `nil` when a derivative doesn't exist. It also
|
64
|
+
# returns `nil` when we pass parameters. This is a fallback way of
|
65
|
+
# avoiding any `nil` returns. However, notice that we can't pass
|
66
|
+
# `params` because Shrine just ignores it and returns `nil` if it's
|
67
|
+
# present (it wasn't like that in Shrine 2).
|
68
|
+
url = file_url if url.blank?
|
69
|
+
|
70
|
+
# Amazon S3 has URLs that include some query strings like signatures
|
71
|
+
# which we don't want to include in URLs.
|
72
|
+
url&.gsub(/\?.*/, "")
|
49
73
|
else
|
50
74
|
raise UnknownPath
|
51
75
|
end
|
@@ -1,14 +1,13 @@
|
|
1
1
|
class ::FileUploader < Shrine
|
2
|
-
plugin :versions
|
3
|
-
plugin :processing
|
4
2
|
|
5
|
-
|
6
|
-
result = {
|
3
|
+
Attacher.derivatives do |original|
|
4
|
+
result = {
|
5
|
+
}
|
6
|
+
|
7
7
|
if context[:record].media_type == 'image'
|
8
|
-
result = Cas::RemoteCallbacks.callbacks[:uploaded_image_versions].call(
|
8
|
+
result = Cas::RemoteCallbacks.callbacks[:uploaded_image_versions].call(original)
|
9
9
|
end
|
10
|
-
|
11
|
-
result = result.merge(original: original) unless result.keys.include?(:original)
|
10
|
+
|
12
11
|
Rails.logger.info "FileUploader, versions: [#{result.keys.join(", ")}]"
|
13
12
|
result
|
14
13
|
end
|
@@ -4,16 +4,15 @@
|
|
4
4
|
require 'shrine'
|
5
5
|
|
6
6
|
Shrine.plugin :activerecord
|
7
|
-
Shrine.plugin :presign_endpoint
|
8
7
|
Shrine.plugin :backgrounding
|
9
8
|
|
9
|
+
Shrine.plugin(
|
10
|
+
:derivatives,
|
11
|
+
create_on_promote: true, # automatically create derivatives on promotion
|
12
|
+
versions_compatibility: true # handle versions column format
|
13
|
+
)
|
14
|
+
|
10
15
|
if Rails.env.test?
|
11
|
-
s3_options = {
|
12
|
-
access_key_id: 'access_key_id',
|
13
|
-
secret_access_key: 'secret_access_key',
|
14
|
-
region: 'us-east-1',
|
15
|
-
bucket: 'com.bucket'
|
16
|
-
}
|
17
16
|
require "shrine/storage/file_system"
|
18
17
|
|
19
18
|
Shrine.storages = {
|
@@ -27,6 +26,7 @@ else
|
|
27
26
|
puts msg
|
28
27
|
|
29
28
|
else
|
29
|
+
Shrine.plugin :presign_endpoint
|
30
30
|
s3_options = {
|
31
31
|
access_key_id: ENV.fetch("S3_ACCESS_KEY_ID"),
|
32
32
|
secret_access_key: ENV.fetch("S3_SECRET_ACCESS_KEY"),
|
@@ -43,12 +43,19 @@ else
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
-
Shrine::Attacher.
|
47
|
-
Rails.logger.info "Shrine promoting file scheduled"
|
48
|
-
::Cas::Images::PromoteJob.perform_async(
|
46
|
+
Shrine::Attacher.promote_block do
|
47
|
+
Rails.logger.info "Shrine promoting #{record.class.name} file scheduled"
|
48
|
+
::Cas::Images::PromoteJob.perform_async(
|
49
|
+
self.class.name,
|
50
|
+
record.class.name,
|
51
|
+
record.id,
|
52
|
+
name.to_s,
|
53
|
+
file_data
|
54
|
+
)
|
49
55
|
end
|
50
56
|
|
51
|
-
|
57
|
+
|
58
|
+
Shrine::Attacher.destroy_block do
|
52
59
|
Rails.logger.info "Shrine deleting file scheduled"
|
53
|
-
::Cas::Images::DeleteJob.perform_async(data)
|
60
|
+
::Cas::Images::DeleteJob.perform_async(self.class.name, data)
|
54
61
|
end
|
data/config/routes.rb
CHANGED
@@ -3,7 +3,12 @@ require 'sidekiq/web'
|
|
3
3
|
#Sidekiq::Web.set :session_secret, Rails.application.secrets[:secret_key_base]
|
4
4
|
|
5
5
|
Cas::Engine.routes.draw do
|
6
|
-
|
6
|
+
if Shrine.respond_to?(:presign_endpoint)
|
7
|
+
mount Shrine.presign_endpoint(:cache) => "/files/cache/presign"
|
8
|
+
else
|
9
|
+
Rails.logger.info "Shrine's presign endpoint is disabled"
|
10
|
+
end
|
11
|
+
|
7
12
|
# TODO - fix
|
8
13
|
# mount Shrine.upload_endpoint(:cache) => "/files/upload"
|
9
14
|
|
data/lib/cas/remote_callbacks.rb
CHANGED
@@ -9,9 +9,9 @@ module Cas
|
|
9
9
|
# big: big_image
|
10
10
|
# }
|
11
11
|
#
|
12
|
-
# `original` should
|
13
|
-
# afterwards automatically.
|
14
|
-
uploaded_image_versions: ->(
|
12
|
+
# `original` should not be present after Shrine 3.0. If it is not, we will
|
13
|
+
# merge it afterwards automatically.
|
14
|
+
uploaded_image_versions: ->(original) {
|
15
15
|
{}
|
16
16
|
},
|
17
17
|
|
data/lib/cas/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cas-cms
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.
|
4
|
+
version: 1.0.0.alpha2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexandre de Oliveira
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-03-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -182,16 +182,16 @@ dependencies:
|
|
182
182
|
name: sidekiq
|
183
183
|
requirement: !ruby/object:Gem::Requirement
|
184
184
|
requirements:
|
185
|
-
- - "
|
185
|
+
- - ">"
|
186
186
|
- !ruby/object:Gem::Version
|
187
|
-
version: '0'
|
187
|
+
version: '5.0'
|
188
188
|
type: :runtime
|
189
189
|
prerelease: false
|
190
190
|
version_requirements: !ruby/object:Gem::Requirement
|
191
191
|
requirements:
|
192
|
-
- - "
|
192
|
+
- - ">"
|
193
193
|
- !ruby/object:Gem::Version
|
194
|
-
version: '0'
|
194
|
+
version: '5.0'
|
195
195
|
- !ruby/object:Gem::Dependency
|
196
196
|
name: sprockets-rails
|
197
197
|
requirement: !ruby/object:Gem::Requirement
|
@@ -238,16 +238,16 @@ dependencies:
|
|
238
238
|
name: shrine
|
239
239
|
requirement: !ruby/object:Gem::Requirement
|
240
240
|
requirements:
|
241
|
-
- -
|
241
|
+
- - "~>"
|
242
242
|
- !ruby/object:Gem::Version
|
243
|
-
version:
|
243
|
+
version: '3.0'
|
244
244
|
type: :runtime
|
245
245
|
prerelease: false
|
246
246
|
version_requirements: !ruby/object:Gem::Requirement
|
247
247
|
requirements:
|
248
|
-
- -
|
248
|
+
- - "~>"
|
249
249
|
- !ruby/object:Gem::Version
|
250
|
-
version:
|
250
|
+
version: '3.0'
|
251
251
|
- !ruby/object:Gem::Dependency
|
252
252
|
name: roda
|
253
253
|
requirement: !ruby/object:Gem::Requirement
|
@@ -263,21 +263,21 @@ dependencies:
|
|
263
263
|
- !ruby/object:Gem::Version
|
264
264
|
version: '0'
|
265
265
|
- !ruby/object:Gem::Dependency
|
266
|
-
name: aws-sdk
|
266
|
+
name: aws-sdk-s3
|
267
267
|
requirement: !ruby/object:Gem::Requirement
|
268
268
|
requirements:
|
269
|
-
- - "
|
269
|
+
- - ">="
|
270
270
|
- !ruby/object:Gem::Version
|
271
|
-
version: '
|
271
|
+
version: '0'
|
272
272
|
type: :runtime
|
273
273
|
prerelease: false
|
274
274
|
version_requirements: !ruby/object:Gem::Requirement
|
275
275
|
requirements:
|
276
|
-
- - "
|
276
|
+
- - ">="
|
277
277
|
- !ruby/object:Gem::Version
|
278
|
-
version: '
|
278
|
+
version: '0'
|
279
279
|
- !ruby/object:Gem::Dependency
|
280
|
-
name:
|
280
|
+
name: amazing_print
|
281
281
|
requirement: !ruby/object:Gem::Requirement
|
282
282
|
requirements:
|
283
283
|
- - ">="
|
@@ -579,7 +579,7 @@ homepage: ''
|
|
579
579
|
licenses:
|
580
580
|
- MIT
|
581
581
|
metadata: {}
|
582
|
-
post_install_message:
|
582
|
+
post_install_message:
|
583
583
|
rdoc_options: []
|
584
584
|
require_paths:
|
585
585
|
- lib
|
@@ -594,8 +594,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
594
594
|
- !ruby/object:Gem::Version
|
595
595
|
version: 1.3.1
|
596
596
|
requirements: []
|
597
|
-
rubygems_version: 3.
|
598
|
-
signing_key:
|
597
|
+
rubygems_version: 3.3.7
|
598
|
+
signing_key:
|
599
599
|
specification_version: 4
|
600
600
|
summary: Summary of Cas.
|
601
601
|
test_files: []
|