pageflow 15.0.0.beta2 → 15.0.0.beta3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of pageflow might be problematic. Click here for more details.

Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +105 -2
  3. data/README.md +5 -1
  4. data/app/assets/javascripts/pageflow/dist/react-client.js +176 -56
  5. data/app/assets/javascripts/pageflow/dist/react-server.js +176 -56
  6. data/app/assets/javascripts/pageflow/editor/api/widget_type.js +0 -1
  7. data/app/assets/javascripts/pageflow/editor/views/widget_types/media_loading_spinner.js +18 -0
  8. data/app/assets/javascripts/pageflow/editor/views/widget_types/title_loading_spinner.js +3 -0
  9. data/app/assets/javascripts/pageflow/ui/views/tabs_view.js +2 -1
  10. data/app/assets/stylesheets/pageflow/themes/default/base.scss +1 -1
  11. data/app/assets/stylesheets/pageflow/themes/default/loading_spinner.scss +37 -1
  12. data/app/assets/stylesheets/pageflow/themes/default/loading_spinner/media.scss +56 -0
  13. data/app/assets/stylesheets/pageflow/themes/default/loading_spinner/title.scss +10 -50
  14. data/app/assets/stylesheets/pageflow/themes/default/logo/variant/watermark.scss +10 -1
  15. data/app/assets/stylesheets/pageflow/themes/default/player_controls/classic/info_box.scss +5 -0
  16. data/app/assets/stylesheets/pageflow/themes/default/player_controls/slim/info_box.scss +4 -0
  17. data/app/controllers/pageflow/editor/files_controller.rb +6 -3
  18. data/app/helpers/pageflow/meta_tags_helper.rb +3 -3
  19. data/app/helpers/pageflow/social_share_links_helper.rb +1 -1
  20. data/app/jobs/pageflow/entry_export_import/upload_and_publish_file_job.rb +41 -0
  21. data/app/models/concerns/pageflow/reusable_file.rb +6 -0
  22. data/app/models/concerns/pageflow/uploadable_file.rb +5 -0
  23. data/app/models/pageflow/draft_entry.rb +26 -2
  24. data/app/models/pageflow/membership.rb +3 -4
  25. data/app/models/pageflow/revision.rb +20 -4
  26. data/app/models/pageflow/widget.rb +12 -6
  27. data/config/locales/de.yml +24 -0
  28. data/config/locales/en.yml +24 -0
  29. data/db/migrate/20140418225525_setup_schema.rb +18 -18
  30. data/db/migrate/20190820152900_drop_accounts_themes.rb +8 -0
  31. data/lib/pageflow/built_in_page_type.rb +3 -0
  32. data/lib/pageflow/built_in_widget_type.rb +7 -0
  33. data/lib/pageflow/built_in_widget_types_plugin.rb +6 -0
  34. data/lib/pageflow/entry_export_import.rb +43 -0
  35. data/lib/pageflow/entry_export_import/attachment_files.rb +65 -0
  36. data/lib/pageflow/entry_export_import/entry_serialization.rb +68 -0
  37. data/lib/pageflow/entry_export_import/file_mappings.rb +32 -0
  38. data/lib/pageflow/entry_export_import/page_type_versions.rb +29 -0
  39. data/lib/pageflow/entry_export_import/revision_serialization.rb +58 -0
  40. data/lib/pageflow/entry_export_import/revision_serialization/import.rb +158 -0
  41. data/lib/pageflow/entry_export_import/zip_archive.rb +36 -0
  42. data/lib/pageflow/file_type.rb +17 -4
  43. data/lib/pageflow/page_type.rb +20 -0
  44. data/lib/pageflow/page_types.rb +8 -0
  45. data/lib/pageflow/react/page_type.rb +10 -0
  46. data/lib/pageflow/version.rb +1 -1
  47. data/lib/pageflow/widget_types.rb +9 -1
  48. data/lib/tasks/entry_export_import.rake +27 -0
  49. data/spec/factories/revisions.rb +6 -0
  50. data/spec/factories/test_multi_attachment_files.rb +16 -0
  51. data/spec/factories/test_revision_components.rb +7 -0
  52. metadata +46 -3
