mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-03 17:49:40 +00:00
added .csv export for ESS40
added details parameter for html export of overall leaderboards
This commit is contained in:
1 parent
833b3abd7d
commit
5c4fa62df7
10 files changed
+220
-17
No files matched your search
@@ -28,7 +28,7 @@
|
||||
<%
|
||||
TimePoint timePoint = MillisecondsTimePoint.now();
|
||||
LeaderboardGroupMetaLeaderboard leaderboard = (LeaderboardGroupMetaLeaderboard) request.getAttribute("leaderboard");
|
||||
Boolean showDetails = (Boolean) request.getAttribute("showDetails");
|
||||
Boolean showRaceDetails = (Boolean) request.getAttribute("showRaceDetails");
|
||||
|
||||
// competitors are ordered according to total rank
|
||||
List<Competitor> competitorsFromBestToWorst = leaderboard.getCompetitorsFromBestToWorst(timePoint);
|
||||
@@ -52,7 +52,8 @@
|
||||
<tr>
|
||||
<th>Rank</th>
|
||||
<th>Team</th>
|
||||
<% for (RaceColumn raceColumn : raceColumns) { %>
|
||||
<% if(showRaceDetails) {
|
||||
for (RaceColumn raceColumn : raceColumns) { %>
|
||||
<th><%
|
||||
String raceColumnName = raceColumn.getName();
|
||||
String prefixToCut = "Extreme 40 ";
|
||||
@@ -60,7 +61,7 @@
|
||||
raceColumnName = raceColumnName.substring(prefixToCut.length(), raceColumnName.length());
|
||||
}
|
||||
%><%= raceColumnName %></th>
|
||||
<% } %>
|
||||
<% } } %>
|
||||
<th>Points</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -81,7 +82,8 @@
|
||||
<tr>
|
||||
<td><%= totalRank %></td>
|
||||
<td style="white-space:nowrap;"><img src="<%= imgFlagPath + nationality.getCountryCode().getTwoLetterISOCode().toLowerCase() + ".png"%>" /> <%= competitor.getName() %></td>
|
||||
<% for (RaceColumn raceColumn : raceColumns) {
|
||||
<% if(showRaceDetails) {
|
||||
for (RaceColumn raceColumn : raceColumns) {
|
||||
List<Competitor> rankedCompetitorsForColumn = rankedCompetitorsPerColumn.get(raceColumn);
|
||||
if (rankedCompetitorsForColumn == null) {
|
||||
rankedCompetitorsForColumn = leaderboard.getCompetitorsFromBestToWorst(raceColumn, timePoint);
|
||||
@@ -123,7 +125,7 @@
|
||||
}
|
||||
%>
|
||||
<td class="<%= racePointsStyleClasses %>"><%= racePoints %></td>
|
||||
<% } %>
|
||||
<% } } %>
|
||||
<td><%= totalPoints %></td>
|
||||
</tr>
|
||||
<% } } %>
|
||||
|
||||
@@ -37,4 +37,13 @@
|
||||
<url-pattern>/html/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
|
||||
<servlet>
|
||||
<servlet-name>ESS40ResultsAsCSVServlet</servlet-name>
|
||||
<servlet-class>com.sap.sailing.server.gateway.ess40.ESS40ResultsAsCSVServlet</servlet-class>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>ESS40ResultsAsCSVServlet</servlet-name>
|
||||
<url-pattern>/csv/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
</web-app>
|
||||
+5
-1
@@ -17,6 +17,7 @@ public class ESS40JspForwardServlet extends SailingServerHttpServlet {
|
||||
private static final long serialVersionUID = -1017961881555515288L;
|
||||
|
||||
private static final String PARAM_NAME_LEADERBOARDNAME = "leaderboardName";
|
||||
private static final String PARAM_NAME_SHOWDETAILS = "showDetails";
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||
@@ -24,6 +25,8 @@ public class ESS40JspForwardServlet extends SailingServerHttpServlet {
|
||||
String pathInfo = request.getPathInfo();
|
||||
String jspPath = "/WEB-INF/jsp";
|
||||
String leaderboardNameParam = request.getParameter(PARAM_NAME_LEADERBOARDNAME);
|
||||
String showDetailsParam = request.getParameter(PARAM_NAME_SHOWDETAILS);
|
||||
Boolean showRaceDetails = showDetailsParam != null && showDetailsParam.equalsIgnoreCase("true");
|
||||
|
||||
if (leaderboardNameParam == null) {
|
||||
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "You need to specify a leaderboard name using the "+
|
||||
@@ -40,6 +43,7 @@ public class ESS40JspForwardServlet extends SailingServerHttpServlet {
|
||||
} else {
|
||||
jspFile = "leaderboard.jsp";
|
||||
}
|
||||
request.setAttribute("showRaceDetails", showRaceDetails);
|
||||
request.setAttribute("leaderboard", leaderboard);
|
||||
request.setAttribute("racingEventService", racingEventService);
|
||||
|
||||
@@ -47,7 +51,7 @@ public class ESS40JspForwardServlet extends SailingServerHttpServlet {
|
||||
RequestDispatcher requestDispatcher = sc.getRequestDispatcher(jspPath + "/" + jspFile);
|
||||
requestDispatcher.forward(request, response);
|
||||
} else {
|
||||
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Error during rendering of the leaderboard");
|
||||
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Error during leaderboard export.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
package com.sap.sailing.server.gateway.ess40;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.MaxPointsReason;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
import com.sap.sailing.server.gateway.AbstractCSVHttpServlet;
|
||||
|
||||
/**
|
||||
* Exports leaderboards of the ESS40 Series to a specific .csv format which is used by a native iOS app to show them.
|
||||
* Sample csv files can be found at http://www.extremesailingseries.com/app/results/csv_uploads/
|
||||
* @author Frank
|
||||
*
|
||||
*/
|
||||
public class ESS40ResultsAsCSVServlet extends AbstractCSVHttpServlet {
|
||||
private static final long serialVersionUID = -3975664653148197608L;
|
||||
private static final String PARAM_NAME_LEADERBOARDNAME = "leaderboardName";
|
||||
|
||||
/*
|
||||
"Alinghi",9,3,9,3,6,6,10,2,1,11,1,11,1,11,7,5,DNF,0,1,11,8,4,1,11,1,11,6,6,4,8,1,11,2,10,1,11,6,6,2,10,1,11,4,8,2,10,5,7,5,7,5,7,4,8,3,9,6,6,10,2,4,8,2,20
|
||||
"Luna Rossa",5,7,5,7,4,8,8,4,5,7,7,5,7,5,1,11,DNF,0,2,10,7,5,4,8,4,8,9,3,6,6,2,10,7,5,4,8,3,9,3,9,3,9,6,6,4,8,1,11,2,10,2,10,5,7,6,6,5,7,9,3,5,7,5,14
|
||||
"Oman Air",1,11,4,8,1,11,3,9,9,3,2,10,8,4,6,6,2,10,9,3,11,1,DNF,0,8,4,DNF,0,7,5,4,8,4,8,2,10,1,11,10,2,4,8,1,11,3,9,7,5,3,9,6,6,1,11,4,8,4,8,5,7,8,4,1,22
|
||||
"Team GAC Pindar",4,8,3,9,10,2,1,11,7,5,9,3,4,8,10,2,5,7,5,7,4,8,2,10,3,9,3,9,5,7,10,2,6,6,8,4,11,1,8,4,6,6,10,2,8,4,2,10,1,11,1,11,2,10,7,5,3,9,2,10,10,2,4,16
|
||||
"Groupe Edmond de Rothschild",3,9,10,2,2,10,2,10,3,9,6,6,9,3,5,7,4,8,8,4,1,11,DNF,0,10,2,8,4,3,9,3,9,9,3,5,7,2,10,1,11,2,10,8,4,6,6,4,8,4,8,7,5,3,9,5,7,8,4,6,6,3,9,9,6
|
||||
"Emirates Team New Zealand",7,5,1,11,3,9,7,5,4,8,5,7,6,6,3,9,3,9,3,9,10,2,DNF,0,9,3,5,7,8,4,6,6,3,9,6,6,7,5,7,5,5,7,2,10,RDG,6.5,RDG,6.5,RDS,6.5,RDS,6.5,RDS,6.5,RDS,6.5,RDS,6.5,RDS,6.5,RDS,6.5,RDG,13
|
||||
"The Wave, Muscat",8,4,8,4,8,4,6,6,2,10,3,9,10,2,2,10,1,11,11,1,5,7,5,7,5,7,1,11,1,11,5,7,5,7,3,9,9,3,4,8,10,2,5,7,9,3,3,9,9,3,9,3,10,2,2,10,2,10,3,9,9,3,7,10
|
||||
"Red Bull Extreme Sailing",2,10,2,10,DNF,0,4,8,11,1,8,4,5,7,4,8,DNF,0,4,8,3,9,3,9,2,10,DNF,0,2,10,7,5,1,11,11,1,5,7,6,6,7,5,3,9,1,11,6,6,6,6,8,4,7,5,8,4,1,11,4,8,7,5,10,4
|
||||
"Team Tilt",11,1,7,5,7,5,9,3,10,2,11,1,2,10,11,1,8,4,6,6,9,3,7,5,6,6,2,10,9,3,9,3,10,2,10,2,10,2,9,3,8,4,7,5,7,5,10,2,8,4,4,8,9,3,1,11,9,3,1,11,2,10,6,12
|
||||
"Team Extreme",10,2,11,1,9,3,5,7,6,6,10,2,3,9,8,4,6,6,7,5,6,6,6,6,7,5,4,8,10,2,11,1,8,4,7,5,8,4,11,1,11,1,11,1,5,7,8,4,10,2,3,9,6,6,9,3,10,2,7,5,6,6,3,18
|
||||
"Niceforyou",6,6,6,6,5,7,11,1,8,4,4,8,11,1,9,3,7,5,10,2,2,10,DNF,0,11,1,7,5,11,1,8,4,11,1,9,3,4,8,5,7,9,3,9,3,10,2,9,3,7,5,10,2,8,4,10,2,7,5,8,4,1,11,8,8
|
||||
*/
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||
RacingEventService racingEventService = getService();
|
||||
String pathInfo = request.getPathInfo();
|
||||
String leaderboardNameParam = request.getParameter(PARAM_NAME_LEADERBOARDNAME);
|
||||
|
||||
if (leaderboardNameParam == null) {
|
||||
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "You need to specify a leaderboard name using the "+
|
||||
PARAM_NAME_LEADERBOARDNAME+" parameter");
|
||||
return;
|
||||
}
|
||||
|
||||
Leaderboard leaderboard = racingEventService.getLeaderboardByName(leaderboardNameParam);
|
||||
|
||||
if(pathInfo.equals("/leaderboard") && leaderboard != null) {
|
||||
try {
|
||||
String fileName = leaderboardNameParam + ".csv";
|
||||
List<List<Object>> csv = new ArrayList<List<Object>>();
|
||||
|
||||
setCSVResponseHeader(response, fileName);
|
||||
|
||||
TimePoint timePoint = MillisecondsTimePoint.now();
|
||||
|
||||
// competitors are ordered according to total rank
|
||||
List<Competitor> suppressedCompetitors = new ArrayList<Competitor>();
|
||||
for(Competitor c: leaderboard.getSuppressedCompetitors()) {
|
||||
suppressedCompetitors.add(c);
|
||||
}
|
||||
List<Competitor> competitorsFromBestToWorst = leaderboard.getCompetitorsFromBestToWorst(timePoint);
|
||||
Map<RaceColumn, List<Competitor>> rankedCompetitorsPerColumn = new HashMap<RaceColumn, List<Competitor>>();
|
||||
Iterable<RaceColumn> raceColumns = leaderboard.getRaceColumns();
|
||||
|
||||
for (Competitor competitor : competitorsFromBestToWorst) {
|
||||
if(!suppressedCompetitors.contains(competitor)) {
|
||||
int totalRank = competitorsFromBestToWorst.indexOf(competitor) + 1;
|
||||
Double totalPoints = leaderboard.getTotalPoints(competitor, timePoint);
|
||||
if(leaderboard.hasCarriedPoints(competitor)) {
|
||||
Double carriedPoints = leaderboard.getCarriedPoints(competitor);
|
||||
if(carriedPoints != null) {
|
||||
totalPoints = totalPoints != null ? totalPoints += carriedPoints : carriedPoints;
|
||||
}
|
||||
}
|
||||
|
||||
List<Object> csvLine = new ArrayList<Object>();
|
||||
csvLine.add(competitor.getName());
|
||||
csv.add(csvLine);
|
||||
|
||||
for (RaceColumn raceColumn : raceColumns) {
|
||||
List<Competitor> rankedCompetitorsForColumn = rankedCompetitorsPerColumn.get(raceColumn);
|
||||
if (rankedCompetitorsForColumn == null) {
|
||||
rankedCompetitorsForColumn = leaderboard.getCompetitorsFromBestToWorst(raceColumn, timePoint);
|
||||
rankedCompetitorsPerColumn.put(raceColumn, rankedCompetitorsForColumn);
|
||||
}
|
||||
Double netRacePoints = leaderboard.getNetPoints(competitor, raceColumn, timePoint);
|
||||
Double totalRacePoints = leaderboard.getTotalPoints(competitor, raceColumn, timePoint);
|
||||
MaxPointsReason maxPointsReason = leaderboard.getMaxPointsReason(competitor, raceColumn, timePoint);
|
||||
int rank = rankedCompetitorsForColumn.indexOf(competitor)+1;
|
||||
TrackedRace trackedRace = raceColumn.getTrackedRace(competitor);
|
||||
if (trackedRace != null) {
|
||||
int raceRank = trackedRace.getRank(competitor, timePoint);
|
||||
}
|
||||
boolean isDiscarded = leaderboard.isDiscarded(competitor, raceColumn, timePoint);
|
||||
boolean isCorrected = leaderboard.getScoreCorrection().isScoreCorrected(competitor, raceColumn);
|
||||
|
||||
if (maxPointsReason == null || maxPointsReason == MaxPointsReason.NONE) {
|
||||
if (!isDiscarded) {
|
||||
if(totalRacePoints != null) {
|
||||
csvLine.add(totalRacePoints);
|
||||
}
|
||||
} else {
|
||||
if(netRacePoints != null) {
|
||||
csvLine.add(netRacePoints);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!isDiscarded) {
|
||||
csvLine.add(maxPointsReason.name());
|
||||
} else {
|
||||
csvLine.add(maxPointsReason.name());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
writeCsv(csv, ',', true, response.getOutputStream());
|
||||
} catch (Exception e) {
|
||||
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Error during leaderboard export");
|
||||
}
|
||||
} else {
|
||||
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Error during leaderboard export");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package com.sap.sailing.server.gateway;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* Base servlet for CSV (comma separated file) exports
|
||||
* @author Frank
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public abstract class AbstractCSVHttpServlet extends SailingServerHttpServlet {
|
||||
|
||||
protected void setCSVResponseHeader(HttpServletResponse resp, String filename) {
|
||||
resp.setContentType("text/csv");
|
||||
resp.setHeader("Content-Disposition", "attachment;filename=\"" + filename + "\"");
|
||||
resp.setCharacterEncoding("UTF-8");
|
||||
}
|
||||
|
||||
protected <T> void writeCsv (List<List<T>> csv, char separator, boolean quoteStrings, OutputStream output) throws IOException {
|
||||
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output, "UTF-8"));
|
||||
for (List<T> row : csv) {
|
||||
StringBuilder line = new StringBuilder();
|
||||
for (Iterator<T> iter = row.iterator(); iter.hasNext();) {
|
||||
T fieldObject = iter.next();
|
||||
String field = String.valueOf(fieldObject).replace("\"", "\"\"");
|
||||
if(fieldObject instanceof String && quoteStrings) {
|
||||
field = '"' + field + '"';
|
||||
}
|
||||
line.append(field);
|
||||
if (iter.hasNext()) {
|
||||
line.append(separator);
|
||||
}
|
||||
}
|
||||
writer.write(line.toString());
|
||||
writer.newLine();
|
||||
}
|
||||
writer.flush();
|
||||
}
|
||||
}
|
||||
+6
-3
@@ -2,9 +2,12 @@ package com.sap.sailing.server.gateway;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
||||
public abstract class JsonExportServlet extends SailingServerHttpServlet {
|
||||
private static final long serialVersionUID = 7007196727805110847L;
|
||||
/**
|
||||
* Base servlet for json exports
|
||||
* @author Frank
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public abstract class AbstractJsonHttpServlet extends SailingServerHttpServlet {
|
||||
|
||||
protected void setJsonResponseHeader(HttpServletResponse resp) {
|
||||
// to allow access to the json document directly from a client side javascript
|
||||
+2
-2
@@ -22,9 +22,9 @@ import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.SettableScoreCorrection;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.server.gateway.JsonExportServlet;
|
||||
import com.sap.sailing.server.gateway.AbstractJsonHttpServlet;
|
||||
|
||||
public class LeaderboardGroupJsonExportServlet extends JsonExportServlet {
|
||||
public class LeaderboardGroupJsonExportServlet extends AbstractJsonHttpServlet {
|
||||
private static final long serialVersionUID = 1351616646322956825L;
|
||||
private static final String PARAM_NAME_LEADERBOARDGROUPNAME = "leaderboardGroupName";
|
||||
|
||||
|
||||
+2
-2
@@ -23,9 +23,9 @@ import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.SettableScoreCorrection;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.server.gateway.JsonExportServlet;
|
||||
import com.sap.sailing.server.gateway.AbstractJsonHttpServlet;
|
||||
|
||||
public class LeaderboardJsonExportServlet extends JsonExportServlet {
|
||||
public class LeaderboardJsonExportServlet extends AbstractJsonHttpServlet {
|
||||
private static final long serialVersionUID = -2460691283231361152L;
|
||||
private static final String PARAM_NAME_LEADERBOARDNAME = "leaderboardName";
|
||||
|
||||
|
||||
+2
-2
@@ -10,9 +10,9 @@ import javax.servlet.http.HttpServletResponse;
|
||||
import org.json.simple.JSONArray;
|
||||
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.server.gateway.JsonExportServlet;
|
||||
import com.sap.sailing.server.gateway.AbstractJsonHttpServlet;
|
||||
|
||||
public class LeaderboardsJsonExportServlet extends JsonExportServlet {
|
||||
public class LeaderboardsJsonExportServlet extends AbstractJsonHttpServlet {
|
||||
private static final long serialVersionUID = -2193421590275280102L;
|
||||
|
||||
@Override
|
||||
|
||||
+2
-2
@@ -34,10 +34,10 @@ import com.sap.sailing.domain.tracking.TrackedLeg;
|
||||
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.domain.tracking.Wind;
|
||||
import com.sap.sailing.server.gateway.JsonExportServlet;
|
||||
import com.sap.sailing.server.gateway.AbstractJsonHttpServlet;
|
||||
import com.sap.sailing.util.InvalidDateException;
|
||||
|
||||
public class RegattaAndRaceDataJsonExportServlet extends JsonExportServlet {
|
||||
public class RegattaAndRaceDataJsonExportServlet extends AbstractJsonHttpServlet {
|
||||
private static final Logger logger = Logger.getLogger(RegattaAndRaceDataJsonExportServlet.class.getName());
|
||||
|
||||
private static final long serialVersionUID = 1333207389294903999L;
|
||||
|
||||
Reference in new issue
Block a user