pageflow 13.6.0 → 14.0.0.beta1

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 (78) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +72 -5
  3. data/app/assets/javascripts/pageflow/dist/react-client.js +22 -27
  4. data/app/assets/javascripts/pageflow/dist/react-server.js +22 -27
  5. data/app/assets/javascripts/pageflow/editor/collections/files_collection.js +0 -1
  6. data/app/assets/javascripts/pageflow/editor/models/file_uploader.js +3 -1
  7. data/app/assets/javascripts/pageflow/editor/models/hosted_file.js +2 -7
  8. data/app/assets/javascripts/pageflow/editor/models/image_file.js +1 -1
  9. data/app/assets/javascripts/pageflow/editor/models/uploaded_file.js +12 -10
  10. data/app/assets/javascripts/pageflow/editor/views/configuration_editors/groups/general.js +4 -4
  11. data/app/assets/javascripts/pageflow/editor/views/uploader_view.js +18 -27
  12. data/app/assets/javascripts/pageflow/slideshow/page_split_layout.js +8 -8
  13. data/app/assets/javascripts/pageflow/slideshow/page_widget.js +1 -1
  14. data/app/assets/stylesheets/pageflow/delayed_text_fade_in.scss +10 -5
  15. data/app/assets/stylesheets/pageflow/editor/file_stages.scss +0 -4
  16. data/app/assets/stylesheets/pageflow/editor/file_thumbnails.scss +0 -4
  17. data/app/assets/stylesheets/pageflow/hide_text.scss +2 -2
  18. data/app/assets/stylesheets/pageflow/lt_ie9.scss +5 -5
  19. data/app/assets/stylesheets/pageflow/navigation_bar.scss +1 -0
  20. data/app/assets/stylesheets/pageflow/navigation_mobile.scss +4 -0
  21. data/app/assets/stylesheets/pageflow/page.scss +2 -2
  22. data/app/assets/stylesheets/pageflow/page_transitions/crossfade.scss +1 -1
  23. data/app/assets/stylesheets/pageflow/page_transitions/fade.scss +11 -11
  24. data/app/assets/stylesheets/pageflow/page_transitions/fade_to_black.scss +13 -10
  25. data/app/assets/stylesheets/pageflow/page_types/audio.scss +3 -3
  26. data/app/assets/stylesheets/pageflow/page_types/video.scss +9 -9
  27. data/app/assets/stylesheets/pageflow/page_types/video/content_hiding.scss +2 -2
  28. data/app/assets/stylesheets/pageflow/page_types/video/mobile_poster.scss +3 -3
  29. data/app/assets/stylesheets/pageflow/print_view.scss +8 -5
  30. data/app/assets/stylesheets/pageflow/slideshow.scss +6 -5
  31. data/app/assets/stylesheets/pageflow/themes/default/base.scss +1 -1
  32. data/app/assets/stylesheets/pageflow/themes/default/page.scss +3 -168
  33. data/app/assets/stylesheets/pageflow/themes/default/page/anchors.scss +2 -2
  34. data/app/assets/stylesheets/pageflow/themes/default/page/content_text_margin.scss +1 -1
  35. data/app/assets/stylesheets/pageflow/themes/default/page/header.scss +172 -0
  36. data/app/assets/stylesheets/pageflow/themes/default/page/hyphenate.scss +1 -1
  37. data/app/assets/stylesheets/pageflow/themes/default/page/line_lengths.scss +12 -14
  38. data/app/assets/stylesheets/pageflow/themes/default/player_controls/vjs_mapping.scss +6 -6
  39. data/app/assets/stylesheets/pageflow/themes/default/{video_wrapper.scss → uncropped_media_wrapper.scss} +1 -1
  40. data/app/controllers/pageflow/editor/files_controller.rb +11 -8
  41. data/app/helpers/pageflow/background_image_helper.rb +2 -1
  42. data/app/helpers/pageflow/files_helper.rb +1 -0
  43. data/app/helpers/pageflow/pages_helper.rb +31 -0
  44. data/app/helpers/pageflow/video_files_helper.rb +3 -3
  45. data/app/jobs/pageflow/process_file_job.rb +15 -5
  46. data/app/models/concerns/pageflow/hosted_file.rb +42 -33
  47. data/app/models/concerns/pageflow/uploaded_file.rb +10 -0
  48. data/app/models/pageflow/audio_file.rb +1 -1
  49. data/app/models/pageflow/audio_file_url_templates.rb +1 -1
  50. data/app/models/pageflow/draft_entry.rb +1 -1
  51. data/app/models/pageflow/image_file.rb +38 -52
  52. data/app/models/pageflow/image_file_css_background_image_urls.rb +4 -4
  53. data/app/models/pageflow/image_file_url_templates.rb +2 -2
  54. data/app/models/pageflow/positioned_file.rb +1 -1
  55. data/app/models/pageflow/text_track_file.rb +15 -32
  56. data/app/models/pageflow/text_track_file_url_templates.rb +2 -3
  57. data/app/models/pageflow/video_file.rb +1 -1
  58. data/app/models/pageflow/video_file_url_templates.rb +1 -1
  59. data/app/state_machines/pageflow/{image_file_state_machine.rb → processed_file_state_machine.rb} +4 -10
  60. data/app/views/pageflow/editor/files/_file.json.jbuilder +4 -0
  61. data/app/views/pageflow/entries/edit.html.erb +2 -2
  62. data/app/views/pageflow/entries/mobile_navigation/_page.html.erb +1 -0
  63. data/app/views/pageflow/entries/navigation/_page.html.erb +2 -1
  64. data/config/initializers/paperclip.rb +6 -0
  65. data/config/routes.rb +1 -1
  66. data/db/migrate/20181115165746_change_processed_attachment_to_attachment_on_s3_for_images.rb +16 -0
  67. data/db/migrate/20190306161431_copy_file_attributes_of_failed_uploads.rb +25 -0
  68. data/lib/pageflow/configuration.rb +23 -5
  69. data/lib/pageflow/configuration/defaults.rb +2 -9
  70. data/lib/pageflow/version.rb +1 -1
  71. data/spec/factories/audio_files.rb +17 -10
  72. data/spec/factories/hosted_files.rb +13 -11
  73. data/spec/factories/image_files.rb +18 -11
  74. data/spec/factories/text_track_files.rb +30 -10
  75. data/spec/factories/video_files.rb +16 -9
  76. metadata +9 -8
  77. data/app/assets/javascripts/pageflow/dist/react.js +0 -29944
  78. data/app/jobs/pageflow/upload_file_to_s3_job.rb +0 -25
