From 0e5548804613f23b4e0303455a0086e98895d48f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Gaya?= <sebastien.gaya@gmail.com> Date: Thu, 21 Oct 2021 18:41:44 +0200 Subject: [PATCH] medium --- .../communication/websites_controller.rb | 4 +- .../communication/website/imported/medium.rb | 78 ++++++++++--------- .../communication/website/imported/page.rb | 9 ++- .../communication/website/imported/post.rb | 3 + app/models/communication/website/medium.rb | 68 ++++++++++++++++ app/models/communication/website/post.rb | 1 + .../communication/websites/import.html.erb | 6 +- ...2416_create_communication_website_media.rb | 14 ++++ ...to_communication_website_imported_media.rb | 5 ++ ...in_communication_website_imported_media.rb | 8 ++ ...to_communication_website_imported_media.rb | 5 ++ db/schema.rb | 27 +++++-- .../communication/website/imported/media.yml | 24 +++--- test/fixtures/communication/website/media.yml | 32 ++++++++ .../website/imported/medium_test.rb | 24 +++--- .../communication/website/medium_test.rb | 31 ++++++++ 16 files changed, 265 insertions(+), 74 deletions(-) create mode 100644 app/models/communication/website/medium.rb create mode 100644 db/migrate/20211021132416_create_communication_website_media.rb create mode 100644 db/migrate/20211021132440_add_medium_to_communication_website_imported_media.rb create mode 100644 db/migrate/20211021144633_replace_datetimes_in_communication_website_imported_media.rb create mode 100644 db/migrate/20211021152728_add_mime_type_to_communication_website_imported_media.rb create mode 100644 test/fixtures/communication/website/media.yml create mode 100644 test/models/communication/website/medium_test.rb diff --git a/app/controllers/admin/communication/websites_controller.rb b/app/controllers/admin/communication/websites_controller.rb index fbe9b765d..4a96cf0be 100644 --- a/app/controllers/admin/communication/websites_controller.rb +++ b/app/controllers/admin/communication/websites_controller.rb @@ -22,8 +22,8 @@ class Admin::Communication::WebsitesController < Admin::Communication::Applicati @imported_website = @website.imported_website @imported_pages = @imported_website.pages.page params[:pages_page] @imported_posts = @imported_website.posts.page params[:posts_page] - @imported_media = @imported_website.media.with_attached_file.page params[:media_page] - @imported_media_total_size = @imported_website.media.joins(file_attachment: :blob).sum(:byte_size) + @imported_media = @imported_website.media.includes(medium: { file_attachment: :blob }).page params[:media_page] + @imported_media_total_size = @imported_website.media.joins(medium: { file_attachment: :blob }).sum(:byte_size) breadcrumb add_breadcrumb Communication::Website::Imported::Website.model_name.human end diff --git a/app/models/communication/website/imported/medium.rb b/app/models/communication/website/imported/medium.rb index ad2308180..0331b0903 100644 --- a/app/models/communication/website/imported/medium.rb +++ b/app/models/communication/website/imported/medium.rb @@ -2,25 +2,27 @@ # # Table name: communication_website_imported_media # -# id :uuid not null, primary key -# data :jsonb -# file_url :text -# filename :string -# identifier :string -# remote_created_at :datetime -# remote_updated_at :datetime -# created_at :datetime not null -# updated_at :datetime not null -# university_id :uuid not null -# website_id :uuid not null +# id :uuid not null, primary key +# data :jsonb +# file_url :text +# filename :string +# identifier :string +# mime_type :string +# created_at :datetime +# updated_at :datetime +# medium_id :uuid +# university_id :uuid not null +# website_id :uuid not null # # Indexes # +# index_communication_website_imported_media_on_medium_id (medium_id) # index_communication_website_imported_media_on_university_id (university_id) # index_communication_website_imported_media_on_website_id (website_id) # # Foreign Keys # +# fk_rails_... (medium_id => communication_website_media.id) # fk_rails_... (university_id => universities.id) # fk_rails_... (website_id => communication_website_imported_websites.id) # @@ -28,43 +30,43 @@ class Communication::Website::Imported::Medium < ApplicationRecord belongs_to :university belongs_to :website, class_name: 'Communication::Website::Imported::Website' + belongs_to :medium, + class_name: 'Communication::Website::Medium', + optional: true has_many :pages, class_name: 'Communication::Website::Imported::Page', foreign_key: :featured_medium_id has_many :posts, class_name: 'Communication::Website::Imported::Post', foreign_key: :featured_medium_id - has_one_attached :file - - after_commit :download_file_from_file_url, on: [:create, :update], if: :saved_change_to_file_url + before_validation :sync def data=(value) super value - escaped_source_url = Addressable::URI.parse(value['source_url']).display_uri.to_s - self.file_url = escaped_source_url - self.filename = File.basename(URI(escaped_source_url).path) - # TODO unify with page and post? - self.remote_created_at = DateTime.parse(value['date_gmt']) - self.remote_updated_at = DateTime.parse(value['modified_gmt']) + sanitized_file_url = Addressable::URI.parse(value['source_url']).display_uri.to_s # ASCII-only for URI + self.file_url = sanitized_file_url + self.filename = File.basename(URI(file_url).path) + self.mime_type = value['mime_type'] + self.created_at = value['date_gmt'] + self.updated_at = value['modified_gmt'] end protected - def download_file_from_file_url - uri = URI(file_url) - http = Net::HTTP.new(uri.host, uri.port) - http.use_ssl = true - # IUT Bordeaux Montaigne pb with certificate - http.verify_mode = OpenSSL::SSL::VERIFY_NONE - request = Net::HTTP::Get.new(uri.request_uri) - response = http.request(request) - tempfile = Tempfile.open("Osuny-ImportedMedium-#{SecureRandom.hex}", Dir.tmpdir) - begin - tempfile.binmode - tempfile.write(response.body) - tempfile.flush - tempfile.rewind - file.attach(io: tempfile, filename: filename, content_type: data['mime_type']) - ensure - tempfile.close! + def sync + if medium.nil? + self.medium = Communication::Website::Medium.new university: university, + website: website.website # Real website, not imported website + self.medium.save + else + # Continue only if there are remote changes + # Don't touch if there are local changes (page.updated_at > updated_at) + # Don't touch if there are no remote changes (page.updated_at == updated_at) + return unless updated_at > medium.updated_at end + puts "Update medium #{medium.id}" + medium.file_url = Addressable::URI.parse(file_url).display_uri.to_s # ASCII-only for ActiveStorage + medium.filename = File.basename(URI(medium.file_url).path) + medium.mime_type = mime_type + medium.created_at = created_at + medium.updated_at = updated_at + medium.save end - handle_asynchronously :download_file_from_file_url, queue: 'default' end diff --git a/app/models/communication/website/imported/page.rb b/app/models/communication/website/imported/page.rb index 25f6fb93e..10de05dda 100644 --- a/app/models/communication/website/imported/page.rb +++ b/app/models/communication/website/imported/page.rb @@ -75,11 +75,12 @@ class Communication::Website::Imported::Page < ApplicationRecord slug: path self.page.title = "Untitled" self.page.save + else + # Continue only if there are remote changes + # Don't touch if there are local changes (page.updated_at > updated_at) + # Don't touch if there are no remote changes (page.updated_at == updated_at) + return unless updated_at > page.updated_at end - # Don't touch if there are local changes (this would destroy some nice work) - return if page.updated_at > updated_at - # Don't touch if there are no remote changes (this would do useless server workload) - return if page.updated_at == updated_at puts "Update page #{page.id}" page.slug = slug page.title = Wordpress.clean title.to_s diff --git a/app/models/communication/website/imported/post.rb b/app/models/communication/website/imported/post.rb index 20cc39941..19ecc883e 100644 --- a/app/models/communication/website/imported/post.rb +++ b/app/models/communication/website/imported/post.rb @@ -89,6 +89,9 @@ class Communication::Website::Imported::Post < ApplicationRecord post.created_at = created_at post.updated_at = updated_at post.published_at = published_at if published_at + if featured_medium.nil? + # Use first image in text as featured medium + end post.save end end diff --git a/app/models/communication/website/medium.rb b/app/models/communication/website/medium.rb new file mode 100644 index 000000000..b9fd23689 --- /dev/null +++ b/app/models/communication/website/medium.rb @@ -0,0 +1,68 @@ +# == Schema Information +# +# Table name: communication_website_media +# +# id :uuid not null, primary key +# file_url :text +# filename :string +# identifier :string +# mime_type :string +# created_at :datetime not null +# updated_at :datetime not null +# university_id :uuid not null +# website_id :uuid not null +# +# Indexes +# +# index_communication_website_media_on_university_id (university_id) +# index_communication_website_media_on_website_id (website_id) +# +# Foreign Keys +# +# fk_rails_... (university_id => universities.id) +# fk_rails_... (website_id => communication_websites.id) +# +class Communication::Website::Medium < ApplicationRecord + belongs_to :university + belongs_to :website + has_one :imported_medium, + class_name: 'Communication::Website::Imported::Medium', + foreign_key: :medium_id, + dependent: :destroy + + has_one_attached_deletable :file + + after_commit :download_file_from_file_url, on: [:create, :update], if: :saved_change_to_file_url + + protected + + def download_file_from_file_url + uri = URI(file_url) + http = Net::HTTP.new(uri.host, uri.port) + http.use_ssl = true + # IUT Bordeaux Montaigne pb with certificate + http.verify_mode = OpenSSL::SSL::VERIFY_NONE + request = Net::HTTP::Get.new(uri.request_uri) + response = http.request(request) + tempfile = Tempfile.open("Osuny-CommunicationWebsiteMedium-#{SecureRandom.hex}", Dir.tmpdir) + begin + tempfile.binmode + tempfile.write(response.body) + tempfile.flush + tempfile.rewind + file.attach(io: tempfile, filename: filename, content_type: mime_type) + set_featured_images + ensure + tempfile.close! + end + end + handle_asynchronously :download_file_from_file_url, queue: 'default' + + def set_featured_images + posts = Communication::Website::Post.joins(:imported_post) + .where(communication_website_imported_posts: { featured_medium_id: imported_medium.id }) + posts.each do |post| + post.featured_image.attach(io: URI.open(file.url), filename: filename, content_type: mime_type) + end + end +end diff --git a/app/models/communication/website/post.rb b/app/models/communication/website/post.rb index 1a146d187..8919f6b46 100644 --- a/app/models/communication/website/post.rb +++ b/app/models/communication/website/post.rb @@ -29,6 +29,7 @@ class Communication::Website::Post < ApplicationRecord include Communication::Website::WithGithub has_rich_text :text + has_one_attached_deletable :featured_image belongs_to :university belongs_to :website, diff --git a/app/views/admin/communication/websites/import.html.erb b/app/views/admin/communication/websites/import.html.erb index 086d4f676..4b8432431 100644 --- a/app/views/admin/communication/websites/import.html.erb +++ b/app/views/admin/communication/websites/import.html.erb @@ -84,11 +84,11 @@ <% @imported_media.each do |medium| %> <tr> <td><%= medium.filename %></td> - <td><%= number_to_human_size(medium.file.blob.byte_size) if medium.file.attached? %></td> + <td><%= number_to_human_size(medium.medium.file.blob.byte_size) if medium.medium&.file&.attached? %></td> <td class="text-end"> - <% if medium.file.attached? %> + <% if medium.medium&.file&.attached? %> <%= link_to t('show'), - url_for(medium.file), + url_for(medium.medium.file), class: button_classes, target: :blank %> <% else %> diff --git a/db/migrate/20211021132416_create_communication_website_media.rb b/db/migrate/20211021132416_create_communication_website_media.rb new file mode 100644 index 000000000..4c67abade --- /dev/null +++ b/db/migrate/20211021132416_create_communication_website_media.rb @@ -0,0 +1,14 @@ +class CreateCommunicationWebsiteMedia < ActiveRecord::Migration[6.1] + def change + create_table :communication_website_media, id: :uuid do |t| + t.string :identifier + t.string :filename + t.string :mime_type + t.text :file_url + t.references :university, null: false, foreign_key: true, type: :uuid + t.references :website, null: false, foreign_key: { to_table: :communication_websites }, type: :uuid + + t.timestamps + end + end +end diff --git a/db/migrate/20211021132440_add_medium_to_communication_website_imported_media.rb b/db/migrate/20211021132440_add_medium_to_communication_website_imported_media.rb new file mode 100644 index 000000000..3c0ed4f57 --- /dev/null +++ b/db/migrate/20211021132440_add_medium_to_communication_website_imported_media.rb @@ -0,0 +1,5 @@ +class AddMediumToCommunicationWebsiteImportedMedia < ActiveRecord::Migration[6.1] + def change + add_reference :communication_website_imported_media, :medium, foreign_key: { to_table: :communication_website_media }, type: :uuid + end +end diff --git a/db/migrate/20211021144633_replace_datetimes_in_communication_website_imported_media.rb b/db/migrate/20211021144633_replace_datetimes_in_communication_website_imported_media.rb new file mode 100644 index 000000000..667fb85a3 --- /dev/null +++ b/db/migrate/20211021144633_replace_datetimes_in_communication_website_imported_media.rb @@ -0,0 +1,8 @@ +class ReplaceDatetimesInCommunicationWebsiteImportedMedia < ActiveRecord::Migration[6.1] + def change + remove_column :communication_website_imported_media, :created_at, :datetime + remove_column :communication_website_imported_media, :updated_at, :datetime + rename_column :communication_website_imported_media, :remote_created_at, :created_at + rename_column :communication_website_imported_media, :remote_updated_at, :updated_at + end +end diff --git a/db/migrate/20211021152728_add_mime_type_to_communication_website_imported_media.rb b/db/migrate/20211021152728_add_mime_type_to_communication_website_imported_media.rb new file mode 100644 index 000000000..22a217137 --- /dev/null +++ b/db/migrate/20211021152728_add_mime_type_to_communication_website_imported_media.rb @@ -0,0 +1,5 @@ +class AddMimeTypeToCommunicationWebsiteImportedMedia < ActiveRecord::Migration[6.1] + def change + add_column :communication_website_imported_media, :mime_type, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 84ec856e3..f632ae2c0 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2021_10_21_095157) do +ActiveRecord::Schema.define(version: 2021_10_21_152728) do # These are extensions that must be enabled in order to support this database enable_extension "pgcrypto" @@ -82,13 +82,14 @@ ActiveRecord::Schema.define(version: 2021_10_21_095157) do t.string "identifier" t.jsonb "data" t.text "file_url" - t.datetime "remote_created_at" - t.datetime "remote_updated_at" + t.datetime "created_at" + t.datetime "updated_at" t.uuid "university_id", null: false t.uuid "website_id", null: false - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false t.string "filename" + t.uuid "medium_id" + t.string "mime_type" + t.index ["medium_id"], name: "index_communication_website_imported_media_on_medium_id" t.index ["university_id"], name: "index_communication_website_imported_media_on_university_id" t.index ["website_id"], name: "index_communication_website_imported_media_on_website_id" end @@ -149,6 +150,19 @@ ActiveRecord::Schema.define(version: 2021_10_21_095157) do t.index ["website_id"], name: "index_communication_website_imported_websites_on_website_id" end + create_table "communication_website_media", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.string "identifier" + t.string "filename" + t.string "mime_type" + t.text "file_url" + t.uuid "university_id", null: false + t.uuid "website_id", null: false + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["university_id"], name: "index_communication_website_media_on_university_id" + t.index ["website_id"], name: "index_communication_website_media_on_website_id" + end + create_table "communication_website_pages", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.uuid "communication_website_id", null: false @@ -366,6 +380,7 @@ ActiveRecord::Schema.define(version: 2021_10_21_095157) do add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id" add_foreign_key "administration_qualiopi_indicators", "administration_qualiopi_criterions", column: "criterion_id" add_foreign_key "communication_website_imported_media", "communication_website_imported_websites", column: "website_id" + add_foreign_key "communication_website_imported_media", "communication_website_media", column: "medium_id" add_foreign_key "communication_website_imported_media", "universities" add_foreign_key "communication_website_imported_pages", "communication_website_imported_media", column: "featured_medium_id" add_foreign_key "communication_website_imported_pages", "communication_website_imported_websites", column: "website_id" @@ -377,6 +392,8 @@ ActiveRecord::Schema.define(version: 2021_10_21_095157) do add_foreign_key "communication_website_imported_posts", "universities" add_foreign_key "communication_website_imported_websites", "communication_websites", column: "website_id" add_foreign_key "communication_website_imported_websites", "universities" + add_foreign_key "communication_website_media", "communication_websites", column: "website_id" + add_foreign_key "communication_website_media", "universities" add_foreign_key "communication_website_pages", "communication_website_pages", column: "parent_id" add_foreign_key "communication_website_pages", "communication_websites" add_foreign_key "communication_website_pages", "universities" diff --git a/test/fixtures/communication/website/imported/media.yml b/test/fixtures/communication/website/imported/media.yml index 3414bff4c..a0c0f6823 100644 --- a/test/fixtures/communication/website/imported/media.yml +++ b/test/fixtures/communication/website/imported/media.yml @@ -2,25 +2,27 @@ # # Table name: communication_website_imported_media # -# id :uuid not null, primary key -# data :jsonb -# file_url :text -# filename :string -# identifier :string -# remote_created_at :datetime -# remote_updated_at :datetime -# created_at :datetime not null -# updated_at :datetime not null -# university_id :uuid not null -# website_id :uuid not null +# id :uuid not null, primary key +# data :jsonb +# file_url :text +# filename :string +# identifier :string +# mime_type :string +# created_at :datetime +# updated_at :datetime +# medium_id :uuid +# university_id :uuid not null +# website_id :uuid not null # # Indexes # +# index_communication_website_imported_media_on_medium_id (medium_id) # index_communication_website_imported_media_on_university_id (university_id) # index_communication_website_imported_media_on_website_id (website_id) # # Foreign Keys # +# fk_rails_... (medium_id => communication_website_media.id) # fk_rails_... (university_id => universities.id) # fk_rails_... (website_id => communication_website_imported_websites.id) # diff --git a/test/fixtures/communication/website/media.yml b/test/fixtures/communication/website/media.yml new file mode 100644 index 000000000..d50a108ec --- /dev/null +++ b/test/fixtures/communication/website/media.yml @@ -0,0 +1,32 @@ +# == Schema Information +# +# Table name: communication_website_media +# +# id :uuid not null, primary key +# file_url :text +# filename :string +# identifier :string +# mime_type :string +# created_at :datetime not null +# updated_at :datetime not null +# university_id :uuid not null +# website_id :uuid not null +# +# Indexes +# +# index_communication_website_media_on_university_id (university_id) +# index_communication_website_media_on_website_id (website_id) +# +# Foreign Keys +# +# fk_rails_... (university_id => universities.id) +# fk_rails_... (website_id => communication_websites.id) +# + +one: + university: one + website: one + +two: + university: two + website: two diff --git a/test/models/communication/website/imported/medium_test.rb b/test/models/communication/website/imported/medium_test.rb index c084dcee9..e20280d2a 100644 --- a/test/models/communication/website/imported/medium_test.rb +++ b/test/models/communication/website/imported/medium_test.rb @@ -2,25 +2,27 @@ # # Table name: communication_website_imported_media # -# id :uuid not null, primary key -# data :jsonb -# file_url :text -# filename :string -# identifier :string -# remote_created_at :datetime -# remote_updated_at :datetime -# created_at :datetime not null -# updated_at :datetime not null -# university_id :uuid not null -# website_id :uuid not null +# id :uuid not null, primary key +# data :jsonb +# file_url :text +# filename :string +# identifier :string +# mime_type :string +# created_at :datetime +# updated_at :datetime +# medium_id :uuid +# university_id :uuid not null +# website_id :uuid not null # # Indexes # +# index_communication_website_imported_media_on_medium_id (medium_id) # index_communication_website_imported_media_on_university_id (university_id) # index_communication_website_imported_media_on_website_id (website_id) # # Foreign Keys # +# fk_rails_... (medium_id => communication_website_media.id) # fk_rails_... (university_id => universities.id) # fk_rails_... (website_id => communication_website_imported_websites.id) # diff --git a/test/models/communication/website/medium_test.rb b/test/models/communication/website/medium_test.rb new file mode 100644 index 000000000..216a43e11 --- /dev/null +++ b/test/models/communication/website/medium_test.rb @@ -0,0 +1,31 @@ +# == Schema Information +# +# Table name: communication_website_media +# +# id :uuid not null, primary key +# file_url :text +# filename :string +# identifier :string +# mime_type :string +# created_at :datetime not null +# updated_at :datetime not null +# university_id :uuid not null +# website_id :uuid not null +# +# Indexes +# +# index_communication_website_media_on_university_id (university_id) +# index_communication_website_media_on_website_id (website_id) +# +# Foreign Keys +# +# fk_rails_... (university_id => universities.id) +# fk_rails_... (website_id => communication_websites.id) +# +require "test_helper" + +class Communication::Website::MediumTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end -- GitLab