From 3f776fc5178b0172c63a762b8ff7ca4fcd2d1b35 Mon Sep 17 00:00:00 2001
From: Arnaud Levy <contact@arnaudlevy.com>
Date: Sat, 23 Oct 2021 11:25:21 +0200
Subject: [PATCH] refactor wip

---
 .../communication/website/posts_controller.rb |   2 +-
 app/models/communication/website/page.rb      |   1 +
 app/models/communication/website/post.rb      |  31 ++++--
 .../communication/website/with_github.rb      |  14 +--
 app/models/research/journal/article.rb        |   2 +-
 app/services/github.rb                        | 104 ++++++++++++++----
 .../website/pages/jekyll.html.erb             |   2 +-
 .../website/posts/_form.html.erb              |   1 +
 .../website/posts/jekyll.html.erb             |   2 +-
 .../communication/website/posts/show.html.erb |   3 +-
 ..._add_path_to_communication_website_post.rb |   7 ++
 db/schema.rb                                  |   5 +-
 12 files changed, 126 insertions(+), 48 deletions(-)
 create mode 100644 db/migrate/20211023063050_add_path_to_communication_website_post.rb

diff --git a/app/controllers/admin/communication/website/posts_controller.rb b/app/controllers/admin/communication/website/posts_controller.rb
index ef53b51ce..72126a1cf 100644
--- a/app/controllers/admin/communication/website/posts_controller.rb
+++ b/app/controllers/admin/communication/website/posts_controller.rb
@@ -57,6 +57,6 @@ class Admin::Communication::Website::PostsController < Admin::Communication::Web
 
   def post_params
     params.require(:communication_website_post)
-          .permit(:university_id, :website_id, :title, :description, :text, :published, :published_at, :featured_image, :featured_image_delete)
+          .permit(:university_id, :website_id, :title, :description, :text, :published, :published_at, :featured_image, :featured_image_delete, :slug)
   end
 end
diff --git a/app/models/communication/website/page.rb b/app/models/communication/website/page.rb
index 09ba7a034..3c00cd34f 100644
--- a/app/models/communication/website/page.rb
+++ b/app/models/communication/website/page.rb
@@ -5,6 +5,7 @@
 #  id                       :uuid             not null, primary key
 #  about_type               :string
 #  description              :text
+#  github_path              :text
 #  path                     :text
 #  position                 :integer          default(0), not null
 #  published                :boolean          default(FALSE)
diff --git a/app/models/communication/website/post.rb b/app/models/communication/website/post.rb
index 731cccc51..fb5fcf313 100644
--- a/app/models/communication/website/post.rb
+++ b/app/models/communication/website/post.rb
@@ -4,7 +4,9 @@
 #
 #  id                       :uuid             not null, primary key
 #  description              :text
+#  github_path              :text
 #  old_text                 :text
+#  path                     :text
 #  published                :boolean          default(FALSE)
 #  published_at             :datetime
 #  slug                     :text
@@ -51,23 +53,28 @@ class Communication::Website::Post < ApplicationRecord
   protected
 
   def github_file
-    "#{published_at.year}/#{published_at.month}/#{published_at.strftime "%Y-%m-%d"}-#{id}.html"
+    "#{published_at.year}/#{published_at.month}/#{published_at.strftime "%Y-%m-%d"}-#{slug}.html"
   end
 
-  def github_path
-    "_posts/#{github_file}"
+  def github_path_generated
+    "_posts/#{published_at.year}/#{published_at.month}/#{published_at.strftime "%Y-%m-%d"}-#{slug}.html"
+  end
+
+  def jekyll
+    ApplicationController.render(
+      template: 'admin/communication/website/posts/jekyll',
+      layout: false,
+      assigns: { post: self }
+    )
   end
 
   def publish_to_github
     return if published_at.nil?
-    github.publish  kind: :posts,
-                    file: github_file,
-                    title: to_s,
-                    data: ApplicationController.render(
-                      template: 'admin/communication/website/posts/jekyll',
-                      layout: false,
-                      assigns: { post: self }
-                    )
+    github.publish  path: github_path_generated,
+                    previous_path: github_path,
+                    commit: "[post] Save #{title}",
+                    data: jekyll
+    update_column :github_path, github_path_generated
   end
-  handle_asynchronously :publish_to_github
+  # handle_asynchronously :publish_to_github
 end
diff --git a/app/models/communication/website/with_github.rb b/app/models/communication/website/with_github.rb
index 368f306c8..51148a60c 100644
--- a/app/models/communication/website/with_github.rb
+++ b/app/models/communication/website/with_github.rb
@@ -5,16 +5,12 @@ module Communication::Website::WithGithub
     after_save :publish_to_github
   end
 