@@ -282,6 +282,10 @@ de:
282
282
  dimensions: Maße
283
283
  duration: Länge
284
284
  format: Format
285
+ pageflow/widget:
286
+ blur_strength: Unschärfe
287
+ invert: Farben invertieren
288
+ remove_logo: Logo entfernen
285
289
  user:
286
290
  account: Konto
287
291
  admin: System-Administrator
@@ -351,6 +355,10 @@ de:
351
355
  attributes:
352
356
  folder:
353
357
  must_be_same_account: Ordner muss zu gleichem Konto gehören wie Beitrag
358
+ pageflow/membership:
359
+ attributes:
360
+ user:
361
+ required: Benutzer muss ausgewählt sein
354
362
  models:
355
363
  account:
356
364
  one: Konto
@@ -1120,6 +1128,8 @@ de:
1120
1128
  audio_files: Audios
1121
1129
  image_files: Bilder
1122
1130
  video_files: Videos
1131
+ media_loading_spinner:
1132
+ widget_type_info_box_text: Dies ist eine Vorschau der Lade-Ansicht von 'Bild'. Die Animation wird ausgeführt, während die Seite geladen wird.
1123
1133
  nested_files:
1124
1134
  text_track_files:
1125
1135
  delete:
@@ -1392,7 +1402,19 @@ de:
1392
1402
  without_parent_page: Ohne übergeordnete Seite
1393
1403
  widgets:
1394
1404
  attributes:
1405
+ media_loading_spinner:
1406
+ blur_strength:
1407
+ inline_help: Steuern Sie die Unschärfe des Hintergrundbilds.
1408
+ label: Unschärfe
1409
+ custom_background_image_id:
1410
+ inline_help: Standardmäßig wird das Hintergrundbild der ersten Seite verwendet.
1411
+ label: Hintegrundbild
1412
+ remove_logo:
1413
+ label: Logo entfernen
1395
1414
  title_loading_spinner:
1415
+ blur_strength:
1416
+ inline_help: Steuern Sie die Unschärfe des Hintergrundbilds.
1417
+ label: Unschärfe
1396
1418
  custom_background_image_id:
1397
1419
  inline_help: Standardmäßig wird das Hintergrundbild der ersten Seite verwendet.
1398
1420
  label: Hintegrundbild
@@ -1733,6 +1755,8 @@ de:
1733
1755
  tr: Türkisch
1734
1756
  unknown: "(Unbekannt)"
1735
1757
  zh: Chinesisch
1758
+ media_loading_spinner:
1759
+ widget_type_name: Media
1736
1760
  page_transitions:
1737
1761
  crossfade: Überblenden
1738
1762
  cut: Harter Schnitt
@@ -282,6 +282,10 @@ en:
282
282
  dimensions: Dimensions
283
283
  duration: Duration
284
284
  format: Format
285
+ pageflow/widget:
286
+ blur_strength: Blurriness
287
+ invert: Invert Color
288
+ remove_logo: Remove Logo
285
289
  user:
286
290
  account: Account
287
291
  admin: System administrator
@@ -351,6 +355,10 @@ en:
351
355
  attributes:
352
356
  folder:
353
357
  must_be_same_account: Folder must belong to same account as story
358
+ pageflow/membership:
359
+ attributes:
360
+ user:
361
+ required: User must be selected
354
362
  models:
355
363
  account:
356
364
  one: Account
@@ -1120,6 +1128,8 @@ en:
1120
1128
  audio_files: Audios
1121
1129
  image_files: Images
1122
1130
  video_files: Videos
1131
+ media_loading_spinner:
1132
+ widget_type_info_box_text: This is a preview of the 'Image' loading view. The animation runs while the page is loading.
1123
1133
  nested_files:
1124
1134
  text_track_files:
1125
1135
  delete:
@@ -1392,7 +1402,19 @@ en:
1392
1402
  without_parent_page: Without parent page
1393
1403
  widgets:
1394
1404
  attributes:
