diff --git a/pom.xml b/pom.xml
index 0a3f3dc..780aec6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -99,20 +99,6 @@
- net.sf.alchim
- yuicompressor-maven-plugin
-
-
-
- compress
-
-
-
-
- true
-
-
-
org.apache.maven.plugins
maven-eclipse-plugin
diff --git a/src/main/scala/bootstrap/liftweb/Boot.scala b/src/main/scala/bootstrap/liftweb/Boot.scala
index bf90104..45bb9a6 100644
--- a/src/main/scala/bootstrap/liftweb/Boot.scala
+++ b/src/main/scala/bootstrap/liftweb/Boot.scala
@@ -7,7 +7,7 @@
import Helpers._
import uk.org.floop.msc.wview.DataCollector
-import uk.org.floop.msc.rest.Graph
+import uk.org.floop.msc.rest.{Graph, Dump}
/**
* A class that's instantiated early and run. It allows the application
@@ -19,7 +19,8 @@
LiftRules.addToPackages("uk.org.floop.msc")
val apiDispatcher: LiftRules.DispatchPf = {
- case RequestMatcher(RequestState("graph" :: args, _) ,_) => graphApi(args)
+ case RequestMatcher(RequestState("graph" :: args, _) ,_) => graphApi(args)
+ case RequestMatcher(RequestState("dump":: args, _), _) => dumpApi(args)
}
LiftRules.statelessDispatchTable =
apiDispatcher orElse LiftRules.statelessDispatchTable
@@ -29,7 +30,12 @@
private def graphApi
(args: List[String])
(req: RequestState): Can[ResponseIt] =
- Graph(args)
+ Graph(args)
+ private def dumpApi
+ (args: List[String])
+ (req: RequestState): Can[ResponseIt] =
+ Dump(args)
+
}
diff --git a/src/main/scala/uk/org/floop/msc/rest/Dump.scala b/src/main/scala/uk/org/floop/msc/rest/Dump.scala
new file mode 100644
index 0000000..469c07c
--- /dev/null
+++ b/src/main/scala/uk/org/floop/msc/rest/Dump.scala
@@ -0,0 +1,15 @@
+package uk.org.floop.msc.rest
+
+import net.liftweb.http._
+import net.liftweb.util._
+
+import uk.org.floop.msc.rrd._
+
+object Dump {
+
+ def apply(args: List[String]): Can[ResponseIt] = {
+ DataStore ! DumpXml()
+ Empty
+ }
+
+}
diff --git a/src/main/scala/uk/org/floop/msc/rrd/DataStore.scala b/src/main/scala/uk/org/floop/msc/rrd/DataStore.scala
index e574f5a..800b10e 100644
--- a/src/main/scala/uk/org/floop/msc/rrd/DataStore.scala
+++ b/src/main/scala/uk/org/floop/msc/rrd/DataStore.scala
@@ -40,6 +40,7 @@
case class AddWeatherListener(l: Actor)
case class RemoveWeatherListener(l: Actor)
case class CurrentWeather(w: List[Pair[String, Any]])
+case class DumpXml()
object DataStore extends Actor {
@@ -99,6 +100,9 @@
reply(CurrentWeather(currentWeather))
case RemoveWeatherListener(l) =>
listeners -= l
+ case DumpXml() =>
+ val rrdb = new RrdDb(STORE.getPath)
+ rrdb.dumpXml("/usr/local/weather/weather.xml")
case StorePacket(p) =>
currentWeather = p
try {
diff --git a/src/main/webapp/charts.js b/src/main/webapp/charts.js
index f021ac6..ea78d63 100644
--- a/src/main/webapp/charts.js
+++ b/src/main/webapp/charts.js
@@ -1,7 +1,8 @@
var CIRCLE_RADIUS = 0.75, REAR_ARROW_WIDTH = 0.18,
FRONT_ARROW_WIDTH = 0.15, BEARING_ARROW_WIDTH = 0.08,
BEARING_ARROW_LENGTH = 0.65, LETTER_SIZE = 0.1,
- LETTER_RADIUS = 0.88, global_angle = 200,
+ LETTER_RADIUS = 0.88, global_angle = 200, COOKIE = "ressie_angle",
+ spin_initialized = 0, dragging = 0, start_drag_angle = 0, old_global_angle = 0,
WIND_STEPS = 20, WIND_TIME = 1,
wind_start = 0, wind_end = 0, wind_step = 0, wind_timer = null,
last_angle = null, cache_ctx = null, cache_canvas = null, minWidthHeight = 1, current_angle = null;
@@ -21,7 +22,7 @@
cache_ctx = cache_canvas.getContext("2d");
}
return cache_ctx;
-}
+}
function svgPathMap(svg_path, move_fun, line_fun, curve_fun, close_fun) {
var i = 0;
@@ -89,7 +90,7 @@
" L 0,-" + REAR_ARROW_WIDTH + " z").split(" ");
ctx.fillStyle = "rgb(0, 0, 255)";
drawPath(SVG_BACK_ARROWS, ctx, 1, scale);
- drawPath(SVG_BACK_ARROWS, ctx, 0, scale);
+ drawPath(SVG_BACK_ARROWS, ctx, 0, scale);
var FRONT_45 = QUART * FRONT_ARROW_WIDTH * scale;
for (var i = 0; i < 2; i++) {
@@ -113,7 +114,7 @@
ctx.lineTo(0, -scale);
ctx.lineTo(0, 0);
ctx.closePath();
- if (i == 0) {
+ if (i === 0) {
ctx.fillStyle = "rgb(255,255,255)";
ctx.fill();
} else {
@@ -123,7 +124,7 @@
}
ctx.restore();
}
- NORTH_PATH = ("M -" + (LETTER_SIZE / 1.4) + ",-" + (LETTER_RADIUS - LETTER_SIZE) +
+ var NORTH_PATH = ("M -" + (LETTER_SIZE / 1.4) + ",-" + (LETTER_RADIUS - LETTER_SIZE) +
" L -" + (LETTER_SIZE / 1.4) + ",-" + (LETTER_RADIUS + LETTER_SIZE) +
" L " + (LETTER_SIZE / 1.4) + ",-" + (LETTER_RADIUS - LETTER_SIZE) +
" L " + (LETTER_SIZE / 1.4) + ",-" + (LETTER_RADIUS + LETTER_SIZE) +
@@ -140,8 +141,8 @@
function drawArrow(ctx, scale) {
ctx.save();
- ARROW_PATH = ("M -0.05,-0.15 L 0.05,-0.15 L 0.05,0.25 L 0.1,0.25 " +
- "L 0,0.4 L -0.1,0.25 L -0.05,0.25 L -0.05,-0.15 z").split(" ");
+ var ARROW_PATH = ("M -0.05,-0.15 L 0.05,-0.15 L 0.05,0.25 L 0.1,0.25 " +
+ "L 0,0.4 L -0.1,0.25 L -0.05,0.25 L -0.05,-0.15 z").split(" ");
ctx.lineWidth = 1.0;
ctx.strokeStyle = "rgb(0,0,0)";
ctx.fillStyle = "rgb(238, 238, 0)";
@@ -191,27 +192,95 @@
ctx.restore();
}
+function drawAll(ctx, wind_angle) {
+ ctx.clearRect(0, 0, cache_canvas.width, cache_canvas.height);
+ ctx.save();
+ ctx.translate(minWidthHeight / 2, minWidthHeight / 2);
+ ctx.rotate(Math.PI * global_angle / 180);
+ drawRessie(ctx, minWidthHeight / 2);
+ ctx.restore();
+ ctx.save();
+ ctx.translate(minWidthHeight / 4, minWidthHeight / 4);
+ ctx.rotate(Math.PI * global_angle / 180);
+ drawCompass(ctx, minWidthHeight / 4);
+ ctx.restore();
+ ctx.save();
+ ctx.translate(minWidthHeight / 2, minWidthHeight / 2);
+ ctx.rotate(Math.PI * (global_angle) / 180 + wind_angle);
+ drawArrow(ctx, minWidthHeight / 2);
+ ctx.restore();
+}
+
+function initSpin(canvas) {
+ var start, end, value;
+ if (document.cookie.length > 0) {
+ start = document.cookie.indexOf(COOKIE + "=");
+ if ((start != -1) && (document.cookie.length >= start + COOKIE.length + 1)) {
+ end = document.cookie.indexOf(";", start + COOKIE.length + 1);
+ if (end == -1) {
+ end = document.cookie.length;
+ }
+ global_angle = parseInt(unescape(document.cookie.substring(start + COOKIE.length + 1, end)), 10);
+ }
+ }
+ $('#compass').mousedown(function(event){
+ if (dragging === 0) {
+ var x = event.clientX - (canvas.width / 2),
+ y = event.clientY - (canvas.height / 2),
+ elem = canvas;
+ while (elem) {
+ x -= elem.offsetLeft;
+ y -= elem.offsetTop;
+ elem = elem.offsetParent;
+ }
+ start_drag_angle = Math.atan2(y, x);
+ old_global_angle = global_angle;
+ dragging = 1;
+ }
+ }).mousemove(function(event){
+ if (dragging == 1) {
+ var x = event.clientX - (canvas.width / 2),
+ y = event.clientY - (canvas.height / 2),
+ elem = canvas;
+ while (elem) {
+ x -= elem.offsetLeft;
+ y -= elem.offsetTop;
+ elem = elem.offsetParent;
+ }
+ var current = Math.atan2(y, x);
+ global_angle = old_global_angle + (current - start_drag_angle) * 180 / Math.PI;
+ drawAll(cache_ctx, current_angle);
+ }
+ }).mouseup(function(event){
+ if (dragging == 1) {
+ dragging = 0;
+ if (global_angle != old_global_angle) {
+ drawAll(cache_ctx, current_angle);
+ var date = new Date();
+ date.setTime(date.getTime() + (10*365.25*60*60*1000));
+ var expires = "; expires="+date.toGMTString();
+ document.cookie = COOKIE + "=" + Math.floor(global_angle) + expires + "path=/";
+ }
+ }
+ }).mouseout(function(event){
+ if (dragging == 1) {
+ dragging = 0;
+ global_angle = old_global_angle;
+ drawAll(cache_ctx, current_angle);
+ }
+ });
+ spin_initialized = 1;
+}
+
function drawStep() {
var ctx = getContext();
if (ctx) {
+ if (spin_initialized === 0) {
+ initSpin(cache_canvas);
+ }
var ratio = (1-Math.cos(wind_step / WIND_STEPS * Math.PI))/2;
current_angle = wind_start + (wind_end - wind_start) * ratio;
- ctx.clearRect(0, 0, cache_canvas.width, cache_canvas.height);
- ctx.save();
- ctx.translate(minWidthHeight / 2, minWidthHeight / 2);
- ctx.rotate(Math.PI * global_angle / 180);
- drawRessie(ctx, minWidthHeight / 2);
- ctx.restore();
- ctx.save();
- ctx.translate(minWidthHeight / 4, minWidthHeight / 4);
- ctx.rotate(Math.PI * global_angle / 180);
- drawCompass(ctx, minWidthHeight / 4);
- ctx.restore();
- ctx.save();
- ctx.translate(minWidthHeight / 2, minWidthHeight / 2);
- ctx.rotate(Math.PI * (global_angle) / 180 + current_angle);
- drawArrow(ctx, minWidthHeight / 2);
- ctx.restore();
+ drawAll(ctx, current_angle);
}
if (wind_step < WIND_STEPS) {
wind_step = wind_step + 1;
@@ -232,9 +301,9 @@
wind_end = wind_end - 2 * Math.PI;
}
wind_step = 0;
- if (wind_timer != null) {
+ if (wind_timer !== null) {
clearInterval(wind_timer);
wind_start = current_angle;
}
wind_timer = setInterval(drawStep, WIND_TIME * 1000 / WIND_STEPS);
-}
\ No newline at end of file
+}
diff --git a/src/main/webapp/gadget.html b/src/main/webapp/gadget.html
new file mode 100644
index 0000000..1645963
--- /dev/null
+++ b/src/main/webapp/gadget.html
@@ -0,0 +1,13 @@
+
+
+
+ |
+
+
+ Loading...
+
+ |
+
+
+
+