FEATURE: Add `Top Uploads` report (#6825)

Co-Authored-By: I am very Pro-Grammer. <khalilovcmded@users.noreply.github.com>
This commit is contained in:
Joffrey JAFFEUX 2018-12-28 20:48:54 +01:00 committed by GitHub
parent 608abd4c08
commit f1269fa807
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 136 additions and 2 deletions

View File

@ -272,6 +272,7 @@ const Report = Discourse.Model.extend({
if (type === "seconds") return this._secondsLabel(value);
if (type === "link") return this._linkLabel(label.properties, row);
if (type === "percent") return this._percentLabel(value);
if (type === "bytes") return this._bytesLabel(value);
if (type === "number") {
return this._numberLabel(value, opts);
}
@ -381,6 +382,13 @@ const Report = Discourse.Model.extend({
};
},
_bytesLabel(value) {
return {
value,
formatedValue: I18n.toHumanSize(value)
};
},
_dateLabel(value, date, format = "LL") {
return {
value,

View File

@ -1433,6 +1433,72 @@ class Report
}
end
def self.report_top_uploads(report)
report.modes = [:table]
report.labels = [
{
type: :link,
properties: [
:file_url,
:file_name,
],
title: I18n.t("reports.top_uploads.labels.filename")
},
{
type: :user,
properties: {
username: :author_username,
id: :author_id,
avatar: :author_avatar_template,
},
title: I18n.t("reports.top_uploads.labels.author")
},
{
type: :text,
property: :extension,
title: I18n.t("reports.top_uploads.labels.extension")
},
{
type: :bytes,
property: :filesize,
title: I18n.t("reports.top_uploads.labels.filesize")
},
]
report.data = []
sql = <<~SQL
SELECT
u.id as user_id,
u.username,
u.uploaded_avatar_id,
up.filesize,
up.original_filename,
up.extension,
up.url
FROM uploads up
JOIN users u
ON u.id = up.user_id
WHERE up.created_at >= '#{report.start_date}' AND up.created_at <= '#{report.end_date}'
ORDER BY up.filesize DESC
LIMIT #{report.limit || 250}
SQL
DB.query(sql).each do |row|
data = {}
data[:author_id] = row.user_id
data[:author_username] = row.username
data[:author_avatar_template] = User.avatar_template(row.username, row.uploaded_avatar_id)
data[:filesize] = row.filesize
data[:extension] = row.extension
data[:file_url] = Discourse.store.cdn_url(row.url)
data[:file_name] = row.original_filename.truncate(25)
report.data << data
end
end
DiscourseEvent.on(:site_setting_saved) do |site_setting|
if ["backup_location", "s3_backup_bucket"].include?(site_setting.name.to_s)
clear_cache(:storage_stats)

View File

@ -1171,6 +1171,14 @@ en:
location: Location
login_at: Login at
description: "List of admin and moderator login times with locations."
top_uploads:
title: "Top Uploads"
labels:
filename: Filename
extension: Extension
author: Author
filesize: File size
description: "List all uploads by extension, filesize and author."
dashboard:
rails_env_warning: "Your server is running in %{env} mode."

View File

@ -1028,4 +1028,45 @@ describe Report do
end
end
end
describe "report_top_uploads" do
let(:report) { Report.find("top_uploads") }
let(:tarek) { Fabricate(:admin, username: "tarek") }
let(:khalil) { Fabricate(:admin, username: "khalil") }
context "with data" do
let!(:tarek_upload) do
Fabricate(:upload, user: tarek,
url: "/uploads/default/original/1X/tarek.jpg",
extension: "jpg",
original_filename: "tarek.jpg",
filesize: 1000)
end
let!(:khalil_upload) do
Fabricate(:upload, user: khalil,
url: "/uploads/default/original/1X/khalil.png",
extension: "png",
original_filename: "khalil.png",
filesize: 2000)
end
it "works" do
expect(report.data.length).to eq(2)
expect_row_to_be_equal(report.data[0], khalil, khalil_upload)
expect_row_to_be_equal(report.data[1], tarek, tarek_upload)
end
def expect_row_to_be_equal(row, user, upload)
expect(row[:author_id]).to eq(user.id)
expect(row[:author_username]).to eq(user.username)
expect(row[:author_avatar_template]).to eq(User.avatar_template(user.username, user.uploaded_avatar_id))
expect(row[:filesize]).to eq(upload.filesize)
expect(row[:extension]).to eq(upload.extension)
expect(row[:file_url]).to eq(Discourse.store.cdn_url(upload.url))
expect(row[:file_name]).to eq(upload.original_filename.truncate(25))
end
end
include_examples "no data"
end
end

View File

@ -404,7 +404,8 @@ QUnit.test("computed labels", assert => {
topic_id: 2,
topic_title: "Test topic",
post_number: 3,
post_raw: "This is the beginning of"
post_raw: "This is the beginning of",
filesize: 582641
}
];
@ -437,7 +438,8 @@ QUnit.test("computed labels", assert => {
truncated_raw: "post_raw"
},
title: "Post"
}
},
{ type: "bytes", property: "filesize", title: "Filesize" }
];
const report = Report.create({
@ -516,6 +518,15 @@ QUnit.test("computed labels", assert => {
);
assert.equal(computedPostLabel.value, "This is the beginning of");
const filesizeLabel = computedLabels[6];
assert.equal(filesizeLabel.mainProperty, "filesize");
assert.equal(filesizeLabel.sortProperty, "filesize");
assert.equal(filesizeLabel.title, "Filesize");
assert.equal(filesizeLabel.type, "bytes");
const computedFilesizeLabel = filesizeLabel.compute(row);
assert.equal(computedFilesizeLabel.formatedValue, "569.0 KB");
assert.equal(computedFilesizeLabel.value, 582641);
// subfolder support
Discourse.BaseUri = "/forum";