mirror of
https://github.com/discourse/discourse.git
synced 2024-11-25 09:42:07 +08:00
Add three reports (#14338)
* Add report top_users_by_received_likes * Add report top_users_by_received_likes_from_inferior_trust_level * Add report top_users_by_likes_received_from_a_variety_of_people * Add test to report_top_users_by_received_likes * add top_users_by_likes_received_from_a_variety_of_people report test * add top_users_by_likes_received_from_inferior_trust_level report tests
This commit is contained in:
parent
2f04a9b9fb
commit
9b5836aa1d
58
app/models/concerns/reports/top_users_by_likes_received.rb
Normal file
58
app/models/concerns/reports/top_users_by_likes_received.rb
Normal file
|
@ -0,0 +1,58 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Reports::TopUsersByLikesReceived
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
class_methods do
|
||||
def report_top_users_by_likes_received(report)
|
||||
report.icon = 'heart'
|
||||
report.data = []
|
||||
|
||||
report.modes = [:table]
|
||||
|
||||
report.dates_filtering = true
|
||||
|
||||
report.labels = [
|
||||
{
|
||||
type: :user,
|
||||
properties: {
|
||||
id: :user_id,
|
||||
username: :username,
|
||||
avatar: :user_avatar_template,
|
||||
},
|
||||
title: I18n.t("reports.top_users_by_likes_received.labels.user")
|
||||
},
|
||||
{
|
||||
type: :number,
|
||||
property: :qtt_like,
|
||||
title: I18n.t("reports.top_users_by_likes_received.labels.qtt_like")
|
||||
},
|
||||
]
|
||||
|
||||
sql = <<~SQL
|
||||
SELECT
|
||||
ua.user_id AS user_id,
|
||||
u.username as username,
|
||||
u.uploaded_avatar_id as uploaded_avatar_id,
|
||||
COUNT(*) qtt_like
|
||||
FROM user_actions ua
|
||||
INNER JOIN users u on ua.user_id = u.id
|
||||
WHERE ua.created_at::date BETWEEN :start_date AND :end_date
|
||||
AND ua.action_type = 2
|
||||
GROUP BY ua.user_id, u.username, u.uploaded_avatar_id
|
||||
ORDER BY qtt_like DESC
|
||||
LIMIT 10
|
||||
SQL
|
||||
|
||||
DB.query(sql, start_date: report.start_date, end_date: report.end_date).each do |row|
|
||||
report.data << {
|
||||
user_id: row.user_id,
|
||||
username: row.username,
|
||||
user_avatar_template: User.avatar_template(row.username, row.uploaded_avatar_id),
|
||||
qtt_like: row.qtt_like,
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,60 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Reports::TopUsersByLikesReceivedFromAVarietyOfPeople
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
class_methods do
|
||||
def report_top_users_by_likes_received_from_a_variety_of_people(report)
|
||||
report.icon = 'heart'
|
||||
report.data = []
|
||||
|
||||
report.modes = [:table]
|
||||
|
||||
report.dates_filtering = true
|
||||
|
||||
report.labels = [
|
||||
{
|
||||
type: :user,
|
||||
properties: {
|
||||
id: :user_id,
|
||||
username: :username,
|
||||
avatar: :user_avatar_template,
|
||||
},
|
||||
title: I18n.t("reports.top_users_by_likes_received_from_a_variety_of_people.labels.user")
|
||||
},
|
||||
{
|
||||
type: :number,
|
||||
property: :qtt_like,
|
||||
title: I18n.t("reports.top_users_by_likes_received_from_a_variety_of_people.labels.qtt_like")
|
||||
},
|
||||
]
|
||||
|
||||
sql = <<~SQL
|
||||
SELECT
|
||||
p.user_id,
|
||||
u.username as username,
|
||||
u.uploaded_avatar_id as uploaded_avatar_id,
|
||||
COUNT(DISTINCT ua.user_id) qtt_like
|
||||
FROM user_actions ua
|
||||
INNER JOIN posts p ON p.id = ua.target_post_id
|
||||
INNER JOIN users u on p.user_id = u.id
|
||||
WHERE ua.created_at::date BETWEEN :start_date AND :end_date
|
||||
AND ua.action_type = 1
|
||||
AND p.user_id > 0
|
||||
GROUP BY p.user_id, u.username, u.uploaded_avatar_id
|
||||
ORDER BY qtt_like DESC
|
||||
LIMIT 10
|
||||
SQL
|
||||
|
||||
DB.query(sql, start_date: report.start_date, end_date: report.end_date).each do |row|
|
||||
report.data << {
|
||||
user_id: row.user_id,
|
||||
username: row.username,
|
||||
user_avatar_template: User.avatar_template(row.username, row.uploaded_avatar_id),
|
||||
qtt_like: row.qtt_like,
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,71 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Reports::TopUsersByLikesReceivedFromInferiorTrustLevel
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
class_methods do
|
||||
def report_top_users_by_likes_received_from_inferior_trust_level(report)
|
||||
report.icon = 'heart'
|
||||
report.data = []
|
||||
|
||||
report.modes = [:table]
|
||||
|
||||
report.dates_filtering = true
|
||||
|
||||
report.labels = [
|
||||
{
|
||||
type: :user,
|
||||
properties: {
|
||||
id: :user_id,
|
||||
username: :username,
|
||||
avatar: :user_avatar_template,
|
||||
},
|
||||
title: I18n.t("reports.top_users_by_likes_received_from_inferior_trust_level.labels.user")
|
||||
},
|
||||
{
|
||||
type: :number,
|
||||
property: :trust_level,
|
||||
title: I18n.t("reports.top_users_by_likes_received_from_inferior_trust_level.labels.trust_level")
|
||||
},
|
||||
{
|
||||
type: :number,
|
||||
property: :qtt_like,
|
||||
title: I18n.t("reports.top_users_by_likes_received_from_inferior_trust_level.labels.qtt_like")
|
||||
},
|
||||
]
|
||||
|
||||
sql = <<~SQL
|
||||
WITH user_liked_tl_lower AS (
|
||||
SELECT
|
||||
users.id user_id,
|
||||
users.username as username,
|
||||
users.uploaded_avatar_id as uploaded_avatar_id,
|
||||
users.trust_level,
|
||||
COUNT(*) qtt_like,
|
||||
rank() OVER (PARTITION BY users.trust_level ORDER BY COUNT(*) DESC)
|
||||
FROM users
|
||||
INNER JOIN posts p ON p.user_id = users.id
|
||||
INNER JOIN user_actions ua ON ua.target_post_id = p.id AND ua.action_type = 1
|
||||
INNER JOIN users u_liked ON ua.user_id = u_liked.id AND u_liked.trust_level < users.trust_level
|
||||
WHERE ua.created_at::date BETWEEN :start_date AND :end_date
|
||||
GROUP BY users.id
|
||||
ORDER BY trust_level DESC, qtt_like DESC
|
||||
)
|
||||
|
||||
SELECT * FROM user_liked_tl_lower
|
||||
WHERE rank <= 10
|
||||
SQL
|
||||
|
||||
DB.query(sql, start_date: report.start_date, end_date: report.end_date).each do |row|
|
||||
report.data << {
|
||||
user_id: row.user_id,
|
||||
username: row.username,
|
||||
user_avatar_template: User.avatar_template(row.username, row.uploaded_avatar_id),
|
||||
trust_level: row.trust_level,
|
||||
qtt_like: row.qtt_like,
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -46,6 +46,9 @@ class Report
|
|||
include Reports::ModeratorWarningPrivateMessages
|
||||
include Reports::ProfileViews
|
||||
include Reports::TopUploads
|
||||
include Reports::TopUsersByLikesReceived
|
||||
include Reports::TopUsersByLikesReceivedFromInferiorTrustLevel
|
||||
include Reports::TopUsersByLikesReceivedFromAVarietyOfPeople
|
||||
|
||||
attr_accessor :type, :data, :total, :prev30Days, :start_date,
|
||||
:end_date, :labels, :prev_period, :facets, :limit, :average,
|
||||
|
|
|
@ -1420,6 +1420,25 @@ en:
|
|||
ignores_count: Ignores count
|
||||
mutes_count: Mutes count
|
||||
description: "Users who have been muted and/or ignored by many other users."
|
||||
top_users_by_likes_received:
|
||||
title: "Top Users by likes received"
|
||||
labels:
|
||||
user: User
|
||||
qtt_like: Likes Received
|
||||
description: "Top 10 users who have been received more likes."
|
||||
top_users_by_likes_received_from_inferior_trust_level:
|
||||
title: "Top Users by likes received from a user with a lower trust level"
|
||||
labels:
|
||||
user: User
|
||||
trust_level: Trust level
|
||||
qtt_like: Likes Received
|
||||
description: "Top 10 users in a higher trust level being liked by people in a lower trust level."
|
||||
top_users_by_likes_received_from_a_variety_of_people:
|
||||
title: "Top Users by likes received from a variety of people"
|
||||
labels:
|
||||
user: User
|
||||
qtt_like: Likes Received
|
||||
description: "Top 10 users who have had the likes from a wide range of people."
|
||||
|
||||
dashboard:
|
||||
rails_env_warning: "Your server is running in %{env} mode."
|
||||
|
|
86
install-imagemagick
Executable file
86
install-imagemagick
Executable file
|
@ -0,0 +1,86 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# version check: https://github.com/ImageMagick/ImageMagick/releases
|
||||
IMAGE_MAGICK_VERSION="7.0.11-13"
|
||||
IMAGE_MAGICK_HASH="fc454be622724c6224fa6c8230bb9c50191a05fbf05b9c9c25aa3e5497090b83"
|
||||
|
||||
# version check: https://github.com/strukturag/libheif/releases
|
||||
LIBHEIF_VERSION="1.12.0"
|
||||
LIBHEIF_HASH="086145b0d990182a033b0011caadb1b642da84f39ab83aa66d005610650b3c65"
|
||||
|
||||
# version check: https://aomedia.googlesource.com/aom
|
||||
LIB_AOM_VERSION="3.1.0"
|
||||
|
||||
# We use debian, but GitHub CI is stuck on Ubuntu Bionic, so this must be compatible with both
|
||||
LIBJPEGTURBO=$(cat /etc/issue | grep -qi Debian && echo 'libjpeg62-turbo libjpeg62-turbo-dev' || echo 'libjpeg-turbo8 libjpeg-turbo8-dev')
|
||||
|
||||
PREFIX=/usr/local
|
||||
WDIR=/tmp/imagemagick
|
||||
|
||||
# Install build deps
|
||||
apt -y -q remove imagemagick
|
||||
apt -y -q install git make gcc pkg-config autoconf curl g++ \
|
||||
yasm cmake \
|
||||
libde265-0 libde265-dev ${LIBJPEGTURBO} x265 libx265-dev libtool \
|
||||
libpng16-16 libpng-dev ${LIBJPEGTURBO} libwebp6 libwebp-dev libgomp1 libwebpmux3 libwebpdemux2 ghostscript libxml2-dev libxml2-utils \
|
||||
libbz2-dev gsfonts libtiff-dev libfreetype6-dev libjpeg-dev
|
||||
|
||||
mkdir -p $WDIR
|
||||
cd $WDIR
|
||||
|
||||
# Building libaom
|
||||
git clone https://aomedia.googlesource.com/aom
|
||||
cd aom && git checkout v${LIB_AOM_VERSION} && cd ..
|
||||
mkdir build_aom
|
||||
cd build_aom
|
||||
cmake ../aom/ -DENABLE_TESTS=0 -DBUILD_SHARED_LIBS=1 && make && make install
|
||||
ldconfig /usr/local/lib
|
||||
cd ..
|
||||
rm -rf aom
|
||||
rm -rf build_aom
|
||||
|
||||
# Build and install libheif
|
||||
cd $WDIR
|
||||
wget -O $WDIR/libheif.tar.gz "https://github.com/strukturag/libheif/archive/v$LIBHEIF_VERSION.tar.gz"
|
||||
sha256sum $WDIR/libheif.tar.gz
|
||||
echo "$LIBHEIF_HASH $WDIR/libheif.tar.gz" | sha256sum -c
|
||||
tar -xzvf $WDIR/libheif.tar.gz
|
||||
cd libheif-$LIBHEIF_VERSION
|
||||
./autogen.sh
|
||||
./configure
|
||||
make && make install
|
||||
|
||||
# Build and install ImageMagick
|
||||
wget -O $WDIR/ImageMagick.tar.gz "https://github.com/ImageMagick/ImageMagick/archive/$IMAGE_MAGICK_VERSION.tar.gz"
|
||||
sha256sum $WDIR/ImageMagick.tar.gz
|
||||
echo "$IMAGE_MAGICK_HASH $WDIR/ImageMagick.tar.gz" | sha256sum -c
|
||||
IMDIR=$WDIR/$(tar tzf $WDIR/ImageMagick.tar.gz --wildcards "ImageMagick-*/configure" |cut -d/ -f1)
|
||||
tar zxf $WDIR/ImageMagick.tar.gz -C $WDIR
|
||||
cd $IMDIR
|
||||
PKG_CONF_LIBDIR=$PREFIX/lib LDFLAGS=-L$PREFIX/lib CFLAGS=-I$PREFIX/include ./configure \
|
||||
--prefix=$PREFIX \
|
||||
--enable-static \
|
||||
--enable-bounds-checking \
|
||||
--enable-hdri \
|
||||
--enable-hugepages \
|
||||
--with-threads \
|
||||
--with-modules \
|
||||
--with-quantum-depth=16 \
|
||||
--without-magick-plus-plus \
|
||||
--with-bzlib \
|
||||
--with-zlib \
|
||||
--without-autotrace \
|
||||
--with-freetype \
|
||||
--with-jpeg \
|
||||
--without-lcms \
|
||||
--with-lzma \
|
||||
--with-png \
|
||||
--with-tiff \
|
||||
--with-heic \
|
||||
--with-webp
|
||||
make all && make install
|
||||
|
||||
cd $HOME
|
||||
rm -rf $WDIR
|
||||
ldconfig /usr/local/lib
|
|
@ -1325,4 +1325,108 @@ describe Report do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'top_users_by_likes_received' do
|
||||
let(:report) { Report.find('top_users_by_likes_received') }
|
||||
|
||||
include_examples 'no data'
|
||||
|
||||
context 'with data' do
|
||||
before do
|
||||
user_1 = Fabricate(:user, username: "jonah")
|
||||
user_2 = Fabricate(:user, username: "jake")
|
||||
user_3 = Fabricate(:user, username: "john")
|
||||
|
||||
3.times { UserAction.create!(user_id: user_1.id, action_type: UserAction::WAS_LIKED) }
|
||||
9.times { UserAction.create!(user_id: user_2.id, action_type: UserAction::WAS_LIKED) }
|
||||
6.times { UserAction.create!(user_id: user_3.id, action_type: UserAction::WAS_LIKED) }
|
||||
end
|
||||
|
||||
it "with category filtering" do
|
||||
report = Report.find('top_users_by_likes_received')
|
||||
|
||||
expect(report.data.length).to eq(3)
|
||||
expect(report.data[0][:username]).to eq("jake")
|
||||
expect(report.data[1][:username]).to eq("john")
|
||||
expect(report.data[2][:username]).to eq("jonah")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'top_users_by_likes_received_from_a_variety_of_people' do
|
||||
let(:report) { Report.find('top_users_by_likes_received_from_a_variety_of_people') }
|
||||
|
||||
include_examples 'no data'
|
||||
|
||||
context 'with data' do
|
||||
before do
|
||||
user_1 = Fabricate(:user, username: "jonah")
|
||||
user_2 = Fabricate(:user, username: "jake")
|
||||
user_3 = Fabricate(:user, username: "john")
|
||||
user_4 = Fabricate(:user, username: "joseph")
|
||||
user_5 = Fabricate(:user, username: "joanne")
|
||||
user_6 = Fabricate(:user, username: "jerome")
|
||||
|
||||
topic_1 = Fabricate(:topic, user: user_1)
|
||||
topic_2 = Fabricate(:topic, user: user_2)
|
||||
topic_3 = Fabricate(:topic, user: user_3)
|
||||
|
||||
post_1 = Fabricate(:post, topic: topic_1, user: user_1)
|
||||
post_2 = Fabricate(:post, topic: topic_2, user: user_2)
|
||||
post_3 = Fabricate(:post, topic: topic_3, user: user_3)
|
||||
|
||||
3.times { UserAction.create!(user_id: user_4.id, target_post_id: post_1.id, action_type: UserAction::LIKE) }
|
||||
6.times { UserAction.create!(user_id: user_5.id, target_post_id: post_2.id, action_type: UserAction::LIKE) }
|
||||
9.times { UserAction.create!(user_id: user_6.id, target_post_id: post_3.id, action_type: UserAction::LIKE) }
|
||||
|
||||
end
|
||||
|
||||
it "with category filtering" do
|
||||
report = Report.find('top_users_by_likes_received_from_a_variety_of_people')
|
||||
|
||||
expect(report.data.length).to eq(3)
|
||||
expect(report.data[0][:username]).to eq("jonah")
|
||||
expect(report.data[1][:username]).to eq("jake")
|
||||
expect(report.data[2][:username]).to eq("john")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'top_users_by_likes_received_from_inferior_trust_level' do
|
||||
let(:report) { Report.find('top_users_by_likes_received_from_inferior_trust_level') }
|
||||
|
||||
include_examples 'no data'
|
||||
|
||||
context 'with data' do
|
||||
before do
|
||||
user_1 = Fabricate(:user, username: "jonah", trust_level: 2)
|
||||
user_2 = Fabricate(:user, username: "jake", trust_level: 2)
|
||||
user_3 = Fabricate(:user, username: "john", trust_level: 2)
|
||||
user_4 = Fabricate(:user, username: "joseph", trust_level: 1)
|
||||
user_5 = Fabricate(:user, username: "joanne", trust_level: 1)
|
||||
user_6 = Fabricate(:user, username: "jerome", trust_level: 2)
|
||||
|
||||
topic_1 = Fabricate(:topic, user: user_1)
|
||||
topic_2 = Fabricate(:topic, user: user_2)
|
||||
topic_3 = Fabricate(:topic, user: user_3)
|
||||
|
||||
post_1 = Fabricate(:post, topic: topic_1, user: user_1)
|
||||
post_2 = Fabricate(:post, topic: topic_2, user: user_2)
|
||||
post_3 = Fabricate(:post, topic: topic_3, user: user_3)
|
||||
|
||||
3.times { UserAction.create!(user_id: user_4.id, target_post_id: post_1.id, action_type: UserAction::LIKE) }
|
||||
6.times { UserAction.create!(user_id: user_5.id, target_post_id: post_2.id, action_type: UserAction::LIKE) }
|
||||
9.times { UserAction.create!(user_id: user_6.id, target_post_id: post_3.id, action_type: UserAction::LIKE) }
|
||||
|
||||
end
|
||||
|
||||
it "with category filtering" do
|
||||
report = Report.find('top_users_by_likes_received_from_inferior_trust_level')
|
||||
|
||||
expect(report.data.length).to eq(2)
|
||||
expect(report.data[0][:username]).to eq("jake")
|
||||
expect(report.data[1][:username]).to eq("jonah")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue
Block a user