0

Merge branch 'JSObserver' of github.com:tswsl1989/Minecraft-Overviewer into JSObserver

This commit is contained in:
Andrew Chin
2012-06-10 15:00:31 -04:00
3 changed files with 84 additions and 20 deletions

View File

@@ -269,16 +269,39 @@ the form ``key = value``. Two items take a different form:, ``worlds`` and
This is used by default when the output is a terminal. Displays a text based This is used by default when the output is a terminal. Displays a text based
progress bar and some statistics. progress bar and some statistics.
``JSObserver`` ``JSObserver(outputdir[, minrefresh][, messages])``
This will display render progress on the output map in the bottom right This will display render progress on the output map in the bottom right
corner of the screen. ``JSObserver`` must be invoked with two parameters. corner of the screen. ``JSObserver``.
The first is output directory. For simplicity, specify this as ``outputdir`` * ``outputdir="<output directory path"``
and place this line after setting ``outputdir = "<output directory path>"``. Path to overviewer output directory. For simplicity, specify this
as ``outputdir=outputdir`` and place this line after setting
``outputdir = "<output directory path>"``.
**Required**
The second parameter is the minimum interval between progress updates in * ``minrefresh=<seconds>``
seconds. Progress information won't be written to file or requested by Progress information won't be written to file or requested by your
your web browser more frequently than this interval. web browser more frequently than this interval.
* ``messages=dict(totalTiles=<string>, renderCompleted=<string>, renderProgress=<string>)``
Customises messages displayed in browser. All three messages must be
defined as follows:
* ``totalTiles="Rendering %d tiles"``
The ``%d`` format string will be replaced with the total number of
tiles to be rendered.
* ``renderCompleted="Render completed in %02d:%02d:%02d"``
The three format strings will be replaced with the number of hours.
minutes and seconds taken to complete this render.
* ``renderProgress="Rendered %d of %d tiles (%d%%)"``
The three format strings will be replaced with the number of tiles
completed, the total number of tiles and the percentage complete
Format strings are explained here: http://docs.python.org/library/stdtypes.html#string-formatting
All format strings must be present in your custom messages.
:: ::
from observer import JSObserver from observer import JSObserver

View File