1405
+ media_loading_spinner:
1406
+ blur_strength:
1407
+ inline_help: Control the bluriness of background image.
1408
+ label: Blur Strength
1409
+ custom_background_image_id:
1410
+ inline_help: By default, the background image of the first page is used.
1411
+ label: Background Image
1412
+ remove_logo:
1413
+ label: Remove logo
1395
1414
  title_loading_spinner:
1415
+ blur_strength:
1416
+ inline_help: Control the bluriness of background image.
1417
+ label: Blur Strength
1396
1418
  custom_background_image_id:
1397
1419
  inline_help: By default the background image of the first page is used.
1398
1420
  label: Background image
@@ -1705,6 +1727,8 @@ en:
1705
1727
  tr: Turkish
1706
1728
  unknown: "(Unknown)"
1707
1729
  zh: Chinese
1730
+ media_loading_spinner:
1731
+ widget_type_name: Media
1708
1732
  page_transitions:
1709
1733
  crossfade: Crossfade
1710
1734
  cut: Cut
@@ -2,7 +2,7 @@
2
2
 
3
3
  class SetupSchema < ActiveRecord::Migration[5.2]
4
4
  def change
5
- create_table 'friendly_id_slugs', id: :integer, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8', force: :cascade do |t|
5
+ create_table 'friendly_id_slugs', id: :integer, options: 'ENGINE=InnoDB', force: :cascade do |t|
6
6
  t.string 'slug', null: false
7
7
  t.integer 'sluggable_id', null: false
8
8
  t.string 'sluggable_type', limit: 50
@@ -14,7 +14,7 @@ class SetupSchema < ActiveRecord::Migration[5.2]
14
14
  t.index ['sluggable_type'], name: 'index_friendly_id_slugs_on_sluggable_type'
15
15
  end
16
16
 
17
- create_table 'pageflow_accounts', id: :integer, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8', force: :cascade do |t|
17
+ create_table 'pageflow_accounts', id: :integer, options: 'ENGINE=InnoDB', force: :cascade do |t|
18
18
  t.string 'name', default: '', null: false
19
19
  t.datetime 'created_at'
20
20
  t.datetime 'updated_at'
@@ -27,12 +27,12 @@ class SetupSchema < ActiveRecord::Migration[5.2]
27
27
  t.index ['default_theming_id'], name: 'index_pageflow_accounts_on_default_theming_id'
28
28
  end
29
29
 
30
- create_table 'pageflow_accounts_themes', id: false, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8', force: :cascade do |t|
30
+ create_table 'pageflow_accounts_themes', id: false, options: 'ENGINE=InnoDB', force: :cascade do |t|
31
31
  t.integer 'account_id'
32
32
  t.integer 'theme_name'
33
33
  end
34
34
 
35
- create_table 'pageflow_audio_files', id: :integer, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8', force: :cascade do |t|
35
+ create_table 'pageflow_audio_files', id: :integer, options: 'ENGINE=InnoDB', force: :cascade do |t|
36
36
  t.integer 'entry_id'
37
37
  t.integer 'uploader_id'
38
38
  t.string 'attachment_on_filesystem_file_name'
@@ -58,7 +58,7 @@ class SetupSchema < ActiveRecord::Migration[5.2]
58
58
  t.index ['parent_file_id', 'parent_file_model_type'], name: 'index_audio_files_on_parent_id_and_parent_model_type'
59
59
  end
60
60
 
61
- create_table 'pageflow_chapters', id: :integer, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8', force: :cascade do |t|
61
+ create_table 'pageflow_chapters', id: :integer, options: 'ENGINE=InnoDB', force: :cascade do |t|
62
62
  t.datetime 'created_at'
63
63
  t.datetime 'updated_at'
64
64
  t.integer 'position', default: 0, null: false
@@ -68,7 +68,7 @@ class SetupSchema < ActiveRecord::Migration[5.2]
68
68
  t.index ['storyline_id'], name: 'index_pageflow_chapters_on_storyline_id'
69
69
  end
70
70
 
71
- create_table 'pageflow_edit_locks', id: :integer, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8', force: :cascade do |t|
71
+ create_table 'pageflow_edit_locks', id: :integer, options: 'ENGINE=InnoDB', force: :cascade do |t|
72
72
  t.integer 'user_id'
