From c1baff9b862f56f2d3ab1fa439f7c85e13872a39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Gaya?= <sebastien.gaya@gmail.com> Date: Tue, 19 Oct 2021 14:08:39 +0200 Subject: [PATCH] imported media --- Gemfile | 1 + Gemfile.lock | 1 + .../communication/websites_controller.rb | 2 + .../communication/website/imported/medium.rb | 66 +++++++++++++++++++ .../communication/website/imported/website.rb | 11 ++++ app/models/research/journal/article.rb | 2 +- app/services/wordpress.rb | 4 ++ .../communication/websites/import.html.erb | 36 ++++++++++ config/locales/communication/en.yml | 5 ++ config/locales/communication/fr.yml | 5 ++ ...te_communication_website_imported_media.rb | 15 +++++ ...to_communication_website_imported_media.rb | 5 ++ db/schema.rb | 21 +++++- .../communication/website/imported/media.yml | 44 +++++++++++++ .../website/imported/medium_test.rb | 33 ++++++++++ 15 files changed, 248 insertions(+), 3 deletions(-) create mode 100644 app/models/communication/website/imported/medium.rb create mode 100644 db/migrate/20211019091847_create_communication_website_imported_media.rb create mode 100644 db/migrate/20211019102112_add_filename_to_communication_website_imported_media.rb create mode 100644 test/fixtures/communication/website/imported/media.yml create mode 100644 test/models/communication/website/imported/medium_test.rb diff --git a/Gemfile b/Gemfile index e9225d991..1f264b24e 100644 --- a/Gemfile +++ b/Gemfile @@ -8,6 +8,7 @@ gem 'pg', '~> 1.1' gem 'aws-sdk-s3' gem 'puma' gem 'image_processing' +gem 'mini_magick' gem 'delayed_job_active_record' gem 'delayed_job_web' gem 'bootsnap', '>= 1.4.4', require: false diff --git a/Gemfile.lock b/Gemfile.lock index aded56c9f..54f6ebefd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -401,6 +401,7 @@ DEPENDENCIES kamifusen kaminari listen (~> 3.3) + mini_magick octokit pg (~> 1.1) puma diff --git a/app/controllers/admin/communication/websites_controller.rb b/app/controllers/admin/communication/websites_controller.rb index 261658aac..fbe9b765d 100644 --- a/app/controllers/admin/communication/websites_controller.rb +++ b/app/controllers/admin/communication/websites_controller.rb @@ -22,6 +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) 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 new file mode 100644 index 000000000..e3d3ae8c0 --- /dev/null +++ b/app/models/communication/website/imported/medium.rb @@ -0,0 +1,66 @@ +# == Schema Information +# +# Table name: communication_website_imported_media +# +# id :uuid not null, primary key +# data :jsonb +# file_url :text +# 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 +# +# Indexes +# +# index_communication_website_imported_media_on_university_id (university_id) +# index_communication_website_imported_media_on_website_id (website_id) +# +# Foreign Keys +# +# fk_rails_... (university_id => universities.id) +# fk_rails_... (website_id => communication_website_imported_websites.id) +# +class Communication::Website::Imported::Medium < ApplicationRecord + belongs_to :university + belongs_to :website, + class_name: 'Communication::Website::Imported::Website' + + has_one_attached :file + + after_commit :download_file_from_file_url, on: [:create, :update], if: :saved_change_to_file_url + + 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) + self.remote_created_at = DateTime.parse(value['date_gmt']) + self.remote_updated_at = DateTime.parse(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! + end + end + handle_asynchronously :download_file_from_file_url, queue: 'default' +end diff --git a/app/models/communication/website/imported/website.rb b/app/models/communication/website/imported/website.rb index 962cd135a..612c30377 100644 --- a/app/models/communication/website/imported/website.rb +++ b/app/models/communication/website/imported/website.rb @@ -23,12 +23,15 @@ class Communication::Website::Imported::Website < ApplicationRecord belongs_to :university belongs_to :website, class_name: 'Communication::Website' + has_many :media, + class_name: 'Communication::Website::Imported::Medium' has_many :pages, class_name: 'Communication::Website::Imported::Page' has_many :posts, class_name: 'Communication::Website::Imported::Post' def run! + sync_media sync_pages sync_posts end @@ -39,6 +42,14 @@ class Communication::Website::Imported::Website < ApplicationRecord @wordpress ||= Wordpress.new website.domain_url end + def sync_media + wordpress.media.each do |data| + medium = media.where(university: university, identifier: data['id']).first_or_create + medium.data = data + medium.save + end + end + def sync_pages wordpress.pages.each do |data| page = pages.where(university: university, identifier: data['id']).first_or_create diff --git a/app/models/research/journal/article.rb b/app/models/research/journal/article.rb index 20a415c65..0410c664d 100644 --- a/app/models/research/journal/article.rb +++ b/app/models/research/journal/article.rb @@ -10,7 +10,7 @@ # text :text # title :string # created_at :datetime not null -# updated_at :date not null +# updated_at :datetime not null # research_journal_id :uuid not null # research_journal_volume_id :uuid # university_id :uuid not null diff --git a/app/services/wordpress.rb b/app/services/wordpress.rb index b30fa53f7..1d9fc1833 100644 --- a/app/services/wordpress.rb +++ b/app/services/wordpress.rb @@ -25,6 +25,10 @@ class Wordpress load "#{domain}/wp-json/wp/v2/pages" end + def media + load "#{domain}/wp-json/wp/v2/media" + end + protected def load(url) diff --git a/app/views/admin/communication/websites/import.html.erb b/app/views/admin/communication/websites/import.html.erb index a3ba7cf48..086d4f676 100644 --- a/app/views/admin/communication/websites/import.html.erb +++ b/app/views/admin/communication/websites/import.html.erb @@ -67,3 +67,39 @@ <%= paginate @imported_pages, param_name: :pages_page, theme: 'bootstrap-5' %> </div> </div> + +<div class="card mt-5"> + <div class="card-header"> + <h2><%= @imported_media.total_count %> media (<%= number_to_human_size(@imported_media_total_size) %>)</h2> + </div> + <table class="<%= table_classes %>"> + <thead> + <tr> + <th><%= Communication::Website::Imported::Medium.human_attribute_name('filename') %></th> + <th><%= t('communication.website.imported.media.file_size') %></th> + <th class="text-end" width="150"> </th> + </tr> + </thead> + <tbody> + <% @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 class="text-end"> + <% if medium.file.attached? %> + <%= link_to t('show'), + url_for(medium.file), + class: button_classes, + target: :blank %> + <% else %> + <%= t('communication.website.imported.media.not_imported_yet') %> + <% end %> + </td> + </tr> + <% end %> + </tbody> + </table> + <div class="card-footer"> + <%= paginate @imported_media, param_name: :media_page, theme: 'bootstrap-5' %> + </div> +</div> diff --git a/config/locales/communication/en.yml b/config/locales/communication/en.yml index 9623e9237..ad4de977c 100644 --- a/config/locales/communication/en.yml +++ b/config/locales/communication/en.yml @@ -3,6 +3,9 @@ en: website: imported: launch: Launch import + media: + file_size: File size + not_imported_yet: Not imported yet refresh: Refresh import show: Show import pending: Import in progress @@ -33,6 +36,8 @@ en: about_: Nothing (independent website) about_Research::Journal: Journal website about_School: School website + communication/website/imported/medium: + filename: Filename communication/website/page: title: Title description: Description (SEO) diff --git a/config/locales/communication/fr.yml b/config/locales/communication/fr.yml index f8c2eb904..a487c22d3 100644 --- a/config/locales/communication/fr.yml +++ b/config/locales/communication/fr.yml @@ -3,6 +3,9 @@ fr: website: imported: launch: Importer le site + media: + file_size: Taille du fichier + not_imported_yet: Non importé pour le moment refresh: Relancer l'import show: Voir l'import pending: Import en cours @@ -33,6 +36,8 @@ fr: about_: Aucun sujet (site indépendant) about_Research::Journal: Site de revue scientifique about_School: Site d'école + communication/website/imported/medium: + filename: Nom du fichier communication/website/page: title: Titre description: Description (SEO) diff --git a/db/migrate/20211019091847_create_communication_website_imported_media.rb b/db/migrate/20211019091847_create_communication_website_imported_media.rb new file mode 100644 index 000000000..b20ab7281 --- /dev/null +++ b/db/migrate/20211019091847_create_communication_website_imported_media.rb @@ -0,0 +1,15 @@ +class CreateCommunicationWebsiteImportedMedia < ActiveRecord::Migration[6.1] + def change + create_table :communication_website_imported_media, id: :uuid do |t| + t.string :identifier + t.jsonb :data + t.text :file_url + t.datetime :remote_created_at + t.datetime :remote_updated_at + t.references :university, null: false, foreign_key: true, type: :uuid + t.references :website, null: false, foreign_key: { to_table: :communication_website_imported_websites }, type: :uuid + + t.timestamps + end + end +end diff --git a/db/migrate/20211019102112_add_filename_to_communication_website_imported_media.rb b/db/migrate/20211019102112_add_filename_to_communication_website_imported_media.rb new file mode 100644 index 000000000..7233345e6 --- /dev/null +++ b/db/migrate/20211019102112_add_filename_to_communication_website_imported_media.rb @@ -0,0 +1,5 @@ +class AddFilenameToCommunicationWebsiteImportedMedia < ActiveRecord::Migration[6.1] + def change + add_column :communication_website_imported_media, :filename, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 683a249f5..7b3b61778 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_19_092503) do +ActiveRecord::Schema.define(version: 2021_10_19_102112) do # These are extensions that must be enabled in order to support this database enable_extension "pgcrypto" @@ -68,6 +68,21 @@ ActiveRecord::Schema.define(version: 2021_10_19_092503) do t.index ["criterion_id"], name: "index_administration_qualiopi_indicators_on_criterion_id" end + create_table "communication_website_imported_media", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.string "identifier" + t.jsonb "data" + t.text "file_url" + t.datetime "remote_created_at" + t.datetime "remote_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.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 + create_table "communication_website_imported_pages", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.uuid "website_id", null: false @@ -220,7 +235,7 @@ ActiveRecord::Schema.define(version: 2021_10_19_092503) do t.uuid "research_journal_id", null: false t.uuid "research_journal_volume_id" t.datetime "created_at", precision: 6, null: false - t.date "updated_at", null: false + t.datetime "updated_at", precision: 6, null: false t.uuid "updated_by_id" t.text "abstract" t.text "references" @@ -335,6 +350,8 @@ ActiveRecord::Schema.define(version: 2021_10_19_092503) do add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id" 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", "universities" add_foreign_key "communication_website_imported_pages", "communication_website_imported_websites", column: "website_id" add_foreign_key "communication_website_imported_pages", "communication_website_pages", column: "page_id" add_foreign_key "communication_website_imported_pages", "universities" diff --git a/test/fixtures/communication/website/imported/media.yml b/test/fixtures/communication/website/imported/media.yml new file mode 100644 index 000000000..3414bff4c --- /dev/null +++ b/test/fixtures/communication/website/imported/media.yml @@ -0,0 +1,44 @@ +# == Schema Information +# +# 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 +# +# Indexes +# +# index_communication_website_imported_media_on_university_id (university_id) +# index_communication_website_imported_media_on_website_id (website_id) +# +# Foreign Keys +# +# fk_rails_... (university_id => universities.id) +# fk_rails_... (website_id => communication_website_imported_websites.id) +# + +one: + university: one + identifier: MyString + website: one + data: + remote_created_at: 2021-10-19 11:18:47 + remote_updated_at: 2021-10-19 11:18:47 + file_url: MyText + +two: + university: two + identifier: MyString + website: two + data: + remote_created_at: 2021-10-19 11:18:47 + remote_updated_at: 2021-10-19 11:18:47 + file_url: MyText diff --git a/test/models/communication/website/imported/medium_test.rb b/test/models/communication/website/imported/medium_test.rb new file mode 100644 index 000000000..c084dcee9 --- /dev/null +++ b/test/models/communication/website/imported/medium_test.rb @@ -0,0 +1,33 @@ +# == Schema Information +# +# 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 +# +# Indexes +# +# index_communication_website_imported_media_on_university_id (university_id) +# index_communication_website_imported_media_on_website_id (website_id) +# +# Foreign Keys +# +# fk_rails_... (university_id => universities.id) +# fk_rails_... (website_id => communication_website_imported_websites.id) +# +require "test_helper" + +class Communication::Website::Imported::MediumTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end -- GitLab