@@ -142,17 +142,24 @@ overviewer.views.ProgressView = Backbone.View.extend({
this.el.id = 'progressDiv'; this.el.id = 'progressDiv';
this.el.innerHTML = 'Current Render Progress'; this.el.innerHTML = 'Current Render Progress';
overviewer.map.controls[google.maps.ControlPosition.BOTTOM_RIGHT].push(this.el); overviewer.map.controls[google.maps.ControlPosition.BOTTOM_RIGHT].push(this.el);
this.hidden = true; this.el.hidden = true;
$.ajaxSetup({cache: false}); $.ajaxSetup({cache: false});
}, },
updateProgress: function() { updateProgress: function() {
e = this; e = this;
$.getJSON('progress.js', null, function(d){ $.getJSON('progress.json', null, function(d){
e.el.hidden = false; if (!(d == null||d=='')) {
e.el.innerHTML = d['message']; e.el.hidden = false;
if (d.update > 0) { e.el.innerHTML = d['message'];
setTimeout("e.updateProgress()", d.update); if (d.update > 0) {
setTimeout("e.updateProgress()", d.update);
} else {
setTimeout("e.updateProgress()", 60000);
e.el.innerHTML="Hidden - d.update < 0";
e.el.hidden = true;
}
} else { } else {
e.el.innerHTML="Hidden - !!d==false";
e.el.hidden = true; e.el.hidden = true;
} }
}); });

View File

@@ -18,6 +18,7 @@ import logging
import progressbar import progressbar
import sys import sys
import os import os
import json
class Observer(object): class Observer(object):
"""Base class that defines the observer interface. """Base class that defines the observer interface.
@@ -170,21 +171,44 @@ class JSObserver(Observer):
"""Display progress on index.html using JavaScript """Display progress on index.html using JavaScript
""" """
def __init__(self, outputdir, minrefresh=5): def __init__(self, outputdir, minrefresh=5, messages=False):
"""Initialise observer """Initialise observer
outputdir must be set to the map output directory path outputdir must be set to the map output directory path
minrefresh specifies the minimum gap between requests, in seconds minrefresh specifies the minimum gap between requests, in seconds [optional]
messages is a dictionary which allows the displayed messages to be customised [optional]
""" """
self.last_update = -11 self.last_update = -11
self.last_update_time = -1 self.last_update_time = -1
self._current_value = -1 self._current_value = -1
self.minrefresh = 1000*minrefresh self.minrefresh = 1000*minrefresh
self.logfile = open(os.path.join(outputdir, "progress.js"), "w+", 0) self.json = dict()
if (messages == False):
self.messages=dict(totalTiles="Rendering %d tiles", renderCompleted="Render completed in %02d:%02d:%02d", renderProgress="Rendered %d of %d tiles (%d%%)")
elif (isinstance(messages, dict)):
if ('totalTiles' in messages and 'renderCompleted' in messages and 'renderProgress' in messages):
self.messages = messages
else:
raise Exception("JSObserver: messages parameter must be a dictionary with three entries: totalTiles, renderCompleted and renderProgress")
else:
raise Exception("JSObserver: messages parameter must be a dictionary with three entries: totalTiles, renderCompleted and renderProgress")
if not os.path.exists(outputdir):
raise Exception("JSObserver: Output directory specified (%s) doesn't appear to exist. This should be the same as the Overviewer output directory")
self.logfile = open(os.path.join(outputdir, "progress.json"), "w+", 0)
self.json["message"]=""
self.json["update"]=self.minrefresh
self.json["messageTime"]=time.time()
json.dump(self.json, self.logfile)
self.logfile.flush()
def start(self, max_value): def start(self, max_value):
self.logfile.seek(0) self.logfile.seek(0)
self.logfile.write('{"message": "Rendering %d tiles", "update": %s}' % (max_value, self.minrefresh))
self.logfile.truncate() self.logfile.truncate()
self.json["message"] = self.messages["totalTiles"] % (max_value)
self.json["update"] = self.minrefresh
self.json["messageTime"] = time.time()
json.dump(self.json, self.logfile)
self.logfile.flush() self.logfile.flush()
self.start_time=time.time() self.start_time=time.time()
self._set_max_value(max_value) self._set_max_value(max_value)
@@ -199,8 +223,15 @@ class JSObserver(Observer):
self.end_time = time.time() self.end_time = time.time()
duration = self.end_time - self.start_time duration = self.end_time - self.start_time
self.logfile.seek(0) self.logfile.seek(0)
self.logfile.write('{"message": "Render completed in %dm %ds", "update": "false"}' % (duration//60, duration - duration//60))
self.logfile.truncate() self.logfile.truncate()
hours = duration // 3600
duration = duration % 3600
minutes = duration // 60
seconds = duration % 60
self.json["message"] = self.messages["renderCompleted"] % (hours, minutes, seconds)
self.json["update"] = -1 # Initially this was set to False, but that runs into some JS strangeness. -1 is less nice, but works
self.json["messageTime"] = time.time()
json.dump(self.json, self.logfile)
self.logfile.close() self.logfile.close()
def is_finished(self): def is_finished(self):
@@ -222,10 +253,13 @@ class JSObserver(Observer):
""" """
self._current_value = current_value self._current_value = current_value
if self._need_update(): if self._need_update():
refresh = max(1500*(time.time() - self.last_update_time), self.minrefresh) refresh = max(1500*(time.time() - self.last_update_time), self.minrefresh) // 1
self.logfile.seek(0) self.logfile.seek(0)
self.logfile.write('{"message": "Rendered %d of %d tiles (%d%%)", "update": %d }' % (self.get_current_value(), self.get_max_value(), self.get_percentage(), refresh))
self.logfile.truncate() self.logfile.truncate()
self.json["message"] = self.messages["renderProgress"] % (self.get_current_value(), self.get_max_value(), self.get_percentage())
self.json["update"] = refresh
self.json["messageTime"] = time.time()
json.dump(self.json, self.logfile)
self.logfile.flush() self.logfile.flush()
self.last_update_time = time.time() self.last_update_time = time.time()
self.last_update = current_value self.last_update = current_value