-  def content
+  def github_content
     @content ||= github.read_file_at github_path
   end
 
-  def frontmatter
-    @frontmatter ||= FrontMatterParser::Parser.new(:md).call(content)
-  end
-
-  def content_without_frontmatter
-    frontmatter.content
+  def github_frontmatter
+    @frontmatter ||= FrontMatterParser::Parser.new(:md).call(github_content)
   end
 
   def github_file
@@ -22,7 +18,7 @@ module Communication::Website::WithGithub
   end
 
   # Needs override
-  def github_path
+  def github_path_generated
     ''
   end
 
@@ -37,5 +33,5 @@ module Communication::Website::WithGithub
     ''
   end
   handle_asynchronously :publish_to_github
-  
+
 end
diff --git a/app/models/research/journal/article.rb b/app/models/research/journal/article.rb
index 0410c664d..20a415c65 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                 :datetime         not null
+#  updated_at                 :date             not null
 #  research_journal_id        :uuid             not null
 #  research_journal_volume_id :uuid
 #  university_id              :uuid             not null
diff --git a/app/services/github.rb b/app/services/github.rb
index b860a19de..f441899ec 100644
--- a/app/services/github.rb
+++ b/app/services/github.rb
@@ -10,44 +10,46 @@ class Github
     @repository = repository
   end
 
-  def publish(kind:, file:, title:, data:)
-    local_directory = "tmp/jekyll/#{ kind }"
-    local_path = "#{ local_directory }/#{ file }"
+  def publish(kind: nil, # Deprecated
+              file: nil, # Deprecated
+              title: nil, # Deprecated
+              path: nil,
+              previous_path: nil,
+              commit: nil,
+              data:)
+    if path
+      local_path = "#{ tmp_directory }/#{ path }"
+      remote_file = path
+    else
+      # Deprecated
+      local_path = "#{ tmp_directory }/#{ file }"
+      remote_file = "_#{ kind }/#{ file }"
+    end
     Pathname(local_path).dirname.mkpath
     File.write local_path, data
     return if repository.blank?
-    remote_file = "_#{ kind }/#{ file }"
-    begin
-      content = client.content repository, path: remote_file
-      sha = content[:sha]
-    rescue
-      sha = nil
+    if !previous_path.blank? && path != previous_path
+      move_file previous_path, path
     end
-    commit_message ||= "[#{kind}] Save #{ title }"
+    commit ||= "Save #{ title }"
     client.create_contents  repository,
                             remote_file,
-                            commit_message,
+                            commit,
                             file: local_path,
-                            sha: sha
+                            sha: file_sha(remote_file)
   rescue
     # byebug
   end
 
   def send_file(attachment, path)
-    begin
-      content = client.content repository, path: path
-      sha = content[:sha]
-    rescue
-      sha = nil
-    end
-    commit_message ||= "[file] Save #{ path }"
     return if repository.blank?
+    commit_message = "[file] Save #{ path }"
     path_without_slash = path[1..-1]
     client.create_contents  repository,
                             path_without_slash,
                             commit_message,
                             attachment.download,
-                            sha: sha
+                            sha: file_sha(path)
   rescue
     # byebug
   end
@@ -83,4 +85,66 @@ class Github
   def client
     @client ||= Octokit::Client.new access_token: access_token
   end
+
+  protected
+
+  # https://medium.com/@obodley/renaming-a-file-using-the-git-api-fed1e6f04188
+  def move_file(from, to)
+    file = find_in_tree from
+    return if file.nil?
+    content = [{
+      path: to,
+      mode: file[:mode],
+      type: file[:type],
+      sha: file[:sha]
+    }]
+    begin
+    new_tree = client.create_tree repository, content, base_tree: tree[:sha]
+    message = "Move #{from} to #{to}"
+    commit = client.create_commit repository, message, new_tree[:sha], branch_sha
+    [:main, :master].each do |branch|
+      client.update_branch repository, branch, commit[:sha]
+    end
+    rescue
+    end
+  end
+
+  def file_sha(path)
+    begin
+      content = client.content repository, path: path
+      sha = content[:sha]
+    rescue
+      sha = nil
+    end
+    sha
+  end
+
+  def branch_sha
+    unless @branch_sha
+      [:main, :master].each do |branch|
+        begin
+          # Crashes if branch does not exist
+          response = client.branch repository, branch
+          @branch_sha = response['commit']['sha']
+        end
+        break if @branch_sha
+      end
+    end
+    @branch_sha
+  end
+
+  def tree
+    @tree ||= client.tree repository, branch_sha, recursive: true
+  end
+
+  def find_in_tree(path)
+    tree[:tree].each do |file|
+      return file if path == file[:path]
+    end
+    nil
+  end
+
+  def tmp_directory
+    "tmp/github/#{repository}"
+  end
 end