73
73
  t.integer 'entry_id'
74
74
  t.datetime 'created_at'
@@ -77,7 +77,7 @@ class SetupSchema < ActiveRecord::Migration[5.2]
77
77
  t.index ['user_id'], name: 'index_pageflow_edit_locks_on_user_id'
78
78
  end
79
79
 
80
- create_table 'pageflow_entries', id: :integer, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8', force: :cascade do |t|
80
+ create_table 'pageflow_entries', id: :integer, options: 'ENGINE=InnoDB', force: :cascade do |t|
81
81
  t.string 'title', default: '', null: false
82
82
  t.datetime 'created_at'
83
83
  t.datetime 'updated_at'
@@ -96,7 +96,7 @@ class SetupSchema < ActiveRecord::Migration[5.2]
96
96
  t.index ['theming_id'], name: 'index_pageflow_entries_on_theming_id'
97
97
  end
98
98
 
99
- create_table 'pageflow_file_usages', id: :integer, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8', force: :cascade do |t|
99
+ create_table 'pageflow_file_usages', id: :integer, options: 'ENGINE=InnoDB', force: :cascade do |t|
100
100
  t.integer 'revision_id'
101
101
  t.integer 'file_id'
102
102
  t.string 'file_type'
@@ -107,7 +107,7 @@ class SetupSchema < ActiveRecord::Migration[5.2]
107
107
  t.index ['revision_id'], name: 'index_pageflow_file_usages_on_revision_id'
108
108
  end
109
109
 
110
- create_table 'pageflow_folders', id: :integer, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8', force: :cascade do |t|
110
+ create_table 'pageflow_folders', id: :integer, options: 'ENGINE=InnoDB', force: :cascade do |t|
111
111
  t.string 'name'
112
112
  t.integer 'account_id'
113
113
  t.datetime 'created_at'
@@ -115,7 +115,7 @@ class SetupSchema < ActiveRecord::Migration[5.2]
115
115
  t.index ['account_id'], name: 'index_pageflow_folders_on_account_id'
116
116
  end
117
117
 
118
- create_table 'pageflow_image_files', id: :integer, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8', force: :cascade do |t|
118
+ create_table 'pageflow_image_files', id: :integer, options: 'ENGINE=InnoDB', force: :cascade do |t|
119
119
  t.integer 'entry_id'
120
120
  t.integer 'uploader_id'
121
121
  t.string 'unprocessed_attachment_file_name'
@@ -137,7 +137,7 @@ class SetupSchema < ActiveRecord::Migration[5.2]
137
137
  t.index ['parent_file_id', 'parent_file_model_type'], name: 'index_image_files_on_parent_id_and_parent_model_type'
138
138
  end
139
139
 
140
- create_table 'pageflow_memberships', id: :integer, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8', force: :cascade do |t|
140
+ create_table 'pageflow_memberships', id: :integer, options: 'ENGINE=InnoDB', force: :cascade do |t|
141
141
  t.integer 'user_id'
142
142
  t.integer 'entity_id'
143
143
  t.string 'name'
@@ -149,7 +149,7 @@ class SetupSchema < ActiveRecord::Migration[5.2]
149
149
  t.index ['user_id'], name: 'index_pageflow_memberships_on_user_id'
150
150
  end
151
151
 
152
- create_table 'pageflow_pages', id: :integer, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8', force: :cascade do |t|
152
+ create_table 'pageflow_pages', id: :integer, options: 'ENGINE=InnoDB', force: :cascade do |t|
153
153
  t.integer 'chapter_id'
154
154
  t.string 'template', default: '', null: false
155
155
  t.text 'configuration'
@@ -162,7 +162,7 @@ class SetupSchema < ActiveRecord::Migration[5.2]
162
162
  t.index ['perma_id'], name: 'index_pageflow_pages_on_perma_id'
163
163
  end
164
164
 
165
- create_table 'pageflow_revisions', id: :integer, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8', force: :cascade do |t|
165
+ create_table 'pageflow_revisions', id: :integer, options: 'ENGINE=InnoDB', force: :cascade do |t|
166
166
  t.integer 'entry_id'
