package controllers; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; import misc.Comparador; import misc.Pair; import misc.RankComparator; import models.Notification; import models.Park; import models.Rank; import models.Report; import models.User; import play.mvc.Controller; import play.mvc.With; @With(Secure.class) public class PrivateWeb extends Controller { // This controller shall comprehend the Web API for the private part of the site public static void ranking() { getRanks(); } public static void stats() { User user = User.find("byUsername", Security.connected()).first(); List<Report> reportsToUser = getNotificationsToUser(user); long timeParked = getSavedTime(user); double savedMoney = getSavedMoney(timeParked); long roundTrips = getSavedRoundtrips(timeParked); List<Report> reportsThatHelped = getReportsThatHelpedUsers(user); int days = (int)((new Date().getTime() - user.registrationDate.getTime()) / (1000 * 60 * 60 * 24)); List<Park> parks = user.parks; List<Report> reports = user.reports; render("Application/stats.html", reportsToUser, roundTrips, savedMoney, days, reportsThatHelped, parks, reports); } protected static List<Report> getNotificationsToUser(User user) { return user.reportsAffectingMe; } protected static long getSavedTime(User user) { long duration = 0L; for (Park park : user.parks) { duration += park.timeParked; } return duration; } protected static double getSavedMoney(long duration) { // Taking into account the place where each park was performed, one // could come up with a more precise amount of money by mapping the // cost of each zone to GPS locations final double pricePerMinute = 0.02 / 60 / 1000; // estimate 1.20euro per hour DecimalFormat twoDForm = new DecimalFormat("#.##"); return Double.valueOf(twoDForm.format(duration * pricePerMinute)); } protected static long getSavedRoundtrips(long duration) { // Assume that every 3h a new coin must be inserted final long hours = 1000 * 60 * 60 * 3; return (long)(duration / hours); } protected static List<Report> getReportsThatHelpedUsers(User user) { List<Report> reports = Report.find("select r from Report r where r.affectedSomeUser = true").fetch(); return reports; } public static void actions() { render("Application/actions.html"); } public static void park(double latitude, double longitude) { // We can assume a User is connected because of the Secure annotation User user = User.find("byUsername", Security.connected()).first(); user.parkCar(latitude, longitude); } public static void isParked() { User user = User.find("byUsername", Security.connected()).first(); for (Park park : user.parks) { if (park.removed) { continue; } renderJSON("{ \"latitude\": " + park.latitude + ", \"longitude\": " + park.longitude + " }"); // unreachable return; } renderJSON("{ \"latitude\": null, \"longitude\": null }"); } public static void unpark() { User user = User.find("byUsername", Security.connected()).first(); user.unpark(); } public static void report(double latitude, double longitude) { User user = User.find("byUsername", Security.connected()).first(); user.report(latitude, longitude, "web"); } public static void anyNewReports() { User user = User.find("byUsername", Security.connected()).first(); List<Report> reports = user.fetchNewReportsSince(request.date.getTime(), false); if (reports.isEmpty()) { // This maintains the HTTP connection and repeats the method in some time suspend("10s"); } // Have to do the JSON manually because of a cyclic dependency in User<->Report that Gson does not support String output = Application.createReportsJSON(reports); renderJSON(output); } public static void recentReports() { User user = User.find("byUsername", Security.connected()).first(); List<Report> reports = user.fetchNewReportsSince(request.date.getTime(), true); if (reports.isEmpty()) { renderJSON("[ ]"); } renderJSON(Application.createReportsJSON(reports)); } public static void getRanks() { int amount = 50; User user = User.find("byUsername", Security.connected()).first(); ArrayList<Rank> ranks = new ArrayList<Rank>(); List<User> users = User.findAll(); for (User u : users) { ranks.add(new Rank(u.username, 0L, u.getScore(), u.username.equals(user.username)? true : false)); } Collections.sort(ranks, new RankComparator()); long ii=1; for(Rank p : ranks) { p.rank = ii; ii++; } ArrayList<Rank> ret = new ArrayList<Rank>(); int index = 0; for(int i=0;i<ranks.size();i++) { if(ranks.get(i).username.equals(user.username)) { index = i; break; } } if(index<amount-1) { for(int i=0;i<ranks.size() && i<amount;i++) { ret.add(ranks.get(i)); } render("Application/ranking.html", ranks); return; } if(index==amount-1) { for(int i=0;i<ranks.size() && i<amount+1;i++) { ret.add(ranks.get(i)); } render("Application/ranking.html", ranks); return; } if(index>amount-1) { for(int i=0;i<amount;i++) { ret.add(ranks.get(i)); } if(amount==index) { ret.add(ranks.get(index)); if(ranks.size()>=index+1) { ret.add(ranks.get(index+1)); } } else { ret.add(ranks.get(index-1)); ret.add(ranks.get(index)); if(ranks.size()>index+1) ret.add(ranks.get(index+1)); } } render("Application/ranking.html", ranks); return; } public static void logout() { try { Secure.logout(); } catch (Throwable e) { e.printStackTrace(); } } }