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... + +
+
+