167
167
  t.integer 'creator_id'
168
168
  t.datetime 'published_at'
@@ -195,7 +195,7 @@ class SetupSchema < ActiveRecord::Migration[5.2]
195
195
  t.index ['restored_from_id'], name: 'index_pageflow_revisions_on_restored_from_id'
196
196
  end
197
197
 
198
- create_table 'pageflow_storylines', id: :integer, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8', force: :cascade do |t|
198
+ create_table 'pageflow_storylines', id: :integer, options: 'ENGINE=InnoDB', force: :cascade do |t|
199
199
  t.integer 'perma_id'
200
200
  t.integer 'revision_id'
201
201
  t.integer 'position'
@@ -205,7 +205,7 @@ class SetupSchema < ActiveRecord::Migration[5.2]
205
205
  t.index ['revision_id'], name: 'index_pageflow_storylines_on_revision_id'
206
206
  end
207
207
 
208
- create_table 'pageflow_text_track_files', id: :integer, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8', force: :cascade do |t|
208
+ create_table 'pageflow_text_track_files', id: :integer, options: 'ENGINE=InnoDB', force: :cascade do |t|
209
209
  t.integer 'entry_id'
210
210
  t.integer 'uploader_id'
211
211
  t.string 'state'
@@ -232,7 +232,7 @@ class SetupSchema < ActiveRecord::Migration[5.2]
232
232
  t.index ['uploader_id'], name: 'index_pageflow_text_track_files_on_uploader_id'
233
233
  end
234
234
 
235
- create_table 'pageflow_themings', id: :integer, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8', force: :cascade do |t|
235
+ create_table 'pageflow_themings', id: :integer, options: 'ENGINE=InnoDB', force: :cascade do |t|
236
236
  t.string 'imprint_link_url'
237
237
  t.string 'imprint_link_label'
238
238
  t.string 'copyright_link_url'
@@ -251,7 +251,7 @@ class SetupSchema < ActiveRecord::Migration[5.2]
251
251
  t.index ['cname'], name: 'index_pageflow_themings_on_cname'
252
252
  end
253
253
 
254
- create_table 'pageflow_video_files', id: :integer, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8', force: :cascade do |t|
254
+ create_table 'pageflow_video_files', id: :integer, options: 'ENGINE=InnoDB', force: :cascade do |t|
255
255
  t.integer 'entry_id'
256
256
  t.integer 'uploader_id'
257
257
  t.string 'attachment_on_filesystem_file_name'
@@ -284,7 +284,7 @@ class SetupSchema < ActiveRecord::Migration[5.2]
284
284
  t.index ['parent_file_id', 'parent_file_model_type'], name: 'index_video_files_on_parent_id_and_parent_model_type'
285
285
  end
286
286
 
287
- create_table 'pageflow_widgets', id: :integer, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8', force: :cascade do |t|
287
+ create_table 'pageflow_widgets', id: :integer, options: 'ENGINE=InnoDB', force: :cascade do |t|
288
288
  t.string 'subject_type'
289
289
  t.integer 'subject_id'
290
290
  t.string 'type_name'
@@ -0,0 +1,8 @@
1
+ class DropAccountsThemes < ActiveRecord::Migration[5.2]
2
+ def change
3
+ drop_table :pageflow_accounts_themes, id: false, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8', force: :cascade do |t|
4
+ t.integer 'account_id'
5
+ t.integer 'theme_name'
6
+ end
7
+ end
8
+ end
@@ -4,6 +4,7 @@ module Pageflow
4
4
  def self.plain
