comfortable_media_surfer 3.1.6 → 3.2.0

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.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/claude-code-review.yml +2 -0
  3. data/.github/workflows/claude.yml +99 -1
  4. data/.github/workflows/coveralls.yml +4 -3
  5. data/.github/workflows/rubyonrails.yml +34 -5
  6. data/CHANGELOG.md +27 -5
  7. data/CONTRIBUTING.md +5 -1
  8. data/Gemfile +6 -5
  9. data/README.md +4 -4
  10. data/Rakefile +201 -0
  11. data/app/assets/javascripts/comfy/admin/cms/application.js +3 -0
  12. data/app/assets/javascripts/comfy/admin/cms/base.js +1 -0
  13. data/app/assets/javascripts/comfy/admin/cms/file_link.js +34 -11
  14. data/app/assets/javascripts/comfy/admin/cms/file_upload.js +37 -28
  15. data/app/assets/javascripts/comfy/admin/cms/files_modal.js +76 -26
  16. data/app/controllers/comfy/admin/cms/categories_controller.rb +1 -1
  17. data/app/controllers/comfy/admin/cms/files_controller.rb +1 -1
  18. data/app/controllers/comfy/admin/cms/layouts_controller.rb +1 -1
  19. data/app/controllers/comfy/admin/cms/pages_controller.rb +33 -4
  20. data/app/controllers/comfy/admin/cms/revisions/base_controller.rb +2 -2
  21. data/app/controllers/comfy/admin/cms/revisions/page_controller.rb +5 -5
  22. data/app/controllers/comfy/admin/cms/revisions/translation_controller.rb +5 -5
  23. data/app/controllers/comfy/admin/cms/sites_controller.rb +3 -3
  24. data/app/controllers/comfy/admin/cms/snippets_controller.rb +1 -1
  25. data/app/controllers/comfy/admin/cms/translations_controller.rb +15 -3
  26. data/app/controllers/comfy/cms/base_controller.rb +16 -7
  27. data/app/controllers/comfy/cms/content_controller.rb +4 -4
  28. data/app/controllers/concerns/comfy/reorder_action.rb +3 -4
  29. data/app/models/comfy/cms/categorization.rb +9 -0
  30. data/app/models/comfy/cms/category.rb +1 -1
  31. data/app/models/comfy/cms/fragment.rb +7 -0
  32. data/app/models/comfy/cms/layout.rb +7 -2
  33. data/app/models/comfy/cms/page.rb +13 -4
  34. data/app/models/comfy/cms/site.rb +3 -3
  35. data/app/models/comfy/cms/translation.rb +5 -0
  36. data/app/models/concerns/comfy/cms/with_categories.rb +1 -1
  37. data/app/models/concerns/comfy/cms/with_fragments.rb +1 -1
  38. data/app/views/comfy/admin/cms/pages/edit.html.haml +5 -1
  39. data/config/database.yml +1 -1
  40. data/config/initializers/json.rb +2 -0
  41. data/config/locales/ar.yml +6 -0
  42. data/config/locales/ca.yml +6 -0
  43. data/config/locales/cs.yml +6 -0
  44. data/config/locales/da.yml +6 -0
  45. data/config/locales/de.yml +6 -0
  46. data/config/locales/en.yml +6 -0
  47. data/config/locales/es.yml +6 -0
  48. data/config/locales/fi.yml +6 -0
  49. data/config/locales/fr.yml +6 -0
  50. data/config/locales/gr.yml +6 -0
  51. data/config/locales/hr.yml +6 -0
  52. data/config/locales/it.yml +6 -0
  53. data/config/locales/ja.yml +6 -0
  54. data/config/locales/nb.yml +6 -0
  55. data/config/locales/nl.yml +6 -0
  56. data/config/locales/pl.yml +6 -0
  57. data/config/locales/pt-BR.yml +6 -0
  58. data/config/locales/ru.yml +6 -0
  59. data/config/locales/sk.yml +6 -0
  60. data/config/locales/sv.yml +6 -0
  61. data/config/locales/tr.yml +6 -0
  62. data/config/locales/uk.yml +6 -0
  63. data/config/locales/zh-CN.yml +6 -0
  64. data/config/locales/zh-TW.yml +6 -0
  65. data/config/storage.yml +1 -1
  66. data/gemfiles/7.2.gemfile +1 -0
  67. data/gemfiles/8.0.gemfile +1 -0
  68. data/gemfiles/8.1.gemfile +1 -0
  69. data/lib/comfortable_media_surfer/access_control/admin_authentication.rb +2 -2
  70. data/lib/comfortable_media_surfer/content/tags/date.rb +1 -1
  71. data/lib/comfortable_media_surfer/content/tags/datetime.rb +1 -1
  72. data/lib/comfortable_media_surfer/extensions/has_revisions.rb +2 -2
  73. data/lib/comfortable_media_surfer/routing.rb +2 -0
  74. data/lib/comfortable_media_surfer/seeds/page/importer.rb +40 -12
  75. data/lib/comfortable_media_surfer/seeds.rb +1 -3
  76. data/lib/comfortable_media_surfer/version.rb +1 -1
  77. metadata +2 -3
  78. data/gemfiles/7.1.gemfile +0 -35