@@ -4,12 +4,12 @@ module Pageflow
4
4
  def call(image_file)
5
5
  {
6
6
  default: {
7
- desktop: image_file.attachment.url(:large),
8
- mobile: image_file.attachment.url(:medium)
7
+ desktop: image_file.ready? ? image_file.attachment.url(:large) : '',
8
+ mobile: image_file.ready? ? image_file.attachment.url(:medium) : ''
9
9
  },
10
10
  panorama: {
11
- desktop: image_file.attachment.url(:panorama_large),
12
- mobile: image_file.attachment.url(:panorama_medium)
11
+ desktop: image_file.ready? ? image_file.attachment.url(:panorama_large) : '',
12
+ mobile: image_file.ready? ? image_file.attachment.url(:panorama_medium) : ''
13
13
  }
14
14
  }
15
15
  end
@@ -9,11 +9,11 @@ module Pageflow
9
9
  private
10
10
 
11
11
  def styles
12
- ImageFile::STYLES.call(example_file.attachment).keys
12
+ example_file.attachment_styles(example_file.attachment).keys
13
13
  end
14
14
 
15
15
  def example_file
16
- @example_file ||= ImageFile.new(id: 0, processed_attachment_file_name: ':basename.jpg')
16
+ @example_file ||= ImageFile.new(id: 0, file_name: ':basename.jpg')
17
17
  end
18
18
  end
19
19
  end
@@ -34,7 +34,7 @@ module Pageflow
34
34
  end
35
35
 
36
36
  def thumbnail_url(*args)
37
- ImageFile.new.processed_attachment.url(*args)
37
+ ImageFile.new.attachment.url(*args)
38
38
  end
39
39
 
40
40
  def blank?
@@ -1,41 +1,24 @@
1
1
  module Pageflow
2
2
  class TextTrackFile < ApplicationRecord
3
3
  include HostedFile
