diff --git a/app/controllers/admin/communication/websites_controller.rb b/app/controllers/admin/communication/websites_controller.rb index fbe9b765d544c2fb14f878feb8132543d711135c..4a96cf0be729866238f1498871920ba00f95627d 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 ad230818055d9bfaca40ed60f3d5d334e612e17a..0331b0903883ef067fd51acc09d2a6dbdd6d222a 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 25f6fb93eedc267fe7c9ddb5eec79baa08f5a721..10de05dda6fa6dc5b171a435013b41a3820d8675 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 20cc39941bd034df58c6cd593eacd2b8fcd5570c..19ecc883ec4f27fc16425bcaeebb2e145ccac50b 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 0000000000000000000000000000000000000000..b9fd23689920c422d9da5264eb6d76743b6f6d2c --- /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 1a146d187481888ec496d019a611964221680804..8919f6b46c7d3b5799220342a97c2354840e3be4 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 086d4f676b9fbf4cb6e4d5e83b3b2fe71b23f26a..4b8432431f279e8391313a70d18aec98adfbbe4c 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 0000000000000000000000000000000000000000..4c67abade8feea97bd0fcffb95f673f070854b1e --- /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 0000000000000000000000000000000000000000..3c0ed4f57742afbced0b0394ffca67d73cab6bb8 --- /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 0000000000000000000000000000000000000000..667fb85a33073bf9aacd328a80206b080d6caeb0 --- /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 0000000000000000000000000000000000000000..22a217137337c5f970f3b89f38b629b820617db9 --- /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 84ec856e3dcd325301e07961061964a644bbc816..f632ae2c05a47280fa04d5f847ea48702ed15764 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 3414bff4c3836dd4bf5fe3edf65305dce2ee33c5..a0c0f6823d370b630e6177a9958909851f0c84eb 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 0000000000000000000000000000000000000000..d50a108ec6351ff3f1614dfd0c8ec421996adc89 --- /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 c084dcee90ecb6e7e80e343b3a0ed8befaae13ac..e20280d2ac70763aeb5aa83f87fc30cc341ac786 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 0000000000000000000000000000000000000000..216a43e11591b9fbfddb3429bca2636fbb99b0b8 --- /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