@@ -120,6 +120,8 @@ zh-CN:
120
120
  creation_failure: 页面创建失败
121
121
  updated: 页面更新成功
122
122
  update_failure: 页面更新失败
123
+ children_published: 子页面已发布
124
+ children_unpublished: 子页面已取消发布
123
125
  deleted: 页面删除成功
124
126
  not_found: 页面不存在
125
127
  layout_not_found: 没有布局,请先创建一个布局。
@@ -137,6 +139,10 @@ zh-CN:
137
139
  title: 新页面
138
140
  edit:
139
141
  title: 编辑页面
142
+ publish_children: 发布子页面
143
+ publish_children_confirmation: 发布所有子页面?
144
+ unpublish_children: 取消发布子页面
145
+ unpublish_children_confirmation: 取消发布所有子页面?
140
146
  form:
141
147
  select_target_page: 没有跳转
142
148
  preview: 预览
@@ -120,6 +120,8 @@ zh-TW:
120
120
  creation_failure: 頁面創建失敗
121
121
  updated: 頁面更新成功
122
122
  update_failure: 頁面更新失敗
123
+ children_published: 子頁面已發佈
124
+ children_unpublished: 子頁面已取消發佈
123
125
  deleted: 頁面刪除成功
124
126
  not_found: 頁面不存在
125
127
  layout_not_found: 沒有佈局,請先創建一個佈局。
@@ -137,6 +139,10 @@ zh-TW:
137
139
  title: 新頁面
138
140
  edit:
139
141
  title: 編輯頁面
142
+ publish_children: 發佈子頁面
143
+ publish_children_confirmation: 發佈所有子頁面?
144
+ unpublish_children: 取消發佈子頁面
145
+ unpublish_children_confirmation: 取消發佈所有子頁面?
140
146
  form:
141
147
  select_target_page: 沒有跳轉
142
148
  preview: 預覽
data/config/storage.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  test:
2
2
  service: Disk
3
- root: <%= Rails.root.join("tmp/storage") %>
3
+ root: <%= Rails.root.join("tmp/storage#{ENV.fetch('TEST_ENV_NUMBER', nil)}") %>
4
4
 
5
5
  local:
6
6
  service: Disk
data/gemfiles/7.2.gemfile CHANGED
@@ -26,6 +26,7 @@ group :test do
26
26
  gem 'minitest-reporters', '>= 1.6.1'
27
27
  gem 'mocha', '>= 2.3.0', require: false
28
28
  gem 'ostruct'
29
+ gem 'parallel_tests', '~> 5.7', require: false
29
30
  gem 'puma'
30
31
  gem 'rails-controller-testing', '~> 1.0.5'
31
32
  gem 'rubocop', '~> 1.81.1', require: false
data/gemfiles/8.0.gemfile CHANGED
@@ -26,6 +26,7 @@ group :test do
26
26
  gem 'minitest-reporters', '>= 1.6.1'
27
27
  gem 'mocha', '>= 2.3.0', require: false
28
28
  gem 'ostruct'
29
+ gem 'parallel_tests', '~> 5.7', require: false
29
30
  gem 'puma'
30
31
  gem 'rails-controller-testing', '~> 1.0.5'
31
32
  gem 'rubocop', '~> 1.81.1', require: false
data/gemfiles/8.1.gemfile CHANGED
@@ -26,6 +26,7 @@ group :test do
26
26
  gem 'minitest-reporters', '>= 1.6.1'
27
27
  gem 'mocha', '>= 2.3.0', require: false
28
28
  gem 'ostruct'
29
+ gem 'parallel_tests', '~> 5.7', require: false
29
30
  gem 'puma'
30
31
  gem 'rails-controller-testing', '~> 1.0.5'
31
32
  gem 'rubocop', '~> 1.81.1', require: false
@@ -7,8 +7,8 @@ module ComfortableMediaSurfer::AccessControl
7
7
  # ComfortableMediaSurfer::AccessControl::AdminAuthentication.username = 'myname'
8
8
  # ComfortableMediaSurfer::AccessControl::AdminAuthentication.password = 'mypassword'
