From 49f2c769a31fe09b726c9a740370d6c64be1e726 Mon Sep 17 00:00:00 2001 From: Adrien Dorsaz Date: Mon, 13 Sep 2021 18:48:53 +0200 Subject: [PATCH] add /comments/latest route This page will be useful for moderators to retrieve latest comments. The limit is based on current date to limit number of comments retrieved from the database. Only comments from the last 7 days will be available. As it's the first page to index all comments with criteria only made on created_at property, I added an index to the comments sql table. As LinuxFr has between 1500 to 2000 comments each 15 days, I've decided to paginate to 50 comments. As the number of comments in the atom feed is linked to this pagination setting, I wanted it to be big enough so RSS readers can take all comments with around 4 requests by day. --- app/assets/stylesheets/parts/content.scss | 5 ++++ app/controllers/comments_controller.rb | 16 +++++++++--- app/models/comment.rb | 5 ++++ app/views/comments/latest.atom.builder | 25 +++++++++++++++++++ app/views/comments/latest.html.haml | 15 +++++++++++ app/views/moderation/news/index.html.haml | 3 +++ config/routes.rb | 1 + ...843_add_index_on_created_at_to_comments.rb | 5 ++++ db/schema.rb | 3 ++- 9 files changed, 74 insertions(+), 4 deletions(-) create mode 100644 app/views/comments/latest.atom.builder create mode 100644 app/views/comments/latest.html.haml create mode 100644 db/migrate/20210913191843_add_index_on_created_at_to_comments.rb diff --git a/app/assets/stylesheets/parts/content.scss b/app/assets/stylesheets/parts/content.scss index a933035c5..25c765c01 100644 --- a/app/assets/stylesheets/parts/content.scss +++ b/app/assets/stylesheets/parts/content.scss @@ -1,6 +1,7 @@ /* contenu du site (hors commentaire) */ article, ul.threads > li.comment, +ul.comments_list > li.comment, .markdown_cheatsheet, #contents > form, form#new_post, @@ -30,6 +31,10 @@ body#wiki_pages-changes #contents { font-size: 1em; } +#contents > ul.comments_list { + padding: 0; +} + article { position: relative; header { diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index 431c72a32..9c594ad71 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -1,8 +1,8 @@ # encoding: UTF-8 class CommentsController < ApplicationController - before_action :authenticate_account!, except: [:index, :show] - before_action :find_node, except: [:templeet] - before_action :find_comment, except: [:index, :new, :answer, :create, :templeet] + before_action :authenticate_account!, except: [:index, :show, :latest] + before_action :find_node, except: [:templeet, :latest] + before_action :find_comment, except: [:index, :new, :answer, :create, :templeet, :latest] def index @comments = @node.comments.published.order('id DESC') @@ -12,6 +12,16 @@ def index end end + def latest + @comments = Comment.latest. + page(params[:page]). + order(created_at: :desc) + respond_to do |wants| + wants.html + wants.atom + end + end + def show enforce_view_permission(@comment) end diff --git a/app/models/comment.rb b/app/models/comment.rb index 32ba6b0d2..eda816d84 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -39,6 +39,11 @@ class Comment < ActiveRecord::Base limit(12). select([:id, :node_id, :title]) } + scope :latest, -> { + where(["created_at >= ?", Date.current - 7.day]) + } + + paginates_per 50 validates :title, presence: { message: "Le titre est obligatoire" }, length: { maximum: 100, message: "Le titre est trop long" } diff --git a/app/views/comments/latest.atom.builder b/app/views/comments/latest.atom.builder new file mode 100644 index 000000000..7c336126c --- /dev/null +++ b/app/views/comments/latest.atom.builder @@ -0,0 +1,25 @@ +atom_feed(:root_url => comments_latest_url) do |feed| + feed.title("LinuxFr.org : les derniers commentaires") + feed.updated(@comments.first.try :created_at) + feed.icon("/favicon.png") + + @comments.each do |comment| + feed.entry(comment, :url => "#{url_for_content comment.node.content}#comment-#{comment.id}") do |entry| + in_response_to = content_tag(:p, + content_tag(:em, + "En réponse #{translate_to_content_type comment.content_type} #{link_to comment.node.content.title, path_for_content(comment.node.content)}.".html_safe + ) + ) + if comment.deleted? + entry.title("Commentaire supprimé") + entry.content("#{content_tag(:p, "Commentaire supprimé")} #{in_response_to}", :type => 'html') + else + entry.title(comment.title) + entry.content("#{comment.body} #{in_response_to}", :type => 'html') + end + entry.author do |author| + author.name(comment.user_name) + end + end + end +end diff --git a/app/views/comments/latest.html.haml b/app/views/comments/latest.html.haml new file mode 100644 index 000000000..9c8f55fe8 --- /dev/null +++ b/app/views/comments/latest.html.haml @@ -0,0 +1,15 @@ += h1 "Les derniers commentaires" +- feed "Flux Atom des derniers commentaires" +%nav.toolbox + .follow_feed + = link_to "Flux Atom des derniers commentaires", "latest.atom" + -# order is not managed, but order_navbar is required due to float property on follow_feed div + .order_navbar +   +%main#contents(role="main") + %ul.comments_list + - @comments.each do |comment| + %li.comment(id="comment-#{comment.id}") + = render comment +%nav.toolbox + = paginate(@comments, inner_window:10) diff --git a/app/views/moderation/news/index.html.haml b/app/views/moderation/news/index.html.haml index 6d18c5b5f..31e5da33a 100644 --- a/app/views/moderation/news/index.html.haml +++ b/app/views/moderation/news/index.html.haml @@ -28,6 +28,9 @@ %h2 = link_to "Étiquettes publiques", moderation_tags_path +%h2 + = link_to "Derniers commentaires", comments_latest_path + %h2 = link_to "Sondages", moderation_polls_path - if @polls.empty? diff --git a/config/routes.rb b/config/routes.rb index 0f1dc60b4..27b8114bb 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -58,6 +58,7 @@ # Nodes get "/tableau-de-bord" => "dashboard#index", as: :dashboard get "/tableau-de-bord/reponses" => "dashboard#answers" + get "/comments/latest" => "comments#latest" get "/comments/:id(,:d)(.html)" => "comments#templeet" resources :nodes, only: [] do resources :comments do diff --git a/db/migrate/20210913191843_add_index_on_created_at_to_comments.rb b/db/migrate/20210913191843_add_index_on_created_at_to_comments.rb new file mode 100644 index 000000000..c9684914c --- /dev/null +++ b/db/migrate/20210913191843_add_index_on_created_at_to_comments.rb @@ -0,0 +1,5 @@ +class AddIndexOnCreatedAtToComments < ActiveRecord::Migration[5.2] + def change + add_index :comments, [:created_at], order: {created_at: :desc} + end +end diff --git a/db/schema.rb b/db/schema.rb index ac4915226..4ec462e90 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_01_31_231806) do +ActiveRecord::Schema.define(version: 2021_09_13_191843) do create_table "accounts", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci", force: :cascade do |t| t.integer "user_id" @@ -93,6 +93,7 @@ t.text "wiki_body", limit: 16777215 t.datetime "created_at" t.datetime "updated_at" + t.index ["created_at"], name: "index_comments_on_created_at" t.index ["node_id"], name: "index_comments_on_node_id" t.index ["state", "created_at"], name: "index_comments_on_state_and_created_at" t.index ["state", "materialized_path"], name: "index_comments_on_state_and_materialized_path", length: { materialized_path: 120 }