First prototype
diff --git a/cron/.htaccess b/cron/.htaccess
new file mode 100644
index 0000000..3a42882
--- /dev/null
+++ b/cron/.htaccess
@@ -0,0 +1 @@
+Deny from all
diff --git a/cron/generate.bash b/cron/generate.bash
new file mode 100644
index 0000000..8e0b569
--- /dev/null
+++ b/cron/generate.bash
@@ -0,0 +1,6 @@
+#!/bin/bash
+php generateData.php
+gnuplot generateGraphs.gnu
+mkdir -p ../output
+mv /tmp/covid19graphgenerator-output.png ../output/graph.png
+mv /tmp/covid19graphgenerator-output.svg ../output/graph.svg
diff --git a/cron/generateData.php b/cron/generateData.php
new file mode 100644
index 0000000..fab3093
--- /dev/null
+++ b/cron/generateData.php
@@ -0,0 +1,129 @@
+<?php
+if (php_sapi_name() != "cli")
+  exit();
+
+// Font dels nombres d'habitants: https://catsalut.gencat.cat/web/.content/minisite/catsalut/proveidors_professionals/registres_catalegs/documents/poblacio-referencia.pdf
+$HABITANTS = [
+  "Alt Pirineu i Aran" => 67277,
+  "Lleida" => 362850,
+  "Camp de Tarragona" => 607999,
+  "Terres de l'Ebre" => 176817,
+  "Girona" => 861753,
+  "Catalunya Central" => 526959,
+  "Barcelona" => 5050190
+];
+
+$CODENAME = [
+  "Alt Pirineu i Aran" => "AltPirineuAran",
+  "Lleida" => "Lleida",
+  "Camp de Tarragona" => "CampDeTarragona",
+  "Terres de l'Ebre" => "TerresDeLEbre",
+  "Girona" => "Girona",
+  "Catalunya Central" => "CatalunyaCentral",
+  "Barcelona" => "Barcelona"
+];
+
+function getSumDay($originalDay, $translation, &$dataRegio) {
+  if ($translation >= 0)
+    $day = (clone $originalDay)->add(new DateInterval("P".abs($translation)."D"));
+  else
+    $day = (clone $originalDay)->sub(new DateInterval("P".abs($translation)."D"));
+
+  foreach ($dataRegio as $row) {
+    $rowDay = new DateTime($row["data"]);
+    if ($day == $rowDay) return $row["sum_numcasos"];
+  }
+
+  return 0;
+}
+
+function query($soql) {
+  $raw = file_get_contents("https://analisi.transparenciacatalunya.cat/resource/xuwf-dxjd.json?\$query=".urlencode($soql));
+  return json_decode($raw, true);
+}
+
+$data = query("SELECT data, regiosanitariadescripcio AS regio, sum(numcasos) AS sum_numcasos
+WHERE
+  resultatcoviddescripcio = 'Positiu' AND
+  regiosanitariadescripcio <> 'No classificat'
+GROUP BY regiosanitariadescripcio, data
+ORDER BY data ASC, regiosanitariadescripcio");
+
+$dataPerRegio = [];
+foreach ($data as $row) {
+  if (!isset($dataPerRegio[$row["regio"]])) $dataPerRegio[$row["regio"]] = [];
+  $dataPerRegio[$row["regio"]][] = $row;
+}
+
+$summary = [];
+foreach ($dataPerRegio as $regio => $dataRegio) {
+  $summary[$regio] = [];
+
+  $oldestDay = new DateTime("today");
+  $newestDay = new DateTime();
+  $newestDay->setTimestamp(0);
+
+  foreach ($dataRegio as $row) {
+    $date = new DateTime($row["data"]);
+    if ($date < $oldestDay) $oldestDay = $date;
+    if ($date > $newestDay) $newestDay = $date;
+  }
+
+  $newestDay->sub(new DateInterval("P1D"));
+
+  $rhos = [];
+
+  for ($currentDate = (clone $oldestDay)->add(new DateInterval("P7D")); $currentDate < $newestDay; $currentDate->add(new DateInterval("P1D"))) {
+    $den = getSumDay($currentDate, -4, $dataRegio) + getSumDay($currentDate, -5, $dataRegio) + getSumDay($currentDate, -6, $dataRegio);
+    if ($den == 0) continue;
+
+    $rho = (getSumDay($currentDate, 1, $dataRegio) + getSumDay($currentDate, 0, $dataRegio) + getSumDay($currentDate, -1, $dataRegio))/($den);
+
+    $rhos[] = [
+      "data" => $currentDate->format("c"),
+      "rho" => $rho
+    ];
+  }
+
+  for ($currentDate = (clone $oldestDay)->add(new DateInterval("P14D")); $currentDate < $newestDay; $currentDate->add(new DateInterval("P1D"))) {
+    $sum = 0;
+
+    $p14Date = (clone $currentDate)->sub(new DateInterval("P14D"));
+    $p7Date = (clone $currentDate)->sub(new DateInterval("P7D"));
+
+    foreach ($dataRegio as $row) {
+      $date = new DateTime($row["data"]);
+      if ($date >= $p14Date && $date < $currentDate) {
+        $sum += $row["sum_numcasos"];
+      }
+    }
+
+    $rhoAverage = 0;
+    $rhoCount = 0;
+
+    foreach ($rhos as $row) {
+      $date = new DateTime($row["data"]);
+      if ($date >= $p7Date && $date < $currentDate) {
+        ++$rhoCount;
+        $rhoAverage += $row["rho"];
+      }
+    }
+
+    $rhoAverage /= $rhoCount;
+
+    $summary[$regio][] = [
+      "data" => $currentDate->format("c"),
+      "ia14" => (isset($HABITANTS[$regio]) ? $sum*(1e5/$HABITANTS[$regio]) : null),
+      "rho7" => $rhoAverage
+    ];
+  }
+}
+
+foreach ($summary as $regio => $summaryRegio) {
+  $file = fopen("/tmp/covid19graphgenerator-".$CODENAME[$regio].".dat", "w");
+
+  foreach ($summaryRegio as $row)
+    fwrite($file, $row["data"]." ".$row["ia14"]." ".$row["rho7"]."\n");
+
+  fclose($file);
+}
diff --git a/cron/generateGraphs.gnu b/cron/generateGraphs.gnu
new file mode 100644
index 0000000..abd2f83
--- /dev/null
+++ b/cron/generateGraphs.gnu
@@ -0,0 +1,13 @@
+filesPrefix = '/tmp/covid19graphgenerator-'
+
+set terminal svg size 1200, 1200
+set output '/tmp/covid19graphgenerator-output.svg'
+
+set pointsize 0.75
+load "plot.gnu"
+
+set terminal png size 1600, 1600
+set output '/tmp/covid19graphgenerator-output.png'
+
+set pointsize 1
+load "plot.gnu"
diff --git a/cron/plot.gnu b/cron/plot.gnu
new file mode 100644
index 0000000..7135467
--- /dev/null
+++ b/cron/plot.gnu
@@ -0,0 +1,39 @@
+set xlabel "Casos actius per 10^5 habitants"
+set ylabel "Mitjana taxa de creixement darrers 7 dies"
+set title font "Helvetica,20"
+
+set xrange[0:600]
+set yrange[0:5]
+set samples 1000
+#unset colorbox
+
+set multiplot layout 3,3
+set key off
+set tics out scale 0.5,0.2
+
+min(a, b) = (a < b ? a : b)
+
+# The different colored areas correspond to the classification of the EPG values defined on page 8 at https://biocomsc.upc.edu/en/shared/20200506_report_web_51.pdf
+
+set title "Terres de l'ebre"
+plot 6*x w filledcurve y1=0 lt rgb "#ff9494", 100/x w filledcurve y1=0 lt rgb "#ffe494", 70/x w filledcurve y1=0 lt rgb "#dbff94", 30/x w filledcurve y1=0 lt rgb "#a0ff94", filesPrefix.'TerresDeLEbre.dat' u 2:3 w lp pt 6 lt rgb "black", "< tail -n 1 ".filesPrefix."TerresDeLEbre.dat" u 2:3 w lp pt 7 lt rgb "black"
+
+set title "Camp de Tarragona"
+plot 6*x w filledcurve y1=0 lt rgb "#ff9494", 100/x w filledcurve y1=0 lt rgb "#ffe494", 70/x w filledcurve y1=0 lt rgb "#dbff94", 30/x w filledcurve y1=0 lt rgb "#a0ff94", filesPrefix.'CampDeTarragona.dat' u 2:3 w lp pt 6 lt rgb "black", "< tail -n 1 ".filesPrefix."CampDeTarragona.dat" u 2:3 w lp pt 7 lt rgb "black"
+
+set title "Alt Pirineu, Aran"
+plot 6*x w filledcurve y1=0 lt rgb "#ff9494", 100/x w filledcurve y1=0 lt rgb "#ffe494", 70/x w filledcurve y1=0 lt rgb "#dbff94", 30/x w filledcurve y1=0 lt rgb "#a0ff94", filesPrefix.'AltPirineuAran.dat' u 2:3 w lp pt 6 lt rgb "black", "< tail -n 1 ".filesPrefix."AltPirineuAran.dat" u 2:3 w lp pt 7 lt rgb "black"
+
+set title "Lleida"
+plot 6*x w filledcurve y1=0 lt rgb "#ff9494", 100/x w filledcurve y1=0 lt rgb "#ffe494", 70/x w filledcurve y1=0 lt rgb "#dbff94", 30/x w filledcurve y1=0 lt rgb "#a0ff94", filesPrefix.'Lleida.dat' u 2:3 w lp pt 6 lt rgb "black", "< tail -n 1 ".filesPrefix."Lleida.dat" u 2:3 w lp pt 7 lt rgb "black"
+
+set title "Girona"
+plot 6*x w filledcurve y1=0 lt rgb "#ff9494", 100/x w filledcurve y1=0 lt rgb "#ffe494", 70/x w filledcurve y1=0 lt rgb "#dbff94", 30/x w filledcurve y1=0 lt rgb "#a0ff94", filesPrefix.'Girona.dat' u 2:3 w lp pt 6 lt rgb "black", "< tail -n 1 ".filesPrefix."Girona.dat" u 2:3 w lp pt 7 lt rgb "black"
+
+set title "Catalunya central"
+plot 6*x w filledcurve y1=0 lt rgb "#ff9494", 100/x w filledcurve y1=0 lt rgb "#ffe494", 70/x w filledcurve y1=0 lt rgb "#dbff94", 30/x w filledcurve y1=0 lt rgb "#a0ff94", filesPrefix.'CatalunyaCentral.dat' u 2:3 w lp pt 6 lt rgb "black", "< tail -n 1 ".filesPrefix."CatalunyaCentral.dat" u 2:3 w lp pt 7 lt rgb "black"
+
+set title "Barcelona"
+plot 6*x w filledcurve y1=0 lt rgb "#ff9494", 100/x w filledcurve y1=0 lt rgb "#ffe494", 70/x w filledcurve y1=0 lt rgb "#dbff94", 30/x w filledcurve y1=0 lt rgb "#a0ff94", filesPrefix.'Barcelona.dat' u 2:3 w lp pt 6 lt rgb "black", "< tail -n 1 ".filesPrefix."Barcelona.dat" u 2:3 w lp pt 7 lt rgb "black"
+
+unset multiplot