Permalink
Browse files

Patch for only sending the guest OS type information once (on full up…

…date), fixed guest OS icons + description, switching to description tab and various other HTML warnings.

git-svn-id: http://vboxweb.googlecode.com/svn/trunk@46 729376a8-6c6b-11de-afdd-bb9f892af8c1
  • Loading branch information...
1 parent a88ce85 commit 0649da54d74dc4a429e11baa763c7d890f2b2cf7 vboxweb committed Aug 12, 2009
Showing with 110 additions and 83 deletions.
  1. +40 −28 VBoxWebSrv.py
  2. +2 −15 www/static/js/vboxGlobal.js
  3. +20 −19 www/static/js/vboxTabWidget.js
  4. +41 −9 www/static/js/vboxVirtualBox.js
  5. +7 −12 www/templates/index.html
View
@@ -54,6 +54,10 @@ class ConvertObjToJSONClass(simplejson.JSONEncoder):
def default(self, obj):
return convertObjToJSON(obj)
+#
+# @todo write autowrapper for attributes main-like classes below.
+# Currently this involves too much copying around.
+#
class jsHeader:
def __init__(self, ctx, arrMach, type, statusMessage = ""):
self.magic = "jsVBxWb"
@@ -64,10 +68,14 @@ def __init__(self, ctx, arrMach, type, statusMessage = ""):
self.updateType = type
self.statusMessage = statusMessage
-#
-# @todo write autowrapper for attributes main-like classes below.
-# Currently this involves too much copying around.
-#
+class jsVirtualBox:
+ def __init__(self, ctx):
+ arrOSTypes = ctx['global'].getArray(ctx['vb'], 'guestOSTypes')
+ self.arrGuestOSTypes = []
+ for type in arrOSTypes:
+ self.arrGuestOSTypes.append(jsGuestOSType(type))
+ self.numGuestOSTypes = len(self.arrGuestOSTypes)
+
class jsVRDPServer:
def __init__(self, ctx, vrdp):
self.enabled = vrdp.enabled
@@ -114,7 +122,7 @@ def __init__(self, ctx, machine):
self.name = machine.name
self.desc = machine.description
self.id = machine.id
- self.ostype = jsGuestOSType(ctx['vb'].getGuestOSType(machine.OSTypeId))
+ self.OSTypeId = machine.OSTypeId
self.CPUCount = machine.CPUCount
self.bootOrder = []
self.memorySize = machine.memorySize
@@ -260,8 +268,9 @@ def __init__(self, mach):
class VBoxPage:
def __init__(self, ctx):
self.ctx = ctx
- self.forceUpdate = False
- self.init = False
+
+ # Ugly COM stuff
+ self.initCOM = False
if sys.platform == 'win32':
self.vbox_stream = pythoncom.CoMarshalInterThreadInterfaceInStream(pythoncom.IID_IDispatch, self.ctx['vb'])
@@ -330,53 +339,59 @@ def onGuestPropertyChange(self, id, name, newValue, flags):
class Root(VBoxPage):
- def initPage(self):
- if self.init is False:
+ def registerCallbacks(self):
+ # Register IVirtualBox (global) callback
+ self.callbackVBox = self.ctx['global'].createCallback('IVirtualBoxCallback', VBoxMonitor, self)
+ self.ctx['vb'].registerCallback(self.callbackVBox)
+
+ def prepareCOM(self):
+ if self.initCOM is False:
if sys.platform == 'win32':
# Get the "real" VBox interface from the stream created in the class constructor above
import win32com
i = pythoncom.CoGetInterfaceAndReleaseStream(self.vbox_stream, pythoncom.IID_IDispatch)
self.ctx['vb'] = win32com.client.Dispatch(i)
-
- # We're done now
- self.init = True
+ self.initCOM = True
@cherrypy.expose
def vboxGetUpdates(self):
+ print "Page: vboxGetUpdates"
arrJSON = []
arrMach = []
# Add all machines that have changed (are dirty) to arrMach
for m in self.arrMach:
- if (m.isDirty is True) or (self.forceUpdate is True):
+ if (m.isDirty is True):
arrMach.append(m)
m.isDirty = False
- if len(arrMach) is len(self.arrMach):
+ if (len(arrMach) is len(self.arrMach)):
updateType = 0 # Full
else:
updateType = 1 # Differential
- # Add header
+ # Add header (must always come first atm)
arrJSON.append(jsHeader(self.ctx, arrMach, updateType))
+ # Add global VirtualBox object on full update
+ if updateType is 0:
+ arrJSON.append(jsVirtualBox(self.ctx))
+
# Add arrMach to the final JSON array
for m in arrMach:
arrJSON.append(jsMachine(self.ctx, m.mach))
- self.forceUpdate = False
-
- print "type %d, %d machines modified" %(updateType, len(arrMach))
+ print "Type %d, %d machines modified" %(updateType, len(arrMach))
if isSimpleJson:
return self.jsonPrinter(arrJSON, cls=ConvertObjToJSONClass)
else:
return self.jsonPrinter(arrJSON, default=convertObjToJSON)
@cherrypy.expose
def vboxVMAction(self, operation, uuid):
- print "vboxVMAction called with operation " + operation + " and uuid " + uuid
-
+ print "Page: vboxVMAction called with operation " + operation + " and uuid " + uuid
+ # Close session if opened
if operation == "startvm":
session = self.ctx['mgr'].getSessionObject(self.ctx['vb'])
progress = self.ctx['vb'].openRemoteSession(session, uuid, "headless", "")
@@ -421,7 +436,7 @@ def vboxVMAction(self, operation, uuid):
@cherrypy.expose
def vboxStartVM(self, uuid):
- print "vboxStartVM called with uuid " + uuid
+ print "Page: vboxStartVM called with uuid " + uuid
session = self.ctx['mgr'].getSessionObject(self.ctx['vb'])
progress = self.ctx['vb'].openRemoteSession(session, uuid, "headless", "")
# todo we shouldn't wait here, perform asynchronously
@@ -435,17 +450,14 @@ def vboxStartVM(self, uuid):
else:
return self.jsonPrinter(arrJSON, default=convertObjToJSON)
+ # Entry point when browser loads the whole page
@cherrypy.expose
def index(self):
+ print "Page: init"
- self.initPage()
-
- # Register IVirtualBox (global) callback
- self.callbackVBox = self.ctx['global'].createCallback('IVirtualBoxCallback', VBoxMonitor, self)
- self.ctx['vb'].registerCallback(self.callbackVBox)
-
+ self.prepareCOM()
+ self.registerCallbacks()
self.populateVMList()
- self.forceUpdate = True
file = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'www/templates/index.html')
return serve_file(file, content_type='text/html')
@@ -22,7 +22,7 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
-
+
VMState =
{
PoweredOff: 1,
@@ -36,7 +36,7 @@ VMState =
Saving: 9,
Restoring: 10,
Discarding: 11,
- SettingUp: 12
+ SettingUp: 12
};
var vboxGlobal = Class.create(
@@ -288,18 +288,5 @@ var vboxGlobal = Class.create(
default: break;
}
return strType;
- },
-
- vmGuestOSTypeDescription: function (osTypeId)
- {
- var strOS = osTypeId;
- switch (osTypeId)
- {
- /** @todo translate ID name to something more beautiful. */
-
- default:
- break;
- }
- return strOS;
}
});
@@ -126,17 +126,18 @@ var vboxTabWidget = Class.create(
var mach = curItem.machine();
var bootOrder = mach.jsonObject.bootOrder; /* A bit hacky, find a better way later! */
var strBootOrder = vbGlobal.deviceType(bootOrder[0])
- for(i=1; i<bootOrder.length; i++) {
- if(bootOrder[i] > 0){
+ for (i=1; i<bootOrder.length; i++)
+ {
+ if (bootOrder[i] > 0)
strBootOrder = strBootOrder + ", " + vbGlobal.deviceType(bootOrder[i]);
- }
}
var vrdpServer = new vboxIVRDPServerImpl(mach.getVRDPServer());
+ var guestOSType = vbGlobal.virtualBox().getGuestOSTypeById(mach.getOSTypeId());
var hardDiskAttachments = mach.getHardDiskAttachments();
jQuery("#tab-details-vm-general-name-val").text(curItem.name());
- jQuery("#tab-details-vm-general-osname-val").text(mach.getOSTypeId());
+ jQuery("#tab-details-vm-general-osname-val").text(guestOSType.getDescription());
jQuery("#tab-details-vm-system-ram-val").text(mach.getMemorySize() + tr(" MB"));
jQuery("#tab-details-vm-system-cpu-val").text(mach.getCPUCount());
@@ -153,20 +154,20 @@ var vboxTabWidget = Class.create(
{
attachment = new vboxIHardDiskAttachmentImpl(hardDiskAttachments[i]);
hardDisk = new vboxIHardDiskImpl(attachment.getHardDisk());
- if (attachment.getController() === 'IDE')
+ if (attachment.getController() === "IDE")
{
- port = (attachment.getPort() === 0) ? tr('Primary') : tr('Secondary');
- device = (attachment.getDevice() === 0) ? tr('Master') : tr('Slave');
+ port = (attachment.getPort() === 0) ? tr("Primary") : tr("Secondary");
+ device = (attachment.getDevice() === 0) ? tr("Master") : tr("Slave");
}
- else if (attachment.getController() === 'SATA')
+ else if (attachment.getController() === "SATA")
{
- port = 'Port ' + attachment.getPort();
- device = '';
+ port = tr("Port ") + attachment.getPort();
+ device = "";
}
- else if (attachment.getController() === 'SCSI')
+ else if (attachment.getController() === "SCSI")
{
- port = 'Port ' + attachment.getPort();
- device = '';
+ port = tr("Port ") + attachment.getPort();
+ device = "";
}
else
{
@@ -176,19 +177,19 @@ var vboxTabWidget = Class.create(
if (device != "")
device = ' ' + device;
- strHardDisk = hardDisk.getName() + ' (' + vbGlobal.hardDiskType(hardDisk.getType()) +
- ', ' + (hardDisk.getLogicalSize() / 1024) + ' GB)';
+ strHardDisk = hardDisk.getName() + " (" + vbGlobal.hardDiskType(hardDisk.getType()) +
+ ", " + (hardDisk.getLogicalSize() / 1024) + " GB)";
strListItem = '<div class="tab-details-vm-attribute">' +
- attachment.getController() + ' ' + port + device + ':' +
+ attachment.getController() + " " + port + device + ":" +
'</div><div class="tab-details-vm-value">' + strHardDisk +
'</div><div style="clear: both"></div>';
- jQuery("#tab-details-vm-harddisks-list").append("<li class='harddisks-list-item'>" + strListItem + "</li>");
+ jQuery("#tab-details-vm-harddisks-list").append('<li class="harddisks-list-item">' + strListItem + "</li>");
}
if (hardDiskAttachments.length <= 0)
{
jQuery("#tab-details-vm-harddisks-list").
- append("<li class='harddisks-list-item'>" + tr("No hard disks attached") + "</li>");
+ append('<li class="harddisks-list-item">' + tr("No hard disks attached") + "</li>");
}
},
@@ -295,7 +296,7 @@ var vboxTabWidget = Class.create(
invalidatePageDesc: function(curItem, pageSelected)
{
- var strDesc = curItem.machine().getDesc();
+ var strDesc = curItem.machine().getDescription();
if (strDesc == null || strDesc == "")
strDesc = tr("No description available.");
jQuery("#tab-desc-desc-val").text(strDesc);
@@ -47,6 +47,7 @@ var vboxVirtualBox = Class.create(
initialize: function()
{
this.mArrMachines = new Array();
+ this.mArrGuestOSTypes = new Array();
this.XMLHttpCatch = new Abstract.XMLHttpCatch();
this.checkForUpdates();
@@ -84,6 +85,17 @@ var vboxVirtualBox = Class.create(
this.receiveData("/vboxGetUpdates");
},
+ updateGuestOSTypes: function(res)
+ {
+ var iNumOSTypes = res.numGuestOSTypes;
+ this.mArrGuestOSTypes.clear();
+ for (var i = 0; i < iNumOSTypes; i++)
+ {
+ var guestOS = res.arrGuestOSTypes[i];
+ this.mArrGuestOSTypes[this.mArrGuestOSTypes.length] = new vboxIGuestOSTypeImpl(guestOS);
+ }
+ },
+
updateProcess: function(response)
{
// don't try to parse empty responses
@@ -97,29 +109,36 @@ var vboxVirtualBox = Class.create(
if ((res[0].magic != "jsVBxWb") || (res[0].ver != "1"))
throw "Invalid header!";
- /* did we get a status messsage to display? */
+ /* Did we get a status messsage to display? */
if (res[0].statusMessage)
vbGlobal.mVirtualBox.addMessage(res[0].statusMessage);
+ /* @todo Get rid of the res[INDEX] handling! This is very error
+ * prone and leads to confusing as more data will be added. */
+
var numUpdates = res[0].numMach;
var updateType = res[0].updateType;
switch (res[0].__class__)
{
case "jsHeader":
+ /* On full update type (0) wipe existing machines. */
+ if (updateType == 0)
+ {
+ this.clearMachines();
+ this.updateGuestOSTypes(res[1]);
+ }
+
+ /* Full or diff update. */
if (numUpdates > 0)
{
var newMach;
console.log("vboxVirtualBox::updateProcess: Updates for %d machine(s) ...", numUpdates);
- /* On full update type (0) wipe existing machines. */
- if (updateType == 0)
- this.clearMachines();
-
/* Add new or update existing machines. */
for (var i = 0; i < numUpdates; i++)
{
- arrJSON = res[i + 1];
+ arrJSON = (updateType == 0) ? res[i + 2] : res[i + 1];
newMach = new vboxIMachineImpl(arrJSON);
curMach = this.getMachineById(newMach.getId());
@@ -131,6 +150,7 @@ var vboxVirtualBox = Class.create(
{
console.log("vboxVirtualBox::updateProcess: Updating machine: %s", curMach.getName());
curMach.loadSettingsJSON(arrJSON);
+
}
}
@@ -190,9 +210,8 @@ var vboxVirtualBox = Class.create(
hours + ':' + minutes + ':' + seconds;
jQuery("#vmMessageTable").prepend('<tr><td class="message" nowrap="nowrap" style="width:100px">' +
- dateStr + '</td><td class="message" width="100%">' + message + '</td></tr>')
-
- },
+ dateStr + '</td><td class="message" width="100%">' + message + '</td></tr>');
+ },
addMachine: function(vboxMachineImpl)
{
@@ -242,6 +261,19 @@ var vboxVirtualBox = Class.create(
return undefined;
},
+ getGuestOSTypeById: function(id)
+ {
+ /** @todo Slow lookup, improve this! */
+ var l = this.mArrGuestOSTypes.length;
+ for (var i = 0; i < l; i++)
+ {
+ if (this.mArrGuestOSTypes[i].getId() == id)
+ return this.mArrGuestOSTypes[i];
+ }
+
+ return undefined;
+ },
+
startVM: function(id)
{
this.receiveData("/vboxVMAction?operation=startvm&uuid=" + id)
Oops, something went wrong.

0 comments on commit 0649da5

Please sign in to comment.