4
+ include ProcessedFileStateMachine
4
5
 
5
- processing_state_machine do
6
- state 'processing'
7
- state 'processed'
8
- state 'processing_failed'
9
-
10
- event :process do
11
- transition any => 'processing'
12
- end
13
-
14
- job ProcessFileJob do
15
- on_enter 'processing'
16
- result :ok, state: 'processed'
17
- result :error, state: 'processing_failed'
18
- end
19
- end
20
-
21
- has_attached_file(:processed_attachment,
22
- Pageflow.config.paperclip_s3_default_options
23
- .merge(styles: {
24
- vtt: {
25
- format: 'vtt',
26
- processors: [:pageflow_vtt],
27
- s3_headers: {
28
- 'Content-Type' => 'text/vtt'
29
- }
30
- }
31
- }))
32
-
33
- def ready?
34
- processed?
6
+ def attachment_styles(_attachment)
7
+ {
8
+ vtt: {
9
+ format: 'vtt',
10
+ processors: [:pageflow_vtt],
11
+ s3_headers: {
12
+ 'Content-Type' => 'text/vtt'
13
+ }
14
+ }
15
+ }
35
16
  end
36
17
 
37
- def unprocessed_attachment
38
- attachment_on_s3
18
+ # used in paperclip initializer to interpolate the storage path
19
+ # needs to be "processed_attachments" for text tracks for legacy reasons
20
+ def attachments_path_name
21
+ 'processed_attachments'
39
22
  end
40
23
 
41
24
  def meta_data_attributes=(attributes)
@@ -2,15 +2,14 @@ module Pageflow
2
2
  class TextTrackFileUrlTemplates
3
3
  def call
4
4
  {
5
- vtt: UrlTemplate.from_attachment(example_file.processed_attachment, :vtt)
5
+ vtt: UrlTemplate.from_attachment(example_file.attachment, :vtt)
6
6
  }
7
7
  end
8
8
 
9
9
  private
10
10
 
11
11
  def example_file
12
- @example_file ||= TextTrackFile.new(id: 0,
13
- processed_attachment_file_name: ':basename.vtt')
12
+ @example_file ||= TextTrackFile.new(id: 0, file_name: ':basename.vtt')
14
13
  end
15
14
  end
16
15
  end
@@ -40,7 +40,7 @@ module Pageflow
40
40
  end
41
41
 
42
42
  def attachment_s3_url
43
- "s3://#{File.join(attachment_on_s3.bucket_name, attachment_on_s3.path)}"
43
+ "s3://#{File.join(attachment.bucket_name, attachment.path)}"
44
44
  end
45
45
 
46
46
  def encode_highdef?
@@ -26,7 +26,7 @@ module Pageflow
26
26
 
27
27
  def example_file
28
28
  @example_file ||= VideoFile.new(id: 0).tap do |video_file|
29
- video_file.attachment_on_s3_file_name = ':basename.mp4'
29
+ video_file.file_name = ':basename.mp4'
30
30
  video_file.poster_file_name = video_file.zencoder_poster.original_filename
31
31
  end
32
32
  end
@@ -1,19 +1,17 @@
1
1
  module Pageflow
2
- module ImageFileStateMachine
2
+ module ProcessedFileStateMachine
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  included do
6
- state_machine :initial => 'not_processed' do
6
+ processing_state_machine do
7
7
  extend StateMachineJob::Macro
8
8
 
9
- state 'not_processed'
10
9
  state 'processing'
11
10
  state 'processed'
12
-
13
- state 'processing_to_s3_failed'
11
+ state 'processing_failed'
14
12
 
15
13
  event :process do
16
- transition 'not_processed' => 'processing'
14
+ transition 'uploaded' => 'processing'
17
15
  transition 'processing_failed' => 'processing'
18
16
  end
19
17
 
@@ -29,10 +27,6 @@ module Pageflow
29
27
  process!
30
28
  end
31
29
 
32
- def publish!
33
- process!
34
- end
35
-
36
30
  def retryable?
37
31
  processing_failed?
38
32
  end
@@ -7,6 +7,10 @@ json.call(file,
7
7
  :rights,
8
8
  :usage_id)
9
9
 
