From 8f9524716f084908042f14891f679dd9540c22aa Mon Sep 17 00:00:00 2001
From: "A. Svensson"
Date: Mon, 18 May 2015 19:40:16 +0200
Subject: [PATCH 001/134] Added scripts to generate graphs.
---
bin/plotter.sh | 23 +++++++++++
bin/update_graphs.go | 93 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 116 insertions(+)
create mode 100755 bin/plotter.sh
create mode 100644 bin/update_graphs.go
diff --git a/bin/plotter.sh b/bin/plotter.sh
new file mode 100755
index 0000000..85a0de1
--- /dev/null
+++ b/bin/plotter.sh
@@ -0,0 +1,23 @@
+#!/usr/bin/env bash
+
+# Simple script to generate a timeseries graph from a data file.
+# Depencies: gnuplot
+
+# arg 1: path to file with the raw data
+# arg 2: path to file to save the graph in (.png will be appended)
+# arg 3: optional title to show on the graph
+
+gnuplot << EOF
+set datafile separator ","
+set xdata time
+set timefmt "%s" #time format of input data
+
+set terminal png size 800,200 transparent truecolor
+set output "$2.png"
+set format x "%d/%m" # format of output time
+set grid
+set title "$3" # If a second arg was supplied we show it as a title too
+unset key
+
+plot "$1" every 4 using 1:2 with lines linewidth 2
+EOF
diff --git a/bin/update_graphs.go b/bin/update_graphs.go
new file mode 100644
index 0000000..df13e92
--- /dev/null
+++ b/bin/update_graphs.go
@@ -0,0 +1,93 @@
+package main
+
+import (
+ "crypto/sha256"
+ "database/sql"
+ "fmt"
+ "io/ioutil"
+ "log"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "time"
+
+ _ "github.com/mattn/go-sqlite3"
+)
+
+// TODO: change these to be cmd args instead!
+const db_file = "/home/lmas/projects/ss13_se/src/db.sqlite3"
+
+// Dir to save new graphs in
+const save_dir = "/home/lmas/projects/ss13_se/src/static/graphs"
+
+// How far back in time the graphs will go
+var last_week = time.Now().AddDate(0, 0, -7)
+
+func checkerror(err error) {
+ if err != nil {
+ log.Fatal(err)
+ }
+}
+
+func main() {
+ // open a db connection
+ db, err := sql.Open("sqlite3", db_file)
+ checkerror(err)
+ defer db.Close()
+
+ // loop over each server in db
+ rows, err := db.Query("select id, title from gameservers_server")
+ checkerror(err)
+ defer rows.Close()
+
+ var (
+ id int
+ title string
+ )
+ for rows.Next() {
+ err := rows.Scan(&id, &title)
+ checkerror(err)
+ creategraphs(db, id, title)
+ }
+ err = rows.Err()
+ checkerror(err)
+}
+
+func creategraphs(db *sql.DB, id int, title string) {
+ // create a tmp file
+ ifile, err := ioutil.TempFile("", "graph")
+ checkerror(err)
+ defer ifile.Close()
+ ifilename := ifile.Name()
+
+ // Make sure we have somewhere to save the stored graphs in
+ err = os.MkdirAll(save_dir, 0777)
+ checkerror(err)
+ hash := fmt.Sprintf("%x", sha256.Sum256([]byte(title)))
+ ofilename := filepath.Join(save_dir, hash)
+
+ // get the server's data and write it to the file
+ rows, err := db.Query("select created,players from gameservers_serverhistory where server_id = ? and created >= ? order by created asc", id, last_week)
+ checkerror(err)
+
+ var (
+ created time.Time
+ players int
+ )
+ for rows.Next() {
+ err := rows.Scan(&created, &players)
+ checkerror(err)
+ _, err = ifile.WriteString(fmt.Sprintf("%d, %d\n", created.Unix(), players))
+ checkerror(err)
+ }
+ err = rows.Err()
+ checkerror(err)
+
+ // run the plotter against the data file
+ err = exec.Command("./plotter.sh", ifilename, ofilename).Run()
+ checkerror(err)
+
+ // close and remove the tmp file
+ ifile.Close()
+ os.Remove(ifilename)
+}
From f1539101d530641fb46458e826123403ca00330a Mon Sep 17 00:00:00 2001
From: "A. Svensson"
Date: Mon, 18 May 2015 19:43:57 +0200
Subject: [PATCH 002/134] Let django display the new graph files.
---
src/gameservers/views.py | 3 +++
src/templates/gameservers/server_detail.html | 1 +
2 files changed, 4 insertions(+)
diff --git a/src/gameservers/views.py b/src/gameservers/views.py
index 05e7a42..d63ffc9 100644
--- a/src/gameservers/views.py
+++ b/src/gameservers/views.py
@@ -1,4 +1,6 @@
+import hashlib
+
from django.shortcuts import render
from django.views import generic
@@ -13,6 +15,7 @@ class ServerDetailView(generic.DetailView):
def get_context_data(self, **kwargs):
context = super(ServerDetailView, self).get_context_data(**kwargs)
server = context['server']
+ context['graph_file'] = hashlib.sha256(server.title).hexdigest()
context['weekly_history'] = server.get_stats_history(days=7.5)
context['averages_for_weekdays'] = server.get_averages_for_weekdays()
return context
diff --git a/src/templates/gameservers/server_detail.html b/src/templates/gameservers/server_detail.html
index 020ede3..974c949 100644
--- a/src/templates/gameservers/server_detail.html
+++ b/src/templates/gameservers/server_detail.html
@@ -55,6 +55,7 @@
Weekly history
+
Average per day
From 548895c71507fc4114eee56ed149cdab6862c120 Mon Sep 17 00:00:00 2001
From: "A. Svensson"
Date: Mon, 18 May 2015 19:45:17 +0200
Subject: [PATCH 003/134] Added gitignore.
---
.gitignore | 2 ++
1 file changed, 2 insertions(+)
create mode 100644 .gitignore
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e0ceaa5
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+
+src/static/graphs
From c07877dd66e0fe845707d65097e2af84c2cb4d21 Mon Sep 17 00:00:00 2001
From: "A. Svensson"
Date: Tue, 19 May 2015 18:17:45 +0200
Subject: [PATCH 004/134] Updated plotter.
---
bin/plotter.sh | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/bin/plotter.sh b/bin/plotter.sh
index 85a0de1..8555416 100755
--- a/bin/plotter.sh
+++ b/bin/plotter.sh
@@ -11,13 +11,15 @@ gnuplot << EOF
set datafile separator ","
set xdata time
set timefmt "%s" #time format of input data
+set format x "%d/%m" # format of output time
+set style data lines
+set style line 1 linewidth 2
+set grid
+unset key
+set title "$3" # If a second arg was supplied we show it as a title too
set terminal png size 800,200 transparent truecolor
set output "$2.png"
-set format x "%d/%m" # format of output time
-set grid
-set title "$3" # If a second arg was supplied we show it as a title too
-unset key
-plot "$1" every 4 using 1:2 with lines linewidth 2
+plot "$1" every 4 using 1:2 ls 1
EOF
From d488bb79e7436d30e5b6df048c3c28e12a71afdc Mon Sep 17 00:00:00 2001
From: "A. Svensson"
Date: Tue, 19 May 2015 18:57:54 +0200
Subject: [PATCH 005/134] Renamed plotter.
---
bin/{plotter.sh => plot_time.sh} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename bin/{plotter.sh => plot_time.sh} (100%)
diff --git a/bin/plotter.sh b/bin/plot_time.sh
similarity index 100%
rename from bin/plotter.sh
rename to bin/plot_time.sh
From d30ad1705437cf2b5f9f8cee266e731725d891ba Mon Sep 17 00:00:00 2001
From: "A. Svensson"
Date: Tue, 19 May 2015 18:58:54 +0200
Subject: [PATCH 006/134] Added a script for making histograms.
---
bin/plot_bar.sh | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
create mode 100755 bin/plot_bar.sh
diff --git a/bin/plot_bar.sh b/bin/plot_bar.sh
new file mode 100755
index 0000000..009e79e
--- /dev/null
+++ b/bin/plot_bar.sh
@@ -0,0 +1,23 @@
+#!/usr/bin/env bash
+
+# Simple script to generate a timeseries graph from a data file.
+# Depencies: gnuplot
+
+# arg 1: path to file with the raw data
+# arg 2: path to file to save the graph in (.png will be appended)
+# arg 3: optional title to show on the graph
+
+gnuplot << EOF
+set datafile separator ","
+
+set style data boxes
+set boxwidth 0.75
+set style fill solid
+set grid
+unset key
+set title "$3" # If a second arg was supplied we show it as a title too
+set terminal png size 800,200 transparent truecolor
+set output "$2.png"
+
+plot "$1" using 2:xtic(1)
+EOF
From 9abe182765cf3ec413ada43f403a81593fedd47c Mon Sep 17 00:00:00 2001
From: "A. Svensson"
Date: Tue, 19 May 2015 19:47:41 +0200
Subject: [PATCH 007/134] Can now generate averages for each week day.
---
bin/update_graphs.go | 61 +++++++++++++++++++++++++++++++++++++++++---
1 file changed, 58 insertions(+), 3 deletions(-)
diff --git a/bin/update_graphs.go b/bin/update_graphs.go
index df13e92..c71585b 100644
--- a/bin/update_graphs.go
+++ b/bin/update_graphs.go
@@ -22,6 +22,17 @@ const save_dir = "/home/lmas/projects/ss13_se/src/static/graphs"
// How far back in time the graphs will go
var last_week = time.Now().AddDate(0, 0, -7)
+var last_month = time.Now().AddDate(0, -1, 0)
+
+var week_days = [7]string{
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday",
+}
func checkerror(err error) {
if err != nil {
@@ -48,14 +59,16 @@ func main() {
err := rows.Scan(&id, &title)
checkerror(err)
creategraphs(db, id, title)
+ createweekdaygraph(db, id, title)
}
err = rows.Err()
checkerror(err)
}
func creategraphs(db *sql.DB, id int, title string) {
+ prefix := "week-"
// create a tmp file
- ifile, err := ioutil.TempFile("", "graph")
+ ifile, err := ioutil.TempFile("", prefix)
checkerror(err)
defer ifile.Close()
ifilename := ifile.Name()
@@ -64,11 +77,12 @@ func creategraphs(db *sql.DB, id int, title string) {
err = os.MkdirAll(save_dir, 0777)
checkerror(err)
hash := fmt.Sprintf("%x", sha256.Sum256([]byte(title)))
- ofilename := filepath.Join(save_dir, hash)
+ ofilename := filepath.Join(save_dir, fmt.Sprintf("%s%s", prefix, hash))
// get the server's data and write it to the file
rows, err := db.Query("select created,players from gameservers_serverhistory where server_id = ? and created >= ? order by created asc", id, last_week)
checkerror(err)
+ defer rows.Close()
var (
created time.Time
@@ -84,7 +98,48 @@ func creategraphs(db *sql.DB, id int, title string) {
checkerror(err)
// run the plotter against the data file
- err = exec.Command("./plotter.sh", ifilename, ofilename).Run()
+ err = exec.Command("./plot_time.sh", ifilename, ofilename).Run()
+ checkerror(err)
+
+ // close and remove the tmp file
+ ifile.Close()
+ os.Remove(ifilename)
+}
+
+func createweekdaygraph(db *sql.DB, id int, title string) {
+ prefix := "avg_days-"
+ // create a tmp file
+ ifile, err := ioutil.TempFile("", prefix)
+ checkerror(err)
+ defer ifile.Close()
+ ifilename := ifile.Name()
+
+ // Make sure we have somewhere to save the stored graphs in
+ err = os.MkdirAll(save_dir, 0777)
+ checkerror(err)
+ hash := fmt.Sprintf("%x", sha256.Sum256([]byte(title)))
+ ofilename := filepath.Join(save_dir, fmt.Sprintf("%s%s", prefix, hash))
+
+ // get the server's data and write it to the file
+ rows, err := db.Query("select strftime('%w', created) as weekday, avg(players) from gameservers_serverhistory where server_id = ? and created >= ? group by weekday;", id, last_week)
+ checkerror(err)
+ defer rows.Close()
+
+ var (
+ day int
+ players float64
+ )
+ for rows.Next() {
+ err := rows.Scan(&day, &players)
+ checkerror(err)
+ _, err = ifile.WriteString(fmt.Sprintf("%s, %f\n", week_days[day], players))
+ checkerror(err)
+ }
+ err = rows.Err()
+ checkerror(err)
+
+ // run the plotter against the data file
+ err = exec.Command("./plot_bar.sh", ifilename, ofilename).Run()
checkerror(err)
// close and remove the tmp file
From 43aae333e269def8619150234b9e8f5809f3dbb2 Mon Sep 17 00:00:00 2001
From: "A. Svensson"
Date: Tue, 19 May 2015 19:48:34 +0200
Subject: [PATCH 008/134] Added new graphs to templates.
---
src/templates/gameservers/server_detail.html | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/templates/gameservers/server_detail.html b/src/templates/gameservers/server_detail.html
index 974c949..ff90a0e 100644
--- a/src/templates/gameservers/server_detail.html
+++ b/src/templates/gameservers/server_detail.html
@@ -55,9 +55,10 @@
Weekly history
-
+
Average per day
+
From fce863fc1ec119e4c4cb4a500562423920c1eb58 Mon Sep 17 00:00:00 2001
From: "A. Svensson"
Date: Tue, 19 May 2015 19:57:56 +0200
Subject: [PATCH 009/134] Removed the js graph crap.
---
src/static/css/style.css | 19 -
src/static/js/jquery.flot.categories.js | 191 --
src/static/js/jquery.flot.js | 3168 ------------------
src/static/js/jquery.flot.time.js | 432 ---
src/templates/gameservers/server_detail.html | 78 +-
5 files changed, 1 insertion(+), 3887 deletions(-)
delete mode 100644 src/static/js/jquery.flot.categories.js
delete mode 100644 src/static/js/jquery.flot.js
delete mode 100644 src/static/js/jquery.flot.time.js
diff --git a/src/static/css/style.css b/src/static/css/style.css
index 0043eee..36f796f 100644
--- a/src/static/css/style.css
+++ b/src/static/css/style.css
@@ -82,25 +82,6 @@ body {
width: 25%;
}
-#weekly_history {
- width:100%;
- height:200px;
-}
-
-#weekday_averages {
- width:100%;
- height:200px;
-}
-
-#tooltip {
- position: absolute;
- display: none;
- border: 1px solid #fdd;
- padding: 2px;
- background-color: #fee;
- opacity: 0.80;
-}
-
/* Footer *********************************************************************/
#bottom_footer {
font-size: 11px;
diff --git a/src/static/js/jquery.flot.categories.js b/src/static/js/jquery.flot.categories.js
deleted file mode 100644
index a1b4c2f..0000000
--- a/src/static/js/jquery.flot.categories.js
+++ /dev/null
@@ -1,191 +0,0 @@
-/* Flot plugin for plotting textual data or categories.
-
-Copyright (c) 2007-2014 IOLA and Ole Laursen.
-Licensed under the MIT license.
-
-Consider a dataset like [["February", 34], ["March", 20], ...]. This plugin
-allows you to plot such a dataset directly.
-
-To enable it, you must specify mode: "categories" on the axis with the textual
-labels, e.g.
-
- $.plot("#placeholder", data, { xaxis: { mode: "categories" } });
-
-By default, the labels are ordered as they are met in the data series. If you
-need a different ordering, you can specify "categories" on the axis options
-and list the categories there:
-
- xaxis: {
- mode: "categories",
- categories: ["February", "March", "April"]
- }
-
-If you need to customize the distances between the categories, you can specify
-"categories" as an object mapping labels to values
-
- xaxis: {
- mode: "categories",
- categories: { "February": 1, "March": 3, "April": 4 }
- }
-
-If you don't specify all categories, the remaining categories will be numbered
-from the max value plus 1 (with a spacing of 1 between each).
-
-Internally, the plugin works by transforming the input data through an auto-
-generated mapping where the first category becomes 0, the second 1, etc.
-Hence, a point like ["February", 34] becomes [0, 34] internally in Flot (this
-is visible in hover and click events that return numbers rather than the
-category labels). The plugin also overrides the tick generator to spit out the
-categories as ticks instead of the values.
-
-If you need to map a value back to its label, the mapping is always accessible
-as "categories" on the axis object, e.g. plot.getAxes().xaxis.categories.
-
-*/
-
-(function ($) {
- var options = {
- xaxis: {
- categories: null
- },
- yaxis: {
- categories: null
- }
- };
-
- function processRawData(plot, series, data, datapoints) {
- // if categories are enabled, we need to disable
- // auto-transformation to numbers so the strings are intact
- // for later processing
-
- var xCategories = series.xaxis.options.mode == "categories",
- yCategories = series.yaxis.options.mode == "categories";
-
- if (!(xCategories || yCategories))
- return;
-
- var format = datapoints.format;
-
- if (!format) {
- // FIXME: auto-detection should really not be defined here
- var s = series;
- format = [];
- format.push({ x: true, number: true, required: true });
- format.push({ y: true, number: true, required: true });
-
- if (s.bars.show || (s.lines.show && s.lines.fill)) {
- var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero));
- format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale });
- if (s.bars.horizontal) {
- delete format[format.length - 1].y;
- format[format.length - 1].x = true;
- }
- }
-
- datapoints.format = format;
- }
-
- for (var m = 0; m < format.length; ++m) {
- if (format[m].x && xCategories)
- format[m].number = false;
-
- if (format[m].y && yCategories)
- format[m].number = false;
- }
- }
-
- function getNextIndex(categories) {
- var index = -1;
-
- for (var v in categories)
- if (categories[v] > index)
- index = categories[v];
-
- return index + 1;
- }
-
- function categoriesTickGenerator(axis) {
- var res = [];
- for (var label in axis.categories) {
- var v = axis.categories[label];
- if (v >= axis.min && v <= axis.max)
- res.push([v, label]);
- }
-
- res.sort(function (a, b) { return a[0] - b[0]; });
-
- return res;
- }
-
- function setupCategoriesForAxis(series, axis, datapoints) {
- if (series[axis].options.mode != "categories")
- return;
-
- if (!series[axis].categories) {
- // parse options
- var c = {}, o = series[axis].options.categories || {};
- if ($.isArray(o)) {
- for (var i = 0; i < o.length; ++i)
- c[o[i]] = i;
- }
- else {
- for (var v in o)
- c[v] = o[v];
- }
-
- series[axis].categories = c;
- }
-
- // fix ticks
- if (!series[axis].options.ticks)
- series[axis].options.ticks = categoriesTickGenerator;
-
- transformPointsOnAxis(datapoints, axis, series[axis].categories);
- }
-
- function transformPointsOnAxis(datapoints, axis, categories) {
- // go through the points, transforming them
- var points = datapoints.points,
- ps = datapoints.pointsize,
- format = datapoints.format,
- formatColumn = axis.charAt(0),
- index = getNextIndex(categories);
-
- for (var i = 0; i < points.length; i += ps) {
- if (points[i] == null)
- continue;
-
- for (var m = 0; m < ps; ++m) {
- var val = points[i + m];
-
- if (val == null || !format[m][formatColumn])
- continue;
-
- if (!(val in categories)) {
- categories[val] = index;
- ++index;
- }
-
- points[i + m] = categories[val];
- }
- }
- }
-
- function processDatapoints(plot, series, datapoints) {
- setupCategoriesForAxis(series, "xaxis", datapoints);
- setupCategoriesForAxis(series, "yaxis", datapoints);
- }
-
- function init(plot) {
- plot.hooks.processRawData.push(processRawData);
- plot.hooks.processDatapoints.push(processDatapoints);
- }
-
- $.plot.plugins.push({
- init: init,
- options: options,
- name: 'categories',
- version: '1.0'
- });
-})(jQuery);
-
diff --git a/src/static/js/jquery.flot.js b/src/static/js/jquery.flot.js
deleted file mode 100644
index 39f3e4c..0000000
--- a/src/static/js/jquery.flot.js
+++ /dev/null
@@ -1,3168 +0,0 @@
-/* Javascript plotting library for jQuery, version 0.8.3.
-
-Copyright (c) 2007-2014 IOLA and Ole Laursen.
-Licensed under the MIT license.
-
-*/
-
-// first an inline dependency, jquery.colorhelpers.js, we inline it here
-// for convenience
-
-/* Plugin for jQuery for working with colors.
- *
- * Version 1.1.
- *
- * Inspiration from jQuery color animation plugin by John Resig.
- *
- * Released under the MIT license by Ole Laursen, October 2009.
- *
- * Examples:
- *
- * $.color.parse("#fff").scale('rgb', 0.25).add('a', -0.5).toString()
- * var c = $.color.extract($("#mydiv"), 'background-color');
- * console.log(c.r, c.g, c.b, c.a);
- * $.color.make(100, 50, 25, 0.4).toString() // returns "rgba(100,50,25,0.4)"
- *
- * Note that .scale() and .add() return the same modified object
- * instead of making a new one.
- *
- * V. 1.1: Fix error handling so e.g. parsing an empty string does
- * produce a color rather than just crashing.
- */
-(function($){$.color={};$.color.make=function(r,g,b,a){var o={};o.r=r||0;o.g=g||0;o.b=b||0;o.a=a!=null?a:1;o.add=function(c,d){for(var i=0;i=1){return"rgb("+[o.r,o.g,o.b].join(",")+")"}else{return"rgba("+[o.r,o.g,o.b,o.a].join(",")+")"}};o.normalize=function(){function clamp(min,value,max){return valuemax?max:value}o.r=clamp(0,parseInt(o.r),255);o.g=clamp(0,parseInt(o.g),255);o.b=clamp(0,parseInt(o.b),255);o.a=clamp(0,o.a,1);return o};o.clone=function(){return $.color.make(o.r,o.b,o.g,o.a)};return o.normalize()};$.color.extract=function(elem,css){var c;do{c=elem.css(css).toLowerCase();if(c!=""&&c!="transparent")break;elem=elem.parent()}while(elem.length&&!$.nodeName(elem.get(0),"body"));if(c=="rgba(0, 0, 0, 0)")c="transparent";return $.color.parse(c)};$.color.parse=function(str){var res,m=$.color.make;if(res=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10));if(res=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10),parseFloat(res[4]));if(res=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55);if(res=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55,parseFloat(res[4]));if(res=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))return m(parseInt(res[1],16),parseInt(res[2],16),parseInt(res[3],16));if(res=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))return m(parseInt(res[1]+res[1],16),parseInt(res[2]+res[2],16),parseInt(res[3]+res[3],16));var name=$.trim(str).toLowerCase();if(name=="transparent")return m(255,255,255,0);else{res=lookupColors[name]||[0,0,0];return m(res[0],res[1],res[2])}};var lookupColors={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(jQuery);
-
-// the actual Flot code
-(function($) {
-
- // Cache the prototype hasOwnProperty for faster access
-
- var hasOwnProperty = Object.prototype.hasOwnProperty;
-
- // A shim to provide 'detach' to jQuery versions prior to 1.4. Using a DOM
- // operation produces the same effect as detach, i.e. removing the element
- // without touching its jQuery data.
-
- // Do not merge this into Flot 0.9, since it requires jQuery 1.4.4+.
-
- if (!$.fn.detach) {
- $.fn.detach = function() {
- return this.each(function() {
- if (this.parentNode) {
- this.parentNode.removeChild( this );
- }
- });
- };
- }
-
- ///////////////////////////////////////////////////////////////////////////
- // The Canvas object is a wrapper around an HTML5
-
Players
@@ -56,84 +55,9 @@
Weekly history
-
+
Average per day
-
-
-
-
-
-
-
{% endblock %}
From e394206f14d7a645840f1ed0455cdb5486a524cc Mon Sep 17 00:00:00 2001
From: "A. Svensson"
Date: Tue, 19 May 2015 20:03:21 +0200
Subject: [PATCH 010/134] Removed unused graph data from django model.
---
...016_remove_server_averages_for_weekdays.py | 18 +++++++++
src/gameservers/models.py | 39 -------------------
src/gameservers/views.py | 2 -
3 files changed, 18 insertions(+), 41 deletions(-)
create mode 100644 src/gameservers/migrations/0016_remove_server_averages_for_weekdays.py
diff --git a/src/gameservers/migrations/0016_remove_server_averages_for_weekdays.py b/src/gameservers/migrations/0016_remove_server_averages_for_weekdays.py
new file mode 100644
index 0000000..87aa34d
--- /dev/null
+++ b/src/gameservers/migrations/0016_remove_server_averages_for_weekdays.py
@@ -0,0 +1,18 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('gameservers', '0015_privateserver'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='server',
+ name='averages_for_weekdays',
+ ),
+ ]
diff --git a/src/gameservers/models.py b/src/gameservers/models.py
index 7144e53..d01b808 100644
--- a/src/gameservers/models.py
+++ b/src/gameservers/models.py
@@ -8,17 +8,6 @@ from django.utils import timezone
from django.utils.encoding import python_2_unicode_compatible
-DAY_NAMES = [
- 'Monday',
- 'Tuesday',
- 'Wednesday',
- 'Thursday',
- 'Friday',
- 'Saturday',
- 'Sunday',
-]
-
-
@python_2_unicode_compatible
class PrivateServer(models.Model):
title = models.CharField(max_length=255)
@@ -57,11 +46,6 @@ class Server(models.Model):
players_avg = models.PositiveIntegerField(default=0, editable=False)
players_min = models.PositiveIntegerField(default=0, editable=False)
players_max = models.PositiveIntegerField(default=0, editable=False)
- averages_for_weekdays = models.CommaSeparatedIntegerField(
- max_length=50,
- editable=False,
- default='',
- )
class Meta:
ordering = ['-players_current', '-last_updated', 'title']
@@ -98,19 +82,6 @@ class Server(models.Model):
stats['players__max'] or 0,
)
- def measure_weekdays(self, days=7):
- history = self.get_stats_history(days=days)
- weekdays = []
- # Why can't it be zero indexed like the rest of the fucking community...
- for day in range(1, 8):
- tmp = history.filter(created__week_day=day)
- avg = tmp.aggregate(models.Avg('players'))['players__avg'] or 0
- weekdays.append(int(round(avg, 0)))
- # HACK: Since django's __week_day starts on a sunday (amurican suckers)
- # we have to move sunday (at the start) to the end of the list
- weekdays.insert(len(weekdays), weekdays.pop(0))
- return weekdays
-
def update_stats(self, player_count=0, time=None):
# TODO: default to setting current time
if time:
@@ -121,16 +92,6 @@ class Server(models.Model):
tmp = self.measure_players(days=31)
self.players_avg, self.players_min, self.players_max = tmp
- tmp = self.measure_weekdays(days=31)
- self.averages_for_weekdays = ','.join([str(i) for i in tmp])
-
- def get_averages_for_weekdays(self):
- try:
- tmp = literal_eval(self.averages_for_weekdays)
- except SyntaxError:
- tmp = [0,0,0,0,0,0,0]
- return zip(DAY_NAMES, tmp)
-
@python_2_unicode_compatible
class ServerHistory(models.Model):
diff --git a/src/gameservers/views.py b/src/gameservers/views.py
index d63ffc9..559c3cf 100644
--- a/src/gameservers/views.py
+++ b/src/gameservers/views.py
@@ -16,7 +16,5 @@ class ServerDetailView(generic.DetailView):
context = super(ServerDetailView, self).get_context_data(**kwargs)
server = context['server']
context['graph_file'] = hashlib.sha256(server.title).hexdigest()
- context['weekly_history'] = server.get_stats_history(days=7.5)
- context['averages_for_weekdays'] = server.get_averages_for_weekdays()
return context
From a13d8abf124875d66dbf6cd22d3225379cbcd55b Mon Sep 17 00:00:00 2001
From: "A. Svensson"
Date: Tue, 19 May 2015 20:04:31 +0200
Subject: [PATCH 011/134] Added todo note.
---
bin/update_graphs.go | 1 +
1 file changed, 1 insertion(+)
diff --git a/bin/update_graphs.go b/bin/update_graphs.go
index c71585b..e786d1f 100644
--- a/bin/update_graphs.go
+++ b/bin/update_graphs.go
@@ -121,6 +121,7 @@ func createweekdaygraph(db *sql.DB, id int, title string) {
ofilename := filepath.Join(save_dir, fmt.Sprintf("%s%s", prefix, hash))
// get the server's data and write it to the file
+ // TODO: Move sunday (first day in list at 0) to the end...
rows, err := db.Query("select strftime('%w', created) as weekday, avg(players) from gameservers_serverhistory where server_id = ? and created >= ? group by weekday;", id, last_week)
checkerror(err)
defer rows.Close()
From 89a6070b5976baadd19f728116dc4d6ed535caf9 Mon Sep 17 00:00:00 2001
From: "A. Svensson"
Date: Tue, 19 May 2015 20:10:59 +0200
Subject: [PATCH 012/134] Make sure jQuery is loaded during debugging.
---
src/templates/base_site.html | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/templates/base_site.html b/src/templates/base_site.html
index bda9f8b..4202d0e 100644
--- a/src/templates/base_site.html
+++ b/src/templates/base_site.html
@@ -49,5 +49,10 @@
+
+ {# jQuery is needed in debug mode for django debug toolbar #}
+ {% if debug %}
+
+ {% endif %}