[tor-commits] [metrics-web/master] Add table of top-10 countries by bridge users.

karsten at torproject.org karsten at torproject.org
Thu Jan 17 08:19:22 UTC 2013


commit 3b35f9b2e3a42b048761f31d00342808bd43c836
Author: Karsten Loesing <karsten.loesing at 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>



More information about the tor-commits mailing list