10
+ if file.can_upload?
11
+ json.direct_upload_config(file.direct_upload_config)
12
+ end
13
+
10
14
  json.retryable(file.retryable?)
11
15
  json.file_name(file.attachment.original_filename)
12
16
 
@@ -28,8 +28,8 @@
28
28
  <div class="editor" id="editor_menu_container">
29
29
  </div>
30
30
 
31
- <%= form_for editor_entry_files_path(@entry, collection_name: 'image_files'), :html => {:multipart => true, :id => 'upload'} do |f| %>
32
- <%= f.file_field :attachment, :multiple => true, :name => 'image_file[attachment]' %>
31
+ <%= form_tag '#', :multipart => true, :id => 'upload' do %>
32
+ <%= file_field_tag :file, :multiple => true %>
33
33
  <% end %>
34
34
 
35
35
  <script>
@@ -1,5 +1,6 @@
1
1
  <li class="<%= page_navigation_css_class(page) %>">
2
2
  <%= link_to "##{page.perma_id}", data: {link: page.id, chapter_id: page.chapter_id} do %>
3
3
  <%= image_tag('', data: {src: asset_path(page.thumbnail_url(:thumbnail_overview_mobile))}) %>
4
+ <%= page.title %>
4
5
  <% end %>
5
6
  </li>
@@ -1,6 +1,7 @@
1
1
  <li class="<%= page_navigation_css_class(page) %>">
2
2
  <%= link_to "##{page.perma_id}", :data => {:link => page.id, :chapter_id => page.chapter_id} do %>
3
- <%= image_tag('', data: {src: asset_path(page.thumbnail_url(:navigation_thumbnail_small))}, width: 85, height: 47) %>
3
+ <%= image_tag('', data: {src: asset_path(page.thumbnail_url(:navigation_thumbnail_small))}, width: 85, height: 47) %>
4
+ <%= page.title %>
4
5
  <% end %>
5
6
  <div class="navigation_site_detail">
6
7
  <%= page.title %>
@@ -10,6 +10,12 @@ Paperclip.interpolates(:class_basename) do |attachment, style|
10
10
  Pageflow::PaperclipInterpolations::Support.class_basename(attachment, style)
11
11
  end
12
12
 
13
+ Paperclip.interpolates(:attachments_path_name) do |attachment, style|
14
+ record = attachment.instance
15
+ return record.attachments_path_name if record.respond_to?(:attachments_path_name)
16
+ self.attachment(attachment, style)
17
+ end
18
+
13
19
  Paperclip.interpolates(:pageflow_placeholder) do |attachment, style|
14
20
  Pageflow::PaperclipInterpolations::Support.pageflow_placeholder(attachment, style)
15
21
  end
@@ -55,9 +55,9 @@ Pageflow::Engine.routes.draw do
55
55
  resources :files,
56
56
  path: 'files/:collection_name',
57
57
  only: [:index, :create, :update, :destroy] do
58
- post :empty, on: :collection, to: 'files#create'
59
58
  post :reuse, on: :collection
60
59
  post :retry, on: :member
60
+ put :publish, on: :member
61
61
  end
62
62
  end
63
63
 
