cas-cms 0.1.3 → 1.0.0.alpha2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +30 -18
  3. data/app/assets/config/cas_manifest.js +2 -0
  4. data/app/assets/javascripts/cas/application.js +4 -2
  5. data/app/assets/javascripts/cas/fileupload_manifest.js +14 -18
  6. data/app/assets/stylesheets/cas/application.sass +4 -4
  7. data/app/assets/stylesheets/cas/form.sass +2 -0
  8. data/app/assets/stylesheets/cas/layout.sass +2 -0
  9. data/app/assets/stylesheets/cas/tables.sass +3 -0
  10. data/app/assets/stylesheets/cas/typography.sass +2 -0
  11. data/app/controllers/cas/activities_controller.rb +9 -0
  12. data/app/controllers/cas/api/files_controller.rb +21 -13
  13. data/app/controllers/cas/application_controller.rb +13 -0
  14. data/app/controllers/cas/file_uploads_controller.rb +1 -1
  15. data/app/controllers/cas/sites/application_controller.rb +0 -13
  16. data/app/controllers/cas/sites/sections/contents_controller.rb +13 -1
  17. data/app/controllers/cas/sites/users_controller.rb +1 -1
  18. data/app/jobs/cas/images/delete_job.rb +5 -2
  19. data/app/jobs/cas/images/promote_job.rb +12 -3
  20. data/app/models/cas/activity.rb +30 -0
  21. data/app/models/cas/content.rb +14 -5
  22. data/app/models/cas/media_file.rb +33 -9
  23. data/app/models/cas/sites_user.rb +1 -1
  24. data/app/models/cas/user.rb +3 -2
  25. data/app/uploaders/file_uploader.rb +7 -8
  26. data/app/views/cas/activities/index.html.erb +56 -0
  27. data/app/views/cas/sites/sections/contents/index.html.erb +0 -1
  28. data/app/views/layouts/cas/application.html.erb +3 -2
  29. data/config/initializers/acts_as_taggable.rb +1 -1
  30. data/config/initializers/shrine.rb +38 -27
  31. data/config/routes.rb +11 -2
  32. data/db/migrate/20180114124600_create_cas_activities.rb +16 -0
  33. data/db/migrate/20230220165900_add_subject_title_to_activities.rb +6 -0
  34. data/lib/cas/config.rb +8 -3
  35. data/lib/cas/engine.rb +5 -1
  36. data/lib/cas/exceptions.rb +7 -0
  37. data/lib/cas/form_field.rb +6 -2
  38. data/lib/cas/installation.rb +103 -0
  39. data/lib/cas/remote_callbacks.rb +3 -3
  40. data/lib/cas/section_config.rb +25 -31
  41. data/lib/cas/version.rb +1 -1
  42. data/lib/cas.rb +3 -1
  43. data/lib/generators/cas/USAGE +14 -0
  44. data/lib/generators/cas/install_generator.rb +14 -0
  45. data/lib/generators/cas/templates/cas.config.yml +82 -0
  46. data/lib/tasks/cas_tasks.rake +6 -4
  47. metadata +62 -26
  48. data/lib/cas/setup.rb +0 -60
  49. /data/app/assets/stylesheets/cas/vendors/{selectize.default.css → selectize.css} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: e4cf4081ecbfe1307e6d39d6b64156b98a494f3b
4
- data.tar.gz: b1b59204366430b4ff05abf74dd64107524373d5
2
+ SHA256:
3
+ metadata.gz: 96db3f49e7ef1be93244ed68bf8a6b7a9ed8fd063c7a8eef270028d3c5a0fe49
4
+ data.tar.gz: 769019cb609a44cb5e10ddae58d9914f6276b373002e8bad542b3988175744b5
5
5
  SHA512:
6
- metadata.gz: 4144df8905ec86fd3102dcf0cfc7cef2053b314f40a749059a305e97b552187144fc8f669e13e90de69649092522a6edf3c9fc8f40bc23f9637be297d8d436da
7
- data.tar.gz: d66d1a0ea481f0e9562e0f370a8dda0fbadcd23787fcbe260a9bfeb9ee3c3e9a8314ae7553312b2854258ffe17343037c24f89a31b5c579a7fe72836217e3336
6
+ metadata.gz: b116b21f10eb582ad68d7664d89b15e9619a459f4f83d0bba55701e77da658a7fecae9900ba56b9bf4f68e8621fb6231d619eb3d64fe7bfb295dce508b87fe2d
7
+ data.tar.gz: 56517fae5fb373605c9c323c1c72a8441564e88419c87af7dbdf73a16b723d81dc38d332680cf8f048a159b894a4ce151ca4fad0b30f22f02a6f74ae99e1147c
data/README.md CHANGED
@@ -1,11 +1,8 @@
1
1
  # Cas
