From 49214f1b18db67b89c42d99b104a39944d3d6641 Mon Sep 17 00:00:00 2001
From: Arnaud Levy <contact@arnaudlevy.com>
Date: Mon, 6 Sep 2021 20:50:17 +0200
Subject: [PATCH] update

---
 .../communication/website/pages_controller.rb | 12 +--
 app/models/communication/website.rb           |  6 +-
 app/models/communication/website/page.rb      | 76 ++++++++-----------
 app/services/github.rb                        | 11 +++
 .../website/pages/index.html.erb              |  6 +-
 .../website/pages/jekyll.html.erb             |  7 ++
 6 files changed, 62 insertions(+), 56 deletions(-)
 create mode 100644 app/views/admin/communication/website/pages/jekyll.html.erb

diff --git a/app/controllers/admin/communication/website/pages_controller.rb b/app/controllers/admin/communication/website/pages_controller.rb
index 7b37bf23b..b03cf1d36 100644
--- a/app/controllers/admin/communication/website/pages_controller.rb
+++ b/app/controllers/admin/communication/website/pages_controller.rb
@@ -1,14 +1,13 @@
 class Admin::Communication::Website::PagesController < Admin::Communication::Website::ApplicationController
+  load_and_authorize_resource class: Communication::Website::Page
+
   def index
-    @pages = @website.pages
+    @pages = @website.pages.order(:path)
     breadcrumb
   end
 
   def show
-    id = "#{params[:id]}.html"
-    @page = Communication::Website::Page.find(id, @website)
     breadcrumb
-    add_breadcrumb @page
   end
 
   def new
@@ -48,8 +47,9 @@ class Admin::Communication::Website::PagesController < Admin::Communication::Web
 
   def breadcrumb
     super
-    add_breadcrumb Communication::Website::Page.model_name.human(count: 2), admin_communication_website_pages_path
-    # breadcrumb_for @page
+    add_breadcrumb  Communication::Website::Page.model_name.human(count: 2), 
+                    admin_communication_website_pages_path
+    breadcrumb_for @page
   end
 
   def page_params
diff --git a/app/models/communication/website.rb b/app/models/communication/website.rb
index a66d7b30c..1c88b3614 100644
--- a/app/models/communication/website.rb
+++ b/app/models/communication/website.rb
@@ -25,16 +25,12 @@
 class Communication::Website < ApplicationRecord
   belongs_to :university
   belongs_to :about, polymorphic: true, optional: true
-  # has_many :pages, foreign_key: :communication_website_id
+  has_many :pages, foreign_key: :communication_website_id
 
   def self.about_types
     [nil, Research::Journal.name]
   end
 
-  def pages
-    Communication::Website::Page.for_website self
-  end
-
   def domain_url
     "https://#{ domain }"
   end
diff --git a/app/models/communication/website/page.rb b/app/models/communication/website/page.rb
index e1b80d24a..cb2940377 100644
--- a/app/models/communication/website/page.rb
+++ b/app/models/communication/website/page.rb
@@ -31,63 +31,53 @@
 #  fk_rails_...  (university_id => universities.id)
 #
 
-# class Communication::Website::Page < ApplicationRecord
-#   belongs_to :university
-#   belongs_to :website, foreign_key: :communication_website_id
-#   belongs_to :parent, class_name: 'Communication::Website::Page', optional: true
-#   belongs_to :about, polymorphic: true, optional: true
-#
-#   validates :title, presence: true
-#
-#   before_save :make_path
-#
-#   def to_s
-#     "#{ title }"
-#   end
-#
-#   protected
-#
-#   def make_path
-#     self.path = "#{parent&.path}/#{slug}"
-#   end
-# end
-
+class Communication::Website::Page < ApplicationRecord
+  belongs_to :university
+  belongs_to :website, foreign_key: :communication_website_id
+  belongs_to :parent, class_name: 'Communication::Website::Page', optional: true
 
-class Communication::Website::Page
-  extend ActiveModel::Naming
-  extend ActiveModel::Translation
+  validates :title, presence: true
 