@@ -0,0 +1,16 @@
1
+ class ChangeProcessedAttachmentToAttachmentOnS3ForImages < ActiveRecord::Migration[5.2]
2
+ def change
3
+ rename_column :pageflow_image_files,
4
+ :processed_attachment_file_name,
5
+ :attachment_on_s3_file_name
6
+ rename_column :pageflow_image_files,
7
+ :processed_attachment_content_type,
8
+ :attachment_on_s3_content_type
9
+ rename_column :pageflow_image_files,
10
+ :processed_attachment_file_size,
11
+ :attachment_on_s3_file_size
12
+ rename_column :pageflow_image_files,
13
+ :processed_attachment_updated_at,
14
+ :attachment_on_s3_updated_at
15
+ end
16
+ end
@@ -0,0 +1,25 @@
1
+ class CopyFileAttributesOfFailedUploads < ActiveRecord::Migration[5.2]
2
+ def up
3
+ %w(audio text_track video).each do |hosted_file_type|
4
+ execute("UPDATE pageflow_#{hosted_file_type}_files hf
5
+ SET hf.attachment_on_s3_file_name = hf.attachment_on_filesystem_file_name,
6
+ hf.attachment_on_s3_content_type = hf.attachment_on_filesystem_content_type,
7
+ hf.attachment_on_s3_file_size = hf.attachment_on_filesystem_file_size,
8
+ hf.attachment_on_s3_updated_at = hf.attachment_on_filesystem_updated_at,
9
+ hf.state = 'uploading_failed'
10
+ WHERE hf.state = 'uploading_to_s3_failed';")
11
+ end
12
+ end
13
+
14
+ def down
15
+ %w(audio text_track video).each do |hosted_file_type|
16
+ execute("UPDATE pageflow_#{hosted_file_type}_files hf
17
+ SET hf.attachment_on_s3_file_name = NULL,
18
+ hf.attachment_on_s3_content_type = NULL,
19
+ hf.attachment_on_s3_file_size = NULL,
20
+ hf.attachment_on_s3_updated_at = NULL,
21
+ hf.state = 'uploading_to_s3_failed'
22
+ WHERE hf.state = 'uploading_failed';")
23
+ end
24
+ end
25
+ end
@@ -1,10 +1,6 @@
1
1
  module Pageflow
2
2
  # Options to be defined in the pageflow initializer of the main app.
3
3
  class Configuration
4
- # Default options for paperclip attachments which are supposed to
5
- # use filesystem storage.
6
- attr_accessor :paperclip_filesystem_default_options
7
-
8
4
  # Default options for paperclip attachments which are supposed to use
9
5
  # s3 storage.
10
6
  attr_accessor :paperclip_s3_default_options
@@ -26,6 +22,16 @@ module Pageflow
26
22
  # @since 13.0
27
23
  attr_accessor :paperclip_s3_root
28
24
 
25
+ # Upload options provided to direct upload form.
26
+ # Defaults to S3 storage options.
27
+ # returns a hash with keys:
28
+ # - url: The URL to use as the action of the form
29
+ # - fields: A hash of fields that will be included in the direct upload form.
30
+ # This hash should include the signed POST policy, the access key ID and
31
+ # security token (if present), etc.
32
+ # These fields will be included as input elements of type 'hidden' on the form
33
+ attr_accessor :paperclip_direct_upload_options
34
+
29
35
  # Refer to the pageflow initializer template for a list of
30
36
  # supported options.
31
37
  attr_accessor :zencoder_options
@@ -314,9 +320,21 @@ module Pageflow
314
320
  @paperclip_filesystem_root = Rails.public_path.join('system/uploads')
315
321
  @paperclip_s3_root = 'main'
316
322
 
317
- @paperclip_filesystem_default_options = Defaults::PAPERCLIP_FILESYSTEM_DEFAULT_OPTIONS.dup
318
323
  @paperclip_s3_default_options = Defaults::PAPERCLIP_S3_DEFAULT_OPTIONS.dup
319
324
 
325
+ @paperclip_direct_upload_options = lambda { |attachment|
326
+ max_upload_size = 4_294_967_296 # max file size in bytes
327
+ presigned_post_config = attachment.s3_bucket
328
+ .presigned_post(key: attachment.path,
329
+ success_action_status: '201',
330
+ acl: 'public-read',
331
+ content_length_range: 0..max_upload_size)
332
+ {
333
+ url: presigned_post_config.url,
334
+ fields: presigned_post_config.fields
335
+ }
336
+ }
337
+
320
338
  @zencoder_options = {}
321
339
 
322
340
  @mailer_sender = 'pageflow@example.com'
@@ -1,20 +1,13 @@
1
1
  module Pageflow
2
2
  class Configuration
3
3
  module Defaults
4
- PAPERCLIP_FILESYSTEM_DEFAULT_OPTIONS = {
5
- storage: :filesystem,
6
- path: ':pageflow_filesystem_root/:class/:attachment/:id_partition/:style/:filename',
7
- url: 'not_uploaded_yet',
8
- validate_media_type: false
9
- }.freeze
10
-
11
4
  PAPERCLIP_S3_DEFAULT_OPTIONS = {
12
5
  storage: :s3,
13
6
  s3_headers: {'Cache-Control' => 'public, max-age=31536000'},
14
7
 
15
8
  url: ':s3_alias_url',
16
- path: ':pageflow_s3_root/:class_basename/:attachment/' \
17
- ':id_partition/:pageflow_attachments_version:style/:filename',
9
+ path: ':pageflow_s3_root/:class_basename/:attachments_path_name/' \
10
+ ':id_partition/:pageflow_attachments_version:style/:filename',
18
11
 
19
12
  validate_media_type: false,
20
13
 
@@ -1,3 +1,3 @@
1
1
  module Pageflow
2
- VERSION = '13.6.0'.freeze
2
+ VERSION = '14.0.0.beta1'.freeze
3
3
  end
@@ -4,7 +4,8 @@ module Pageflow
4
4
  entry
5
5
  uploader { create(:user) }
6
6
 
7
- attachment_on_s3 { File.open(Engine.root.join('spec', 'fixtures', 'et.ogg')) }
7
+ attachment { File.open(Engine.root.join('spec', 'fixtures', 'et.ogg')) }
8
+ state { 'encoded' }
8
9
 
9
10
  transient do
10
11
  used_in { nil }
@@ -18,16 +19,23 @@ module Pageflow
18
19
  create(:file_usage, :file => file, :revision => evaluator.used_in) if evaluator.used_in
19
20
  end
20
21
 
21
- trait :on_filesystem do
22
- attachment_on_filesystem { File.open(Engine.root.join('spec', 'fixtures', 'et.ogg')) }
23
- attachment_on_s3 { nil }
24
- state { 'not_uploaded_to_s3' }
22
+ trait :uploading do
23
+ attachment { nil }
24
+ file_name { 'et.ogg' }
25
+ state { 'uploading' }
26
+
27
+ after :create do |audio_file|
28
+ simulate_direct_upload(audio_file)
29
+ end
30
+ end
31
+
32
+ trait :uploaded do
33
+ uploading
34
+ state { 'uploaded' }
25
35
  end
26
36
 
27
- trait :uploading_to_s3_failed do
28
- attachment_on_filesystem { File.open(Engine.root.join('spec', 'fixtures', 'et.ogg')) }
29
- attachment_on_s3 { nil }
30
- state { 'uploading_to_s3_failed' }
37
+ trait :uploading_failed do
38
+ state { 'uploading_failed' }
31
39
  end
32
40
 
33
41
  trait :waiting_for_confirmation do
@@ -39,7 +47,6 @@ module Pageflow
39
47
  end
40
48
 
41
49
  trait :encoded do
42
- state { 'encoded' }
43
50
  end
44
51
  end
45
52
  end
@@ -1,8 +1,8 @@
1
1
  module Pageflow
2
2
  FactoryBot.define do
3
3
  factory :hosted_file, class: 'Pageflow::TestHostedFile' do
4
- attachment_on_s3 { File.open(Engine.root.join('spec', 'fixtures', 'image.png')) }
5
- state { 'uploaded_to_s3' }
4
+ attachment { File.open(Engine.root.join('spec', 'fixtures', 'image.png')) }
5
+ state { 'uploaded' }
6
6
 
7
7
  transient do
8
8
  used_in { nil }
@@ -12,19 +12,21 @@ module Pageflow
12
12
  create(:file_usage, file: file, revision: evaluator.used_in) if evaluator.used_in
13
13
  end
14
14
 
15
- trait :on_filesystem do
16
- attachment_on_filesystem { File.open(Engine.root.join('spec', 'fixtures', 'image.png')) }
17
- attachment_on_s3 { nil }
18
- state { 'not_uploaded_to_s3' }
15
+ trait :uploading do
16
+ attachment { nil }
17
+ file_name { 'image.jpg' }
18
+ state { 'uploading' }
19
+
20
+ after :create do |hosted_file|
21
+ simulate_direct_upload(hosted_file)
22
+ end
19
23
  end
20
24
 
21
- trait :uploading_to_s3_failed do
22
- attachment_on_filesystem { File.open(Engine.root.join('spec', 'fixtures', 'image.png')) }
23
- attachment_on_s3 { nil }
24
- state { 'uploading_to_s3_failed' }
25
+ trait :uploaded do
25
26
  end
26
27
 
27
- trait :uploaded_to_s3 do
28
+ trait :uploading_failed do
29
+ state { 'uploading_failed' }
28
30
  end
29
31
  end
30
32
  end