2
- Short description and motivation.
3
2
 
4
- ## Usage
5
-
6
- How to use my plugin.
3
+ For branches for specific versions: [rails-5](https://github.com/cas-cms/cas-core/tree/rails-5)
7
4
 
8
- ## Installation
5
+ ## Usage
9
6
 
10
7
  Add this line to your application's Gemfile:
11
8
 
@@ -13,22 +10,25 @@ Add this line to your application's Gemfile:
13
10
  gem 'cas'
14
11
  ```
15
12
 
16
- ### Setup
13
+ ### Installation
17
14
 
18
- **Engine:** Cas is mounted in your main Rails application. Say your application
19
- is called MyBlog, you make can make it accessible at `myblog.com/admin`
20
- by setting the following in the `config/routes.rb` file in your main
21
- application:
15
+ ```
16
+ bin/rails generate cas:install
17
+ ```
22
18
 
23
- ```ruby
24
- Rails.application.routes.draw do
25
- mount Cas::Engine, at: "/admin"
19
+ This adds an `/admin` entry to `config/routes.rb` and generates a new file,
20
+ `config/cas.config.yml` which contains all sections your site is supposed to
21
+ have.
22
+
23
+ Once the file is edited, run
26
24
 
27
- # ... other routes
28
- end
29
25
  ```
26
+ bin/rails cas:apply_config
27
+ ```
28
+
29
+ ### File Uploads
30
30
 
31
- **S3:** you need S3 credentials to use Cas (for file uploads). Set the
31
+ You need S3 credentials to use Cas (for file uploads). Set the
32
32
  following ENV vars (e.g paste in your `~/.bash_profile` or use the `dotenv`
33
33
  gem in your main Rails application):
34
34
 
@@ -37,8 +37,20 @@ gem in your main Rails application):
37
37
  export S3_REGION="value"
38
38
  export S3_BUCKET="value"
39
39
 
40
- ## Contributing
41
- Contribution directions go here.
40
+ ## Development
41
+
42
+ Quick start:
43
+
44
+ ```
45
+ bundle install
46
+ bundle exec rake db:create db:migrate db:test:prepare
47
+ cd spec/test_app/ && bin/rails server
48
+ ```
49
+
50
+ ### The Longer Version
51
+
52
+
42
53
 
43
54
  ## License
55
+
44
56
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -1,2 +1,4 @@
1
+ //= link cas/application.js
2
+ //= link cas/application.css
1
3
  //= link_directory ../javascripts/cas .js
2
4
  //= link_directory ../stylesheets/cas .css
@@ -1,6 +1,6 @@
1
1
  //= require jquery
2
2
  //= require jquery_ujs
3
- //= require tinymce-jquery
3
+ //= require tinymce
4
4
  //= require cas/vendor/selectize.min
5
5
  //= require_self
6
6
 
@@ -37,6 +37,8 @@ $(document).ready(function() {
37
37
  });
38
38
 
