iron-cms 0.5.2 → 0.7.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.
- checksums.yaml +4 -4
- data/app/assets/builds/iron.css +682 -388
- data/app/assets/tailwind/iron/application.css +1 -0
- data/app/assets/tailwind/iron/components/button.css +0 -7
- data/app/assets/tailwind/iron/components/checkbox.css +21 -0
- data/app/assets/tailwind/iron/components/form.css +1 -1
- data/app/assets/tailwind/iron/lexxy.css +165 -51
- data/app/controllers/iron/account/exports_controller.rb +26 -0
- data/app/controllers/iron/account/imports_controller.rb +27 -0
- data/app/helpers/iron/form_builder.rb +7 -0
- data/app/javascript/iron/controllers/local_preference_controller.js +62 -0
- data/app/jobs/iron/export_job.rb +9 -0
- data/app/jobs/iron/import_job.rb +9 -0
- data/app/models/concerns/iron/broadcastable.rb +9 -0
- data/app/models/concerns/iron/processable.rb +34 -0
- data/app/models/iron/account/export.rb +86 -0
- data/app/models/iron/account/import.rb +208 -0
- data/app/models/iron/block_definition/exportable.rb +14 -0
- data/app/models/iron/block_definition/importable.rb +27 -0
- data/app/models/iron/block_definition.rb +1 -1
- data/app/models/iron/content_type/exportable.rb +20 -0
- data/app/models/iron/content_type/importable.rb +32 -0
- data/app/models/iron/content_type.rb +1 -1
- data/app/models/iron/current.rb +6 -3
- data/app/models/iron/entry/exportable.rb +49 -0
- data/app/models/iron/entry/importable.rb +181 -0
- data/app/models/iron/entry.rb +1 -1
- data/app/models/iron/field.rb +9 -1
- data/app/models/iron/field_definition/exportable.rb +23 -0
- data/app/models/iron/field_definition/importable.rb +39 -0
- data/app/models/iron/field_definition.rb +1 -1
- data/app/models/iron/fields/block.rb +34 -0
- data/app/models/iron/fields/block_list.rb +8 -0
- data/app/models/iron/fields/boolean.rb +4 -0
- data/app/models/iron/fields/date.rb +4 -0
- data/app/models/iron/fields/file.rb +16 -0
- data/app/models/iron/fields/number.rb +4 -0
- data/app/models/iron/fields/reference.rb +4 -0
- data/app/models/iron/fields/reference_list.rb +4 -0
- data/app/models/iron/fields/rich_text_area.rb +32 -0
- data/app/models/iron/fields/text_area.rb +4 -0
- data/app/models/iron/fields/text_field.rb +4 -0
- data/app/models/iron/user.rb +2 -0
- data/app/views/iron/account/exports/index.html.erb +43 -0
- data/app/views/iron/account/exports/new.html.erb +39 -0
- data/app/views/iron/account/exports/show.html.erb +40 -0
- data/app/views/iron/account/imports/index.html.erb +43 -0
- data/app/views/iron/account/imports/new.html.erb +52 -0
- data/app/views/iron/account/imports/show.html.erb +37 -0
- data/app/views/iron/content_types/index.html.erb +1 -8
- data/app/views/iron/entries/fields/_block.html.erb +23 -10
- data/app/views/iron/entries/fields/_file.html.erb +3 -3
- data/app/views/iron/settings/show.html.erb +4 -11
- data/app/views/layouts/iron/application.html.erb +14 -0
- data/config/routes.rb +3 -9
- data/db/migrate/20251209103109_create_iron_account_exports.rb +13 -0
- data/db/migrate/20251209103110_create_iron_account_imports.rb +13 -0
- data/lib/iron/version.rb +1 -1
- data/lib/iron.rb +1 -1
- metadata +41 -28
- data/app/controllers/iron/contents_controller.rb +0 -33
- data/app/controllers/iron/schemas_controller.rb +0 -32
- data/app/models/concerns/iron/csv_serializable.rb +0 -28
- data/app/models/iron/archive.rb +0 -69
- data/app/models/iron/block_definition/portable.rb +0 -20
- data/app/models/iron/content_export.rb +0 -73
- data/app/models/iron/content_import/entry_builder.rb +0 -80
- data/app/models/iron/content_import/entry_snapshot.rb +0 -23
- data/app/models/iron/content_import/field_reconstructor.rb +0 -276
- data/app/models/iron/content_import/field_snapshot.rb +0 -33
- data/app/models/iron/content_import/registry.rb +0 -32
- data/app/models/iron/content_import/session.rb +0 -89
- data/app/models/iron/content_import.rb +0 -15
- data/app/models/iron/content_type/portable.rb +0 -30
- data/app/models/iron/entry/portable.rb +0 -35
- data/app/models/iron/field/portable.rb +0 -33
- data/app/models/iron/field_definition/portable.rb +0 -42
- data/app/models/iron/schema_archive.rb +0 -71
- data/app/models/iron/schema_exporter.rb +0 -15
- data/app/models/iron/schema_importer/import_strategy.rb +0 -59
- data/app/models/iron/schema_importer/merge_strategy.rb +0 -52
- data/app/models/iron/schema_importer/replace_strategy.rb +0 -51
- data/app/models/iron/schema_importer/safe_strategy.rb +0 -55
- data/app/models/iron/schema_importer.rb +0 -108
- data/app/views/iron/contents/new.html.erb +0 -34
- data/app/views/iron/schemas/new.html.erb +0 -57
- data/lib/iron/test_fixtures.rb +0 -50
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
class CreateIronAccountExports < ActiveRecord::Migration[8.1]
|
|
2
|
+
def change
|
|
3
|
+
create_table :iron_account_exports do |t|
|
|
4
|
+
t.references :user, null: false, foreign_key: { to_table: :iron_users }
|
|
5
|
+
t.string :status, default: "pending", null: false
|
|
6
|
+
t.boolean :include_schema, default: true, null: false
|
|
7
|
+
t.boolean :include_content, default: true, null: false
|
|
8
|
+
t.datetime :completed_at
|
|
9
|
+
t.string :error_message
|
|
10
|
+
t.timestamps
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
class CreateIronAccountImports < ActiveRecord::Migration[8.1]
|
|
2
|
+
def change
|
|
3
|
+
create_table :iron_account_imports do |t|
|
|
4
|
+
t.references :user, null: false, foreign_key: { to_table: :iron_users }
|
|
5
|
+
t.string :status, default: "pending", null: false
|
|
6
|
+
t.boolean :include_schema, default: true, null: false
|
|
7
|
+
t.boolean :include_content, default: true, null: false
|
|
8
|
+
t.datetime :completed_at
|
|
9
|
+
t.string :error_message
|
|
10
|
+
t.timestamps
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
data/lib/iron/version.rb
CHANGED
data/lib/iron.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: iron-cms
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Massimo De Marchi
|
|
@@ -177,6 +177,20 @@ dependencies:
|
|
|
177
177
|
- - "~>"
|
|
178
178
|
- !ruby/object:Gem::Version
|
|
179
179
|
version: '3.3'
|
|
180
|
+
- !ruby/object:Gem::Dependency
|
|
181
|
+
name: rubyzip
|
|
182
|
+
requirement: !ruby/object:Gem::Requirement
|
|
183
|
+
requirements:
|
|
184
|
+
- - "~>"
|
|
185
|
+
- !ruby/object:Gem::Version
|
|
186
|
+
version: '2.3'
|
|
187
|
+
type: :runtime
|
|
188
|
+
prerelease: false
|
|
189
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
190
|
+
requirements:
|
|
191
|
+
- - "~>"
|
|
192
|
+
- !ruby/object:Gem::Version
|
|
193
|
+
version: '2.3'
|
|
180
194
|
description: A Rails engine for managing and publishing content with a flexible schema.
|
|
181
195
|
email:
|
|
182
196
|
- massimo@inkofpixel.com
|
|
@@ -193,6 +207,7 @@ files:
|
|
|
193
207
|
- app/assets/tailwind/iron/application.css
|
|
194
208
|
- app/assets/tailwind/iron/components/badge.css
|
|
195
209
|
- app/assets/tailwind/iron/components/button.css
|
|
210
|
+
- app/assets/tailwind/iron/components/checkbox.css
|
|
196
211
|
- app/assets/tailwind/iron/components/dropdown.css
|
|
197
212
|
- app/assets/tailwind/iron/components/fieldset.css
|
|
198
213
|
- app/assets/tailwind/iron/components/form.css
|
|
@@ -206,13 +221,14 @@ files:
|
|
|
206
221
|
- app/controllers/concerns/iron/authorization.rb
|
|
207
222
|
- app/controllers/concerns/iron/locale_aware.rb
|
|
208
223
|
- app/controllers/concerns/iron/web_page.rb
|
|
224
|
+
- app/controllers/iron/account/exports_controller.rb
|
|
225
|
+
- app/controllers/iron/account/imports_controller.rb
|
|
209
226
|
- app/controllers/iron/application_controller.rb
|
|
210
227
|
- app/controllers/iron/block_definitions/field_definitions_controller.rb
|
|
211
228
|
- app/controllers/iron/block_definitions_controller.rb
|
|
212
229
|
- app/controllers/iron/blocks_controller.rb
|
|
213
230
|
- app/controllers/iron/content_types/field_definitions_controller.rb
|
|
214
231
|
- app/controllers/iron/content_types_controller.rb
|
|
215
|
-
- app/controllers/iron/contents_controller.rb
|
|
216
232
|
- app/controllers/iron/entries_controller.rb
|
|
217
233
|
- app/controllers/iron/field_definitions_controller.rb
|
|
218
234
|
- app/controllers/iron/first_runs_controller.rb
|
|
@@ -221,7 +237,6 @@ files:
|
|
|
221
237
|
- app/controllers/iron/locales_controller.rb
|
|
222
238
|
- app/controllers/iron/passwords_controller.rb
|
|
223
239
|
- app/controllers/iron/references_controller.rb
|
|
224
|
-
- app/controllers/iron/schemas_controller.rb
|
|
225
240
|
- app/controllers/iron/sessions_controller.rb
|
|
226
241
|
- app/controllers/iron/settings_controller.rb
|
|
227
242
|
- app/controllers/iron/users_controller.rb
|
|
@@ -242,32 +257,31 @@ files:
|
|
|
242
257
|
- app/javascript/iron/controllers/handle_controller.js
|
|
243
258
|
- app/javascript/iron/controllers/icon_picker_controller.js
|
|
244
259
|
- app/javascript/iron/controllers/index.js
|
|
260
|
+
- app/javascript/iron/controllers/local_preference_controller.js
|
|
245
261
|
- app/javascript/iron/controllers/sortable_list_controller.js
|
|
246
262
|
- app/javascript/iron/controllers/toggle_controller.js
|
|
247
263
|
- app/javascript/iron/lib/lexorank.js
|
|
248
264
|
- app/jobs/iron/application_job.rb
|
|
265
|
+
- app/jobs/iron/export_job.rb
|
|
249
266
|
- app/jobs/iron/generate_entry_routes_job.rb
|
|
267
|
+
- app/jobs/iron/import_job.rb
|
|
250
268
|
- app/mailers/iron/application_mailer.rb
|
|
251
269
|
- app/mailers/passwords_mailer.rb
|
|
252
|
-
- app/models/concerns/iron/
|
|
270
|
+
- app/models/concerns/iron/broadcastable.rb
|
|
253
271
|
- app/models/concerns/iron/instance_scoped.rb
|
|
272
|
+
- app/models/concerns/iron/processable.rb
|
|
254
273
|
- app/models/iron/account.rb
|
|
274
|
+
- app/models/iron/account/export.rb
|
|
275
|
+
- app/models/iron/account/import.rb
|
|
255
276
|
- app/models/iron/account/joinable.rb
|
|
256
277
|
- app/models/iron/application_record.rb
|
|
257
|
-
- app/models/iron/archive.rb
|
|
258
278
|
- app/models/iron/block_definition.rb
|
|
259
|
-
- app/models/iron/block_definition/
|
|
260
|
-
- app/models/iron/
|
|
261
|
-
- app/models/iron/content_import.rb
|
|
262
|
-
- app/models/iron/content_import/entry_builder.rb
|
|
263
|
-
- app/models/iron/content_import/entry_snapshot.rb
|
|
264
|
-
- app/models/iron/content_import/field_reconstructor.rb
|
|
265
|
-
- app/models/iron/content_import/field_snapshot.rb
|
|
266
|
-
- app/models/iron/content_import/registry.rb
|
|
267
|
-
- app/models/iron/content_import/session.rb
|
|
279
|
+
- app/models/iron/block_definition/exportable.rb
|
|
280
|
+
- app/models/iron/block_definition/importable.rb
|
|
268
281
|
- app/models/iron/content_type.rb
|
|
282
|
+
- app/models/iron/content_type/exportable.rb
|
|
269
283
|
- app/models/iron/content_type/field_queryable.rb
|
|
270
|
-
- app/models/iron/content_type/
|
|
284
|
+
- app/models/iron/content_type/importable.rb
|
|
271
285
|
- app/models/iron/content_type/titlable.rb
|
|
272
286
|
- app/models/iron/content_type/web_publishable.rb
|
|
273
287
|
- app/models/iron/content_types/collection.rb
|
|
@@ -275,16 +289,17 @@ files:
|
|
|
275
289
|
- app/models/iron/current.rb
|
|
276
290
|
- app/models/iron/entry.rb
|
|
277
291
|
- app/models/iron/entry/deep_validation.rb
|
|
278
|
-
- app/models/iron/entry/
|
|
292
|
+
- app/models/iron/entry/exportable.rb
|
|
293
|
+
- app/models/iron/entry/importable.rb
|
|
279
294
|
- app/models/iron/entry/presentable.rb
|
|
280
295
|
- app/models/iron/entry/schemable.rb
|
|
281
296
|
- app/models/iron/entry/titlable.rb
|
|
282
297
|
- app/models/iron/entry/web_publishable.rb
|
|
283
298
|
- app/models/iron/field.rb
|
|
284
299
|
- app/models/iron/field/belongs_to_entry.rb
|
|
285
|
-
- app/models/iron/field/portable.rb
|
|
286
300
|
- app/models/iron/field_definition.rb
|
|
287
|
-
- app/models/iron/field_definition/
|
|
301
|
+
- app/models/iron/field_definition/exportable.rb
|
|
302
|
+
- app/models/iron/field_definition/importable.rb
|
|
288
303
|
- app/models/iron/field_definitions/block.rb
|
|
289
304
|
- app/models/iron/field_definitions/block_list.rb
|
|
290
305
|
- app/models/iron/field_definitions/boolean.rb
|
|
@@ -311,17 +326,16 @@ files:
|
|
|
311
326
|
- app/models/iron/icon_catalog.rb
|
|
312
327
|
- app/models/iron/locale.rb
|
|
313
328
|
- app/models/iron/reference.rb
|
|
314
|
-
- app/models/iron/schema_archive.rb
|
|
315
|
-
- app/models/iron/schema_exporter.rb
|
|
316
|
-
- app/models/iron/schema_importer.rb
|
|
317
|
-
- app/models/iron/schema_importer/import_strategy.rb
|
|
318
|
-
- app/models/iron/schema_importer/merge_strategy.rb
|
|
319
|
-
- app/models/iron/schema_importer/replace_strategy.rb
|
|
320
|
-
- app/models/iron/schema_importer/safe_strategy.rb
|
|
321
329
|
- app/models/iron/session.rb
|
|
322
330
|
- app/models/iron/user.rb
|
|
323
331
|
- app/models/iron/user/role.rb
|
|
324
332
|
- app/views/active_storage/blobs/_blob.html.erb
|
|
333
|
+
- app/views/iron/account/exports/index.html.erb
|
|
334
|
+
- app/views/iron/account/exports/new.html.erb
|
|
335
|
+
- app/views/iron/account/exports/show.html.erb
|
|
336
|
+
- app/views/iron/account/imports/index.html.erb
|
|
337
|
+
- app/views/iron/account/imports/new.html.erb
|
|
338
|
+
- app/views/iron/account/imports/show.html.erb
|
|
325
339
|
- app/views/iron/block_definitions/_block_definition.html.erb
|
|
326
340
|
- app/views/iron/block_definitions/_form.html.erb
|
|
327
341
|
- app/views/iron/block_definitions/edit.html.erb
|
|
@@ -335,7 +349,6 @@ files:
|
|
|
335
349
|
- app/views/iron/content_types/index.html.erb
|
|
336
350
|
- app/views/iron/content_types/new.html.erb
|
|
337
351
|
- app/views/iron/content_types/show.html.erb
|
|
338
|
-
- app/views/iron/contents/new.html.erb
|
|
339
352
|
- app/views/iron/entries/_entry.html.erb
|
|
340
353
|
- app/views/iron/entries/_entry_option.html.erb
|
|
341
354
|
- app/views/iron/entries/_form.html.erb
|
|
@@ -386,7 +399,6 @@ files:
|
|
|
386
399
|
- app/views/iron/passwords_mailer/reset.text.erb
|
|
387
400
|
- app/views/iron/published_pages/show.html.erb
|
|
388
401
|
- app/views/iron/references/new.turbo_stream.erb
|
|
389
|
-
- app/views/iron/schemas/new.html.erb
|
|
390
402
|
- app/views/iron/sessions/new.html.erb
|
|
391
403
|
- app/views/iron/settings/show.html.erb
|
|
392
404
|
- app/views/iron/shared/_icon_picker.html.erb
|
|
@@ -423,6 +435,8 @@ files:
|
|
|
423
435
|
- db/migrate/20250609091605_add_web_publishing_to_iron_content_types.rb
|
|
424
436
|
- db/migrate/20250609091813_add_route_to_iron_entries.rb
|
|
425
437
|
- db/migrate/20250908203158_add_instance_token_to_iron_accounts.rb
|
|
438
|
+
- db/migrate/20251209103109_create_iron_account_exports.rb
|
|
439
|
+
- db/migrate/20251209103110_create_iron_account_imports.rb
|
|
426
440
|
- lib/generators/iron/pages/pages_generator.rb
|
|
427
441
|
- lib/generators/iron/pages/templates/pages_controller.rb
|
|
428
442
|
- lib/generators/iron/pages/templates/show.html.erb
|
|
@@ -440,7 +454,6 @@ files:
|
|
|
440
454
|
- lib/iron/lexorank/utils.rb
|
|
441
455
|
- lib/iron/routing.rb
|
|
442
456
|
- lib/iron/sdk.rb
|
|
443
|
-
- lib/iron/test_fixtures.rb
|
|
444
457
|
- lib/iron/version.rb
|
|
445
458
|
- lib/puma/plugin/iron_tailwindcss.rb
|
|
446
459
|
- lib/tasks/iron_tailwindcss.rake
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
module Iron
|
|
2
|
-
class ContentsController < ApplicationController
|
|
3
|
-
before_action :ensure_can_administer
|
|
4
|
-
|
|
5
|
-
def export
|
|
6
|
-
send_data ContentExport.export.to_tar,
|
|
7
|
-
filename: "iron-content-#{Date.current}.tar",
|
|
8
|
-
type: "application/x-tar",
|
|
9
|
-
disposition: "attachment"
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def new
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def import
|
|
16
|
-
file = params[:content_file]
|
|
17
|
-
|
|
18
|
-
unless file.present?
|
|
19
|
-
redirect_to new_content_path, alert: "Please select a file to import"
|
|
20
|
-
return
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
archive = Archive.from_file(file)
|
|
24
|
-
result = ContentImport.import(archive)
|
|
25
|
-
|
|
26
|
-
if result.success?
|
|
27
|
-
redirect_to settings_path, notice: "Content imported successfully"
|
|
28
|
-
else
|
|
29
|
-
redirect_to new_content_path, alert: result.errors.join(". ")
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
module Iron
|
|
2
|
-
class SchemasController < ApplicationController
|
|
3
|
-
def export
|
|
4
|
-
send_data SchemaExporter.export,
|
|
5
|
-
filename: "iron-schema-#{Date.current}.tar",
|
|
6
|
-
type: "application/x-tar",
|
|
7
|
-
disposition: "attachment"
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def new
|
|
11
|
-
@import_modes = SchemaImporter::IMPORT_MODES
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def import
|
|
15
|
-
file = params[:schema_file]
|
|
16
|
-
mode = params[:import_mode]
|
|
17
|
-
|
|
18
|
-
unless file.present?
|
|
19
|
-
redirect_to schema_path, alert: "Please select a file to import"
|
|
20
|
-
return
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
result = SchemaImporter.import(file, mode:)
|
|
24
|
-
|
|
25
|
-
if result.success?
|
|
26
|
-
redirect_to content_types_path, notice: "Schema imported successfully"
|
|
27
|
-
else
|
|
28
|
-
redirect_to schema_path, alert: result.errors.join(". ")
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
module Iron
|
|
2
|
-
module CsvSerializable
|
|
3
|
-
extend ActiveSupport::Concern
|
|
4
|
-
|
|
5
|
-
class_methods do
|
|
6
|
-
def to_csv
|
|
7
|
-
CSV.generate do |csv|
|
|
8
|
-
csv << csv_headers
|
|
9
|
-
csv_scope.find_each do |record|
|
|
10
|
-
csv << record.to_csv_row
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def csv_headers
|
|
16
|
-
raise NotImplementedError, "#{name} must implement csv_headers"
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def csv_scope
|
|
20
|
-
all
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def to_csv_row
|
|
25
|
-
raise NotImplementedError, "#{self.class.name} must implement to_csv_row"
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
data/app/models/iron/archive.rb
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
require "rubygems/package"
|
|
2
|
-
require "stringio"
|
|
3
|
-
|
|
4
|
-
module Iron
|
|
5
|
-
class Archive
|
|
6
|
-
attr_reader :files
|
|
7
|
-
|
|
8
|
-
def initialize(tar_content = nil)
|
|
9
|
-
@files = {}
|
|
10
|
-
extract_from_tar(tar_content) if tar_content
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def self.from_file(file)
|
|
14
|
-
new(file.read)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def add_file(path, content)
|
|
18
|
-
@files[path] = content
|
|
19
|
-
self
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def [](path)
|
|
23
|
-
@files[path]
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def file_exists?(path)
|
|
27
|
-
@files.key?(path)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def file_paths
|
|
31
|
-
@files.keys
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def to_tar
|
|
35
|
-
tarfile = StringIO.new
|
|
36
|
-
|
|
37
|
-
Gem::Package::TarWriter.new(tarfile) do |tar|
|
|
38
|
-
@files.each do |path, content|
|
|
39
|
-
content_string = content.is_a?(StringIO) ? content.string : content.to_s
|
|
40
|
-
tar.add_file_simple(path, 0644, content_string.bytesize) do |io|
|
|
41
|
-
io.write(content_string)
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
tarfile.string
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def to_file(path)
|
|
50
|
-
File.open(path, "wb") { |f| f.write(to_tar) }
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
private
|
|
54
|
-
|
|
55
|
-
def extract_from_tar(tar_content)
|
|
56
|
-
tar_io = StringIO.new(tar_content)
|
|
57
|
-
|
|
58
|
-
Gem::Package::TarReader.new(tar_io) do |tar|
|
|
59
|
-
tar.each do |entry|
|
|
60
|
-
if entry.file?
|
|
61
|
-
@files[entry.full_name] = entry.read.force_encoding("UTF-8")
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
rescue => e
|
|
66
|
-
raise "Failed to extract tar archive: #{e.message}"
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
end
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
module Iron
|
|
2
|
-
module BlockDefinition::Portable
|
|
3
|
-
extend ActiveSupport::Concern
|
|
4
|
-
include ::Iron::CsvSerializable
|
|
5
|
-
|
|
6
|
-
class_methods do
|
|
7
|
-
def csv_headers
|
|
8
|
-
%w[handle name description]
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def to_csv_row
|
|
13
|
-
[
|
|
14
|
-
handle,
|
|
15
|
-
name,
|
|
16
|
-
description
|
|
17
|
-
]
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
require "csv"
|
|
2
|
-
|
|
3
|
-
module Iron
|
|
4
|
-
class ContentExport
|
|
5
|
-
def self.export
|
|
6
|
-
new.export
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
def initialize
|
|
10
|
-
@archive = Archive.new
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def export
|
|
14
|
-
export_entries_by_content_type
|
|
15
|
-
export_files
|
|
16
|
-
|
|
17
|
-
@archive
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
private
|
|
21
|
-
|
|
22
|
-
def export_entries_by_content_type
|
|
23
|
-
ContentType.find_each do |content_type|
|
|
24
|
-
next if content_type.entries.empty?
|
|
25
|
-
|
|
26
|
-
@archive.add_file("content/#{content_type.handle}.csv", csv_for(content_type))
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def csv_for(content_type)
|
|
31
|
-
CSV.generate do |csv|
|
|
32
|
-
csv << %w[entry_key locale path type value]
|
|
33
|
-
|
|
34
|
-
content_type.entries.find_each do |entry|
|
|
35
|
-
entry.to_csv_rows.each do |row|
|
|
36
|
-
csv << row
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def export_files
|
|
43
|
-
collect_blob_ids.each do |blob_id|
|
|
44
|
-
blob = ActiveStorage::Blob.find_by(id: blob_id)
|
|
45
|
-
next unless blob
|
|
46
|
-
|
|
47
|
-
begin
|
|
48
|
-
blob.open do |file|
|
|
49
|
-
@archive.add_file("uploads/#{blob_id}", file.read)
|
|
50
|
-
end
|
|
51
|
-
rescue => e
|
|
52
|
-
Rails.logger.warn "Failed to export blob #{blob_id}: #{e.message}"
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def collect_blob_ids
|
|
58
|
-
ids = Set.new
|
|
59
|
-
|
|
60
|
-
Fields::File.joins(file_attachment: :blob).pluck("active_storage_blobs.id").each do |id|
|
|
61
|
-
ids << id
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
ActionText::RichText.includes(:embeds_attachments).find_each do |rich_text|
|
|
65
|
-
rich_text.embeds_attachments.each do |attachment|
|
|
66
|
-
ids << attachment.blob.id if attachment.blob
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
ids
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
end
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
require "csv"
|
|
2
|
-
|
|
3
|
-
module Iron
|
|
4
|
-
class ContentImport::EntryBuilder
|
|
5
|
-
def initialize(content_type, registry)
|
|
6
|
-
@content_type = content_type
|
|
7
|
-
@registry = registry
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def ensure_entries_exist(csv_data)
|
|
11
|
-
entry_snapshots = parse_entry_snapshots(csv_data)
|
|
12
|
-
|
|
13
|
-
entry_snapshots.each do |_entry_gid, snapshot|
|
|
14
|
-
ensure_entry(snapshot)
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
private
|
|
19
|
-
|
|
20
|
-
def parse_entry_snapshots(csv_data)
|
|
21
|
-
snapshots = {}
|
|
22
|
-
return snapshots unless csv_data.present?
|
|
23
|
-
|
|
24
|
-
CSV.parse(csv_data, headers: true) do |row|
|
|
25
|
-
entry_key = row["entry_key"]
|
|
26
|
-
next if entry_key.blank?
|
|
27
|
-
|
|
28
|
-
snapshot = (snapshots[entry_key] ||= ContentImport::EntrySnapshot.new(entry_key))
|
|
29
|
-
add_row_to_snapshot(snapshot, row)
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
snapshots
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def add_row_to_snapshot(snapshot, row)
|
|
36
|
-
path = row["path"]
|
|
37
|
-
return if path.blank?
|
|
38
|
-
|
|
39
|
-
if path == "/route"
|
|
40
|
-
snapshot.add_route(row["value"])
|
|
41
|
-
elsif path.start_with?("/fields/")
|
|
42
|
-
locale_code = row["locale"]
|
|
43
|
-
return unless locale_code.present?
|
|
44
|
-
|
|
45
|
-
field_snapshot = ContentImport::FieldSnapshot.new(
|
|
46
|
-
locale_code: locale_code,
|
|
47
|
-
path: path,
|
|
48
|
-
value: row["value"]
|
|
49
|
-
)
|
|
50
|
-
snapshot.add_field_snapshot(field_snapshot)
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def ensure_entry(snapshot)
|
|
55
|
-
if snapshot.route.present?
|
|
56
|
-
existing_by_route = @content_type.entries.find_by(route: snapshot.route)
|
|
57
|
-
if existing_by_route
|
|
58
|
-
@registry.register_entry(snapshot.gid, existing_by_route)
|
|
59
|
-
return existing_by_route
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
existing_entry = @registry.find_entry(snapshot.gid)
|
|
64
|
-
# Only use the existing entry if it belongs to the correct content type
|
|
65
|
-
if existing_entry && existing_entry.content_type_id == @content_type.id
|
|
66
|
-
return existing_entry
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
new_entry = create_entry
|
|
70
|
-
@registry.register_entry(snapshot.gid, new_entry)
|
|
71
|
-
new_entry
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def create_entry
|
|
75
|
-
entry = @content_type.entries.build
|
|
76
|
-
entry.save(validate: false)
|
|
77
|
-
entry
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
end
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
module Iron
|
|
2
|
-
class ContentImport::EntrySnapshot
|
|
3
|
-
attr_reader :gid, :route, :field_snapshots
|
|
4
|
-
|
|
5
|
-
def initialize(gid)
|
|
6
|
-
@gid = gid
|
|
7
|
-
@route = nil
|
|
8
|
-
@field_snapshots = []
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def add_route(route)
|
|
12
|
-
@route = route
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def add_field_snapshot(snapshot)
|
|
16
|
-
@field_snapshots << snapshot
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def group_field_snapshots_by_locale
|
|
20
|
-
@field_snapshots.group_by(&:locale_code)
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|