commit 3b35f9b2e3a42b048761f31d00342808bd43c836 Author: Karsten Loesing karsten.loesing@gmx.net Date: Thu Jan 17 09:18:33 2013 +0100
Add table of top-10 countries by bridge users.
Implements #7973. --- rserve/tables.R | 24 +++++++++++++++ .../ernie/web/graphs/GraphsSubpagesServlet.java | 2 +- .../ernie/web/graphs/RObjectGenerator.java | 1 + web/WEB-INF/users.jsp | 31 ++++++++++++++++++++ 4 files changed, 57 insertions(+), 1 deletions(-)
diff --git a/rserve/tables.R b/rserve/tables.R index 47f1a29..eb8f676 100644 --- a/rserve/tables.R +++ b/rserve/tables.R @@ -68,3 +68,27 @@ write_censorship_events <- function(start, end, path) { write.csv(r, path, quote = FALSE, row.names = FALSE) }
+write_bridge_users <- function(start, end, path) { + drv <- dbDriver("PostgreSQL") + con <- dbConnect(drv, user = dbuser, password = dbpassword, dbname = db) + q <- paste("SELECT date, country, users AS bridgeusers ", + "FROM bridge_stats WHERE date >= '", start, "' AND date <= '", end, + "' AND date < current_date - 3 ORDER BY date, country", sep = "") + rs <- dbSendQuery(con, q) + d <- fetch(rs, n = -1) + dbDisconnect(con) + dbUnloadDriver(drv) + d <- aggregate(d$bridgeusers, by = list(country = d$country), mean) + total <- d[d$country == "zy", "x"] + d <- d[!(d$country %in% c("zy", "??", "a1", "a2", "o1", "ap", "eu")), ] + d <- data.frame(country = d$country, bridgeusers = d$x) + d <- d[order(d$bridgeusers, decreasing = TRUE), ] + d <- d[1:10, ] + d <- data.frame( + cc = as.character(d$country), + country = sub('the ', '', countrynames(as.character(d$country))), + abs = round(d$bridgeusers), + rel = round(100 * d$bridgeusers / total, 2)) + write.csv(d, path, quote = FALSE, row.names = FALSE) +} + diff --git a/src/org/torproject/ernie/web/graphs/GraphsSubpagesServlet.java b/src/org/torproject/ernie/web/graphs/GraphsSubpagesServlet.java index c522bfa..12a098d 100644 --- a/src/org/torproject/ernie/web/graphs/GraphsSubpagesServlet.java +++ b/src/org/torproject/ernie/web/graphs/GraphsSubpagesServlet.java @@ -51,7 +51,7 @@ public class GraphsSubpagesServlet extends HttpServlet { new HashMap<String, Set<String>>(); this.availableGraphsSubpageTables.put("users.html", new HashSet<String>(Arrays.asList( - "direct-users,censorship-events".split(",")))); + "direct-users,censorship-events,bridge-users".split(","))));
this.knownCountries = Countries.getInstance().getCountryList(); } diff --git a/src/org/torproject/ernie/web/graphs/RObjectGenerator.java b/src/org/torproject/ernie/web/graphs/RObjectGenerator.java index f678ff4..c4eb801 100644 --- a/src/org/torproject/ernie/web/graphs/RObjectGenerator.java +++ b/src/org/torproject/ernie/web/graphs/RObjectGenerator.java @@ -78,6 +78,7 @@ public class RObjectGenerator implements ServletContextListener { this.availableTables = new HashMap<String, String>(); this.availableTables.put("direct-users", "start,end,filename"); this.availableTables.put("censorship-events", "start,end,filename"); + this.availableTables.put("bridge-users", "start,end,filename"); TableParameterChecker.getInstance().setAvailableTables( availableTables);
diff --git a/web/WEB-INF/users.jsp b/web/WEB-INF/users.jsp index b7fdb13..d75bf7a 100644 --- a/web/WEB-INF/users.jsp +++ b/web/WEB-INF/users.jsp @@ -170,6 +170,37 @@ by a few hundred bridges.</p> <a href="bridge-users.pdf${bridge_users_url}">PDF</a> or <a href="bridge-users.svg${bridge_users_url}">SVG</a>.</p> <hr> +<a name="bridge-users-table"></a> +<p><b>Top-10 countries by bridge users:</b></p> +<form action="users.html#bridge-users-table"> + <div class="formrow"> + <input type="hidden" name="table" value="bridge-users"> + <p> + <label>Start date (yyyy-mm-dd):</label> + <input type="text" name="start" size="10" + value="<c:choose><c:when test="${fn:length(bridge_users_start) == 0}">${default_start_date}</c:when><c:otherwise>${bridge_users_start[0]}</c:otherwise></c:choose>"> + <label>End date (yyyy-mm-dd):</label> + <input type="text" name="end" size="10" + value="<c:choose><c:when test="${fn:length(bridge_users_end) == 0}">${default_end_date}</c:when><c:otherwise>${bridge_users_end[0]}</c:otherwise></c:choose>"> + </p><p> + <input class="submit" type="submit" value="Update table"> + </p> + </div> +</form> +<br> +<table> + <tr> + <th>Country</th> + <th>Mean daily users</th> + </tr> + <c:forEach var="row" items="${bridge_users_tabledata}"> + <tr> + <td><a href="users.html?graph=bridge-users&country=${row['cc']}#bridge-users">${row['country']}</a> </td> + <td>${row['abs']} (<fmt:formatNumber type="number" minFractionDigits="2" value="${row['rel']}" /> %)</td> + </tr> + </c:forEach> +</table> +<hr> <p><a href="csv/bridge-users.csv">CSV</a> file containing all data.</p> <p><a href="csv/monthly-users-peak.csv">CSV</a> file containing peak daily Tor users (direct and bridge) per month by country.</p>
tor-commits@lists.torproject.org