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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +105 -2
- data/README.md +5 -1
- data/app/assets/javascripts/pageflow/dist/react-client.js +176 -56
- data/app/assets/javascripts/pageflow/dist/react-server.js +176 -56
- data/app/assets/javascripts/pageflow/editor/api/widget_type.js +0 -1
- data/app/assets/javascripts/pageflow/editor/views/widget_types/media_loading_spinner.js +18 -0
- data/app/assets/javascripts/pageflow/editor/views/widget_types/title_loading_spinner.js +3 -0
- data/app/assets/javascripts/pageflow/ui/views/tabs_view.js +2 -1
- data/app/assets/stylesheets/pageflow/themes/default/base.scss +1 -1
- data/app/assets/stylesheets/pageflow/themes/default/loading_spinner.scss +37 -1
- data/app/assets/stylesheets/pageflow/themes/default/loading_spinner/media.scss +56 -0
- data/app/assets/stylesheets/pageflow/themes/default/loading_spinner/title.scss +10 -50
- data/app/assets/stylesheets/pageflow/themes/default/logo/variant/watermark.scss +10 -1
- data/app/assets/stylesheets/pageflow/themes/default/player_controls/classic/info_box.scss +5 -0
- data/app/assets/stylesheets/pageflow/themes/default/player_controls/slim/info_box.scss +4 -0
- data/app/controllers/pageflow/editor/files_controller.rb +6 -3
- data/app/helpers/pageflow/meta_tags_helper.rb +3 -3
- data/app/helpers/pageflow/social_share_links_helper.rb +1 -1
- data/app/jobs/pageflow/entry_export_import/upload_and_publish_file_job.rb +41 -0
- data/app/models/concerns/pageflow/reusable_file.rb +6 -0
- data/app/models/concerns/pageflow/uploadable_file.rb +5 -0
- data/app/models/pageflow/draft_entry.rb +26 -2
- data/app/models/pageflow/membership.rb +3 -4
- data/app/models/pageflow/revision.rb +20 -4
- data/app/models/pageflow/widget.rb +12 -6
- data/config/locales/de.yml +24 -0
- data/config/locales/en.yml +24 -0
- data/db/migrate/20140418225525_setup_schema.rb +18 -18
- data/db/migrate/20190820152900_drop_accounts_themes.rb +8 -0
- data/lib/pageflow/built_in_page_type.rb +3 -0
- data/lib/pageflow/built_in_widget_type.rb +7 -0
- data/lib/pageflow/built_in_widget_types_plugin.rb +6 -0
- data/lib/pageflow/entry_export_import.rb +43 -0
- data/lib/pageflow/entry_export_import/attachment_files.rb +65 -0
- data/lib/pageflow/entry_export_import/entry_serialization.rb +68 -0
- data/lib/pageflow/entry_export_import/file_mappings.rb +32 -0
- data/lib/pageflow/entry_export_import/page_type_versions.rb +29 -0
- data/lib/pageflow/entry_export_import/revision_serialization.rb +58 -0
- data/lib/pageflow/entry_export_import/revision_serialization/import.rb +158 -0
- data/lib/pageflow/entry_export_import/zip_archive.rb +36 -0
- data/lib/pageflow/file_type.rb +17 -4
- data/lib/pageflow/page_type.rb +20 -0
- data/lib/pageflow/page_types.rb +8 -0
- data/lib/pageflow/react/page_type.rb +10 -0
- data/lib/pageflow/version.rb +1 -1
- data/lib/pageflow/widget_types.rb +9 -1
- data/lib/tasks/entry_export_import.rake +27 -0
- data/spec/factories/revisions.rb +6 -0
- data/spec/factories/test_multi_attachment_files.rb +16 -0
- data/spec/factories/test_revision_components.rb +7 -0
- metadata +46 -3
data/config/locales/de.yml
CHANGED
@@ -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
|
data/config/locales/en.yml
CHANGED
@@ -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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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'
|
@@ -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
|