added .csv export for ESS40

added details parameter for html export of overall leaderboards
This commit is contained in:
fmittag committed 2013-02-07 14:55:51 +01:00
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"%>" />&nbsp;&nbsp;<%= 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>
@@ -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.");
}
}
@@ -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");
}
}
}
@@ -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();
}
}
@@ -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
@@ -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";
@@ -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";
@@ -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
@@ -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;