diff --git a/app/models/communication/website.rb b/app/models/communication/website.rb index 31b134effe1672da24f45207acf0b84bb9b1fd71..15048d7d5e32eeaa48510b9a30b56809409c0fe6 100644 --- a/app/models/communication/website.rb +++ b/app/models/communication/website.rb @@ -54,6 +54,9 @@ class Communication::Website < ApplicationRecord has_one :imported_website, class_name: 'Communication::Website::Imported::Website', dependent: :destroy + has_many :github_files, + class_name: 'Communication::Website::GithubFile', + dependent: :destroy after_create :create_home after_save :publish_about_object, if: :saved_change_to_about_id? diff --git a/app/models/communication/website/github_file.rb b/app/models/communication/website/github_file.rb index 9f456c6e97d5a5d72e22dc24cd1bfe577f7edf8f..17aa444517ca08198c3f580f910f9a72d2867926 100644 --- a/app/models/communication/website/github_file.rb +++ b/app/models/communication/website/github_file.rb @@ -27,17 +27,42 @@ class Communication::Website::GithubFile < ApplicationRecord def publish return unless github.valid? - if github.publish(path: about.github_path_generated, - previous_path: github_path, - commit: github_commit_message, - data: about.to_jekyll(self)) + params = github_params.merge({ + commit: github_commit_message + }) + if github.publish(params) update_column :github_path, about.github_path_generated + publish_media end end handle_asynchronously :publish, queue: 'default' + def publish_media + return unless about.respond_to?(:active_storage_blobs) + about.active_storage_blobs.each { |blob| publish_blob(blob) } + end + + def publish_blob(blob) + return unless github.valid? + params = github_blob_params(blob).merge({ + commit: github_blob_commit_message(blob) + }) + github.publish(params) + end + handle_asynchronously :publish_blob, queue: 'default' + def add_to_batch(github) + github.add_to_batch github_params + add_media_to_batch(github) + end + + def add_media_to_batch(github) + return unless about.respond_to?(:active_storage_blobs) + about.active_storage_blobs.each { |blob| add_blob_to_batch(github, blob) } + end + def add_blob_to_batch(github, blob) + github.add_to_batch github_blob_params(blob) end def github_frontmatter @@ -60,10 +85,34 @@ class Communication::Website::GithubFile < ApplicationRecord @github ||= Github.with_website(website) end + def github_params + { + path: about.github_path_generated, + previous_path: github_path, + data: about.to_jekyll(self) + } + end + + def github_blob_params(blob) + blob.analyze unless blob.analyzed? + { + path: "_data/media/#{blob.id[0..1]}/#{blob.id}.yml", + data: ApplicationController.render( + template: 'active_storage/blobs/jekyll', + layout: false, + assigns: { blob: blob } + ) + } + end + def github_commit_message "[#{about.class.name.demodulize}] Save #{about.to_s}" end + def github_blob_commit_message(blob) + "[Medium] Save ##{blob.id}" + end + def github_remove_commit_message "[#{about.class.name.demodulize}] Remove #{about.to_s}" end diff --git a/app/models/communication/website/imported/website.rb b/app/models/communication/website/imported/website.rb index 06ccdf35c67358f42ff18d7ebc2cb0b255bf5420..9dabc4851e20c763a92732d8d385bb5fce8a225f 100644 --- a/app/models/communication/website/imported/website.rb +++ b/app/models/communication/website/imported/website.rb @@ -60,7 +60,7 @@ class Communication::Website::Imported::Website < ApplicationRecord def sync_authors begin - Communication::Website::Author.skip_callback(:save, :after, :publish_to_github) + Communication::Website::Author.skip_callback(:save, :after, :publish_github_files) wordpress.authors.each do |data| author = authors.where(university: university, identifier: data['id']).first_or_initialize author.data = data @@ -69,13 +69,13 @@ class Communication::Website::Imported::Website < ApplicationRecord # Batch update all changes (1 query only, good for github API limits) website.publish_authors! ensure - Communication::Website::Author.set_callback(:save, :after, :publish_to_github) + Communication::Website::Author.set_callback(:save, :after, :publish_github_files) end end def sync_categories begin - Communication::Website::Category.skip_callback(:save, :after, :publish_to_github) + Communication::Website::Category.skip_callback(:save, :after, :publish_github_files) wordpress.categories.each do |data| category = categories.where(university: university, identifier: data['id']).first_or_initialize category.data = data @@ -85,7 +85,7 @@ class Communication::Website::Imported::Website < ApplicationRecord # Batch update all changes (1 query only, good for github API limits) website.publish_categories! ensure - Communication::Website::Category.set_callback(:save, :after, :publish_to_github) + Communication::Website::Category.set_callback(:save, :after, :publish_github_files) end end @@ -99,7 +99,7 @@ class Communication::Website::Imported::Website < ApplicationRecord def sync_pages begin - Communication::Website::Page.skip_callback(:save, :after, :publish_to_github) + Communication::Website::Page.skip_callback(:save, :after, :publish_github_files) wordpress.pages.each do |data| page = pages.where(university: university, identifier: data['id']).first_or_initialize page.data = data @@ -109,13 +109,13 @@ class Communication::Website::Imported::Website < ApplicationRecord # Batch update all changes (1 query only, good for github API limits) website.publish_pages! ensure - Communication::Website::Page.set_callback(:save, :after, :publish_to_github) + Communication::Website::Page.set_callback(:save, :after, :publish_github_files) end end def sync_posts begin - Communication::Website::Post.skip_callback(:save, :after, :publish_to_github) + Communication::Website::Post.skip_callback(:save, :after, :publish_github_files) wordpress.posts.each do |data| post = posts.where(university: university, identifier: data['id']).first_or_initialize post.data = data @@ -124,7 +124,7 @@ class Communication::Website::Imported::Website < ApplicationRecord # Batch update all changes (1 query only, good for github API limits) website.publish_posts! ensure - Communication::Website::Post.set_callback(:save, :after, :publish_to_github) + Communication::Website::Post.set_callback(:save, :after, :publish_github_files) end end diff --git a/app/models/communication/website/with_batch_publication.rb b/app/models/communication/website/with_batch_publication.rb index 9fe423ed0047f417e6b1ae1a8bfbaf2b2a4ee03c..0692613531fa46127f9f0dc07ceaba68ad26326c 100644 --- a/app/models/communication/website/with_batch_publication.rb +++ b/app/models/communication/website/with_batch_publication.rb @@ -3,103 +3,59 @@ module Communication::Website::WithBatchPublication included do def force_publish! - publish_authors! - publish_categories! - publish_pages! - publish_posts! - publish_menus! - publish_school! if about.is_a?(Education::School) - publish_journal! if about.is_a?(Research::Journal) + commit_files_in_batch github_files, + "[Website] Batch update from import" end handle_asynchronously :force_publish!, queue: 'default' def publish_authors! - publish_objects(Communication::Website::Author, authors) + commit_files_in_batch github_files.where(about_type: "Communication::Website::Author"), + "[Author] Batch update from import" end def publish_categories! - publish_objects(Communication::Website::Category, categories) + commit_files_in_batch github_files.where(about_type: "Communication::Website::Category"), + "[Category] Batch update from import" end def publish_pages! - publish_objects_with_blobs(Communication::Website::Page, pages) + commit_files_in_batch github_files.where(about_type: "Communication::Website::Page"), + "[Page] Batch update from import" end def publish_posts! - publish_objects_with_blobs(Communication::Website::Post, posts) + commit_files_in_batch github_files.where(about_type: "Communication::Website::Post"), + "[Post] Batch update from import" end def publish_menus! - publish_objects(Communication::Website::Menu, menus) + commit_files_in_batch github_files.where(about_type: "Communication::Website::Menu"), + "[Menu] Batch update from import" end def publish_school! - github.publish(path: about.github_path, commit: "[School] Save #{about.to_s}", data: about.to_jekyll) - publish_shared_objects(Education::Program, about.programs) - publish_shared_objects(Education::Teacher, about.teachers) + commit_files_in_batch github_files.where(about_type: [ + "Education::School", + "Education::Program", + "Education::Teacher" + ]), + "[Education School/Program/Teacher] Batch update from import" end def publish_journal! - github.publish(path: about.github_path, commit: "[Journal] Save #{about.to_s}", data: about.to_jekyll) - publish_shared_objects(Research::Article, about.articles) - publish_shared_objects(Research::Volume, about.volumes) + commit_files_in_batch github_files.where(about_type: [ + "Research::Journal", + "Research::Journal::Article", + "Research::Journal::Volume" + ]), + "[Research Journal/Article/Volume] Batch update from import" end protected - def publish_objects(model, objects) - return if objects.empty? - begin - had_callback = model.__callbacks[:save].find { |c| c.matches?(:after, :publish_to_github) } - model.skip_callback(:save, :after, :publish_to_github) if had_callback - return unless github.valid? - objects.each do |object| - github.add_to_batch path: object.github_path_generated, - previous_path: object.github_path, - data: object.to_jekyll - yield(github, object) if block_given? - end - github.commit_batch "[#{model.name.demodulize}] Batch update from import" - ensure - model.set_callback(:save, :after, :publish_to_github) if had_callback - end - end - - def publish_objects_with_blobs(model, objects) - publish_objects(model, objects) { |github, object| - object.active_storage_blobs.each do |blob| - blob.analyze unless blob.analyzed? - github_path = "_data/media/#{blob.id[0..1]}/#{blob.id}.yml" - data = ApplicationController.render( - template: 'active_storage/blobs/jekyll', - layout: false, - assigns: { blob: blob } - ) - github.add_to_batch(path: github_path, data: data) - end - } - end - - def publish_shared_objects(model, objects) - return if objects.empty? - begin - had_callback = model.__callbacks[:save].find { |c| c.matches?(:after, :publish_to_every_websites) } - model.skip_callback(:save, :after, :publish_to_every_websites) if had_callback - return unless github.valid? - clean_model_name = model.name.demodulize - objects.each do |object| - if object.respond_to?(:github_path) - github_path = object.github_path - else - root_folder = "_#{clean_model_name.pluralize.underscore}" - github_path = "#{root_folder}/#{object.id}.md" - end - github.add_to_batch(path: github_path, data: object.to_jekyll) - end - github.commit_batch "[#{clean_model_name}] Batch update from import" - ensure - model.set_callback(:save, :after, :publish_to_every_websites) if had_callback - end + def commit_files_in_batch(files, commit_message) + files.find_each { |file| file.add_to_batch(github) } + github.commit_batch commit_message end end diff --git a/app/models/communication/website/with_media.rb b/app/models/communication/website/with_media.rb index 3b354cdfc4c2c46e53659105b4053d405a5d7198..c4aad2b352486abc95685d5ba03e22f6d97d99d5 100644 --- a/app/models/communication/website/with_media.rb +++ b/app/models/communication/website/with_media.rb @@ -1,23 +1,8 @@ module Communication::Website::WithMedia extend ActiveSupport::Concern - included do - after_save_commit :publish_media_to_github - after_destroy :remove_media_from_github - end - def active_storage_blobs blob_ids = [featured_image&.blob_id, text.embeds.blobs.pluck(:id)].flatten.compact university.active_storage_blobs.where(id: blob_ids) end - - protected - - def publish_media_to_github - active_storage_blobs.each { |blob| website.publish_blob(blob) } - end - - def remove_media_from_github - active_storage_blobs.each { |blob| website.remove_blob(blob) } - end end