[asterisk-commits] rizzo: branch rizzo/astobj2 r46342 - in /team/rizzo/astobj2/static-http/obeli...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Thu Oct 26 11:57:39 MST 2006


Author: rizzo
Date: Thu Oct 26 13:57:38 2006
New Revision: 46342

URL: http://svn.digium.com/view/asterisk?rev=46342&view=rev
Log:
save this stuff, it is reasonably usable now (layout to be improved)


Added:
    team/rizzo/astobj2/static-http/obelisk/
    team/rizzo/astobj2/static-http/obelisk/README   (with props)
    team/rizzo/astobj2/static-http/obelisk/css/
    team/rizzo/astobj2/static-http/obelisk/css/leftstructure.css   (with props)
    team/rizzo/astobj2/static-http/obelisk/css/main.css   (with props)
    team/rizzo/astobj2/static-http/obelisk/images/
    team/rizzo/astobj2/static-http/obelisk/images/call_btn.png   (with props)
    team/rizzo/astobj2/static-http/obelisk/images/ic-telefono01.png   (with props)
    team/rizzo/astobj2/static-http/obelisk/images/logo.gif   (with props)
    team/rizzo/astobj2/static-http/obelisk/images/logo.jpg   (with props)
    team/rizzo/astobj2/static-http/obelisk/images/phone_gra.png   (with props)
    team/rizzo/astobj2/static-http/obelisk/images/phone_grn.png   (with props)
    team/rizzo/astobj2/static-http/obelisk/images/phone_red.png   (with props)
    team/rizzo/astobj2/static-http/obelisk/index.html   (with props)
    team/rizzo/astobj2/static-http/obelisk/script/
    team/rizzo/astobj2/static-http/obelisk/script/data.js   (with props)
    team/rizzo/astobj2/static-http/obelisk/script/dump.js   (with props)
    team/rizzo/astobj2/static-http/obelisk/script/layout.js   (with props)
    team/rizzo/astobj2/static-http/obelisk/script/main.js   (with props)
    team/rizzo/astobj2/static-http/obelisk/script/sprintf.js   (with props)
    team/rizzo/astobj2/static-http/obelisk/script/utils.js   (with props)

