Added QueueMetrics XMLRPC PHP script for auto-lookups of recordings within the QueueMetrics interface

Updated QueueMetrics installation instructions and integration options documentation

git-svn-id: svn://192.168.202.10@1127 3d104415-ff17-0410-8863-d5cf3c621b8a
This commit is contained in:
mattf
2009-05-26 14:58:19 +00:00
parent 9398a29320
commit f919e3026c
3 changed files with 478 additions and 3 deletions
+185
View File
@@ -14,9 +14,14 @@ as of 2008-10-30, several validation and correction functions were added to the
Another very important issue to note is that just like with VICIDIAL on multi-server systems, if QueueMetrics data is being generated on a multi-server system the data will be corrupted if all of the servers are not on the same time. I strongly recommend getting ntp working properly on all servers in a VICIDIAL or QueueMetrics server cluster.
To be able to view stats for inbound and outbound calls properly you need to add each one individually in QueueMetrics "queues" and properly set whether each one is inbound or outbound. After that you can create a combined queue-alias with all of the campaigns and in-groups in it and it will tell you correctly the number of inbound and outbound calls.
Here is a short summary of the needed steps to install QueueMetrics on your system:
NOTE: further down in this document are updated installation instructions and instructions for installing on OpenSuSE 11.1.
First, get Sun Java SDK/JRE and install on your system.
NOTE: the GCJ java JRE available on most RedHat/Feroda/CentOS systems WILL NOT WORK
@@ -210,3 +215,183 @@ queuemetrics_pass VARCHAR(50),
queuemetrics_url VARCHAR(255),
queuemetrics_log_id VARCHAR(10) default 'VIC'
queuemetrics_eq_prepend VARCHAR(255) default 'NONE'
Instructions for setting up the XML RPC recording lookup php script:
Install PEAR XML_RPC libraries:
pear install XML_RPC-1.5.1
updated install instructions (2009-05-25):
wget http://www.mirrorgeek.com/apache.org/tomcat/tomcat-6/v6.0.18/bin/apache-tomcat-6.0.18.tar.gz
gunzip apache-tomcat-6.0.18.tar.gz
tar xvf apache-tomcat-6.0.18.tar
ln -s apache-tomcat-6.0.18 tomcat
cd apache-tomcat-6.0.18
/usr/local/tomcat/bin/startup.sh
At this point you should go here on your web browser to see if the tomcat installation went well:
http://192.168.1.100:8080/
If it did, then you want to add the following lines to your /etc/rc.d/rc.local file so that tomcat will start up on boot:
/usr/local/tomcat/bin/startup.sh
cd /usr/local
wget http://queuemetrics.com/download/QueueMetrics-1.5.3-trial.tar.gz
gunzip QueueMetrics-1.5.3-trial.tar.gz
tar xvf QueueMetrics-1.5.3-trial.tar
mv queuemetrics-1.5.3 /usr/local/tomcat/webapps/QM
cd /usr/local/tomcat/webapps/QM/WEB-INF
wget http://mirror.services.wisc.edu/mysql/Downloads/Connector-J/mysql-connector-java-3.0.10-stable.tar.gz
gunzip mysql-connector-java-3.0.10-stable.tar.gz
tar xvf mysql-connector-java-3.0.10-stable.tar
cp mysql-connector-java-3.0.10-stable/mysql-connector-java-3.0.10-stable-bin.jar ./lib/
At this point you should go here on your web browser to see if the tomcat installation went well:
http://ip-address:8080/QM
If you see a QueueMetrics page(probably with many errors), then installation went well up to this point.
You now need to add the database tables, configure the web.xml file and configuration.properties file for your system.
mysql
CREATE DATABASE queuemetrics;
GRANT ALL PRIVILEGES ON queuemetrics.* TO 'queuemetrics'@'localhost' IDENTIFIED BY 'javadude';
GRANT ALL PRIVILEGES ON queuemetrics.* TO queuemetrics@localhost IDENTIFIED BY 'javadude';
GRANT ALL PRIVILEGES ON queuemetrics.* TO queuemetrics@'%' IDENTIFIED BY 'javadude';
mysql --user=queuemetrics --password=javadude queuemetrics < /usr/local/apache-tomcat-6.0.18/webapps/QM/WEB-INF/README/queuemetrics_sample.sql
change the following in the configuration.properties file:
# This is the default queue log file.
default.queue_log_file=sql:P01
# audio recording lookup link, change the audioRpcServer to point to your server
audio.server=it.loway.app.queuemetrics.callListen.listeners.ClassicXmlRpcRecordings
audio.liveserver=it.loway.app.queuemetrics.callListen.RTlisteners.ClassicXmlRpcListenerRT
default.audioRpcServer=http://10.0.0.4/vicidial/xml_rpc_audio_server_vicidial.php
change the following in the web.xml file(change server IP):
<param-value>jdbc:mysql://10.0.0.4/queuemetrics?autoReconnect=true&amp;zeroDateTimeBehavior=convertToNull&amp;jdbcCompliantTruncation=false&amp;us
er=queuemetrics&amp;password=javadude</param-value>
</init-param>
OpenSuSE 11.1 installation instructions:
How to install Queue Metrics on OpenSuSE v.11.1 (32 or 64 bit) with a system that was installed with the ViciDial Group install script. Run them in this order to avoid funky java script bugs :D
1) Type: zypper in tomcat6 tomcat6-webapps
- Say yes to install, and say yes to license
2) Type: zypper in java-1_6_0-sun
- Say yes to install, and say yes to license
3) cd /usr/src
4) wget http://queuemetrics.com/download/QueueMetrics-1.5.3-trial.tar.gz
5) mkdir tars (incase it doesn't exist)
6) tar -xzf QueueMetrics-1.5.3-trial.tar.gz
7) mv QueueMetrics-1.5.3-trial.tar.gz ./tars/
8) mkdir /srv/tomcat6/webapps/QM
9) cp -r queuemetrics-1.5.3/* /srv/tomcat6/webapps/QM/
10) zypper in mysql-connector-java
11) cp /usr/share/java/mysql-connector-java.jar /srv/tomcat6/webapps/QM/WEB-INF/lib/
12) chkconfig tomcat6 on
13) mysql --execute="CREATE DATABASE queuemetrics;"
14) mysql queuemetrics --execute="GRANT ALL PRIVILEGES ON queuemetrics.* TO 'queuemetrics'@'localhost' IDENTIFIED BY 'javadude';"
15) mysql queuemetrics --execute="GRANT ALL PRIVILEGES ON queuemetrics.* TO queuemetrics@localhost IDENTIFIED BY 'javadude';"
16) mysql queuemetrics --execute="GRANT ALL PRIVILEGES ON queuemetrics.* TO queuemetrics@'%' IDENTIFIED BY 'javadude';"
17) mysql queuemetrics --user=queuemetrics --password=javadude < /srv/tomcat6/webapps/QM/WEB-INF/README/queuemetrics_sample.sql
18) rctomcat6 start
19) Edit /srv/tomcat6/webapps/QM/WEB-INF/configuration.properties and change the entry to the following:
- # This is the default queue log file.
- default.queue_log_file=sql:P01
20) Edit /srv/tomcat6/webapps/QM/WEB-INF/web.xml and change the IP address of the following entry:
- <param-value>jdbc:mysql://10.0.0.4/queuemetrics?autoReconnect=true&amp;zeroDateTimeBehavior=convertToNull&amp;jdbcCompliantTruncation=false&amp;user=queuemetrics&amp;password=javadude</param-value>
21) Go to http://<ip-addr>:8080/QM and it should tell you the schema is old, just click next or yes to everything and have fun
Example queue_log output generated by ViciDial:
+-----------+------------+----------------------+----------+------------+-----------------+-------------+------------+-------+-------+----------+------------------+
| partition | time_id | call_id | queue | agent | verb | data1 | data2 | data3 | data4 | serverid | unique_row_count |
+-----------+------------+----------------------+----------+------------+-----------------+-------------+------------+-------+-------+----------+------------------+
| P01 | 1243280596 | NONE | NONE | Agent/6666 | AGENTLOGIN | 6666@agents | | | | VIC | 1 |
| P01 | 1243280596 | NONE | NONE | Agent/6666 | PAUSEALL | NULL | | | | VIC | 2 |
| P01 | 1243280603 | NONE | NONE | Agent/6666 | UNPAUSEALL | NULL | | | | VIC | 1 |
| P01 | 1243280614 | V0525154325000035377 | TESTCAMP | NONE | ENTERQUEUE | NULL | 9998888112 | | | VIC | 1 |
| P01 | 1243280614 | V0525154325000035377 | TESTCAMP | Agent/6666 | CONNECT | 0 | | | | VIC | 2 |
| P01 | 1243280619 | V0525154328000213841 | TESTCAMP | NONE | ENTERQUEUE | NULL | 9999000016 | | | VIC | 1 |
| P01 | 1243280625 | V0525154328000213841 | TESTCAMP | NONE | EXITWITHTIMEOUT | 1 | | | | VIC | 1 |
| P01 | 1243280625 | V0525154328000213841 | TESTCAMP | NONE | CALLSTATUS | DROP | | | | VIC | 2 |
| P01 | 1243280626 | Y0525154346000213841 | TEST_IN | NONE | ENTERQUEUE | NULL | 9999000016 | | | VIC | 1 |
| P01 | 1243280631 | V0525154325000035377 | TESTCAMP | Agent/6666 | COMPLETEAGENT | 0 | 17 | 1 | | VIC | 1 |
| P01 | 1243280631 | NONE | NONE | Agent/6666 | PAUSEALL | NULL | | | | VIC | 2 |
| P01 | 1243280633 | NONE | NONE | Agent/6666 | UNPAUSEALL | NULL | | | | VIC | 1 |
| P01 | 1243280633 | V0525154325000035377 | TESTCAMP | Agent/6666 | CALLSTATUS | N | | | | VIC | 2 |
| P01 | 1243280646 | V0525154353000213842 | TESTCAMP | NONE | ENTERQUEUE | NULL | 9999000017 | | | VIC | 1 |
| P01 | 1243280646 | V0525154353000213842 | TESTCAMP | Agent/6666 | CONNECT | 0 | | | | VIC | 2 |
| P01 | 1243280650 | V0525154353000213842 | TESTCAMP | Agent/6666 | COMPLETEAGENT | 0 | 4 | 1 | | VIC | 1 |
| P01 | 1243280650 | NONE | NONE | Agent/6666 | PAUSEALL | NULL | | | | VIC | 2 |
| P01 | 1243280659 | V0525154353000213842 | TESTCAMP | Agent/6666 | CALLSTATUS | NP | | | | VIC | 1 |
| P01 | 1243280672 | Y0525154346000213841 | TEST_IN | NONE | EXITWITHTIMEOUT | 1 | | | | VIC | 1 |
| P01 | 1243280672 | Y0525154346000213841 | TEST_IN | NONE | CALLSTATUS | DROP | | | | VIC | 2 |
| P01 | 1243280673 | Y0525154433000213841 | TEST_IN2 | NONE | ENTERQUEUE | NULL | 9999000016 | | | VIC | 1 |
| P01 | 1243280686 | Y0525154433000213841 | TEST_IN2 | NONE | ABANDON | 1 | 1 | 3 | | VIC | 1 |
| P01 | 1243280940 | NONE | NONE | Agent/6666 | UNPAUSEALL | NULL | | | | VIC | 1 |
| P01 | 1243280940 | M0525154900000194239 | TESTCAMP | NONE | ENTERQUEUE | NULL | 9998888112 | | | VIC | 2 |
| P01 | 1243280940 | M0525154900000194239 | TESTCAMP | Agent/6666 | CONNECT | 0 | | | | VIC | 3 |
| P01 | 1243280965 | M0525154900000194239 | TESTCAMP | Agent/6666 | COMPLETEAGENT | 0 | 17 | 1 | | VIC | 1 |
| P01 | 1243280965 | NONE | NONE | Agent/6666 | PAUSEALL | NULL | | | | VIC | 2 |
| P01 | 1243280973 | M0525154900000194239 | TESTCAMP | Agent/6666 | CALLSTATUS | N | | | | VIC | 1 |
| P01 | 1243281049 | Y0525155049000194239 | TEST_IN2 | NONE | ENTERQUEUE | NULL | 9998888112 | | | VIC | 1 |
| P01 | 1243281052 | NONE | NONE | Agent/6666 | UNPAUSEALL | NULL | | | | VIC | 1 |
| P01 | 1243281057 | Y0525155049000194239 | TEST_IN2 | Agent/6666 | CONNECT | 3 | | | | VIC | 1 |
| P01 | 1243281073 | Y0525155049000194239 | TEST_IN2 | Agent/6666 | COMPLETEAGENT | 3 | 24 | 1 | | VIC | 1 |
| P01 | 1243281073 | NONE | NONE | Agent/6666 | PAUSEALL | NULL | | | | VIC | 2 |
| P01 | 1243281079 | Y0525155049000194239 | TEST_IN2 | Agent/6666 | CALLSTATUS | WN | | | | VIC | 1 |
| P01 | 1243281088 | NONE | NONE | Agent/6666 | UNPAUSEALL | NULL | | | | VIC | 1 |
| P01 | 1243281088 | M0525155128000194239 | TESTCAMP | NONE | ENTERQUEUE | NULL | 9998888112 | | | VIC | 2 |
| P01 | 1243281088 | M0525155128000194239 | TESTCAMP | Agent/6666 | CONNECT | 0 | | | | VIC | 3 |
| P01 | 1243281105 | M0525155128000194239 | TESTCAMP | Agent/6666 | COMPLETEAGENT | 0 | 7 | 1 | | VIC | 1 |
| P01 | 1243281105 | NONE | NONE | Agent/6666 | PAUSEALL | NULL | | | | VIC | 2 |
| P01 | 1243281111 | M0525155128000194239 | TESTCAMP | Agent/6666 | CALLSTATUS | NP | | | | VIC | 1 |
| P01 | 1243281112 | NONE | NONE | Agent/6666 | AGENTLOGOFF | 6666@agents | 516 | | | VIC | 1 |
+-----------+------------+----------------------+----------+------------+-----------------+-------------+------------+-------+-------+----------+------------------+
+1 -3
View File
@@ -1158,8 +1158,7 @@ if ($ACTION == 'manDiaLnextCaLL')
if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00037',$user,$server_ip,$session_name,$one_mysql_log);}
if ($DB) {echo "$stmt\n";}
$qm_conf_ct = mysql_num_rows($rslt);
$i=0;
while ($i < $qm_conf_ct)
if ($qm_conf_ct > 0)
{
$row=mysql_fetch_row($rslt);
$enable_queuemetrics_logging = $row[0];
@@ -1168,7 +1167,6 @@ if ($ACTION == 'manDiaLnextCaLL')
$queuemetrics_login = $row[3];
$queuemetrics_pass = $row[4];
$queuemetrics_log_id = $row[5];
$i++;
}
##### END QUEUEMETRICS LOGGING LOOKUP #####
###########################################
@@ -0,0 +1,292 @@
<?php
# xml_rpc_audio_server_vicidial.php
#
# Used for integration with QueueMetrics of audio recordings
#
# Copyright (C) 2009 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
# Copyright (C) 2007 Lenz Emilitri <lenz.loway@gmail.com> LICENSE: ????
#
# CHANGES
# 90525-1141 - First build
#
// $Id: xmlrpc_audio_server.php,v 1.3 2007/11/12 17:53:09 lenz Exp $
//
// This is an example of a remote audio XML-RPC server for QueueMetrics.
// In QueueMetrics, calls to this client are activated by entering its URL in
// the 'default.audioRpcServer' property.
//
// In order to make it very easy to customize, you should change the contents of the
// functions 'find_file()' and 'listen_call()' only. You can populate some or all of the
// return fields, according to the data you actually have. As the calling user is passed along,
// it's pretty easy to log who listened to which calls if you need to do it.
//
//
// IMPORTANT:
// in order to run this, you must have the XML_RPC module that comes with the PEAR library
// correctly installed on your PHP server. See http://pear.php.net
// "pear install XML_RPC-1.5.1"
//
require_once 'XML/RPC/Server.php';
// the following variables hold the return status for your file.
// Listening to a stored call
$FILE_FOUND = false;
$FILE_LISTEN_URL = "";
$FILE_LENGTH = "";
$FILE_ENCODING = "";
$FILE_DURATION = "";
// Listening to an ongoing call
$CALL_FOUND = false;
$CALL_LISTEN_URL = "";
$CALL_POPUP_WIDTH = "";
$CALL_POPUP_HEIGHT = "";
//
// This function must be implemented by the user.
//
function find_file( $ServerID, $AsteriskID, $QMUserID, $QMUserName )
{
global $FILE_FOUND;
global $FILE_LISTEN_URL;
global $FILE_LENGTH;
global $FILE_ENCODING;
global $FILE_DURATION;
require("dbconnect.php");
require("functions.php");
#############################################
##### START QUEUEMETRICS LOGGING LOOKUP #####
$stmt = "SELECT enable_queuemetrics_logging,queuemetrics_server_ip,queuemetrics_dbname,queuemetrics_login,queuemetrics_pass,queuemetrics_log_id FROM system_settings;";
$rslt=mysql_query($stmt, $link);
if ($DB) {echo "$stmt\n";}
$qm_conf_ct = mysql_num_rows($rslt);
if ($qm_conf_ct > 0)
{
$row=mysql_fetch_row($rslt);
$enable_queuemetrics_logging = $row[0];
$queuemetrics_server_ip = $row[1];
$queuemetrics_dbname = $row[2];
$queuemetrics_login = $row[3];
$queuemetrics_pass = $row[4];
$queuemetrics_log_id = $row[5];
}
##### END QUEUEMETRICS LOGGING LOOKUP #####
###########################################
if ($enable_queuemetrics_logging > 0)
{
$linkB=mysql_connect("$queuemetrics_server_ip", "$queuemetrics_login", "$queuemetrics_pass");
mysql_select_db("$queuemetrics_dbname", $linkB);
$stmt="SELECT time_id from queue_log where call_id='$AsteriskID' limit 1;";
$rslt=mysql_query($stmt, $linkB);
if ($DB) {echo "$stmt\n";}
$QM_ql_ct = mysql_num_rows($rslt);
if ($QM_ql_ct > 0)
{
$row=mysql_fetch_row($rslt);
$time_id = $row[0];
$time_id_end = ($time_id + 14400);
$lead_id = substr($AsteriskID, -9);
$lead_id = ($lead_id + 0);
$stmt = "SELECT start_epoch,length_in_sec,location from recording_log where start_epoch>=$time_id and start_epoch<=$time_id_end and lead_id='$lead_id' order by recording_id limit 1;";
$rslt=mysql_query($stmt, $link);
if ($DB) {echo "$stmt\n";}
$rl_ct = mysql_num_rows($rslt);
if ($rl_ct > 0)
{
$row=mysql_fetch_row($rslt);
$start_epoch = $row[0];
$length_in_sec = $row[1];
$location = $row[2];
if (strlen($location)>2)
{
$extension = substr($location, strrpos($location, '.') + 1);
if (ereg("mp3|gsm",$extension))
{$filesize = (2000 * $length_in_sec);}
else
{$filesize = (15660 * $length_in_sec);}
$URLserver_ip = $location;
$URLserver_ip = eregi_replace('http://','',$URLserver_ip);
$URLserver_ip = eregi_replace('https://','',$URLserver_ip);
$URLserver_ip = eregi_replace("\/.*",'',$URLserver_ip);
$stmt="select count(*) from servers where server_ip='$URLserver_ip';";
$rsltx=mysql_query($stmt, $link);
$rowx=mysql_fetch_row($rsltx);
if ($rowx[0] > 0)
{
$stmt="select recording_web_link,alt_server_ip from servers where server_ip='$URLserver_ip';";
$rsltx=mysql_query($stmt, $link);
$rowx=mysql_fetch_row($rsltx);
if (eregi("ALT_IP",$rowx[0]))
{
$location = eregi_replace($URLserver_ip, $rowx[1], $location);
}
}
$FILE_FOUND = true;
$FILE_LISTEN_URL = "$location";
$FILE_LENGTH = "$filesize";
$FILE_ENCODING = "$extension";
$FILE_DURATION = sec_convert($length_in_sec,'H');
}
else
{
$FILE_FOUND = false;
$FILE_LISTEN_URL = "";
$FILE_LENGTH = "0";
$FILE_ENCODING = "wav";
$FILE_DURATION = "0:00";
}
}
else
{
$FILE_FOUND = false;
$FILE_LISTEN_URL = "";
$FILE_LENGTH = "0";
$FILE_ENCODING = "wav";
$FILE_DURATION = "0:00";
}
}
else
{
$FILE_FOUND = false;
$FILE_LISTEN_URL = "";
$FILE_LENGTH = "0";
$FILE_ENCODING = "wav";
$FILE_DURATION = "0:00";
}
mysql_close($linkB);
}
# $FILE_FOUND = true;
# $FILE_LISTEN_URL = "http://listennow.server/$ServerID/$AsteriskID/$QMUserID/$QMUserName";
# $FILE_LENGTH = "125000";
# $FILE_ENCODING = "mp3";
# $FILE_DURATION = "1:12";
}
function listen_call( $ServerID, $AsteriskID, $Agent, $QMUserID, $QMUserName, $Direction )
{
global $CALL_FOUND;
global $CALL_LISTEN_URL;
global $CALL_POPUP_WIDTH;
global $CALL_POPUP_HEIGHT;
$CALL_FOUND = false;
$CALL_LISTEN_URL = "http://listennow.server/$ServerID/$AsteriskID/$QMUserID/$QMUserName/$Agent/$Direction";
$CALL_POPUP_WIDTH = "200";
$CALL_POPUP_HEIGHT = "250";
}
//
// This function does the XML-RPC call handling
// All the PHP's XML-RPC details are handled here.
//
function xmlrpc_find_file( $params ) {
global $FILE_FOUND;
global $FILE_LISTEN_URL;
global $FILE_LENGTH;
global $FILE_ENCODING;
global $FILE_DURATION;
$p0 = $params->getParam(0)->scalarval(); // server ID
$p1 = $params->getParam(1)->scalarval(); // Asterisk call ID
$p2 = $params->getParam(2)->scalarval(); // QM User ID
$p3 = $params->getParam(3)->scalarval(); // Qm user name
find_file( $p0, $p1, $p2, $p3 );
$response = new XML_RPC_Value(array(
new XML_RPC_Value( $FILE_FOUND, 'boolean' ),
new XML_RPC_Value( $FILE_LISTEN_URL ),
new XML_RPC_Value( $FILE_LENGTH ),
new XML_RPC_Value( $FILE_ENCODING ),
new XML_RPC_Value( $FILE_DURATION ),
), "array");
return new XML_RPC_Response($response);
}
function xmlrpc_listen_call_inbound( $params ) {
xmlrpc_listen_call( $params, "INBOUND" );
}
function xmlrpc_listen_call_outbound( $params ) {
xmlrpc_listen_call( $params, "OUTBOUND" );
}
function xmlrpc_listen_call( $params, $direction ) {
global $CALL_FOUND;
global $CALL_LISTEN_URL;
global $CALL_POPUP_WIDTH;
global $CALL_POPUP_HEIGHT;
$p0 = $params->getParam(0)->scalarval(); // server ID
$p1 = $params->getParam(1)->scalarval(); // asterisk call ID
$p2 = $params->getParam(2)->scalarval(); // agent code
$p3 = $params->getParam(3)->scalarval(); // QM user ID
$p4 = $params->getParam(3)->scalarval(); // QM user name
listen_call( $p0, $p1, $p2, $p3, $p4, $direction );
$response = new XML_RPC_Value(array(
new XML_RPC_Value( $CALL_FOUND, 'boolean' ),
new XML_RPC_Value( $CALL_LISTEN_URL ),
new XML_RPC_Value( $CALL_POPUP_WIDTH, 'int' ),
new XML_RPC_Value( $CALL_POPUP_HEIGHT, 'int' ),
), "array");
return new XML_RPC_Response($response);
}
//
// Instantiates a very simple XML-RPC audio server for QueueMetrics
//
$server = new XML_RPC_Server(
array(
'QMAudio.findStoredFile' => array(
'function' => 'xmlrpc_find_file'
),
'QMAudio.listenOngoingCall' => array(
'function' => 'xmlrpc_listen_call_inbound'
),
'QMAudio.listenOngoingCallOutbound' => array(
'function' => 'xmlrpc_listen_call_outbound'
),
),
1 // serviceNow
);
// $Log: xmlrpc_audio_server.php,v $
// Revision 1.3 2007/11/12 17:53:09 lenz
// Bug #182: queue direction for inbound/outbound call listen.
//
// Revision 1.2 2007/05/12 20:45:06 lenz
// Merge IMM4
//
// Revision 1.1.2.1 2007/04/03 17:43:06 lenz
// Prima versione.
//
//
//
//
?>