-  attr_accessor :id, :title, :permalink, :content, :raw
+  before_save :make_path
+  after_save :publish_to_github
 
-  def self.for_website(website)
-    return [] if website.repository.blank?
-    github = Github.new website.access_token, website.repository
-    github.pages
+  def content
+    @content ||= github.read_file_at "_pages/#{id}.html"
   end
 
-  def self.find(id, website)
-    return [] if website.repository.blank?
-    github = Github.new website.access_token, website.repository
-    github.page_with_id(id)
+  def content_without_frontmatter
+    frontmatter.content
   end
 
-  def description
-    ""
+  def to_s
+    "#{ title }"
   end
 
-  def slug
-    ""
+  protected
+
+  def github
+    @github ||= Github.with_site(website)
   end
 
-  def path
-    permalink
+  def frontmatter
+    @frontmatter ||= FrontMatterParser::Parser.new(:md).call(content)
   end
 
-  def persisted?
-    true
+  def make_path
+    self.path = "#{parent&.path}/#{slug}"
   end
 
-  def to_s
-    "#{ title }"
+  def publish_to_github
+    return if website&.repository.blank?
+    data = ApplicationController.render(
+      template: 'admin/communication/website/pages/jekyll',
+      layout: false,
+      assigns: { page: self }
+    )
+    github.publish  local_directory: "tmp/pages",
+                    local_file: "#{id}.md",
+                    data: data,
+                    remote_file: "_pages/#{id}.html",
+                    commit_message: "Save page #{ title }"
   end
 end
diff --git a/app/services/github.rb b/app/services/github.rb
index 7999d7af9..07694d47f 100644
--- a/app/services/github.rb
+++ b/app/services/github.rb
@@ -1,6 +1,10 @@
 class Github
   attr_reader :access_token, :repository
 
+  def self.with_site(site)
+    new site.access_token, site.repository
+  end
+
   def initialize(access_token, repository)
     @access_token = access_token
     @repository = repository
@@ -24,6 +28,13 @@ class Github
 
   end
 
+  def read_file_at(path)
+    data = client.content repository, path: path
+    Base64.decode64 data.content
+  rescue
+    ''
+  end
+
   def pages
     list = client.contents repository, path: '_pages'
     list.map do |hash|
diff --git a/app/views/admin/communication/website/pages/index.html.erb b/app/views/admin/communication/website/pages/index.html.erb
index 68b0968f7..829bfcfff 100644
--- a/app/views/admin/communication/website/pages/index.html.erb
+++ b/app/views/admin/communication/website/pages/index.html.erb
@@ -4,7 +4,7 @@
   <thead>
     <tr>
       <th><%= Communication::Website::Page.human_attribute_name('title') %></th>
-      <th><%= Communication::Website::Page.human_attribute_name('permalink') %></th>
+      <th><%= Communication::Website::Page.human_attribute_name('path') %></th>
       <th></th>
     </tr>
   </thead>
@@ -12,8 +12,10 @@
     <% @pages.each do |page| %>
       <tr>
         <td><%= link_to page, admin_communication_website_page_path(page.id) %></td>
-        <td><%= page.permalink %></td>
+        <td><%= page.path %></td>
         <td class="text-end">
+          <%= edit_link page %>
+          <%= destroy_link page %>
         </td>
       </tr>
     <% end %>
diff --git a/app/views/admin/communication/website/pages/jekyll.html.erb b/app/views/admin/communication/website/pages/jekyll.html.erb
new file mode 100644
index 000000000..d4e12cef2
--- /dev/null
+++ b/app/views/admin/communication/website/pages/jekyll.html.erb
@@ -0,0 +1,7 @@
+---
+title: "<%= @page.title %>"
+permalink: "<%= @page.path %>"
+parent: "<%= @page.parent_id %>"
+description: "<%= @page.description %>"
+---
+<%= @page.content_without_frontmatter.html_safe %>
-- 
GitLab