Added: team/rizzo/astobj2/static-http/obelisk/README
URL: http://svn.digium.com/view/asterisk/team/rizzo/astobj2/static-http/obelisk/README?rev=46342&view=auto
==============================================================================
--- team/rizzo/astobj2/static-http/obelisk/README (added)
+++ team/rizzo/astobj2/static-http/obelisk/README Thu Oct 26 13:57:38 2006
@@ -1,0 +1,14 @@
+OBELISK PROJECT (temporary name)
+
+AUTHORS:
+	Michele Barsanti, Paolo Bernini, Luigi Rizzo
+	(C) 2006 Universita` di Pisa
+
+GOALS
+	This project aim is to be a portable and user-friendly Asterisk Operator Panel
+	Written in javascript and using the embedded http
+	interface in asterisk.
+
+INSTALL
+	just dump the obelisk directory into static-http
+	and then call http://your.host:port/asterisk/static/obelisk/index.html

Propchange: team/rizzo/astobj2/static-http/obelisk/README
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/rizzo/astobj2/static-http/obelisk/README
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/rizzo/astobj2/static-http/obelisk/README
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: team/rizzo/astobj2/static-http/obelisk/css/leftstructure.css
URL: http://svn.digium.com/view/asterisk/team/rizzo/astobj2/static-http/obelisk/css/leftstructure.css?rev=46342&view=auto
==============================================================================
--- team/rizzo/astobj2/static-http/obelisk/css/leftstructure.css (added)
+++ team/rizzo/astobj2/static-http/obelisk/css/leftstructure.css Thu Oct 26 13:57:38 2006
@@ -1,0 +1,86 @@
+/** leftstructure.css
+ *
+ * Describes the look and feel of peers buttons
+ */
+
+/* general properties for button containers */
+.buttonContainer {
+	position: relative; top: 10px; /* top spacing. XXX to be revised */
+	width: 225px; height: auto;	/* standard dimensions */
+	padding: 10px; margin: 5px;	/* standard padding */
+}
+
+/* containers for phone buttons */
+#operatorNode{
+	border: 1px dashed black;
+	margin-top: 15px;
+}
+
+#busyPeers{
+	border: 1px solid red; 
+}
+
+#onLinePeers{	
+	border: 1px solid green; 
+}
+
+#offLinePeers{
+	border: 1px solid gray; 
+}
+
+/* individual phone buttons are a container (peerButton)
+ * with three elements in them: peerIcon, peerNumber, peerState
+ */
+.peerButton {	/* telephone icon, name and status */
+	position: relative;	/* needed to become reference point for children */
+	border: 1px solid blue;
+	background-color: #66CCFF;
+	width: 220px; height: 53px;
+	margin: 2px;
+	cursor: pointer;	/* changes cursor when we move on it */
+	font-size: 10px;
+}
+
+/* styles for peer sections: icon on the left, Number, state and Info (operator, etc.) */
+.peerIcon {
+	position: absolute;
+	margin: 2px;
+}
+
+.peerNumber {
+	position: absolute;
+	top: 5px;
+	left: 55px;	/* leave room for peerIcon */
+	font-size: 12px;
+	font-weight: bold;
+}
+
+.peerState {
+	position: absolute;
+	top: 20px;
+	left: 110px;
+}
+
+.peerInfo {
+	position: absolute; top: 5px; right: 10px;
+	font-size: 12px;
+	font-weight: bold;
+}
+
+/* the 'Change Operator' button */
+#changeButton {
+	position: relative;
+	border: 1px solid blue;
+	width: 220px; margin: 2px;
+	background-color: #3366FF;
+	cursor: pointer; color: #FFFF00;
+	font-weight: bold;
+	text-align: center;
+}
+/* and the 'Double click...' message */
+#changeText {
+	margin: 2px;
+	color: red;
+	font-weight: bold;
+}
+/* end of file */

Propchange: team/rizzo/astobj2/static-http/obelisk/css/leftstructure.css
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/rizzo/astobj2/static-http/obelisk/css/leftstructure.css
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/rizzo/astobj2/static-http/obelisk/css/leftstructure.css
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: team/rizzo/astobj2/static-http/obelisk/css/main.css
URL: http://svn.digium.com/view/asterisk/team/rizzo/astobj2/static-http/obelisk/css/main.css?rev=46342&view=auto
==============================================================================
--- team/rizzo/astobj2/static-http/obelisk/css/main.css (added)
+++ team/rizzo/astobj2/static-http/obelisk/css/main.css Thu Oct 26 13:57:38 2006
@@ -1,0 +1,113 @@
+/* style for the main document */
+BODY{
+	font-family: "Verdana";
+	font-size: 10px;
+	padding: 0px;
+	color: #000000;
+}
+
+#header{	/* username, password and various buttons */
+	position: relative;	
+	margin-top: 15px;	
+	padding-top: 4px; padding-bottom: 4px; padding-left: 4px;
+	border-top: 1px solid black;
+	border-bottom: 1px solid black;
+	background-color: #55BBFF;
+	width: 100%; /* height: 75px; */
+	font-size: 14px; font-weight: bold;
+}
+
+#logo{	/* the obelisk logo */
+	position: absolute;
+	top: 0px;
+	right: 100px;
+	z-index: 1;	/* keep high */
+}
+
+#root{
+	position: relative;
+}
+
+#rightNode{
+	/* border: 1px solid black; */
+	width: 550px; height: auto;
+	padding: 10px; margin: -7px;
+	position: absolute; left: 280px; top: 5px;
+	visibility: hidden; z-index: 2;
+}
+
+#informationNode{
+	position: relative;
+	border: 1px solid blue;
+	background-color: #66CCFF;
+	width: auto;
+	margin: 2px; padding: 4;
+}
+
+#informationTitle{
+	position: relative;
+}
+
+#status{
+	height: 60px;
+}
+
+.information{
+	border: 1px solid black;
+	background-color: #3399FF;
+	width: auto; height: 30px;
+	margin-bottom: 2px;
+	padding-left: 5px;
+}
+
+.action{
+	border: 1px solid black;
+	background-color: #3399FF;
+	width: auto; height: auto;
+	margin-bottom: 2px;
+	padding: 5px;
+	height: 50px;
+}
+
+#actionNode{
+	position: relative;
+	border: 1px solid blue;
+	background-color: #66CCFF;
+	width: auto;
+	margin: 2px; padding: 4;
+}
+
+#hiderNode{
+	border: 1px solid blue;
+	background-color: #66CCFF;
+	width: auto; height: 32px;
+	margin: 2px; padding: 4;
+	cursor: pointer;
+}
+
+.titleText{
+	position: relative;
+	left: 50px;
+	font-family: "Verdana";
+	font-size: 12px;
+	font-weight: bold;
+	text-align: left;
+}
+
+#titleImage{
+	position: absolute;
+	top: -3px;
+	left: 0px;
+}
+
+#redirectNumber{
+	background-color: #3399FF;
+	border: 1px solid black;
+	width: 80px; text-align: center;
+}
+
+#callButton {
+	position: absolute; top: 15px; left: 350px;
+	cursor: pointer;
+}
+/* end of file */

Propchange: team/rizzo/astobj2/static-http/obelisk/css/main.css
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/rizzo/astobj2/static-http/obelisk/css/main.css
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/rizzo/astobj2/static-http/obelisk/css/main.css
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: team/rizzo/astobj2/static-http/obelisk/images/call_btn.png
URL: http://svn.digium.com/view/asterisk/team/rizzo/astobj2/static-http/obelisk/images/call_btn.png?rev=46342&view=auto
==============================================================================
Binary file - no diff available.

Propchange: team/rizzo/astobj2/static-http/obelisk/images/call_btn.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: team/rizzo/astobj2/static-http/obelisk/images/ic-telefono01.png
URL: http://svn.digium.com/view/asterisk/team/rizzo/astobj2/static-http/obelisk/images/ic-telefono01.png?rev=46342&view=auto
==============================================================================
Binary file - no diff available.

Propchange: team/rizzo/astobj2/static-http/obelisk/images/ic-telefono01.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: team/rizzo/astobj2/static-http/obelisk/images/logo.gif
URL: http://svn.digium.com/view/asterisk/team/rizzo/astobj2/static-http/obelisk/images/logo.gif?rev=46342&view=auto
==============================================================================
Binary file - no diff available.

Propchange: team/rizzo/astobj2/static-http/obelisk/images/logo.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: team/rizzo/astobj2/static-http/obelisk/images/logo.jpg
URL: http://svn.digium.com/view/asterisk/team/rizzo/astobj2/static-http/obelisk/images/logo.jpg?rev=46342&view=auto
==============================================================================
Binary file - no diff available.

Propchange: team/rizzo/astobj2/static-http/obelisk/images/logo.jpg
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: team/rizzo/astobj2/static-http/obelisk/images/phone_gra.png
URL: http://svn.digium.com/view/asterisk/team/rizzo/astobj2/static-http/obelisk/images/phone_gra.png?rev=46342&view=auto
==============================================================================
Binary file - no diff available.

Propchange: team/rizzo/astobj2/static-http/obelisk/images/phone_gra.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: team/rizzo/astobj2/static-http/obelisk/images/phone_grn.png
URL: http://svn.digium.com/view/asterisk/team/rizzo/astobj2/static-http/obelisk/images/phone_grn.png?rev=46342&view=auto
==============================================================================
Binary file - no diff available.

Propchange: team/rizzo/astobj2/static-http/obelisk/images/phone_grn.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: team/rizzo/astobj2/static-http/obelisk/images/phone_red.png
URL: http://svn.digium.com/view/asterisk/team/rizzo/astobj2/static-http/obelisk/images/phone_red.png?rev=46342&view=auto
==============================================================================
Binary file - no diff available.

Propchange: team/rizzo/astobj2/static-http/obelisk/images/phone_red.png
------------------------------------------------------------------------------
    svn:executable = *

Propchange: team/rizzo/astobj2/static-http/obelisk/images/phone_red.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: team/rizzo/astobj2/static-http/obelisk/index.html
URL: http://svn.digium.com/view/asterisk/team/rizzo/astobj2/static-http/obelisk/index.html?rev=46342&view=auto
==============================================================================
--- team/rizzo/astobj2/static-http/obelisk/index.html (added)
+++ team/rizzo/astobj2/static-http/obelisk/index.html Thu Oct 26 13:57:38 2006
@@ -1,0 +1,69 @@
+<html>
+	<head>
+		<title>Obelisk AOI - Asterisk Operator Interface </title>
+		<link rel="stylesheet" href="css/main.css" type="text/css" media="screen">
+		<link rel="stylesheet" href="css/leftstructure.css" type="text/css" media="screen">
+		
+		<script type="text/javascript" language="JavaScript" src="script/utils.js"></script>
+		<script type="text/javascript" language="JavaScript" src="script/data.js"></script>
+		<script type="text/javascript" language="JavaScript" src="script/main.js"></script>
+		<script type="text/javascript" language="JavaScript" src="script/layout.js"></script>
+	</head>
+	<body id="thebody" onload="main()">
+		<img id="logo" src="images/logo.gif" alt="Obelisk's logo"/>
+                <div id="debug">Debugging window<br>
+			<select id="sel" size="10"></select>
+		</div>
+		<div id="header">Obelisk AOI
+			<a id="toggle_debug" href=""  onclick="return toggle_debug(); return false">toggle debug</a><br>
+			<div id="login">
+				<form onSubmit="return do_login()">
+					Username: <input id="username">
+					Password: <input type="password" id="pass">
+					<input type="submit" value="Login">
+					<input type="button" value="Logout" onclick="return do_logout()">
+				</form>
+				<br>
+					Context: <input id="context">
+					Operator Call: <input id="callNumber" onkeypress="do_opcall(event)">
+			</div>
+		</div>
+		<div id="root">
+			<div class="buttonContainer" id="operatorNode">
+				<div id="changeText">Double click on the operator's Peer</div>
+				<div id="changeButton" onClick="changeOperator()">Change Operator</div>
+			</div>
+			<div id="leftNode">
+				<div class="buttonContainer" id="busyPeers"></div>
+				<div class="buttonContainer" id="onLinePeers"></div>
+				<div class="buttonContainer" id="offLinePeers"></div>
+			</div>
+			<div id="rightNode">
+				<div id="informationNode">
+					<div id="informationTitle" class="information">
+						<img id="titleImage" src="images/ic-telefono01.png"/>
+						<p class="titleText">Peer detailed information</p>
+					</div>
+					<div id="number" class="information"></div>
+					<div id="status" class="information"></div>
+				</div>
+				<div id="actionNode">
+					<div class="action">
+						<form id="redirectionForm">
+							<p>Redirect to other peer:
+								<select name="number" id="redirectNumber"></select>
+								<input type="button" value="Redirect" id="redirectButton" onclick="redirect()"/>
+							</p>
+						</form>
+						<a id="callButton" onclick="call()"><img src="images/call_btn.png"/></a>
+					</div>
+				</div>
+				<div id="hiderNode">
+					<div id="hider"  class="information">
+						<p>Click to hide details</p>
+					</div>
+				</div>
+			</div> <!-- End of DIV rightNode -->
+		</div> <!-- End of DIV root -->
+	</body>
+</html>

Propchange: team/rizzo/astobj2/static-http/obelisk/index.html
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/rizzo/astobj2/static-http/obelisk/index.html
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/rizzo/astobj2/static-http/obelisk/index.html
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: team/rizzo/astobj2/static-http/obelisk/script/data.js
URL: http://svn.digium.com/view/asterisk/team/rizzo/astobj2/static-http/obelisk/script/data.js?rev=46342&view=auto
==============================================================================
--- team/rizzo/astobj2/static-http/obelisk/script/data.js (added)
+++ team/rizzo/astobj2/static-http/obelisk/script/data.js Thu Oct 26 13:57:38 2006
@@ -1,0 +1,313 @@
+// data.js
+// Definition of some data structures for obelisk
+
+var /*const*/ ICON_OFFLINE = "images/phone_gra.png";
+var /*const*/ ICON_ONLINE = "images/phone_grn.png";
+var /*const*/ ICON_BUSY = "images/phone_red.png";
+
+var activePeers = new Peers();
+
+// create server request, hiding browser dependencies
+function newXmlHttpInstance() {
+        if (window.XMLHttpRequest) { // native XMLHttpRequest e.g. mozilla
+                try {
+                        return new XMLHttpRequest();
+                } catch (e) {}
+        } else if (window.ActiveXObject) { // branch for IE/Windows ActiveX version
+                try {
+                        return new ActiveXObject("Msxml2.XMLHTTP");
+                } catch (e) {
+                        try {
+                                return new ActiveXObject("Microsoft.XMLHTTP");
+                        } catch (e) {}
+                }
+        }
+
+        return null;
+}
+
+// handler for document coming in. We cannot pass an argument ? */
+function xml_done(arg) {
+	requests.done();
+}
+
+/*
+ * schedule requests, both periodic and one-shot.
+ * They are inserted in a list by deadline.
+ */
+function RequestsQueue() {
+	this.first = null;	// head of the list
+	this.run = 1;		// set to enable activity.
+	this.cur = null;	// request under service
+	this.latecount = 0;	// how many requests were late ?
+	this.working = false;	// a request is either scheduled or running.
+	this.cur_xml = null;
+
+	// we create request objects only in here.
+	function Request(strUrl, handler, intDelay) {
+		this.url = strUrl;
+		this.responseHandler = handler;
+		
+		this.delay = (intDelay == undefined) ? 0 : intDelay;
+		this.due = time();
+
+		this.next = null;
+		deb("new request for " + strUrl + " delay " + intDelay + " due at " + this.due);
+	}
+
+	this.schedule = function(url, handler, period) {
+		if (this.run != 1)
+			return;
+		var obj = new Request(url, handler, period);
+		this.push(obj);
+
+		if (!this.working) { // first one, and no request pending
+			deb("send request " + obj.url);
+			this.sendReq(); // request accepted
+		}
+	}
+
+	this.login = function() { this.run = 1; }
+	this.logout = function() { this.run = 0; }
+		
+	this.push = function(obj) {	// insert by deadline
+		deb("push " + obj.url);
+		var prev = null, cur = this.first;
+		while (cur != null && obj.due >= cur.due) {
+			prev = cur;
+			cur = cur.next;
+		}
+		deb("-- insert between " + (prev == null ? "none" : prev.due) +
+			" and " + (cur == null ? "none" : cur.due) );
+		if (prev == null) {
+			this.first = obj;
+		} else {
+			prev.next = obj;
+		}
+		obj.next = cur;
+	}
+
+	this.pop = function() {
+		var cur = this.first;
+		this.first = this.first.next;
+		return cur;
+	}
+
+	this.done = function() {
+		// deb("xmlHttpChange state " + cur_xml.readyState + " for " + this.cur.url);
+		if (this.cur_xml.readyState != 4)    // no Answer received yet.
+			return;
+		deb("done with status " + this.cur_xml.status + " for " + this.cur.url);
+		if (this.cur_xml.status != 200) {    // Answer OK
+			alert("There was a problem retrieving the XML data:\n" + this.cur_xml.statusText);
+		} else if (this.cur.responseHandler != null) {
+			this.cur.responseHandler(this.cur_xml.responseXML);
+		}
+		if (this.run != 1) {	// drop everything
+			while (this.first != null)
+				this.pop();
+			deb("logging out");
+			this.run = 0;
+			return;
+		}
+		if (this.cur.delay != NO_REPEAT) {
+			var tmin = time() + 1000;	// make sure requests are at least 1sec apart
+			this.cur.due += this.cur.delay;
+			if (this.cur.due < tmin)
+				this.cur.due = tmin;
+			this.push(this.cur);
+		}
+		this.cur = null;
+		if (this.first == null) {
+			this.working = false;
+			return;
+		}
+		deb("next is " + this.first.url + " due at " + this.first.due);
+		var t = this.first.due - time();
+		if (t < 100) {	// 100 milliseconds is a short time, run it now.
+			if (t < 0) {
+				this.latecount++;
+				deb("we are " + (-t) + "ms late [" + this.latecount + "], scheduling now.");
+			}
+			this.sendReq();
+		} else {	// else wait UPDATE_DELAY
+			setTimeout("requests.sendReq()", t);
+		}
+	}
+
+	this.sendReq = function() {
+		this.working = true;
+		this.cur = this.pop();
+		//deb("send now " + req.url);
+		this.cur_xml = newXmlHttpInstance(); // initialization
+		this.cur_xml.onreadystatechange = xml_done;
+		try {
+			this.cur_xml.open("GET", this.cur.url, true);
+			this.cur_xml.send(null);
+		} catch (e) {
+			alert("Cannot send " + this.cur.url);
+		}
+	}
+}
+
+/** Peer class
+ * Peers base data structure
+ */
+function Peer(name, strStatus, boolOnline) {
+	this.number = name; // number (name) of peer
+	this.status = strStatus;
+	this.online = (boolOnline != undefined) ? boolOnline : false;
+
+	this.node = null;
+	
+	this.calling = null; // number of receiver (sip calls)
+	this.channel = null; // channel owned by the peer
+	this.action = null; // performing action ( "Calling" | "Chatting with" )
+	
+	if (this.online)
+		activePeers.addPeer(this);
+	
+	this.ring = function(strChannel) {
+		this.node.status.style.color = "navy";
+		this.node.status.style.fontWeight = "bold";
+		this.node.status.firstChild.nodeValue = "[Ringing]";
+		this.channel = strChannel;
+		
+		if (currentNode == this.number)
+			insertInfo(this.number);
+	}
+	
+	this.call = function(strReceiver, strChannel, channelState) {
+		this.calling = strReceiver;
+		this.channel = strChannel;
+		this.action = (channelState == "Up") ? "Chatting with" : "Calling";
+		
+		// performs action to show the calling state of the peer
+		if ( strReceiver != "Extern/Unknown" )
+			this.node.status.firstChild.nodeValue = this.action + " " + this.calling;
+		else
+			this.node.status.firstChild.nodeValue = this.action + "..." ;
+						
+		this.node.icon.src = this.getIconURL();
+		
+		if (currentNode == this.number)
+			insertInfo(this.number);
+		
+		this.position("busyPeers");
+	}
+	
+	this.reset = function() {
+		this.calling = null;
+		this.channel = null;
+		this.action = null;
+	
+		// performs actions to show that the peer is free
+		this.node.status.style.color = "black";
+		this.node.status.style.fontWeight = "normal";
+		this.state(this.online);		
+				
+		if (currentNode == this.number)
+			insertInfo(this.number);
+	}
+
+	this.state = function(boolOnline) {
+		if (this.online && !boolOnline)
+			activePeers.delPeer(this);
+		else if (!this.online && boolOnline)
+			activePeers.addPeer(this);
+		this.online = boolOnline;
+
+		this.node.icon.src = this.getIconURL();
+	
+		if (this.online && this.channel == null) {// we change the text only if we are not calling anybody
+			this.node.status.firstChild.nodeValue = "on-line";
+			if (this.status == "OK")
+				this.node.status.firstChild.nodeValue = "line free";
+			this.position("onLinePeers");
+		} else if (this.channel == null) {
+			this.node.status.firstChild.nodeValue = "off-line";
+			this.position("offLinePeers");
+		} else {
+			this.position("busyPeers");
+		}
+		
+	}
+	
+	this.getIconURL = function() {
+		if (!this.online)
+			return ICON_OFFLINE;
+		if ( this.calling == null )
+			return ICON_ONLINE;
+		return ICON_BUSY;
+	}
+
+	this.position = function(strPos) {
+		if (this.number == operatorNumber)
+			return;
+		if (this.node.parentNode.id == strPos)
+			return;	
+	
+		this.node.parentNode.removeChild(this.node);
+		document.getElementById(strPos).appendChild(this.node);
+	}
+
+};
+
+/**
+ * Peers array and linked data
+ */
+function Peers() {
+	this.peer_list = new Array();
+	this.changed = false;
+	this.length = 0;
+	
+	this.calls = 0; // number of running calls
+	this.channels = 0; // number of active channels
+	
+	this.addNewPeer = function(number,status,online) {
+		//deb("call addNewPeer for " + name + " status " + status + " online " + online);
+		var newPeer = new Peer(number,status,online);
+		this.addPeer(newPeer);
+		return newPeer;
+	}
+	
+	this.addPeer = function(p) {
+		//deb("call addPeer for " + p.number);
+		if (this.peer_list[p.name] == null)
+			this.count++;
+		this.peer_list[p.number] = p;	// reference, not copy ?
+		this.changed = true;
+	}
+	
+	this.delPeer = function(peer) {
+		if (this.peer_list[peer.number] != null) {
+			delete this.peer_list[peer.number];
+			this.count--;
+			this.changed = true;
+		}
+	}
+	
+	this.getPeer = function(name) {
+		return this.peer_list[name];
+	}
+	
+	// same as getPeer ?
+	this.getPeerByUsername = function(name) {
+		return this.peer_list[name];
+	}
+	
+	this.resetAll = function() {
+		for (var i in this.peer_list)
+			this.peer_list[i].reset();
+	}
+	
+	this.count = function() {
+		return this.peer_list.length;
+	}
+	
+	this.ck = function() {
+		deb("resetting change flags for peers");
+		this.changed = false;
+	}
+}
+/* end of file */

Propchange: team/rizzo/astobj2/static-http/obelisk/script/data.js
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/rizzo/astobj2/static-http/obelisk/script/data.js
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/rizzo/astobj2/static-http/obelisk/script/data.js
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: team/rizzo/astobj2/static-http/obelisk/script/dump.js
URL: http://svn.digium.com/view/asterisk/team/rizzo/astobj2/static-http/obelisk/script/dump.js?rev=46342&view=auto
==============================================================================
--- team/rizzo/astobj2/static-http/obelisk/script/dump.js (added)
+++ team/rizzo/astobj2/static-http/obelisk/script/dump.js Thu Oct 26 13:57:38 2006
@@ -1,0 +1,90 @@
+// return a string version of a thing, without name. 
+// calls recursive function to actually traverse content. 
+function dump(content)
+{ 
+	return dumpRecur(content,0,true) + "\n"; 
+} 
+
+// put content into an alert box
+function dumpAlert(label,content)
+{
+	alert(label+"\n"+dump(content)); 
+} 
+
+function dumpConfirm(label,content)
+{ 
+	confirm(label+"\n"+dump(content)); 
+} 
+
+// recursive function traverses content, returns string version of thing
+// content: what to dump. 
+// indent: how far to indent. 
+// neednl: true if need newline, false if not
+function dumpRecur(content,indent,neednl)
+{ 
+	var out = ""; 
+	if (typeof(content) == 'function')
+		return 'function'; 
+	else if (dumpIsArray(content)) { 	// handle real arrays in brackets
+		if (neednl)
+			out += "\n"+dumpSpaces(indent); 
+		out+="[ "; 
+		var inside = false; 
+		for (var i=0; i<content.length; i++) { 
+			if (inside) 
+				out+=",\n"+dumpSpaces(indent+1); 
+			else 
+				inside=true; 
+			out+=dumpRecur(content[i],indent+1,false); 
+		} 
+		out+="\n"+dumpSpaces(indent)+"]"; 
+	} else if (dumpIsObject(content)) { 	// handle objects by association 
+		if (neednl)
+			out+="\n"+dumpSpaces(indent); 
+		out+="{ "; 
+		var inside = false; 
+		for (var i in content) { 
+			if (inside) 
+				out+=",\n"+dumpSpaces(indent+1); 
+			else 
+				inside = true; 
+			out+="'" + i + "':"
+				+ dumpRecur(content[i],indent+1,true); 
+		} 
+		out+="\n"+dumpSpaces(indent)+"}"; 
+	} else if (typeof(content) == 'string') { 
+		out+="'" + content + "'"; 
+	} else { 
+		out+=content; 
+	} 
+	return out; 
+} 
+
+// print n groups of two spaces for indent
+function dumpSpaces (n) { 
+	var out = ''; 
+	for (var i=0; i<n; i++) out += '  '; 
+		return out; 
+} 
+
+// Naive way to tell an array from an object: 
+// it's an array if it has a defined length
+function dumpIsArray (thing) { 
+	deb(typeof(thing) + " has len " + thing.length);
+	if (typeof(thing) != 'object')
+		return false; 
+	if (thing.length == 'undefined')
+		return false; 
+	return true; 
+} 
+
+// Naive way to tell an array from an object: 
+// it's an array if it has a defined length
+function dumpIsObject (thing) { 
+	deb(typeof(thing) + " has len " + thing.length);
+	if (typeof(thing) != 'object')
+		return false; 
+	if (thing.length != 'undefined')
+		return false; 
+	return true; 
+} 

Propchange: team/rizzo/astobj2/static-http/obelisk/script/dump.js
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/rizzo/astobj2/static-http/obelisk/script/dump.js
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/rizzo/astobj2/static-http/obelisk/script/dump.js
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: team/rizzo/astobj2/static-http/obelisk/script/layout.js
URL: http://svn.digium.com/view/asterisk/team/rizzo/astobj2/static-http/obelisk/script/layout.js?rev=46342&view=auto
==============================================================================
--- team/rizzo/astobj2/static-http/obelisk/script/layout.js (added)
+++ team/rizzo/astobj2/static-http/obelisk/script/layout.js Thu Oct 26 13:57:38 2006
@@ -1,0 +1,230 @@
+// play with the layout
+var rootNode = null;
+var leftNode = null;
+var rightNode = null;
+var operatorNode = null;
+
+var currentNode = false;
+
+var bgColor = null;
+
+
+// create a list of div for show peers
+function initLayout() {
+	rootNode = document.getElementById("root");
+	leftNode = document.getElementById("leftNode");
+	rightNode = document.getElementById("rightNode");
+	operatorNode = document.getElementById("operatorNode");
+
+	document.getElementById("changeButton").onmouseover = changeStyle;
+	document.getElementById("changeButton").onmouseout = changeStyle;	
+	document.getElementById("hiderNode").onclick = hideDetails;
+
+	document.getElementById("redirectionForm").style.visibility = "hidden";
+	if (operatorNumber == null)
+		document.getElementById("changeButton").style.visibility = "hidden";
+	else
+		document.getElementById("changeText").style.visibility = "hidden";
+}
+
+// build the info (typically the 'operator' string) for a node.
+function add_info(node, text) {
+	node.info = document.createElement("div");
+	node.info.className = "peerInfo";
+	node.info.appendChild(document.createTextNode(text));
+	node.appendChild(node.info);
+
+	operatorNode.insertBefore(node, document.getElementById("changeText"));
+}
+
+/* creates a peer entry */
+function createPeerButton(peer) {
+	peer.node = document.createElement("div");
+	var ref = peer.node; // fast reference
+	ref.id = peer.number; // Needed for the click event handling
+	ref.className = "peerButton";
+	ref.title = "Info on " + peer.number;
+
+	var x;
+	// Set up text
+	x = document.createElement("div");
+	x.className = "peerNumber";
+	x.appendChild(document.createTextNode(peer.number));
+	ref.appendChild(x);
+	
+	// Set up icon and state. they need to be attribute as they are modified.
+	ref.icon = document.createElement("img");
+	ref.icon.className = "peerIcon";
+	ref.icon.src = peer.getIconURL();	// icon changes based on status
+	ref.appendChild(ref.icon);
+
+	ref.status = document.createElement("div");
+	ref.status.className = "peerState";
+	ref.status.appendChild(document.createTextNode("[STATUS]"));
+	ref.appendChild(ref.status);
+
+	ref.onmouseover = changeStyle;
+	ref.onmouseout = changeStyle;
+	ref.onclick = showDetails;
+	ref.ondblclick = selectAsOperator;
+
+	// place in the appropriate section
+	if (peer.number == operatorNumber) {
+		add_info(ref, "Operator");
+	} else {	// missing other info, go into offline.
+		document.getElementById("offLinePeers").appendChild(ref);
+	}
+	
+	peer.state(peer.online);
+}
+
+/* display the big window on the right with node info,
+ * updating fields and hiding/showing it
+ */
+function insertInfo(identification) {
+	var numberNode = document.getElementById("number");
+	var statusNode = document.getElementById("status");
+	var redirectionForm = document.getElementById("redirectionForm");
+	var redirectNumber = document.getElementById("redirectNumber");
+	var callButton = document.getElementById("callButton");
+	var peer = peers.getPeer(identification);
+
+	callButton.title = "Call operator (" + operatorNumber + ")";
+	
+	// remove old information if present
+	if (currentNode != false) {
+		while (numberNode.hasChildNodes())
+			numberNode.removeChild(numberNode.firstChild);
+		while (statusNode.hasChildNodes())
+			statusNode.removeChild(statusNode.firstChild);
+		if (activePeers.changed) {
+			while (redirectNumber.hasChildNodes())
+				redirectNumber.removeChild(redirectNumber.firstChild);
+		}
+	}
+	
+	currentNode = identification;
+
+	// insert number info
+	var ref = document.createElement("P");
+	ref.innerHTML = "<b>Number:</b> " + peer.number;
+	numberNode.appendChild(ref);
+
+	// insert status info
+	var firstLine = document.createElement("P");
+	
+	str = "Status: ";
+	str += (peer.online) ? "Connected" : "Not Connected";
+	str += " - " + peer.status;
+	firstLine.appendChild(document.createTextNode(str));
+	if (peer.status == "OK") // is this a general law? (status=OK <=> outgoingline)
+		firstLine.appendChild(document.createTextNode(" (this is an outgoing line)"));
+	statusNode.appendChild(firstLine);
+
+	// manage action and status info
+	if (activePeers.changed) { // we update the list only if there were changes
+		deb("rebuilding redirect list");
+		for (var i in activePeers.peer_list) {
+			var dst = activePeers.peer_list[i].number;
+			var option = document.createElement("option");
+			option.value = dst;
+			option.appendChild(document.createTextNode(dst));
+			redirectNumber.appendChild(option);
+		}
+		
+		activePeers.ck(); // checked
+	}
+
+	if (peer.calling != null && rightNode.style.visibility == "visible" && peer.number != operatorNumber) {
+		// in this case 
+		statusNode.appendChild(document.createTextNode(peer.action + " " + peer.calling));
+		redirectionForm.style.visibility = "visible";
+		callButton.style.visibility = "visible";
+	} else if (peer.channel != null && rightNode.style.visibility == "visible" && peer.number != operatorNumber) {
+		statusNode.appendChild(document.createTextNode("Ringing"));
+		redirectionForm.style.visibility = "hidden";
+		callButton.style.visibility = "hidden";
+	} else if (peer.online == true && rightNode.style.visibility == "visible" && peer.number != operatorNumber) {
+		redirectionForm.style.visibility = "hidden";
+		callButton.style.visibility = "visible";
+	} else {
+		if (peer.number == operatorNumber) {
+			if (peer.calling != null) {
+				statusNode.appendChild(document.createTextNode(peer.action + " " + peer.calling));
+			} else if (peer.channel != null) {
+				statusNode.appendChild(document.createTextNode("Ringing"));
+			}
+		}
+		redirectionForm.style.visibility = "hidden";
+		callButton.style.visibility = "hidden";
+	}
+	
+	if (peer.status == "OK") // this peer is an external channel (outgoing line)
+		callButton.style.visibility = "hidden"; // than it can not be "called" directly
+}
+
+
+
+/**************************/
+/* EVENT HANDLERS         */
+/**************************/
+
+function changeStyle(evt) { // Mozilla pass the Event Object to the function, IE don't
+	if (window.ActiveXObject)
+		evt = window.event;
+	if (evt.type == "mouseover") { 
+		this.bgColor = (this.bgColor == null) ? this.style.backgroundColor : this.bgColor;
+		this.style.backgroundColor = "#3399FF";
+	} else if (evt.type == "mouseout") {
+		this.style.backgroundColor = this.bgColor;
+		this.bgColor = null;
+	}
+}
+
+function showDetails(evt) {
+	if (operatorNumber == null)
+		return false;
+
+	rightNode.style.visibility = "visible";
+	insertInfo(this.id);
+}
+
+function changeOperator() {
+	var operator = peers.getPeer(operatorNumber);
+		
+	operator.node.className = "peerButton";
+	operator.node.removeChild(operator.node.info);
+
+	document.getElementById("changeButton").style.visibility = "hidden";
+	document.getElementById("changeText").style.visibility = "visible";
+	
+	operatorNumber = null;
+	operator.state(operator.online);
+	eraseCookie("operator");
+}
+
+function selectAsOperator(evt) {
+	if (operatorNumber != null)
+		return;
+
+	if (this.status.firstChild.nodeValue == "line free") {
+		alert("CHANGING OPERATOR'S PEER:\nYou can not select an outgoing line");
+		return false;
+	}
+	
+	this.parentNode.removeChild(this);
+	operatorNumber = this.id;	
+	
+	add_info(this, "Operator");
+
+	document.getElementById("changeButton").style.visibility = "visible";
+	document.getElementById("changeText").style.visibility = "hidden";
+	
+	createCookie("operator", operatorNumber);
+}
+
+function hideDetails(evt) {
+	document.getElementById("redirectionForm").style.visibility = "hidden";
+	document.getElementById("callButton").style.visibility = "hidden";
+	document.getElementById("rightNode").style.visibility = "hidden";
+}

Propchange: team/rizzo/astobj2/static-http/obelisk/script/layout.js
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/rizzo/astobj2/static-http/obelisk/script/layout.js
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/rizzo/astobj2/static-http/obelisk/script/layout.js
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: team/rizzo/astobj2/static-http/obelisk/script/main.js
URL: http://svn.digium.com/view/asterisk/team/rizzo/astobj2/static-http/obelisk/script/main.js?rev=46342&view=auto
==============================================================================
--- team/rizzo/astobj2/static-http/obelisk/script/main.js (added)
+++ team/rizzo/astobj2/static-http/obelisk/script/main.js Thu Oct 26 13:57:38 2006
@@ -1,0 +1,179 @@
+/**
+ * Obelisk version 2 - 2006.10.24
+ * We only have two config parameters
+ */
+
+var /*const*/ UPDATE_DELAY = 2000; // how often to update the display
+
+var AMI_base = "/asterisk/mxml?Action=";	// base command for AMI commands
+
+/* the constructor of Request() accepts a repetition interval as an argument.
+ * an argument of 0 means one-shot, hence we define the following constant
+ * (Request() is in data.js)
+ */
+var /*const*/ NO_REPEAT = 0;
+
+var operatorNumber;	// stores the operator peer number
+
+var peers = new Peers();	// the peers we want to display
+
+var requests = new RequestsQueue(); // pointer to the Requests list
+
+/*
+ * Handlers for the various commands we support
+ */
+
+// extracts information about sip peers from the xml response.
+function sipLoadPeers(xmlDoc) {
+	var success = xmlDoc.getElementsByTagName("generic").item(0).getAttribute("response");
+
+	if (success != "Success")
+		return;
+	for (var i = 1; (sipResponse = xmlDoc.getElementsByTagName("generic").item(i)).getAttribute("event") != "PeerlistComplete"; i++){
+		var sipName = sipResponse.getAttribute("objectname");
+		var sipStatus = sipResponse.getAttribute("status");
+		var sipHost = sipResponse.getAttribute("ipaddress");
+		var online = (sipHost == "-none-") ? false : true;
+		var peer = peers.getPeer(sipName);
+		if (peer != null) {
+			peer.state(online); // the peer is already in list, we only update its state
+		} else {
+			createPeerButton(peers.addNewPeer(sipName, sipStatus, online));
+		}
+	}
+}
+
+// extracts information about the status of channels
+function updateChannelsState(xmlDoc) {

[... 483 lines stripped ...]


More information about the asterisk-commits mailing list