39
39
  tinyMCE.init({
40
+ branding: false,
41
+ promotion: false,
40
42
  selector: 'textarea.editor',
41
43
  mode : "exact",
42
44
  relative_urls : false,
@@ -48,7 +50,7 @@ $(document).ready(function() {
48
50
  inline_styles: false,
49
51
  extended_valid_elements: "embed,param,object,iframe[src|title|width|height|allowfullscreen|frameborder]",
50
52
  language : "pt_BR",
51
- plugins : 'image,imagetools,code,paste,pagebreak,table,wordcount,link',
53
+ plugins : 'image code pagebreak table wordcount link',
52
54
  default_link_target: "_blank",
53
55
  images_upload_url: paths.fileUpload.path,
54
56
  images_upload_credentials: true
@@ -30,7 +30,7 @@ var UploadSharedFunctions = {
30
30
  console.log("error", e);
31
31
  console.log("data", data);
32
32
  data.progressBar.remove();
33
- alert('Falha ao enviar arquivo: '+data.files[0].name);
33
+ alert('Failed sending file: '+data.files[0].name);
34
34
  }
35
35
  };
36
36
 
@@ -47,7 +47,7 @@ var ImageGalleryUploadFunctions = {
47
47
  for (var index in data.originalFiles) {
48
48
  var file = data.originalFiles[index];
49
49
  if(file['type'].length && !acceptFileTypes.test(file['type'])) {
50
- alert('O arquivo enviado não é uma imagem.');
50
+ alert('File is not a valid image.');
51
51
  return false;
52
52
  }
53
53
  }
@@ -77,14 +77,12 @@ var ImageGalleryUploadFunctions = {
77
77
  data.progressBar.remove();
78
78
 
79
79
  var file = {
80
- original: {
81
- id: data.formData.key.match(/cache\/(.+)/)[1], // we have to remove the prefix part
82
- storage: 'cache',
83
- metadata: {
84
- size: data.files[0].size,
85
- filename: data.files[0].name.match(/[^\/\\]*$/)[0], // IE returns full path
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
- original: {
152
- id: data.formData.key.match(/cache\/(.+)/)[1], // we have to remove the prefix part
153
- storage: 'cache',
154
- metadata: {
155
- size: data.files[0].size,
156
- filename: data.files[0].name.match(/[^\/\\]*$/)[0], // IE returns full path
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
 
@@ -1,10 +1,10 @@
1
-
2
1
  /*
3
- * require_tree .
4
2
  *= require_self
3
+ * require cas/vendors/simplegrid.css
4
+ * require ./cas/vendors/selectize.default.css
5
5
  */
6
- @import 'vendors/simplegrid.css'
7
- @import 'vendors/selectize.default.css'
6
+ @import 'cas/vendors/selectize.css'
7
+ @import 'cas/vendors/simplegrid.css'
8
8
 
9
9
  @import 'mixins'
10
10
  @import 'colors'
@@ -1,3 +1,5 @@
1
+ @import 'colors'
2
+
1
3
  label
2
4
  display: block
3
5
  div.input.boolean
@@ -1,3 +1,5 @@
1
+ @import 'colors'
2
+ @import 'mixins'
1
3
 
2
4
  body
3
5
  margin: 0
@@ -1,3 +1,6 @@
1
+ @import 'colors'
2
+ @import 'mixins'
3
+
1
4
  table
2
5
  width: 100%
3
6
  border-spacing: 0
@@ -1,4 +1,6 @@
1
1
  // @import url('https://fonts.googleapis.com/css?family=Lato')
2
+ @import 'colors'
3
+ @import 'mixins'
2
4
 
3
5
  body
4
6
  margin: 0
@@ -0,0 +1,9 @@
1
+ class Cas::ActivitiesController < Cas::ApplicationController
2
+ def index
3
+ @activities = Cas::Activity
4
+ .where(site_id: current_user.sites.map(&:id))
5
+ .order('created_at DESC')
6
+ .page(params[:page])
7
+ .per(25)
8
+ end
9
+ end
@@ -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[:original][:metadata][:size].to_i,
12
- original_name: metadata[:original][:metadata][:filename],
13
- mime_type: metadata[:original][:metadata][:mime_type],
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
- file.save
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
- original: [
57
- :id,
58
- :storage,
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][:original][:metadata][:mime_type].blank?
72
- r[:attributes][:metadata][:original][:metadata][:mime_type] = r[:attributes][:metadata][:original][:metadata][:"mime-type"]
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][:original][:metadata].delete(:"mime-type")
82
+ r[:attributes][:metadata][:metadata].delete(:"mime-type")
75
83
  end
76
84
  r
77
85
  end
@@ -5,6 +5,7 @@ module Cas
5
5
  before_action :set_current_user
6
6
  before_action :set_user_sites
7
7
  before_action :set_domain
8
+ before_action :set_site
8
9
 
9
10
  private
10
11
 
@@ -22,6 +23,18 @@ module Cas
22
23
  if @domain.blank? || (ENV["DOMAIN"].blank? && @domain == "localhost")
23
24
  @domain = ::Cas::Site.first!.domains.first
24
25
  end
26
+ rescue ActiveRecord::RecordNotFound => e
27
+ raise Cas::Exceptions::IncompleteSetup, "IncompleteSetup: check README.md. #{e.message}: #{e.inspect}"
28
+ end
29
+
30
+ def set_site
31
+ if params[:site_id].present?
32
+ @site = ::Cas::Site.find_by!(slug: params[:site_id])
33
+ else
34
+ @site = ::Cas::Site
35
+ .where("cas_sites.domains::text[] && '{#{@domain}}'::text[]")
36
+ .first!
37
+ end
25
38
  end
26
39
  end
27
40
  end
@@ -1,6 +1,6 @@
1
1
  class Cas::FileUploadsController < Cas::ApplicationController
2
2
  skip_before_action :authenticate_user!
3
- skip_before_filter :verify_authenticity_token
3
+ skip_before_action :verify_authenticity_token
4
4
 
5
5
  def create
6
6
  file = params.fetch(:file)
@@ -1,15 +1,2 @@
1
1
  class Cas::Sites::ApplicationController < ::Cas::ApplicationController
2
- before_action :set_site
3
-
4
- private
5
-
6
- def set_site
7
- if params[:site_id].present?
8
- @site = ::Cas::Site.find_by!(slug: params[:site_id])
9
- else
10
- @site = ::Cas::Site
11
- .where("cas_sites.domains::text[] && '{#{@domain}}'::text[]")
12
- .first!
13
- end
14
- end
15
2
  end
@@ -25,10 +25,13 @@ 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
+
29
+ ::Cas::Activity.create!(user: current_user, site: @site, subject: @content, event_name: 'create')
28
30
  associate_files(@content, :images)
29
31
  associate_files(@content, :attachments)
30
32
  end
31
33
  rescue ActiveRecord::RecordInvalid
34
+ Rails.logger.info "Errors: #{@content.errors.full_messages.inspect}"
32
35
  success = nil
33
36
  end
34
37
 
@@ -62,6 +65,7 @@ module Cas
62
65
  success = @content.update!(content_params)
63
66
  associate_files(@content, :images)
64
67
  associate_files(@content, :attachments)
68
+ ::Cas::Activity.create!(user: current_user, site: @site, subject: @content, event_name: 'update')
65
69
  end
66
70
  rescue ActiveRecord::RecordInvalid
67
71
  success = nil
@@ -90,6 +94,13 @@ module Cas
90
94
 
91
95
  def content_params
92
96
  @content_params ||= begin
97
+ # When no file is uploaded, when the content form is submitted the
98
+ # `file` input ends up being sent empty (e.g file: [""]). This confuses
99
+ # Rails.
100
+ if params[:content][:file].present?
101
+ params[:content].delete(:file) if params[:content][:file].map(&:presence)&.compact.blank?
102
+ end
103
+
93
104
  result = params.require(:content).permit(
94
105
  :category_id,
95
106
  :title,
@@ -100,7 +111,8 @@ module Cas
100
111
  :text,
101
112
  :url,
102
113
  :embedded,
103
- :tag_list
114
+ :tag_list,
115
+ :file
104
116
  )
105
117
 
106
118
  unless result.keys.map(&:to_sym).include?(:published)
@@ -36,7 +36,7 @@ module Cas
36
36
  without_password = user_params.except(:password, :password_confirmation)
37
37
  success = @user.update_without_password(without_password)
38
38
  else
39
- success = @user.update_attributes(user_params)
39
+ success = @user.update(user_params)
40
40
  end
41
41
 
42
42
  if success
@@ -3,8 +3,11 @@ module Cas
3
3
  class DeleteJob
4
4
  include ::Sidekiq::Worker
5
5
 
6
- def perform(data)
7
- ::Shrine::Attacher.delete(data)
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
- def perform(data)
7
- ::Shrine::Attacher.promote(data)
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
@@ -0,0 +1,30 @@
1
+ module Cas
2
+ class Activity < ApplicationRecord
3
+ belongs_to :site
4
+ belongs_to :user, optional: true
5
+ belongs_to :subject, polymorphic: true
6
+
7
+ # To prevent losing data in case the subject is ever destroyed
8
+ before_validation :cache_description
9
+
10
+ private
11
+
12
+ def cache_description
13
+ if self.user_description.blank?
14
+ user_string = [user.name]
15
+ user_string << ["(admin)"] if user.admin?
16
+ self.user_description = user_string.join(" ")
17
+ end
18
+
19
+ if self.subject_description.blank?
20
+ subject_string = []
21
+ if subject.respond_to?(:title)
22
+ subject_string << [subject.title]
23
+ elsif subject.respond_to?(:name)
24
+ subject_string << [subject.name]
25
+ end
26
+ self.subject_description = subject_string.join(" ")
27
+ end
28
+ end
29
+ end
30
+ end
@@ -9,12 +9,21 @@ module Cas
9
9
  serialize :metadata
10
10
 
11
11
  belongs_to :section
12
+ belongs_to :category, optional: true
13
+ belongs_to :author, class_name: "::Cas::User"
14
+
15
+ has_many :images,
16
+ ->{ where(media_type: :image).order("cas_media_files.order ASC") },
17
+ class_name: "::Cas::MediaFile", as: :attachable, dependent: :destroy
18
+ has_many :attachments,
19
+ ->{ where(media_type: :attachment).order("cas_media_files.order ASC") },
20
+ class_name: "::Cas::MediaFile", as: :attachable, dependent: :destroy
21
+ has_many :activities, as: :subject
22
+
12
23
  has_one :site, through: :section
13
- belongs_to :category
14
- belongs_to :author, class_name: Cas::User
15
- has_many :images, ->{ where(media_type: :image).order("cas_media_files.order ASC") }, class_name: Cas::MediaFile, as: :attachable, dependent: :destroy
16
- has_many :attachments, ->{ where(media_type: :attachment).order("cas_media_files.order ASC") }, class_name: Cas::MediaFile, as: :attachable, dependent: :destroy
17
- has_one :cover_image, ->{ where(media_type: :image, cover: true) }, class_name: Cas::MediaFile, as: :attachable
24
+ has_one :cover_image,
25
+ ->{ where(media_type: :image, cover: true) },
26
+ class_name: "::Cas::MediaFile", as: :attachable
18
27
 
19
28
  validates :title, presence: true
20
29
 
@@ -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
- if cdn.present?
45
- file_url(version.to_sym, host: cdn, public: true)
46
- else
47
- file_url(version.to_sym, public: true).gsub(/\?.*/, "")
48
- end
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
@@ -2,6 +2,6 @@ module Cas
2
2
  class SitesUser < ApplicationRecord
3
3
  belongs_to :site
4
4
  belongs_to :user
5
- belongs_to :owner, class_name: '::Cas::User'
5
+ belongs_to :owner, class_name: '::Cas::User', optional: true
6
6
  end
7
7
  end
@@ -6,9 +6,10 @@ module Cas
6
6
  :rememberable, :trackable, :validatable, request_keys: [:domain]
7
7
 
8
8
  has_many :contents
9
- has_many :files, class_name: 'Cas::MediaFile', as: :attachable
10
- has_many :sites_users, class_name: 'Cas::SitesUser'
9
+ has_many :files, class_name: '::Cas::MediaFile', as: :attachable
10
+ has_many :sites_users, class_name: '::Cas::SitesUser'
11
11
  has_many :sites, through: :sites_users
12
+ has_many :activities, as: :subject
12
13
 
13
14
  validates :name, presence: true, length: { maximum: 50 }
14
15
  validates :email, presence: true, length: { maximum: 255 },
@@ -1,19 +1,18 @@
1
1
  class ::FileUploader < Shrine
2
- plugin :versions
3
- plugin :processing
4
2
 
5
- process(:store) do |io, context|
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(io, context)
8
+ result = Cas::RemoteCallbacks.callbacks[:uploaded_image_versions].call(original)
9
9
  end
10
- original = (io.respond_to?(:[]) && io[:original]) ? io[:original] : io
11
- result = result.merge(original: original) unless result.keys.include?(:original)
10
+
11
+ Rails.logger.info "FileUploader, versions: [#{result.keys.join(", ")}]"
12
12
  result
13
13
  end
14
14
 
15
15
  def generate_location(io, context)
16
- Rails.logger.info "FileUploader#generate_location"
17
16
  year = Time.now.strftime("%Y")
18
17
  month = Time.now.strftime("%m")
19
18
  original_filename = context[:metadata]["filename"]