mirror of
https://github.com/discourse/discourse-rewind.git
synced 2025-12-12 18:33:30 +00:00
FIX: Various bugs from 2024 rewind (#29)
* Use post excerpt for best posts to avoid giant posts ruining it * Make sure short emojis (e.g. `😂`) render in best posts and best topics * Make images show in best post excerpts (requires core change) * Fix invite action error, using column that doesn't exist * Add missing # for top category slugs * Refactor report service + controller a little to make it easier to figure out what went wrong if it fails, and to use the guardian user Copies a couple of fixes from https://github.com/discourse/discourse-rewind/pull/28 to make things work locally, the conflicts will be easy to resolve. **Best topics before** <img width="977" height="712" alt="image" src="https://github.com/user-attachments/assets/e120507f-d0d8-44f0-b242-e1056084ef03" /> **Best topics after** <img width="969" height="648" alt="image" src="https://github.com/user-attachments/assets/dd13f6ac-35df-4e9a-907e-9ed5102843b6" /> **Categories before** <img width="904" height="465" alt="image" src="https://github.com/user-attachments/assets/0d15e73d-3534-4836-b776-2c97381e58ef" /> **Categories after** <img width="925" height="466" alt="image" src="https://github.com/user-attachments/assets/3d6e4eae-32ed-4f11-a4f4-090e4473ebe9" />
This commit is contained in:
parent
972cc6e5d9
commit
1cdd3fd708
@ -8,8 +8,12 @@ module ::DiscourseRewind
|
|||||||
|
|
||||||
def show
|
def show
|
||||||
DiscourseRewind::FetchReports.call(service_params) do
|
DiscourseRewind::FetchReports.call(service_params) do
|
||||||
on_model_not_found(:year) { raise Discourse::NotFound }
|
on_model_not_found(:year) do
|
||||||
on_model_not_found(:user) { raise Discourse::NotFound }
|
raise Discourse::NotFound.new(nil, custom_message: "discourse_rewind.invalid_year")
|
||||||
|
end
|
||||||
|
on_model_not_found(:reports) do
|
||||||
|
raise Discourse::NotFound.new(nil, custom_message: "discourse_rewind.report_failed")
|
||||||
|
end
|
||||||
on_success { |reports:| render json: MultiJson.dump(reports), status: :ok }
|
on_success { |reports:| render json: MultiJson.dump(reports), status: :ok }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -10,9 +10,19 @@ module DiscourseRewind
|
|||||||
.where(created_at: date)
|
.where(created_at: date)
|
||||||
.where(deleted_at: nil)
|
.where(deleted_at: nil)
|
||||||
.where("post_number > 1")
|
.where("post_number > 1")
|
||||||
.order("like_count DESC NULLS LAST")
|
.order("like_count DESC NULLS LAST, created_at ASC")
|
||||||
.limit(3)
|
.limit(3)
|
||||||
.pluck(:post_number, :topic_id, :like_count, :reply_count, :raw, :cooked)
|
.select(:post_number, :topic_id, :like_count, :reply_count, :raw, :cooked)
|
||||||
|
.map do |post|
|
||||||
|
{
|
||||||
|
post_number: post.post_number,
|
||||||
|
topic_id: post.topic_id,
|
||||||
|
like_count: post.like_count,
|
||||||
|
reply_count: post.reply_count,
|
||||||
|
excerpt:
|
||||||
|
post.excerpt(200, { strip_links: true, remap_emoji: true, keep_images: true }),
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
{ data: best_posts, identifier: "best-posts" }
|
{ data: best_posts, identifier: "best-posts" }
|
||||||
end
|
end
|
||||||
|
|||||||
@ -41,16 +41,11 @@ module DiscourseRewind
|
|||||||
]
|
]
|
||||||
|
|
||||||
model :year
|
model :year
|
||||||
model :user
|
|
||||||
model :date
|
model :date
|
||||||
model :reports
|
model :reports
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def fetch_user(guardian:)
|
|
||||||
User.find_by_username(guardian.user.username)
|
|
||||||
end
|
|
||||||
|
|
||||||
def fetch_year
|
def fetch_year
|
||||||
current_date = Time.zone.now
|
current_date = Time.zone.now
|
||||||
current_month = current_date.month
|
current_month = current_date.month
|
||||||
@ -76,12 +71,13 @@ module DiscourseRewind
|
|||||||
Date.new(year).all_year
|
Date.new(year).all_year
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch_reports(date:, user:, guardian:, year:)
|
def fetch_reports(date:, guardian:, year:)
|
||||||
key = "rewind:#{guardian.user.username}:#{year}"
|
key = "rewind:#{guardian.user.username}:#{year}"
|
||||||
reports = Discourse.redis.get(key)
|
reports = Discourse.redis.get(key)
|
||||||
|
|
||||||
if !reports
|
if !reports
|
||||||
reports = REPORTS.map { |report| report.call(date:, user:, guardian:) }.compact
|
reports =
|
||||||
|
REPORTS.map { |report| report.call(date:, user: guardian.user, guardian:) }.compact
|
||||||
Discourse.redis.setex(key, CACHE_DURATION, MultiJson.dump(reports))
|
Discourse.redis.setex(key, CACHE_DURATION, MultiJson.dump(reports))
|
||||||
else
|
else
|
||||||
reports = MultiJson.load(reports, symbolize_keys: true)
|
reports = MultiJson.load(reports, symbolize_keys: true)
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import Component from "@glimmer/component";
|
import Component from "@glimmer/component";
|
||||||
import { concat } from "@ember/helper";
|
import { concat } from "@ember/helper";
|
||||||
import { get } from "@ember/object";
|
|
||||||
import { htmlSafe } from "@ember/template";
|
import { htmlSafe } from "@ember/template";
|
||||||
import icon from "discourse/helpers/d-icon";
|
import icon from "discourse/helpers/d-icon";
|
||||||
import { i18n } from "discourse-i18n";
|
import { i18n } from "discourse-i18n";
|
||||||
@ -22,13 +21,15 @@ export default class BestPosts extends Component {
|
|||||||
<div class={{concat "rewind-card" " rank-" (this.rank idx)}}>
|
<div class={{concat "rewind-card" " rank-" (this.rank idx)}}>
|
||||||
<span class="best-posts -rank"></span>
|
<span class="best-posts -rank"></span>
|
||||||
<span class="best-posts -rank"></span>
|
<span class="best-posts -rank"></span>
|
||||||
<div class="best-posts__post">{{htmlSafe (get post "5")}}</div>
|
<div class="best-posts__post"><p>{{htmlSafe
|
||||||
|
post.excerpt
|
||||||
|
}}</p></div>
|
||||||
<div class="best-posts__metadata">
|
<div class="best-posts__metadata">
|
||||||
<span class="best-posts__likes">
|
<span class="best-posts__likes">
|
||||||
{{icon "heart"}}{{htmlSafe (get post "2")}}</span>
|
{{icon "heart"}}{{post.like_count}}</span>
|
||||||
<span class="best-posts__replies">
|
<span class="best-posts__replies">
|
||||||
{{icon "comment"}}{{htmlSafe (get post "3")}}</span>
|
{{icon "comment"}}{{post.reply_count}}</span>
|
||||||
<a href="/t/{{get post '1'}}/{{get post '0'}}">{{i18n
|
<a href="/t/{{post.topic_id}}/{{post.post_number}}">{{i18n
|
||||||
"discourse_rewind.reports.best_posts.view_post"
|
"discourse_rewind.reports.best_posts.view_post"
|
||||||
}}</a>
|
}}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import Component from "@glimmer/component";
|
import Component from "@glimmer/component";
|
||||||
import { concat } from "@ember/helper";
|
import { concat } from "@ember/helper";
|
||||||
import { htmlSafe } from "@ember/template";
|
import { htmlSafe } from "@ember/template";
|
||||||
|
import replaceEmoji from "discourse/helpers/replace-emoji";
|
||||||
import { i18n } from "discourse-i18n";
|
import { i18n } from "discourse-i18n";
|
||||||
|
|
||||||
export default class BestTopics extends Component {
|
export default class BestTopics extends Component {
|
||||||
@ -25,8 +26,8 @@ export default class BestTopics extends Component {
|
|||||||
<span class="best-topics -rank"></span>
|
<span class="best-topics -rank"></span>
|
||||||
<span class="best-topics -rank"></span>
|
<span class="best-topics -rank"></span>
|
||||||
<h2 class="best-topics__header">{{topic.title}}</h2>
|
<h2 class="best-topics__header">{{topic.title}}</h2>
|
||||||
<span class="best-topics__excerpt">{{htmlSafe
|
<span class="best-topics__excerpt">{{replaceEmoji
|
||||||
topic.excerpt
|
(htmlSafe topic.excerpt)
|
||||||
}}</span>
|
}}</span>
|
||||||
</a>
|
</a>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|||||||
@ -13,7 +13,7 @@ const MostViewedCategories = <template>
|
|||||||
<a class="folder-wrapper" href={{concat "/c/-/" data.category_id}}>
|
<a class="folder-wrapper" href={{concat "/c/-/" data.category_id}}>
|
||||||
<span class="folder-tab"></span>
|
<span class="folder-tab"></span>
|
||||||
<div class="rewind-card">
|
<div class="rewind-card">
|
||||||
<p class="most-viewed-categories__category">{{data.name}}</p>
|
<p class="most-viewed-categories__category">#{{data.name}}</p>
|
||||||
</div>
|
</div>
|
||||||
<span class="folder-bg"></span>
|
<span class="folder-bg"></span>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@ -1,3 +1,6 @@
|
|||||||
en:
|
en:
|
||||||
site_settings:
|
site_settings:
|
||||||
discourse_rewind_enabled: "Enable Discourse Rewind for a fun end-of-year summary for members' activity in the community."
|
discourse_rewind_enabled: "Enable Discourse Rewind for a fun end-of-year summary for members' activity in the community."
|
||||||
|
discourse_rewind:
|
||||||
|
report_failed: "Failed to generate Discourse Rewind report."
|
||||||
|
invalid_year: "Rewind can only be generated in January or December."
|
||||||
|
|||||||
@ -15,6 +15,7 @@ RSpec.describe DiscourseRewind::RewindsController do
|
|||||||
get "/rewinds.json"
|
get "/rewinds.json"
|
||||||
|
|
||||||
expect(response.status).to eq(404)
|
expect(response.status).to eq(404)
|
||||||
|
expect(response.parsed_body["errors"].first).to eq(I18n.t("discourse_rewind.invalid_year"))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -26,6 +27,21 @@ RSpec.describe DiscourseRewind::RewindsController do
|
|||||||
|
|
||||||
expect(response.status).to eq(200)
|
expect(response.status).to eq(200)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "when reports are not found or error" do
|
||||||
|
before do
|
||||||
|
DiscourseRewind::Action::TopWords.stubs(:call).raises(StandardError.new("Some error"))
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns 404 with message" do
|
||||||
|
get "/rewinds.json"
|
||||||
|
|
||||||
|
expect(response.status).to eq(404)
|
||||||
|
expect(response.parsed_body["errors"].first).to eq(
|
||||||
|
I18n.t("discourse_rewind.report_failed"),
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user