9
9
 
10
- mattr_accessor :username,
11
- :password
10
+ mattr_accessor :username,
11
+ :password
12
12
 
13
13
  # Simple http_auth. When implementing some other form of authentication
14
14
  # this method should return +true+ if everything is great, or redirect user
@@ -7,7 +7,7 @@ class ComfortableMediaSurfer::Content::Tags::Date < ComfortableMediaSurfer::Cont
7
7
  def form_field(object_name, view, index)
8
8
  name = "#{object_name}[fragments_attributes][#{index}][datetime]"
9
9
  options = { id: form_field_id, class: 'form-control', data: { 'cms-date' => true } }
10
- value = content.present? ? content.to_s(:db) : ''
10
+ value = content.present? ? content.to_fs(:db) : ''
11
11
  input = view.send(:text_field_tag, name, value, options)
12
12
 
13
13
  yield input
@@ -30,7 +30,7 @@ class ComfortableMediaSurfer::Content::Tags::Datetime < ComfortableMediaSurfer::
30
30
  def form_field(object_name, view, index)
31
31
  name = "#{object_name}[fragments_attributes][#{index}][datetime]"
32
32
  options = { id: form_field_id, class: 'form-control', data: { 'cms-datetime' => true } }
33
- value = content.present? ? content.to_s(:db) : ''
33
+ value = content.present? ? content.to_fs(:db) : ''
34
34
  input = view.send(:text_field_tag, name, value, options)
35
35
 
36
36
  yield input
@@ -32,8 +32,8 @@ module ComfortableMediaSurfer::Extensions::HasRevisions
32
32
 
33
33
  if (respond_to?(:fragments_attributes_changed) && fragments_attributes_changed) ||
34
34
  !!changed.intersect?(revision_fields)
35
- self.revision_data = revision_fields.each_with_object({}) do |field, c|
36
- c[field] = send("#{field}_was")
35
+ self.revision_data = revision_fields.to_h do |field|
36
+ [field, send("#{field}_was")]
37
37
  end
38
38
  end
39
39
  end
@@ -35,6 +35,8 @@ module ComfortableMediaSurfer::Routing
35
35
  concerns :with_revisions, controller: 'revisions/page'
36
36
 
37
37
  get :toggle_branch, on: :member
38
+ patch :publish_children, on: :member
39
+ patch :unpublish_children, on: :member
38
40
 
39
41
  resources :translations, except: [:index] do
40
42
  concerns :with_form_fragments
@@ -63,16 +63,21 @@ module ComfortableMediaSurfer::Seeds::Page
63
63
 
64
64
  new_frag_identifiers, fragments_attributes =
65
65
  construct_fragments_attributes(fragments_hash, page, path)
66
- page.fragments_attributes = fragments_attributes
66
+ page_saved = begin
67
+ page.fragments_attributes = fragments_attributes
68
+ page.save
69
+ ensure
70
+ close_fragment_files(fragments_attributes)
71
+ end
67
72
 
68
- if page.save
73
+ if page_saved
69
74
  message = "[CMS SEEDS] Imported Page \t #{page.full_path}"
70
75
  ComfortableMediaSurfer.logger.info(message)
71
76
 
72
77
  # defering target page linking
73
78
  if target_page.present?
74
79
  self.target_pages ||= {}
75
- self.target_pages[page.id] = target_page
80
+ target_pages[page.id] = target_page
76
81
  end
77
82
 
78
83
  # cleaning up old fragments
@@ -127,9 +132,14 @@ module ComfortableMediaSurfer::Seeds::Page
127
132
 
128
133
  new_frag_identifiers, fragments_attributes =
129
134
  construct_fragments_attributes(fragments_hash, translation, path)
130
- translation.fragments_attributes = fragments_attributes
135
+ translation_saved = begin
136
+ translation.fragments_attributes = fragments_attributes
137
+ translation.save
138
+ ensure
139
+ close_fragment_files(fragments_attributes)
140
+ end
131
141
 
132
- if translation.save
142
+ if translation_saved
133
143
  message = "[CMS SEEDS] Imported Translation \t #{locale}"
134
144
  ComfortableMediaSurfer.logger.info(message)
135
145
 
@@ -186,13 +196,15 @@ module ComfortableMediaSurfer::Seeds::Page
186
196
  # ActiveStorage and a list of ids of old attachements to destroy
187
197
  def files_content(record, identifier, path, frag_content)
188
198
  # preparing attachments
