PC-1153 Add /reportmetrics command
This commit is contained in:
parent
e4c7e31185
commit
52d001c26e
@ -34,6 +34,7 @@ import mineplex.core.portal.Portal;
|
||||
import mineplex.core.punish.Category;
|
||||
import mineplex.core.punish.Punish;
|
||||
import mineplex.core.punish.PunishClient;
|
||||
import mineplex.core.report.data.metrics.ReportMetricsRepository;
|
||||
import mineplex.core.report.redis.HandlerNotification;
|
||||
import mineplex.core.report.data.Report;
|
||||
import mineplex.core.report.data.ReportMessage;
|
||||
@ -64,7 +65,8 @@ public class ReportManager
|
||||
private final int _serverWeight;
|
||||
|
||||
private final ReportRepository _reportRepository;
|
||||
private final ReportUserRepository _reportUserRepository;
|
||||
private final ReportUserRepository _userRepository;
|
||||
private final ReportMetricsRepository _metricsRepository;
|
||||
|
||||
public ReportManager(JavaPlugin plugin, SnapshotManager snapshotManager, CoreClientManager clientManager,
|
||||
IncognitoManager incognitoManager, Punish punish, Region region, String serverName, int serverWeight)
|
||||
@ -79,8 +81,8 @@ public class ReportManager
|
||||
_serverWeight = serverWeight;
|
||||
|
||||
_reportRepository = new ReportRepository(this, _plugin.getLogger());
|
||||
|
||||
_reportUserRepository = new ReportUserRepository(plugin);
|
||||
_userRepository = new ReportUserRepository(plugin);
|
||||
_metricsRepository = new ReportMetricsRepository(_plugin.getLogger());
|
||||
|
||||
ServerCommandManager commandManager = ServerCommandManager.getInstance();
|
||||
ReportRedisManager notificationCallback = new ReportRedisManager(this, _serverName);
|
||||
@ -101,7 +103,7 @@ public class ReportManager
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link ReportRepository} we are using.
|
||||
* Gets the {@link ReportRepository} this instance is using.
|
||||
*
|
||||
* @return the repository
|
||||
*/
|
||||
@ -110,6 +112,26 @@ public class ReportManager
|
||||
return _reportRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link ReportUserRepository} this instance is using.
|
||||
*
|
||||
* @return the repository
|
||||
*/
|
||||
public ReportUserRepository getUserRepository()
|
||||
{
|
||||
return _userRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link ReportMetricsRepository} this instance is using.
|
||||
*
|
||||
* @return the repository
|
||||
*/
|
||||
public ReportMetricsRepository getMetricsRepository()
|
||||
{
|
||||
return _metricsRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new report or adds to an existing one.
|
||||
*
|
||||
@ -595,7 +617,7 @@ public class ReportManager
|
||||
for (Map.Entry<Integer, ReportMessage> entry : report.getMessages().entrySet())
|
||||
{
|
||||
int accountId = entry.getKey();
|
||||
ReportUser user = _reportUserRepository.getUser(accountId).join();
|
||||
ReportUser user = _userRepository.getUser(accountId).join();
|
||||
int categoryReputation = user.getReputation(report.getCategory());
|
||||
|
||||
ReportMessage message = entry.getValue();
|
||||
|
@ -11,6 +11,7 @@ import mineplex.core.report.command.ReportCommand;
|
||||
import mineplex.core.report.command.ReportHandleCommand;
|
||||
import mineplex.core.report.command.ReportInfoCommand;
|
||||
import mineplex.core.report.command.ReportHistoryCommand;
|
||||
import mineplex.core.report.command.ReportMetricsCommand;
|
||||
|
||||
/**
|
||||
* Main class for this module, handles initialization and disabling of the module.
|
||||
@ -38,6 +39,7 @@ public class ReportPlugin extends MiniPlugin
|
||||
addCommand(new ReportCloseCommand(this));
|
||||
addCommand(new ReportHistoryCommand(this));
|
||||
addCommand(new ReportInfoCommand(this));
|
||||
addCommand(new ReportMetricsCommand(this));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
@ -7,23 +7,23 @@ import org.apache.commons.lang3.text.WordUtils;
|
||||
*/
|
||||
public enum ReportResultType
|
||||
{
|
||||
ACCEPTED(0, false),
|
||||
DENIED(1, false),
|
||||
ABUSIVE(2, true),
|
||||
EXPIRED(3, true);
|
||||
ACCEPTED((short) 0, false),
|
||||
DENIED((short) 1, false),
|
||||
ABUSIVE((short) 2, true),
|
||||
EXPIRED((short) 3, true);
|
||||
|
||||
private final int _id;
|
||||
private final short _id;
|
||||
private final boolean _globalStat;
|
||||
private final String _name;
|
||||
|
||||
ReportResultType(int id, boolean globalStat)
|
||||
ReportResultType(short id, boolean globalStat)
|
||||
{
|
||||
_id = id;
|
||||
_globalStat = globalStat;
|
||||
_name = WordUtils.capitalizeFully(name().replace('_', ' '));
|
||||
}
|
||||
|
||||
public int getId()
|
||||
public short getId()
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
|
@ -0,0 +1,108 @@
|
||||
package mineplex.core.report.command;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import mineplex.core.command.CommandBase;
|
||||
import mineplex.core.common.Rank;
|
||||
import mineplex.core.common.util.BukkitFuture;
|
||||
import mineplex.core.common.util.C;
|
||||
import mineplex.core.common.util.F;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.core.report.ReportPlugin;
|
||||
import mineplex.core.report.data.metrics.ReportMetrics;
|
||||
|
||||
/**
|
||||
* Displays various report-related metrics on a player.
|
||||
*/
|
||||
public class ReportMetricsCommand extends CommandBase<ReportPlugin>
|
||||
{
|
||||
public ReportMetricsCommand(ReportPlugin plugin)
|
||||
{
|
||||
super(plugin, Rank.MODERATOR, "reportmetrics");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Execute(Player player, String[] args)
|
||||
{
|
||||
if (args.length <= 2)
|
||||
{
|
||||
int days = 30;
|
||||
|
||||
if (args.length >= 1) // has target argument
|
||||
{
|
||||
String targetName = args[0];
|
||||
|
||||
if (args.length > 1)
|
||||
{
|
||||
String daysString = args[1];
|
||||
|
||||
try
|
||||
{
|
||||
days = Integer.parseInt(daysString);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
UtilPlayer.message(player, F.main(Plugin.getName(), F.elem(daysString) + C.cRed + " is not a valid number."));
|
||||
}
|
||||
}
|
||||
|
||||
int finalDays = days;
|
||||
Plugin.getReportManager().getRepository().getAccountId(targetName).thenAccept(targetIdOptional ->
|
||||
{
|
||||
if (targetIdOptional.isPresent())
|
||||
{
|
||||
int targetId = targetIdOptional.get();
|
||||
displayUserMetrics(player, targetName, targetId, finalDays);
|
||||
}
|
||||
else
|
||||
{
|
||||
UtilPlayer.message(player, F.main(Plugin.getName(), C.cRed + "Player not found."));
|
||||
}
|
||||
});
|
||||
}
|
||||
else // display global metrics
|
||||
{
|
||||
// TODO: do we parse days for global metrics?
|
||||
UtilPlayer.message(player, F.main("Report Metrics", F.elem("Global Metrics") + " (" + F.elem(days + " days") + ")"));
|
||||
displayGlobalMetrics(player, days);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UtilPlayer.message(player,
|
||||
F.main(Plugin.getName(), C.cRed + "Invalid Usage: "
|
||||
+ F.elem("/" + _aliasUsed + " <player> [days]")));
|
||||
}
|
||||
}
|
||||
|
||||
public void displayGlobalMetrics(Player player, int days)
|
||||
{
|
||||
Plugin.getReportManager().getMetricsRepository().getGlobalMetrics(days).thenCompose(
|
||||
BukkitFuture.accept(globalMetrics ->
|
||||
{
|
||||
UtilPlayer.message(player, F.main("Report Metrics", "Submitted: " + F.elem(globalMetrics.getSubmitted())));
|
||||
UtilPlayer.message(player, F.main("Report Metrics", "Expired: " + F.elem(globalMetrics.getExpired())));
|
||||
displayMetrics(player, globalMetrics);
|
||||
}));
|
||||
}
|
||||
|
||||
public void displayUserMetrics(Player player, String targetName, int targetId, int days)
|
||||
{
|
||||
Plugin.getReportManager().getMetricsRepository().getUserMetrics(targetId, days).thenCompose(
|
||||
BukkitFuture.accept(userMetrics ->
|
||||
{
|
||||
UtilPlayer.message(player,
|
||||
F.main("Report Metrics",
|
||||
F.elem(targetName) + " (" + F.elem(days + " days") + ")"));
|
||||
|
||||
displayMetrics(player, userMetrics);
|
||||
}));
|
||||
}
|
||||
|
||||
public void displayMetrics(Player player, ReportMetrics reportMetrics)
|
||||
{
|
||||
UtilPlayer.message(player, F.main("Report Metrics", "Accepted: " + F.elem(reportMetrics.getAccepted())));
|
||||
UtilPlayer.message(player, F.main("Report Metrics", "Denied: " + F.elem(reportMetrics.getDenied())));
|
||||
UtilPlayer.message(player, F.main("Report Metrics", "Flagged Abusive: " + F.elem(reportMetrics.getFlagged())));
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package mineplex.core.report.data.metrics;
|
||||
|
||||
/**
|
||||
* Extends the standard report metrics class to hold global-scope metrics.
|
||||
*/
|
||||
public class ReportGlobalMetrics extends ReportMetrics
|
||||
{
|
||||
private final long _submitted;
|
||||
private final long _expired;
|
||||
|
||||
public ReportGlobalMetrics(long submitted, long expired, long accepted, long denied, long flagged)
|
||||
{
|
||||
super(accepted, denied, flagged);
|
||||
_submitted = submitted;
|
||||
_expired = expired;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount of reports submitted.
|
||||
*
|
||||
* @return the amount
|
||||
*/
|
||||
public long getSubmitted()
|
||||
{
|
||||
return _submitted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount of reports expired.
|
||||
*
|
||||
* @return the amount
|
||||
*/
|
||||
public long getExpired()
|
||||
{
|
||||
return _expired;
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package mineplex.core.report.data.metrics;
|
||||
|
||||
/**
|
||||
* Holds report-related metrics which can be applied to a user or global scope.
|
||||
*/
|
||||
public class ReportMetrics
|
||||
{
|
||||
private final long _accepted;
|
||||
private final long _denied;
|
||||
private final long _flagged;
|
||||
|
||||
public ReportMetrics(long accepted, long denied, long flagged)
|
||||
{
|
||||
_accepted = accepted;
|
||||
_denied = denied;
|
||||
_flagged = flagged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount of reports accepted.
|
||||
*
|
||||
* @return the amount
|
||||
*/
|
||||
public long getAccepted()
|
||||
{
|
||||
return _accepted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount of reports denied.
|
||||
*
|
||||
* @return the amount
|
||||
*/
|
||||
public long getDenied()
|
||||
{
|
||||
return _denied;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount of reports flagged (marked as spam).
|
||||
*
|
||||
* @return the amount
|
||||
*/
|
||||
public long getFlagged()
|
||||
{
|
||||
return _flagged;
|
||||
}
|
||||
}
|
@ -0,0 +1,156 @@
|
||||
package mineplex.core.report.data.metrics;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import mineplex.core.report.ReportResultType;
|
||||
import mineplex.serverdata.database.DBPool;
|
||||
|
||||
/**
|
||||
* Handles all fetching of report-related metrics.
|
||||
*/
|
||||
public class ReportMetricsRepository
|
||||
{
|
||||
private static final String GET_GLOBAL_SUBMITTED = "SELECT COUNT(DISTINCT reportReasons.reportId) AS submitted FROM reportReasons\n" +
|
||||
" WHERE reportReasons.time BETWEEN NOW() - INTERVAL ? DAY AND NOW();";
|
||||
|
||||
private static final String GET_GLOBAL_RESULT = "SELECT COUNT(reportResults.reportId) AS amount FROM reportResults\n" +
|
||||
" WHERE reportResults.resultId = ?\n" +
|
||||
" AND reportResults.closedTime BETWEEN NOW() - INTERVAL ? DAY AND NOW();";
|
||||
|
||||
private static final String GET_USER_RESULT = "SELECT COUNT(reportResults.reportId) AS amount FROM reportResults\n" +
|
||||
" LEFT JOIN reportHandlers ON reportResults.reportId = reportHandlers.reportId AND reportHandlers.aborted IS FALSE\n" +
|
||||
" WHERE reportHandlers.handlerId = ?\n" +
|
||||
" AND reportResults.resultId = ?\n" +
|
||||
" AND reportResults.closedTime BETWEEN NOW() - INTERVAL ? DAY AND NOW();";
|
||||
|
||||
private final Logger _logger;
|
||||
|
||||
public ReportMetricsRepository(Logger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public CompletableFuture<ReportGlobalMetrics> getGlobalMetrics(int days)
|
||||
{
|
||||
CompletableFuture<ReportGlobalMetrics> future = CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
try (Connection connection = DBPool.getAccount().getConnection())
|
||||
{
|
||||
long submitted = getGlobalSubmitted(connection, days);
|
||||
|
||||
try (PreparedStatement preparedStatement = connection.prepareStatement(GET_GLOBAL_RESULT))
|
||||
{
|
||||
long expired = getGlobalResult(preparedStatement, ReportResultType.EXPIRED, days);
|
||||
long accepted = getGlobalResult(preparedStatement, ReportResultType.ACCEPTED, days);
|
||||
long denied = getGlobalResult(preparedStatement, ReportResultType.DENIED, days);
|
||||
long flagged = getGlobalResult(preparedStatement, ReportResultType.ABUSIVE, days);
|
||||
|
||||
return new ReportGlobalMetrics(submitted, expired, accepted, denied, flagged);
|
||||
}
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
|
||||
future.exceptionally(throwable ->
|
||||
{
|
||||
_logger.log(Level.SEVERE, "Error fetching global metrics.", throwable);
|
||||
return null;
|
||||
});
|
||||
|
||||
return future;
|
||||
}
|
||||
|
||||
private long getGlobalSubmitted(Connection connection, int days) throws SQLException
|
||||
{
|
||||
PreparedStatement preparedStatement = connection.prepareStatement(GET_GLOBAL_SUBMITTED);
|
||||
preparedStatement.setInt(1, days);
|
||||
|
||||
try (ResultSet resultSet = preparedStatement.executeQuery())
|
||||
{
|
||||
if (resultSet.next())
|
||||
{
|
||||
return resultSet.getLong("submitted");
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private long getGlobalResult(PreparedStatement preparedStatement, ReportResultType resultType, int days) throws SQLException
|
||||
{
|
||||
preparedStatement.setShort(1, resultType.getId());
|
||||
preparedStatement.setInt(2, days);
|
||||
|
||||
try (ResultSet resultSet = preparedStatement.executeQuery())
|
||||
{
|
||||
if (resultSet.next())
|
||||
{
|
||||
return resultSet.getLong("amount");
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CompletableFuture<ReportMetrics> getUserMetrics(int accountId, int days)
|
||||
{
|
||||
CompletableFuture<ReportMetrics> future = CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
try (Connection connection = DBPool.getAccount().getConnection())
|
||||
{
|
||||
try (PreparedStatement preparedStatement = connection.prepareStatement(GET_USER_RESULT))
|
||||
{
|
||||
long accepted = getUserResult(preparedStatement, accountId, ReportResultType.ACCEPTED, days);
|
||||
long denied = getUserResult(preparedStatement, accountId, ReportResultType.DENIED, days);
|
||||
long flagged = getUserResult(preparedStatement, accountId, ReportResultType.ABUSIVE, days);
|
||||
|
||||
return new ReportMetrics(accepted, denied, flagged);
|
||||
}
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
|
||||
future.exceptionally(throwable ->
|
||||
{
|
||||
_logger.log(Level.SEVERE, "Error fetching user metrics.", throwable);
|
||||
return null;
|
||||
});
|
||||
|
||||
return future;
|
||||
}
|
||||
|
||||
private long getUserResult(PreparedStatement preparedStatement, int accountId, ReportResultType resultType, int days) throws SQLException
|
||||
{
|
||||
preparedStatement.setInt(1, accountId);
|
||||
preparedStatement.setShort(2, resultType.getId());
|
||||
preparedStatement.setInt(3, days);
|
||||
|
||||
try (ResultSet resultSet = preparedStatement.executeQuery())
|
||||
{
|
||||
if (resultSet.next())
|
||||
{
|
||||
return resultSet.getLong("amount");
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user