[tor-commits] [metrics-web/master] Add top-10 country by possible censorship events.

karsten at torproject.org karsten at torproject.org
Fri Jul 29 03:02:43 UTC 2011


commit f3044b212baab32583db8ce107796d1b2e2a705b
Author: Karsten Loesing <karsten.loesing at gmx.net>
Date:   Thu Jul 28 23:00:17 2011 -0400

    Add top-10 country by possible censorship events.
    
    Implements some more of #2718.
---
 rserve/tables.R                                    |   39 ++++++++++++++++++++
 .../ernie/web/GraphsSubpagesServlet.java           |    3 +-
 .../ernie/web/TableParameterChecker.java           |    1 +
 web/WEB-INF/users.jsp                              |   37 ++++++++++++++++++-
 4 files changed, 78 insertions(+), 2 deletions(-)

diff --git a/rserve/tables.R b/rserve/tables.R
index 725bc31..6d3b5fb 100644
--- a/rserve/tables.R
+++ b/rserve/tables.R
@@ -30,3 +30,42 @@ write_direct_users <- function(start, end, path) {
   write.csv(d, path, quote = FALSE, row.names = FALSE)
 }
 
+write_censorship_events <- function(start, end, path) {
+  drv <- dbDriver("PostgreSQL")
+  con <- dbConnect(drv, user = dbuser, password = dbpassword, dbname = db)
+  q <- paste("SELECT date, country, r, bwp, brn, bwn, brp, bwr, brr ",
+      "FROM user_stats WHERE date >= '", start, "' AND date <= '", end,
+      "' AND date < (SELECT MAX(date) FROM user_stats) - 1",
+      sep = "")
+  rs <- dbSendQuery(con, q)
+  u <- fetch(rs, n = -1)
+  dbDisconnect(con)
+  dbUnloadDriver(drv)
+  u <- data.frame(date = u$date, country = u$country,
+       users = u$r * (u$bwp * u$brn / u$bwn - u$brp) /
+               (u$bwr * u$brn / u$bwn - u$brr) / 10)
+  dates <- seq(from = as.Date(start, "%Y-%m-%d"),
+      to = as.Date(end, "%Y-%m-%d"), by="1 day")
+  missing <- setdiff(dates, u$date)
+  r <- read.csv(
+    "/srv/metrics.torproject.org/web/detector/direct-users-ranges.csv",
+    stringsAsFactors = FALSE)
+  r <- r[r$date >= start & r$date <= end,
+      c("date", "country", "minusers", "maxusers")]
+  r <- cast(rbind(melt(u, id.vars = c("date", "country")),
+      melt(r, id.vars = c("date", "country"))))
+  r <- na.omit(r[r$users < r$minusers | r$users > r$maxusers, ])
+  r <- data.frame(date = r$date, country = r$country,
+    upturn = ifelse(r$users > r$maxusers, 1, 0),
+    downturn = ifelse(r$users < r$minusers, 1, 0))
+  r <- aggregate(r[, c("upturn", "downturn")],
+    by = list(country = r$country), sum)
+  r <- r[order(r$downturn, r$upturn, decreasing = TRUE), ]
+  r <- r[1:10, ] 
+  r <- data.frame(cc = r$country,
+    country = sub('the ', '', countrynames(as.character(r$country))),
+    downturns = r$downturn, 
+    upturns = r$upturn)
+  write.csv(r, path, quote = FALSE, row.names = FALSE)
+}
+
diff --git a/src/org/torproject/ernie/web/GraphsSubpagesServlet.java b/src/org/torproject/ernie/web/GraphsSubpagesServlet.java
index e3845cf..c7f3056 100644
--- a/src/org/torproject/ernie/web/GraphsSubpagesServlet.java
+++ b/src/org/torproject/ernie/web/GraphsSubpagesServlet.java
@@ -34,7 +34,8 @@ public class GraphsSubpagesServlet extends HttpServlet {
     this.availableGraphsSubpageTables =
         new HashMap<String, Set<String>>();
     this.availableGraphsSubpageTables.put("users.html",
-        new HashSet<String>(Arrays.asList("direct-users".split(","))));
+        new HashSet<String>(Arrays.asList(
+        "direct-users,censorship-events".split(","))));
 
     this.knownCountries = Countries.getInstance().getCountryList();
   }
diff --git a/src/org/torproject/ernie/web/TableParameterChecker.java b/src/org/torproject/ernie/web/TableParameterChecker.java
index 9bf1c33..5b6f627 100644
--- a/src/org/torproject/ernie/web/TableParameterChecker.java
+++ b/src/org/torproject/ernie/web/TableParameterChecker.java
@@ -40,6 +40,7 @@ public class TableParameterChecker {
 
     this.availableTables = new HashMap<String, String>();
     this.availableTables.put("direct-users", "start,end,filename");
+    this.availableTables.put("censorship-events", "start,end,filename");
 
     this.knownParameterValues = new HashMap<String, String>();
   }
diff --git a/web/WEB-INF/users.jsp b/web/WEB-INF/users.jsp
index b378af1..bb4e11c 100644
--- a/web/WEB-INF/users.jsp
+++ b/web/WEB-INF/users.jsp
@@ -24,6 +24,7 @@ out of a few hundred directory mirrors to save bandwidth of the directory
 authorities. The following graphs show an estimate of recurring Tor users
 based on the requests seen by a few dozen directory mirrors.</p>
 <a name="direct-users"></a>
+<p><b>Daily directly connecting users:</b></p>
 <img src="direct-users.png${direct_users_url}"
      width="576" height="360" alt="Direct users graph">
 <form action="users.html#direct-users">
@@ -60,6 +61,7 @@ based on the requests seen by a few dozen directory mirrors.</p>
   </div>
 </form>
 <a name="direct-users-table"></a>
+<p><b>Top-10 countries by directly connecting users:</b></p>
 <table>
   <tr>
     <th>Country</th>
@@ -88,7 +90,40 @@ based on the requests seen by a few dozen directory mirrors.</p>
     </p>
   </div>
 </form>
-<p><a href="csv/direct-users.csv">CSV</a> file containing all data.</p>
+<a name="censorship-events"></a>
+<p><b>Top-10 countries by possible censorship events (BETA):</b></p>
+<table>
+  <tr>
+    <th>Country</th>
+    <th>Downturns</th>
+    <th>Upturns</th>
+  </tr>
+  <c:forEach var="row" items="${censorship_events_tabledata}">
+    <tr>
+      <td><a href="users.html?graph=direct-users&country=${row['cc']}&events=on#direct-users">${row['country']}</a>&emsp;</td>
+      <td>${row['downturns']}</td>
+      <td>${row['upturns']}</td>
+    </tr>
+  </c:forEach>
+</table>
+<br>
+<form action="users.html#censorship-events">
+  <div class="formrow">
+    <input type="hidden" name="table" value="censorship-events">
+    <p>
+    <label>Start date (yyyy-mm-dd):</label>
+      <input type="text" name="start" size="10"
+             value="<c:choose><c:when test="${fn:length(censorship_events_start) == 0}">${default_start_date}</c:when><c:otherwise>${censorship_events_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(censorship_events_end) == 0}">${default_end_date}</c:when><c:otherwise>${censorship_events_end[0]}</c:otherwise></c:choose>">
+    </p><p>
+    <input class="submit" type="submit" value="Update table">
+    </p>
+  </div>
+</form>
+<p><a href="csv/direct-users.csv">CSV</a> file containing daily directly
+connecting users by country.</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>
 <p><a href="csv/monthly-users-average.csv">CSV</a> file containing average



More information about the tor-commits mailing list