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:
Michelle Bueno Saquetim Vendrame 2021-12-02 17:11:55 +00:00 committed by GitHub
parent 2f04a9b9fb
commit 9b5836aa1d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 401 additions and 0 deletions

View 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

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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
View 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

View File

@ -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