189
- files = frag_content.split("\n").collect do |filename|
190
- file_handler = File.open(File.join(path, filename))
191
- {
199
+ files = []
200
+ frag_content.split("\n").each do |filename|
201
+ file_handler = File.new(File.join(path, filename), 'rb')
202
+ attachment = {
192
203
  io: file_handler,
193
- filename: filename,
194
- content_type: MimeMagic.by_magic(file_handler)
204
+ filename: filename
195
205
  }
206
+ files << attachment
207
+ attachment[:content_type] = MimeMagic.by_magic(file_handler)
196
208
  end
197
209
 
198
210
  # ensuring that old attachments get removed
@@ -202,12 +214,28 @@ module ComfortableMediaSurfer::Seeds::Page
202
214
  end
203
215
 
204
216
  [files, ids_destroy]
217
+ rescue StandardError
218
+ close_files(files)
219
+ raise
220
+ end
221
+
222
+ def close_fragment_files(fragment_attributes)
223
+ fragment_attributes.each do |attributes|
224
+ close_files(attributes[:files])
225
+ end
226
+ end
227
+
228
+ def close_files(files)
229
+ Array(files).each do |file|
230
+ io = file[:io]
231
+ io.close unless io.closed?
232
+ end
205
233
  end
206
234
 
207
235
  def link_target_pages
208
- return unless self.target_pages.present?
236
+ return unless target_pages.present?
209
237
 
210
- self.target_pages.each do |page_id, target|
238
+ target_pages.each do |page_id, target|
211
239
  if (target = site.pages.find_by(full_path: target))
212
240
  @site.pages.find(page_id).update_column(:target_page_id, target.id)
213
241
  end
@@ -46,9 +46,7 @@ module ComfortableMediaSurfer::Seeds
46
46
  text = ::File.read(file_path)
47
47
  tokens = text.split(%r{^\[(.*?)\]\r?\n})
48
48
  tokens.shift # first item should be blank
49
- tokens.in_groups_of(2).each_with_object({}) do |pair, h|
50
- h[pair[0]] = pair[1]
51
- end
49
+ tokens.in_groups_of(2).to_h
52
50
  end
53
51
 
54
52
  def fresh_seed?(object, file_path)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ComfortableMediaSurfer
4
- VERSION = '3.1.6'
4
+ VERSION = '3.2.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: comfortable_media_surfer
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.6
4
+ version: 3.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oleg Khabarov
@@ -556,7 +556,6 @@ files:
556
556
  - db/migrate/00_create_active_storage_tables.active_storage.rb
557
557
  - db/migrate/01_create_cms.rb
558
558
  - db/migrate/02_add_markdown_to_snippets.rb
559
- - gemfiles/7.1.gemfile
560
559
  - gemfiles/7.2.gemfile
561
560
  - gemfiles/8.0.gemfile
562
561
  - gemfiles/8.1.gemfile
@@ -659,7 +658,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
659
658
  - !ruby/object:Gem::Version
660
659
  version: '0'
661
660
  requirements: []
662
- rubygems_version: 3.7.2
661
+ rubygems_version: 4.0.18
663
662
  specification_version: 4
664
663
  summary: Rails 7.0+ CMS Engine
665
664
  test_files: []
data/gemfiles/7.1.gemfile DELETED
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- source 'https://rubygems.org'
4
- git_source(:github) { |repo| "https://github.com/#{repo}.git" }
5
-
6
- gemspec path: '../'
7
-
8
- gem 'rails', '~> 7.1.0', '>= 7.1.5.1'
9
-
10
- group :development, :test do
11
- gem 'autoprefixer-rails', '~> 10.4.16.0'
12
- gem 'byebug', '~> 11.1.0', platforms: %i[mri mingw x64_mingw]
13
- gem 'image_processing', '>= 1.12.0'
14
- gem 'propshaft', '~> 1.1.0'
15
- gem 'sqlite3', '>= 2.1'
16
- end
17
-
18
- group :test do
19
- gem 'brakeman', '~> 7.1.0'
20
- gem 'bundler-audit', '~> 0.9.1'
21
- gem 'coveralls_reborn', '~> 0.29.0', require: false
22
- gem 'cuprite', '>= 0.15'
23
- gem 'diffy'
24
- gem 'equivalent-xml', '~> 0.6.0'
25
- gem 'minitest', '< 6.0.0'
26
- gem 'minitest-reporters', '>= 1.6.1'
27
- gem 'mocha', '>= 2.3.0', require: false
28
- gem 'ostruct'
29
- gem 'puma'
30
- gem 'rails-controller-testing', '~> 1.0.5'
31
- gem 'rubocop', '~> 1.81.1', require: false
32
- gem 'rubocop-minitest'
33
- gem 'rubocop-rails'
34
- gem 'simplecov', '~> 0.22.0', require: false
35
- end