mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-12-26 19:17:43 +01:00
Inspect Page Parsing. (Fixes Inspect command)
This commit is contained in:
parent
32ce997d51
commit
150c4825fd
@ -13,6 +13,9 @@ import main.java.com.djrapitops.plan.Plan;
|
|||||||
import main.java.com.djrapitops.plan.command.ConditionUtils;
|
import main.java.com.djrapitops.plan.command.ConditionUtils;
|
||||||
import main.java.com.djrapitops.plan.locale.Locale;
|
import main.java.com.djrapitops.plan.locale.Locale;
|
||||||
import main.java.com.djrapitops.plan.locale.Msg;
|
import main.java.com.djrapitops.plan.locale.Msg;
|
||||||
|
import main.java.com.djrapitops.plan.systems.processing.Processor;
|
||||||
|
import main.java.com.djrapitops.plan.systems.webserver.PageCache;
|
||||||
|
import main.java.com.djrapitops.plan.systems.webserver.response.InspectPageResponse;
|
||||||
import main.java.com.djrapitops.plan.utilities.Check;
|
import main.java.com.djrapitops.plan.utilities.Check;
|
||||||
import main.java.com.djrapitops.plan.utilities.MiscUtils;
|
import main.java.com.djrapitops.plan.utilities.MiscUtils;
|
||||||
import main.java.com.djrapitops.plan.utilities.html.HtmlUtils;
|
import main.java.com.djrapitops.plan.utilities.html.HtmlUtils;
|
||||||
@ -87,8 +90,14 @@ public class InspectCommand extends SubCommand {
|
|||||||
sender.sendMessage(ChatColor.YELLOW + "[Plan] You might not have a web user, use /plan register <password>");
|
sender.sendMessage(ChatColor.YELLOW + "[Plan] You might not have a web user, use /plan register <password>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//TODO Inspect Request.
|
|
||||||
runMessageSenderTask(uuid, sender, playerName);
|
plugin.addToProcessQueue(new Processor<UUID>(uuid) {
|
||||||
|
@Override
|
||||||
|
public void process() {
|
||||||
|
PageCache.loadPage("inspectPage: " + uuid, () -> new InspectPageResponse(plugin.getInfoManager(), uuid));
|
||||||
|
sendInspectMsg(sender, playerName);
|
||||||
|
}
|
||||||
|
});
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
Log.toLog(this.getClass().getName(), ex);
|
Log.toLog(this.getClass().getName(), ex);
|
||||||
} finally {
|
} finally {
|
||||||
@ -116,7 +125,7 @@ public class InspectCommand extends SubCommand {
|
|||||||
}).runTaskTimer(TimeAmount.SECOND.ticks(), 5 * TimeAmount.SECOND.ticks());
|
}).runTaskTimer(TimeAmount.SECOND.ticks(), 5 * TimeAmount.SECOND.ticks());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendInspectMsg(ISender sender, String playerName, UUID uuid) {
|
private void sendInspectMsg(ISender sender, String playerName) {
|
||||||
sender.sendMessage(Locale.get(Msg.CMD_HEADER_INSPECT) + " " + playerName);
|
sender.sendMessage(Locale.get(Msg.CMD_HEADER_INSPECT) + " " + playerName);
|
||||||
// Link
|
// Link
|
||||||
String url = HtmlUtils.getInspectUrlWithProtocol(playerName);
|
String url = HtmlUtils.getInspectUrlWithProtocol(playerName);
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
package main.java.com.djrapitops.plan.systems.info;
|
package main.java.com.djrapitops.plan.systems.info;
|
||||||
|
|
||||||
import com.djrapitops.plugin.command.ISender;
|
import com.djrapitops.plugin.command.ISender;
|
||||||
|
import main.java.com.djrapitops.plan.Log;
|
||||||
import main.java.com.djrapitops.plan.Plan;
|
import main.java.com.djrapitops.plan.Plan;
|
||||||
import main.java.com.djrapitops.plan.bungee.PlanBungee;
|
import main.java.com.djrapitops.plan.bungee.PlanBungee;
|
||||||
import main.java.com.djrapitops.plan.command.commands.AnalyzeCommand;
|
import main.java.com.djrapitops.plan.command.commands.AnalyzeCommand;
|
||||||
@ -12,10 +13,14 @@ import main.java.com.djrapitops.plan.data.AnalysisData;
|
|||||||
import main.java.com.djrapitops.plan.database.Database;
|
import main.java.com.djrapitops.plan.database.Database;
|
||||||
import main.java.com.djrapitops.plan.systems.cache.DataCache;
|
import main.java.com.djrapitops.plan.systems.cache.DataCache;
|
||||||
import main.java.com.djrapitops.plan.systems.cache.SessionCache;
|
import main.java.com.djrapitops.plan.systems.cache.SessionCache;
|
||||||
|
import main.java.com.djrapitops.plan.systems.info.parsing.InspectPageParser;
|
||||||
import main.java.com.djrapitops.plan.systems.info.parsing.UrlParser;
|
import main.java.com.djrapitops.plan.systems.info.parsing.UrlParser;
|
||||||
|
import main.java.com.djrapitops.plan.systems.webserver.PageCache;
|
||||||
import main.java.com.djrapitops.plan.utilities.MiscUtils;
|
import main.java.com.djrapitops.plan.utilities.MiscUtils;
|
||||||
import main.java.com.djrapitops.plan.utilities.analysis.Analysis;
|
import main.java.com.djrapitops.plan.utilities.analysis.Analysis;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.sql.SQLException;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -92,12 +97,19 @@ public class InformationManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCached(UUID uuid) {
|
public boolean isCached(UUID uuid) {
|
||||||
// TODO
|
if (usingBungeeWebServer) {
|
||||||
return false;
|
// TODO bungee part
|
||||||
|
}
|
||||||
|
return PageCache.isCached("inspectPage: " + uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPlayerHtml(UUID uuid) {
|
public String getPlayerHtml(UUID uuid) {
|
||||||
// TODO
|
// TODO Bungee part.
|
||||||
|
try {
|
||||||
|
return new InspectPageParser(uuid, plugin).parse();
|
||||||
|
} catch (SQLException | FileNotFoundException e) {
|
||||||
|
Log.toLog(this.getClass().getName(), e);
|
||||||
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,172 @@
|
|||||||
|
/*
|
||||||
|
* Licence is provided in the jar as license.yml also here:
|
||||||
|
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml
|
||||||
|
*/
|
||||||
|
package main.java.com.djrapitops.plan.systems.info.parsing;
|
||||||
|
|
||||||
|
import com.djrapitops.plugin.api.TimeAmount;
|
||||||
|
import main.java.com.djrapitops.plan.Log;
|
||||||
|
import main.java.com.djrapitops.plan.Settings;
|
||||||
|
import main.java.com.djrapitops.plan.api.IPlan;
|
||||||
|
import main.java.com.djrapitops.plan.data.Action;
|
||||||
|
import main.java.com.djrapitops.plan.data.PlayerKill;
|
||||||
|
import main.java.com.djrapitops.plan.data.Session;
|
||||||
|
import main.java.com.djrapitops.plan.data.UserInfo;
|
||||||
|
import main.java.com.djrapitops.plan.database.Database;
|
||||||
|
import main.java.com.djrapitops.plan.database.tables.SessionsTable;
|
||||||
|
import main.java.com.djrapitops.plan.utilities.Benchmark;
|
||||||
|
import main.java.com.djrapitops.plan.utilities.FormatUtils;
|
||||||
|
import main.java.com.djrapitops.plan.utilities.MiscUtils;
|
||||||
|
import main.java.com.djrapitops.plan.utilities.analysis.AnalysisUtils;
|
||||||
|
import main.java.com.djrapitops.plan.utilities.comparators.ActionComparator;
|
||||||
|
import main.java.com.djrapitops.plan.utilities.comparators.SessionLengthComparator;
|
||||||
|
import main.java.com.djrapitops.plan.utilities.comparators.SessionStartComparator;
|
||||||
|
import main.java.com.djrapitops.plan.utilities.file.FileUtil;
|
||||||
|
import main.java.com.djrapitops.plan.utilities.html.HtmlStructure;
|
||||||
|
import main.java.com.djrapitops.plan.utilities.html.HtmlUtils;
|
||||||
|
import main.java.com.djrapitops.plan.utilities.html.graphs.PunchCardGraphCreator;
|
||||||
|
import main.java.com.djrapitops.plan.utilities.html.tables.ActionsTableCreator;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* //TODO Class Javadoc Comment
|
||||||
|
*
|
||||||
|
* @author Rsl1122
|
||||||
|
*/
|
||||||
|
public class InspectPageParser {
|
||||||
|
|
||||||
|
private final UUID uuid;
|
||||||
|
private final IPlan plugin;
|
||||||
|
|
||||||
|
private final Map<String, Serializable> placeHolders;
|
||||||
|
|
||||||
|
public InspectPageParser(UUID uuid, IPlan plugin) {
|
||||||
|
this.uuid = uuid;
|
||||||
|
this.plugin = plugin;
|
||||||
|
placeHolders = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String parse() throws SQLException, FileNotFoundException {
|
||||||
|
Log.debug("Database", "Inspect Parse Fetch");
|
||||||
|
Benchmark.start("Inspect Parse, Fetch");
|
||||||
|
Database db = plugin.getDB();
|
||||||
|
UserInfo userInfo = db.getUserInfoTable().getUserInfo(uuid);
|
||||||
|
int timesKicked = db.getUsersTable().getTimesKicked(uuid);
|
||||||
|
|
||||||
|
addValue("version", MiscUtils.getPlanVersion());
|
||||||
|
addValue("serverName", Settings.SERVER_NAME.toString());
|
||||||
|
|
||||||
|
addValue("playerName", userInfo.getName());
|
||||||
|
addValue("registered", FormatUtils.formatTimeStampYear(userInfo.getRegistered()));
|
||||||
|
long lastSeen = userInfo.getLastSeen();
|
||||||
|
addValue("lastSeen", FormatUtils.formatTimeStampYear(lastSeen));
|
||||||
|
addValue("kickCount", timesKicked);
|
||||||
|
|
||||||
|
SessionsTable sessionsTable = db.getSessionsTable();
|
||||||
|
Map<String, Long> playtimeByServer = sessionsTable.getPlaytimeByServer(uuid);
|
||||||
|
|
||||||
|
List<String> geolocations = db.getIpsTable().getGeolocations(uuid);
|
||||||
|
List<String> nicknames = db.getNicknamesTable().getNicknames(uuid).stream()
|
||||||
|
.map(HtmlUtils::swapColorsToSpan)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
addValue("nicknames", HtmlStructure.createDotList(nicknames.toArray(new String[nicknames.size()])));
|
||||||
|
addValue("geolocations", HtmlStructure.createDotList(geolocations.toArray(new String[geolocations.size()])));
|
||||||
|
|
||||||
|
Map<String, List<Session>> sessions = sessionsTable.getSessions(uuid);
|
||||||
|
List<Session> allSessions = sessions.values().stream()
|
||||||
|
.flatMap(Collection::stream)
|
||||||
|
.sorted(new SessionStartComparator())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
addValue("contentSessions", HtmlStructure.createSessionsTabContent(sessions, allSessions));
|
||||||
|
addValue("contentServerOverview", HtmlStructure.createServerOverviewColumn(sessions));
|
||||||
|
|
||||||
|
long now = MiscUtils.getTime();
|
||||||
|
long dayAgo = now - TimeAmount.DAY.ms();
|
||||||
|
long weekAgo = now - TimeAmount.WEEK.ms();
|
||||||
|
|
||||||
|
List<Session> sessionsDay = allSessions.stream()
|
||||||
|
.filter(s -> s.getSessionStart() > dayAgo)
|
||||||
|
.sorted(new SessionLengthComparator())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
List<Session> sessionsWeek = allSessions.stream()
|
||||||
|
.filter(s -> s.getSessionStart() > weekAgo)
|
||||||
|
.sorted(new SessionLengthComparator())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
int sessionCountDay = sessionsDay.size();
|
||||||
|
int sessionCountWeek = sessionsDay.size();
|
||||||
|
long playtimeDay = AnalysisUtils.getTotalPlaytime(sessionsDay);
|
||||||
|
long playtimeWeek = AnalysisUtils.getTotalPlaytime(sessionsWeek);
|
||||||
|
|
||||||
|
addValue("sessionCountDay", sessionCountDay);
|
||||||
|
addValue("sessionCountWeek", sessionCountWeek);
|
||||||
|
addValue("playtimeDay", FormatUtils.formatTimeAmount(playtimeDay));
|
||||||
|
addValue("playtimeWeek", FormatUtils.formatTimeAmount(playtimeWeek));
|
||||||
|
|
||||||
|
List<Action> actions = db.getActionsTable().getActions(uuid);
|
||||||
|
actions.addAll(allSessions.stream()
|
||||||
|
.map(Session::getPlayerKills)
|
||||||
|
.flatMap(Collection::stream)
|
||||||
|
.map(PlayerKill::convertToAction)
|
||||||
|
.collect(Collectors.toList()));
|
||||||
|
actions.sort(new ActionComparator());
|
||||||
|
|
||||||
|
addValue("tableBodyActions", ActionsTableCreator.createTableContent(actions));
|
||||||
|
|
||||||
|
Benchmark.stop("Inspect Parse, Fetch");
|
||||||
|
|
||||||
|
long playTime = AnalysisUtils.getTotalPlaytime(allSessions);
|
||||||
|
int sessionCount = allSessions.size();
|
||||||
|
|
||||||
|
addValue("sessionCount", sessionCount);
|
||||||
|
addValue("playtimeTotal", FormatUtils.formatTimeAmount(playTime));
|
||||||
|
addValue("lastSeen", FormatUtils.formatTimeAmount(playTime));
|
||||||
|
|
||||||
|
String puchCardData = PunchCardGraphCreator.createDataSeries(allSessions);
|
||||||
|
List<Session> sessionsInLengthOrder = allSessions.stream().sorted(new SessionLengthComparator()).collect(Collectors.toList());
|
||||||
|
if (sessionsInLengthOrder.isEmpty()) {
|
||||||
|
addValue("sessionLengthMedian", "No Sessions");
|
||||||
|
addValue("sessionLengthLongest", "No Sessions");
|
||||||
|
} else {
|
||||||
|
Session medianSession = sessionsInLengthOrder.get(sessionsInLengthOrder.size() / 2);
|
||||||
|
addValue("sessionLengthMedian", FormatUtils.formatTimeAmount(medianSession.getLength()));
|
||||||
|
addValue("sessionLengthLongest", FormatUtils.formatTimeAmount(sessionsInLengthOrder.get(0).getLength()));
|
||||||
|
}
|
||||||
|
|
||||||
|
long playerKillCount = allSessions.stream().map(Session::getPlayerKills).mapToLong(Collection::size).sum();
|
||||||
|
long mobKillCount = allSessions.stream().mapToLong(Session::getMobKills).sum();
|
||||||
|
long deathCount = allSessions.stream().mapToLong(Session::getDeaths).sum();
|
||||||
|
|
||||||
|
addValue("playerKillCount", playerKillCount);
|
||||||
|
addValue("mobKillCount", mobKillCount);
|
||||||
|
addValue("deathCount", deathCount);
|
||||||
|
|
||||||
|
|
||||||
|
playerClassification(userInfo, lastSeen, playTime, sessionCount);
|
||||||
|
|
||||||
|
return HtmlUtils.replacePlaceholders(FileUtil.getStringFromResource("player.html"), placeHolders);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void playerClassification(UserInfo userInfo, long lastPlayed, long playTime, int loginTimes) {
|
||||||
|
boolean isBanned = userInfo.isBanned();
|
||||||
|
boolean isOP = userInfo.isOpped();
|
||||||
|
boolean isActive = AnalysisUtils.isActive(MiscUtils.getTime(), lastPlayed, playTime, loginTimes);
|
||||||
|
|
||||||
|
String active = isActive ? "Active" : "Inactive";
|
||||||
|
String banned = isBanned ? "Banned" : "";
|
||||||
|
String op = isOP ? "Operator (OP)" : "";
|
||||||
|
|
||||||
|
addValue("playerclassification", HtmlStructure.separateWithDots(active, banned, op));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addValue(String placeholder, Serializable value) {
|
||||||
|
placeHolders.put(placeholder, value);
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,7 @@ import main.java.com.djrapitops.plan.data.additional.AnalysisType;
|
|||||||
import main.java.com.djrapitops.plan.data.additional.PluginData;
|
import main.java.com.djrapitops.plan.data.additional.PluginData;
|
||||||
import main.java.com.djrapitops.plan.utilities.FormatUtils;
|
import main.java.com.djrapitops.plan.utilities.FormatUtils;
|
||||||
import main.java.com.djrapitops.plan.utilities.MiscUtils;
|
import main.java.com.djrapitops.plan.utilities.MiscUtils;
|
||||||
|
import main.java.com.djrapitops.plan.utilities.comparators.SessionLengthComparator;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@ -32,7 +33,6 @@ public class AnalysisUtils {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static boolean isActive(long now, long lastPlayed, long playTime, int loginTimes) {
|
public static boolean isActive(long now, long lastPlayed, long playTime, int loginTimes) {
|
||||||
|
|
||||||
int timeToActive = 10;
|
int timeToActive = 10;
|
||||||
long twoWeeks = 1209600000;
|
long twoWeeks = 1209600000;
|
||||||
return now - lastPlayed < twoWeeks
|
return now - lastPlayed < twoWeeks
|
||||||
@ -318,4 +318,13 @@ public class AnalysisUtils {
|
|||||||
day.setTimeInMillis(date);
|
day.setTimeInMillis(date);
|
||||||
return day.get(Calendar.DAY_OF_YEAR);
|
return day.get(Calendar.DAY_OF_YEAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static long getTotalPlaytime(List<Session> sessions) {
|
||||||
|
return sessions.stream().mapToLong(Session::getLength).sum();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long getLongestSessionLength(List<Session> sessions) {
|
||||||
|
Optional<Session> longest = sessions.stream().sorted(new SessionLengthComparator()).findFirst();
|
||||||
|
return longest.map(Session::getLength).orElse(0L);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
package main.java.com.djrapitops.plan.utilities.comparators;
|
||||||
|
|
||||||
|
import main.java.com.djrapitops.plan.data.Action;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Comparator for comparing Actions so that latest is the first component.
|
||||||
|
*
|
||||||
|
* @author Rsl1122
|
||||||
|
*/
|
||||||
|
public class ActionComparator implements Comparator<Action> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(Action o1, Action o2) {
|
||||||
|
return -Long.compare(o1.getDate(), o2.getDate());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package main.java.com.djrapitops.plan.utilities.comparators;
|
||||||
|
|
||||||
|
import main.java.com.djrapitops.plan.data.Session;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Rsl1122
|
||||||
|
*/
|
||||||
|
public class SessionLengthComparator implements Comparator<Session> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(Session s1, Session s2) {
|
||||||
|
return Long.compare(s1.getLength(), s2.getLength());
|
||||||
|
}
|
||||||
|
}
|
@ -7,7 +7,7 @@ import java.util.Comparator;
|
|||||||
/**
|
/**
|
||||||
* @author Rsl1122
|
* @author Rsl1122
|
||||||
*/
|
*/
|
||||||
public class SessionDataComparator implements Comparator<Session> {
|
public class SessionStartComparator implements Comparator<Session> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compare(Session s1, Session s2) {
|
public int compare(Session s1, Session s2) {
|
@ -42,7 +42,7 @@ public enum Html {
|
|||||||
TABLE_START_3("<table class=\"sortable table\"><thead><tr><th>${0}</th><th>${1}</th><th>${2}</th></tr></thead><tbody>"),
|
TABLE_START_3("<table class=\"sortable table\"><thead><tr><th>${0}</th><th>${1}</th><th>${2}</th></tr></thead><tbody>"),
|
||||||
TABLE_START_4("<table class=\"sortable table\"><thead><tr><th>${0}</th><th>${1}</th><th>${2}</th><th>${3}</th></tr></thead><tbody>"),
|
TABLE_START_4("<table class=\"sortable table\"><thead><tr><th>${0}</th><th>${1}</th><th>${2}</th><th>${3}</th></tr></thead><tbody>"),
|
||||||
TABLE_SESSIONS_START(TABLE_START_3.parse("Session Started", "Session Ended", "Session Length")),
|
TABLE_SESSIONS_START(TABLE_START_3.parse("Session Started", "Session Ended", "Session Length")),
|
||||||
TABLE_KILLS_START(TABLE_START_3.parse("Date", "Killed", "With")),
|
TABLE_KILLS_START(TABLE_START_3.parse(FONT_AWESOME_ICON.parse("clock-o") + " Time", "Killed", "With")),
|
||||||
TABLE_FACTIONS_START(TABLE_START_4.parse(FONT_AWESOME_ICON.parse("flag") + " Faction", FONT_AWESOME_ICON.parse("bolt") + " Power", FONT_AWESOME_ICON.parse("map-o") + " Land", FONT_AWESOME_ICON.parse("user") + " Leader")),
|
TABLE_FACTIONS_START(TABLE_START_4.parse(FONT_AWESOME_ICON.parse("flag") + " Faction", FONT_AWESOME_ICON.parse("bolt") + " Power", FONT_AWESOME_ICON.parse("map-o") + " Land", FONT_AWESOME_ICON.parse("user") + " Leader")),
|
||||||
TABLE_TOWNS_START(TABLE_START_4.parse(FONT_AWESOME_ICON.parse("bank") + " Town", FONT_AWESOME_ICON.parse("users") + " Residents", FONT_AWESOME_ICON.parse("map-o") + " Land", FONT_AWESOME_ICON.parse("user") + " Mayor")),
|
TABLE_TOWNS_START(TABLE_START_4.parse(FONT_AWESOME_ICON.parse("bank") + " Town", FONT_AWESOME_ICON.parse("users") + " Residents", FONT_AWESOME_ICON.parse("map-o") + " Land", FONT_AWESOME_ICON.parse("user") + " Mayor")),
|
||||||
TABLELINE_2("<tr><td><b>${0}</b></td><td>${1}</td></tr>"),
|
TABLELINE_2("<tr><td><b>${0}</b></td><td>${1}</td></tr>"),
|
||||||
|
@ -4,10 +4,158 @@
|
|||||||
*/
|
*/
|
||||||
package main.java.com.djrapitops.plan.utilities.html;
|
package main.java.com.djrapitops.plan.utilities.html;
|
||||||
|
|
||||||
|
import main.java.com.djrapitops.plan.data.Session;
|
||||||
|
import main.java.com.djrapitops.plan.utilities.FormatUtils;
|
||||||
|
import main.java.com.djrapitops.plan.utilities.analysis.AnalysisUtils;
|
||||||
|
import main.java.com.djrapitops.plan.utilities.html.tables.KillsTableCreator;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class for parsing layout components of the websites.
|
* Class for parsing layout components of the websites.
|
||||||
*
|
*
|
||||||
* @author Rsl1122
|
* @author Rsl1122
|
||||||
*/
|
*/
|
||||||
public class HtmlStructure {
|
public class HtmlStructure {
|
||||||
|
|
||||||
|
public static String separateWithDots(String... elements) {
|
||||||
|
if (elements.length == 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
StringBuilder builder = new StringBuilder(elements[0]);
|
||||||
|
for (int i = 1; i < elements.length; i++) {
|
||||||
|
String element = elements[i];
|
||||||
|
if (element.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
builder.append(" • ");
|
||||||
|
builder.append(element);
|
||||||
|
}
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String createDotList(String... elements) {
|
||||||
|
if (elements.length == 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
for (int i = 0; i < elements.length; i++) {
|
||||||
|
String element = elements[i];
|
||||||
|
if (element.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
builder.append("• ");
|
||||||
|
builder.append(element);
|
||||||
|
if (i < elements.length - 1) {
|
||||||
|
builder.append("<br>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String createServerOverviewColumn(Map<String, List<Session>> sessions) {
|
||||||
|
StringBuilder builder = new StringBuilder("<div class=\"column\">");
|
||||||
|
for (Map.Entry<String, List<Session>> entry : sessions.entrySet()) {
|
||||||
|
String serverName = entry.getKey();
|
||||||
|
List<Session> serverSessions = entry.getValue();
|
||||||
|
|
||||||
|
// Header
|
||||||
|
builder.append("<div class=\"box-header\"><h2><i class=\"fa fa-server\" aria-hidden=\"true\"></i> ").append(serverName).append("</h2> </div>");
|
||||||
|
|
||||||
|
// White box
|
||||||
|
builder.append("<div class=\"box\" style=\"margin-bottom: 5px;\">");
|
||||||
|
|
||||||
|
// Content
|
||||||
|
builder.append("<p>Sessions: ").append(serverSessions.size()).append("<br>");
|
||||||
|
long playTime = AnalysisUtils.getTotalPlaytime(serverSessions);
|
||||||
|
builder.append("Playtime: ").append(FormatUtils.formatTimeAmount(playTime)).append("<br>");
|
||||||
|
builder.append("<br>");
|
||||||
|
long longestSessionLength = AnalysisUtils.getLongestSessionLength(serverSessions);
|
||||||
|
builder.append("Longest Session: " + FormatUtils.formatTimeAmount(longestSessionLength));
|
||||||
|
|
||||||
|
// Content and box end
|
||||||
|
builder.append("</p></div>");
|
||||||
|
|
||||||
|
}
|
||||||
|
// Column ends
|
||||||
|
builder.append("</div>");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String createSessionsTabContent(Map<String, List<Session>> sessions, List<Session> allSessions) {
|
||||||
|
Map<Integer, String> serverNameIDRelationMap = new HashMap<>();
|
||||||
|
|
||||||
|
for (Map.Entry<String, List<Session>> entry : sessions.entrySet()) {
|
||||||
|
String serverName = entry.getKey();
|
||||||
|
List<Session> serverSessions = entry.getValue();
|
||||||
|
for (Session session : serverSessions) {
|
||||||
|
serverNameIDRelationMap.put(session.getSessionID(), serverName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
int i = 0;
|
||||||
|
for (Session session : allSessions) {
|
||||||
|
if (i >= 50) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
String sessionStart = FormatUtils.formatTimeStampYear(session.getSessionStart());
|
||||||
|
String sessionLength = FormatUtils.formatTimeAmount(session.getLength());
|
||||||
|
String sessionEnd = FormatUtils.formatTimeStampYear(session.getSessionEnd());
|
||||||
|
|
||||||
|
String dotSeparated = separateWithDots(sessionStart, sessionLength);
|
||||||
|
|
||||||
|
// Session-column starts & header.
|
||||||
|
builder.append("<div class=\"session column\">")
|
||||||
|
.append("<div class=\"session-header\">")
|
||||||
|
.append("<div class=\"session-col\" style=\"width: 200%;\">")
|
||||||
|
.append("<h3>").append(dotSeparated).append("</h3>")
|
||||||
|
.append("<p>Click to Expand</p>")
|
||||||
|
.append("</div>")
|
||||||
|
.append("</div>");
|
||||||
|
|
||||||
|
String serverName = serverNameIDRelationMap.get(session.getSessionID());
|
||||||
|
|
||||||
|
// Left side of Session box
|
||||||
|
builder.append("<div class=\"session-content\">")
|
||||||
|
.append("<div class=\"row\">") //
|
||||||
|
.append("<div class=\"session-col\" style=\"padding: 0px;\">");
|
||||||
|
|
||||||
|
// Left side header
|
||||||
|
builder.append("<div class=\"box-header\" style=\"margin: 0px;\">")
|
||||||
|
.append("<h2><i class=\"fa fa-calendar\" aria-hidden=\"true\"></i> ")
|
||||||
|
.append(sessionStart)
|
||||||
|
.append("</h2>")
|
||||||
|
.append("</div>");
|
||||||
|
|
||||||
|
// Left side content
|
||||||
|
builder.append("<div class=\"box\" style=\"margin: 0px;\">")
|
||||||
|
.append("<p>Session Length: ").append(sessionLength).append("<br>")
|
||||||
|
.append("Session Ended: ").append(sessionEnd).append("<br>")
|
||||||
|
.append("Server: ").append(serverName).append("<br><br>")
|
||||||
|
.append("Mob Kills: ").append(session.getMobKills()).append("<br>")
|
||||||
|
.append("Deaths: ").append(session.getDeaths()).append("</p>");
|
||||||
|
|
||||||
|
builder.append(KillsTableCreator.createTable(session.getPlayerKills()))
|
||||||
|
.append("</div>"); // Left Side content ends
|
||||||
|
|
||||||
|
// Left side ends & Right side starts
|
||||||
|
builder.append("</div>")
|
||||||
|
.append("<div class=\"session-col\">");
|
||||||
|
|
||||||
|
// TODO WorldTimes Pie
|
||||||
|
|
||||||
|
// Session-col, Row, Session-Content, Session-column ends.
|
||||||
|
builder.append("</div>")
|
||||||
|
.append("</div>")
|
||||||
|
.append("</div>")
|
||||||
|
.append("</div>");
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
}
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Licence is provided in the jar as license.yml also here:
|
||||||
|
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml
|
||||||
|
*/
|
||||||
|
package main.java.com.djrapitops.plan.utilities.html.tables;
|
||||||
|
|
||||||
|
import main.java.com.djrapitops.plan.data.Action;
|
||||||
|
import main.java.com.djrapitops.plan.utilities.FormatUtils;
|
||||||
|
import main.java.com.djrapitops.plan.utilities.html.Html;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility Class for creating Actions Table for inspect page.
|
||||||
|
*
|
||||||
|
* @author Rsl1122
|
||||||
|
*/
|
||||||
|
public class ActionsTableCreator {
|
||||||
|
|
||||||
|
|
||||||
|
public ActionsTableCreator() {
|
||||||
|
throw new IllegalStateException("Utility class");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String createTableContent(List<Action> actions) {
|
||||||
|
StringBuilder html = new StringBuilder();
|
||||||
|
if (actions.isEmpty()) {
|
||||||
|
html.append(Html.TABLELINE_3.parse("", "", ""));
|
||||||
|
} else {
|
||||||
|
int i = 0;
|
||||||
|
for (Action action : actions) {
|
||||||
|
if (i >= 100) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
long date = action.getDate();
|
||||||
|
|
||||||
|
html.append(Html.TABLELINE_3_CUSTOMKEY_1.parse(
|
||||||
|
String.valueOf(date), FormatUtils.formatTimeStamp(date),
|
||||||
|
action.getDoneAction().toString(),
|
||||||
|
action.getAdditionalInfo()
|
||||||
|
));
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return html.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -29,7 +29,7 @@ public class KillsTableCreator {
|
|||||||
* @param playerKills The list of the {@link PlayerKill} Objects from which the kill table should be created
|
* @param playerKills The list of the {@link PlayerKill} Objects from which the kill table should be created
|
||||||
* @return The created kills table
|
* @return The created kills table
|
||||||
*/
|
*/
|
||||||
public static String createKillsTable(List<PlayerKill> playerKills) {
|
public static String createTable(List<PlayerKill> playerKills) {
|
||||||
StringBuilder html = new StringBuilder(Html.TABLE_KILLS_START.parse());
|
StringBuilder html = new StringBuilder(Html.TABLE_KILLS_START.parse());
|
||||||
|
|
||||||
if (playerKills.isEmpty()) {
|
if (playerKills.isEmpty()) {
|
||||||
|
@ -217,7 +217,7 @@ tr:nth-child(odd) {background: #eee}
|
|||||||
transform: translate3d(0, 0, 0);
|
transform: translate3d(0, 0, 0);
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: 1.5s;
|
transition: 1.5s;
|
||||||
width: 100%;
|
width: 500%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,60 @@
|
|||||||
|
package main.java.com.djrapitops.plan.utilities.html;
|
||||||
|
|
||||||
|
import main.java.com.djrapitops.plan.data.Session;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||||
|
import org.powermock.modules.junit4.PowerMockRunner;
|
||||||
|
import test.java.utils.TestInit;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* //TODO Class Javadoc Comment
|
||||||
|
*
|
||||||
|
* @author Rsl1122
|
||||||
|
*/
|
||||||
|
@RunWith(PowerMockRunner.class)
|
||||||
|
@PrepareForTest(JavaPlugin.class)
|
||||||
|
public class HtmlStructureTest {
|
||||||
|
|
||||||
|
private Map<String, List<Session>> sessions;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
TestInit t = TestInit.init();
|
||||||
|
sessions = new HashMap<>();
|
||||||
|
sessions.put("World 1", new ArrayList<>());
|
||||||
|
sessions.get("World 1").add(new Session(1, 12345L, 23455L, 1, 2));
|
||||||
|
sessions.get("World 1").add(new Session(2, 23455L, 23457L, 1, 2));
|
||||||
|
sessions.put("World 2", new ArrayList<>());
|
||||||
|
sessions.get("World 2").add(new Session(3, 23455L, 23457L, 1, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createServerOverviewColumn() throws Exception {
|
||||||
|
String serverOverviewColumn = HtmlStructure.createServerOverviewColumn(sessions);
|
||||||
|
int opened = StringUtils.countMatches(serverOverviewColumn, "<div");
|
||||||
|
int closed = StringUtils.countMatches(serverOverviewColumn, "</div");
|
||||||
|
System.out.println(opened + " / " + closed);
|
||||||
|
assertEquals(opened, closed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createSessionsTabContent() throws Exception {
|
||||||
|
|
||||||
|
List<Session> allSessions = sessions.values().stream().flatMap(Collection::stream).collect(Collectors.toList());
|
||||||
|
String sessionsTab = HtmlStructure.createSessionsTabContent(sessions, allSessions);
|
||||||
|
int opened = StringUtils.countMatches(sessionsTab, "<div");
|
||||||
|
int closed = StringUtils.countMatches(sessionsTab, "</div");
|
||||||
|
System.out.println(opened + " / " + closed);
|
||||||
|
assertEquals(opened, closed);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -35,7 +35,7 @@ public class ComparatorTest {
|
|||||||
List<Session> test = RandomData.randomSessions();
|
List<Session> test = RandomData.randomSessions();
|
||||||
List<Long> longValues = test.stream().map(Session::getSessionStart).collect(Collectors.toList());
|
List<Long> longValues = test.stream().map(Session::getSessionStart).collect(Collectors.toList());
|
||||||
longValues.sort(Long::compare);
|
longValues.sort(Long::compare);
|
||||||
test.sort(new SessionDataComparator());
|
test.sort(new SessionStartComparator());
|
||||||
List<Long> afterSort = test.stream().map(Session::getSessionStart).collect(Collectors.toList());
|
List<Long> afterSort = test.stream().map(Session::getSessionStart).collect(Collectors.toList());
|
||||||
assertEquals(longValues, afterSort);
|
assertEquals(longValues, afterSort);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user