diff --git a/app/views/admin/communication/website/pages/jekyll.html.erb b/app/views/admin/communication/website/pages/jekyll.html.erb
index 0af5dda1a..16629fafa 100644
--- a/app/views/admin/communication/website/pages/jekyll.html.erb
+++ b/app/views/admin/communication/website/pages/jekyll.html.erb
@@ -7,4 +7,4 @@ description: >
 text: >
   <%= prepare_for_github @page.text %>
 ---
-<%= @page.content_without_frontmatter.html_safe %>
+<%= @page.github_frontmatter.content.html_safe %>
diff --git a/app/views/admin/communication/website/posts/_form.html.erb b/app/views/admin/communication/website/posts/_form.html.erb
index 7096f6dab..004e6c9ce 100644
--- a/app/views/admin/communication/website/posts/_form.html.erb
+++ b/app/views/admin/communication/website/posts/_form.html.erb
@@ -18,6 +18,7 @@
           <h5 class="card-title mb-0"><%= t('communication.website.metadata') %></h5>
         </div>
         <div class="card-body">
+          <%= f.input :slug, as: :string %>
           <%= f.input :published %>
           <%= f.input :published_at, html5: true %>
         </div>
diff --git a/app/views/admin/communication/website/posts/jekyll.html.erb b/app/views/admin/communication/website/posts/jekyll.html.erb
index 69385f9ae..72ba13921 100644
--- a/app/views/admin/communication/website/posts/jekyll.html.erb
+++ b/app/views/admin/communication/website/posts/jekyll.html.erb
@@ -10,4 +10,4 @@ description: >
 text: >
   <%= prepare_for_github @post.text %>
 ---
-<%= @post.content_without_frontmatter.html_safe %>
+<%= @post.github_frontmatter.content.html_safe %>
diff --git a/app/views/admin/communication/website/posts/show.html.erb b/app/views/admin/communication/website/posts/show.html.erb
index 4b39d1f82..887a61249 100644
--- a/app/views/admin/communication/website/posts/show.html.erb
+++ b/app/views/admin/communication/website/posts/show.html.erb
@@ -53,9 +53,8 @@
           <h5 class="card-title mb-0"><%= t('activerecord.attributes.communication/website/post.featured_image') %></h5>
         </div>
         <div class="card-body">
-          <%= image_tag @post.featured_image.variant(resize: '400'), class: 'img-fluid' %>
+          <%= image_tag @post.featured_image.variant(resize: '600'), class: 'img-fluid mb-3' %><br>
           <%= @post.featured_image.url %>
-          <%= @post.featured_image.variant(resize: '400').url %>
         </div>
       </div>
     <% end %>
diff --git a/db/migrate/20211023063050_add_path_to_communication_website_post.rb b/db/migrate/20211023063050_add_path_to_communication_website_post.rb
new file mode 100644
index 000000000..0cd1c7266
--- /dev/null
+++ b/db/migrate/20211023063050_add_path_to_communication_website_post.rb
@@ -0,0 +1,7 @@
+class AddPathToCommunicationWebsitePost < ActiveRecord::Migration[6.1]
+  def change
+    add_column :communication_website_posts, :path, :text
+    add_column :communication_website_posts, :github_path, :text
+    add_column :communication_website_pages, :github_path, :text
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index cbe2bcb20..a4a758579 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_152728) do
+ActiveRecord::Schema.define(version: 2021_10_23_063050) do
 
   # These are extensions that must be enabled in order to support this database
   enable_extension "pgcrypto"
@@ -178,6 +178,7 @@ ActiveRecord::Schema.define(version: 2021_10_21_152728) do
     t.datetime "updated_at", precision: 6, null: false
     t.text "text"
     t.boolean "published", default: false
+    t.text "github_path"
     t.index ["about_type", "about_id"], name: "index_communication_website_pages_on_about"
     t.index ["communication_website_id"], name: "index_communication_website_pages_on_communication_website_id"
     t.index ["parent_id"], name: "index_communication_website_pages_on_parent_id"
@@ -195,6 +196,8 @@ ActiveRecord::Schema.define(version: 2021_10_21_152728) do
     t.datetime "created_at", precision: 6, null: false
     t.datetime "updated_at", precision: 6, null: false
     t.text "slug"
+    t.text "path"
+    t.text "github_path"
     t.index ["communication_website_id"], name: "index_communication_website_posts_on_communication_website_id"
     t.index ["university_id"], name: "index_communication_website_posts_on_university_id"
   end
-- 
GitLab