5
5
  Pageflow::React.create_page_type('background_image',
6
6
  thumbnail_candidates: default_thumbnail_candidates,
7
+ export_version: Pageflow::VERSION,
7
8
  file_types: [
8
9
  BuiltInFileType.image,
9
10
  BuiltInFileType.video
@@ -13,6 +14,7 @@ module Pageflow
13
14
  def self.video
14
15
  Pageflow::React.create_page_type('video',
15
16
  thumbnail_candidates: video_thumbnail_candidates,
17
+ export_version: Pageflow::VERSION,
16
18
  file_types: [
17
19
  BuiltInFileType.image,
18
20
  BuiltInFileType.video
@@ -22,6 +24,7 @@ module Pageflow
22
24
  def self.audio
23
25
  Pageflow::React.create_page_type('audio',
24
26
  thumbnail_candidates: default_thumbnail_candidates,
27
+ export_version: Pageflow::VERSION,
25
28
  file_types: [
26
29
  BuiltInFileType.audio,
27
30
  BuiltInFileType.image,
@@ -61,5 +61,12 @@ module Pageflow
61
61
  insert_point: :before_entry,
62
62
  server_rendering: true)
63
63
  end
64
+
65
+ def self.media_loading_spinner
66
+ Pageflow::React.create_widget_type('media_loading_spinner',
67
+ 'loading_spinner',
68
+ insert_point: :before_entry,
69
+ server_rendering: true)
70
+ end
64
71
  end
65
72
  end
@@ -9,12 +9,18 @@ module Pageflow
9
9
  .phone_horizontal_slideshow_mode)
10
10
  end
11
11
 
12
+ config.widget_types.register_widget_defaults('loading_spinner',
13
+ 'blur_strength' => 50,
14
+ 'remove_logo' => false,
15
+ 'invert' => false)
12
16
  config.widget_types.register(Pageflow::BuiltInWidgetType.classic_loading_spinner,
13
17
  default: true)
14
18
 
15
19
  config.features.register('title_loading_spinner') do |feature_config|
20
+ feature_config.widget_types.register(Pageflow::BuiltInWidgetType.media_loading_spinner)
16
21
  feature_config.widget_types.register(Pageflow::BuiltInWidgetType.title_loading_spinner)
17
22
  end
23
+ config.features.enable_by_default('title_loading_spinner')
18
24
 
19
25
  config.widget_types.register(Pageflow::BuiltInWidgetType.navigation, default: true)
20
26
  config.widget_types.register(Pageflow::BuiltInWidgetType.mobile_navigation, default: true)
@@ -0,0 +1,43 @@
1
+ module Pageflow
2
+ module EntryExportImport
3
+ extend self
4
+
5
+ def export(entry, archive_file_path)
6
+ archive = ZipArchive.new(archive_file_path)
7
+ publication = most_recent_publication(entry)
8
+
9
+ archive.add('entry.json', StringIO.new(EntrySerialization.dump(entry, publication).to_json))
10
+
11
+ AttachmentFiles.download_and_archive_originals(entry.draft, archive)
12
+ AttachmentFiles.download_and_archive_originals(publication, archive) if publication
13
+
14
+ archive.close
15
+ end
16
+
17
+ def import(archive_file_path, creator:)
18
+ archive = ZipArchive.new(archive_file_path)
19
+ file_mappings = FileMappings.new
20
+
21
+ entry = extract_entry(archive, creator, file_mappings)
22
+ AttachmentFiles.extract_and_upload_originals(entry,
23
+ archive_file_path,
24
+ file_mappings)
25
+ entry
26
+ end
27
+
28
+ private
29
+
30
+ def extract_entry(archive, creator, file_mappings)
31
+ archive.extract_to_tempfile('entry.json') do |tempfile|
32
+ EntrySerialization.import(JSON.parse(tempfile.read),
33
+ creator: creator,
34
+ account: creator.accounts.first,
35
+ file_mappings: file_mappings)
36
+ end
37
+ end
38
+
39
+ def most_recent_publication(entry)
40
+ entry.revisions.publications.first
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,65 @@
1
+ module Pageflow
2
+ module EntryExportImport
3
+ # Download/upload files during export/import
4
+ module AttachmentFiles
5
+ extend self
6
+
7
+ def download_and_archive_originals(revision, archive)
8
+ revision.file_usages.each do |file_usage|
9
+ reusable_file = file_usage.file
10
+
11
+ reusable_file.attachments_for_export.each do |attachment|
12
+ download_and_archive_attachment_file(reusable_file, attachment, archive)
13
+ end
14
+ end
15
+ end
16
+
17
+ def extract_and_upload_originals(entry, archive_file_name, file_mappings)
18
+ each_reusable_file(entry) do |reusable_file|
19
+ exported_id = file_mappings.exported_id_for(reusable_file.class.name,
20
+ reusable_file.id)
21
+
22
+ UploadAndPublishFileJob.perform_later(reusable_file,
23
+ exported_id,
24
+ archive_file_name)
25
+ end
26
+ end
27
+
28
+ def archive_path(reusable_file, attachment, exported_id: reusable_file.id)
29
+ File.join(reusable_file.file_type.collection_name,
30
+ exported_id.to_s,
31
+ attachment.name.to_s,
32
+ attachment.original_filename)
33
+ end
34
+
35
+ private
36
+
37
+ def each_reusable_file(entry, &block)
38
+ Pageflow.config.file_types.each do |file_type|
39
+ file_type.model.where(entry: entry).each(&block)
40
+ end
41
+ end
42
+
43
+ def download_and_archive_attachment_file(reusable_file, attachment, archive)
44
+ archive_path = archive_path(reusable_file, attachment)
45
+
46
+ return if archive.include?(archive_path)
47
+
48
+ download_attachment_file(attachment) do |tempfile|
49
+ archive.add(archive_path, tempfile)
50
+ end
51
+ end
52
+
53
+ def download_attachment_file(attachment)
54
+ tempfile = Paperclip.io_adapters.for(attachment)
55
+
56
+ begin
57
+ yield(tempfile)
58
+ ensure
59
+ tempfile.close
60
+ tempfile.unlink
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,68 @@
1
+ module Pageflow
2
+ module EntryExportImport
3
+ module EntrySerialization
4
+ extend self
5
+
6
+ DEFAULT_REMOVAL_COLUMNS = %w[id updated_at].freeze
7
+
8
+ # Turn entry into JSON compatible data structure.
9
+ def dump(entry, publication = nil)
10
+ {
11
+ 'page_type_versions' => PageTypeVersions.dump,
12
+ # features_configuration is specifically excluded via `Entry#blacklist_for_serialization`
13
+ # to prevent it from showing up in Active Admin JSON exports.
14
+ # It is included separately as part of the entry export.
15
+ 'entry' => entry
16
+ .as_json(except: [:folder_id, :password_digest, :users_count])
17
+ .merge('features_configuration' => entry.features_configuration,
18
+ 'draft' => RevisionSerialization.dump(entry.draft),
19
+ 'last_publication' => dump_publication(publication))
20
+ }
21
+ end
22
+
23
+ # Create entry from serialized JSON export
24
+ def import(data, options)
25
+ PageTypeVersions.verify_compatibility!(data['page_type_versions'])
26
+
27
+ entry_data = data['entry']
28
+ entry = create_entry(entry_data.except('draft', 'last_publication'), options)
29
+
30
+ file_mappings = options.fetch(:file_mappings, FileMappings.new)
31
+
32
+ import_draft(entry_data, options, entry, file_mappings)
33
+ import_last_publication(entry_data, options, entry, file_mappings)
34
+
35
+ entry
36
+ end
37
+
38
+ private
39
+
40
+ def dump_publication(publication)
41
+ publication && RevisionSerialization.dump(publication)
42
+ end
43
+
44
+ def create_entry(data, options)
45
+ entry_data = data.except(*DEFAULT_REMOVAL_COLUMNS)
46
+ entry_data['account_id'] = options[:account].id
47
+ entry_data['theming_id'] = options[:account].default_theming.id
48
+ Entry.create!(entry_data.merge(skip_draft_creation: true))
49
+ end
50
+
51
+ def import_draft(entry_data, options, entry, file_mappings)
52
+ RevisionSerialization.import(entry_data['draft'],
53
+ entry: entry,
54
+ creator: options[:creator],
55
+ file_mappings: file_mappings)
56
+ end
57
+
58
+ def import_last_publication(entry_data, options, entry, file_mappings)
59
+ return unless entry_data['last_publication']
60
+
61
+ RevisionSerialization.import(entry_data['last_publication'],
62
+ entry: entry,
63
+ creator: options[:creator],
64
+ file_mappings: file_mappings)
65
+ end
66
+ end
67
+ end
68
+ end